Compare commits

...

146 Commits

Author SHA1 Message Date
Wayne Stambaugh 2eaa9236f2 Tag release version 5.1.6. 2020-05-11 14:27:08 -04:00
Jeff Young e4bab37b62 Don't try and run drawing tools in ModEdit with no module selected.
Fixes: lp:1836673
* https://bugs.launchpad.net/kicad/+bug/1836673

(cherry picked from commit 02eb1d2c62)
2020-05-09 17:41:56 +01:00
Jeff Young 105c9c71ee Don't let point editor interrupt other operations.
Fixes: lp:1832416
* https://bugs.launchpad.net/kicad/+bug/1832416

(cherry picked from commit ae8daee83c)
2020-05-09 17:41:56 +01:00
Jon Evans e135229ca6 Don't try to draw a zone that has no outline
Fixes #4352

(cherry picked from commit 366673d995)
2020-05-07 17:54:00 -04:00
jean-pierre charras 97dea6ede5 Gerbview: Fix a crash Don't try to close an empty polygon on G37 command.
Can happens with malformed Gerber files.
From Master, commit 528ebf8.
2020-05-07 09:55:13 +02:00
jean-pierre charras d871a92d1c library viewers: fix a focus issue that prevent using arrow keys in lib or fp lists.
Once the gal canvas hsad the focus, it was not possible to use arrow keys in library
or symbols or fp lists even after clicking on an item.

This focus issue is now fixed.

From the fix in Master
2020-05-03 20:23:41 +02:00
jean-pierre charras a152aa125b Footprint editor: fix a crash when a graphic item is selected and the
measurement tool is active and closing the frame, or selecting a new footprint.
I am guessing it was a use after delete data.

Fixes #4302
https://gitlab.com/kicad/code/kicad/issues/4302
2020-05-03 09:03:32 +02:00
jean-pierre charras 4e217d4028 SVG plotter: fix some issues: incorrect bitmap size and missing lines in header.
From master branch.
2020-04-24 16:52:50 +02:00
Jeff Young e5da7a4606 Fix via printing.
LAYER_VIAS needs to get set for them to print at all, and GetLOD
needs too look at the view layer visibiilties, not the board layer
visibilities.

Also implements a more pad-like strategy for printing blind/buried
vias when printing one layer per page (where the top/bottom arcs
don't make sense).

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

(cherry picked from commit dce42612d3)
2020-04-20 20:29:05 +01:00
Jeff Young faace3090c Add specific selection updating when adding 3D models.
This keeps us from being at the receiving end of wxWidgets' vagaries.

Fixes https://gitlab.com/kicad/code/kicad/issues/3760
2020-04-19 22:43:32 +01:00
jean-pierre charras d3e2345f94 Dxf import: fix a bug that disable import of data inside blocks 2020-04-19 13:32:59 +02:00
jean-pierre charras a3e087ab51 Pcbnew: Fix crashes when delete footprint text in some cases.
Fixes #4221
https://gitlab.com/kicad/code/kicad/issues/4221
2020-04-18 20:00:26 +02:00
jean-pierre charras 3a614a8ea1 Legacy plugin: fix incorrect number of copper layers after loading a .brd file. 2020-04-18 19:58:45 +02:00
Marcus Comstedt 9cb60dcdf5 Cairo GAL: fix incorrect use of pixman formats
Fixes https://gitlab.com/kicad/code/kicad/issues/3970

(cherry-picked from 55ac575a88)
2020-04-15 01:29:50 +01:00
Jon Evans af6db68816 Defer image surface destruction until next paint
Fixes #4043

(cherry picked from commit 23c1baae8e)
2020-04-15 01:18:55 +01:00
Adam Wolf 305ed0b65a For macOS, fix KICAD_BUNDLE_LIBS in ogltest.
(Cherry-picked from e143ecbf40)
2020-04-10 20:09:34 +01:00
jean-pierre charras 263efb41e8 Gerbview: fix incorrect rendering of oval vertical standard aperture with hole.
Fix also incorrect display of dcode size in toolbal: was Y size, X size.
Now is X size, Y size as expected.

From master branch
2020-04-10 16:26:38 +02:00
jean-pierre charras d6312c7b92 Gerbview: add a error message for invalid files missing G74 or G75 commands.
They are mandatory to read arc coordinates.
2020-04-10 13:38:11 +02:00
Jeff Young b31af4891d Be smarter about determining if there are modules in the selection list.
The old algorithm would delete modules if another module was in the
list, which was not the intention.

Fixes https://gitlab.com/kicad/code/kicad/issues/4175
2020-04-09 00:07:07 +01:00
Adam Wolf 0ba08f57f2 Add macOS KICAD_BUNDLE_LIBS search path for bundle fixup.
(cherry-picked from ac20428b82)
2020-04-03 01:39:31 +01:00
Wayne Stambaugh a2d7881afe Fix cherry pick error on previous commit. 2020-04-02 16:09:25 -04:00
Wayne Stambaugh d79e598bf8 Eeschema: fix symbol cache library look up bug.
Use an underscore character instead of a semicolon between the library
ID library nickname and symbol name in library ID search strings when
looking up symbols in the cache library since that is how they are saved
when creating the cache library.  This fixes rescuing missing symbols
from the cache when they have been removed from the original library and
preventing a broken symbol link indicator from being shown when a symbol
is removed from the library.

Add some defensive testing to make sure the library passed to function
SchGetLibPart() is actually the cache library.

(cherry picked from commit f6d7ef367d)
2020-04-02 16:04:59 -04:00
jean-pierre charras a6a39cb842 Gerber plotter: Non horiz or vertical oval pads: better plot output:
These pads were plotted as a segment. This is not the right way:
Pads must be flashed or plotted as regions, not painted.
They are now plotted as Gerber regions round rectangle pads.
These regions are similar to flashed pads.

From Master branch, commit de7154e8e.
2020-04-02 19:50:59 +02:00
Wayne Stambaugh 5d0883c0e4 Eeschema: fix rescue multiple unit symbol bug.
The code that checked for pin conflicts to determine if a symbol needed
rescued did not check either the pin convert setting so it was possible
for a pin from the other convert on symbols that do not have identical
units to appear to not have a pin conflict.  Add tests for pin unit and
convert setting to prevent that from breaking the comparison.  This must
have always been broken.

Fix the symbol preview widget to prevent drawing all symbols on top of
each other (if we need to do this the code will have to be revised) and
also show the convert if valid.

Fix broken symbol cache library when saving alias symbols.

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

(cherry picked from commit e91f1f57dd)
2020-04-02 09:31:25 -04:00
Seth Hillbrand e6d49424cf PNS: Don't link unroutable items
The joint map only works for items that are routable, so don't bother
adding unroutable items as this only takes additional time to process

Fixes #3976 | https://gitlab.com/kicad/code/kicad/issues/3976

(cherry picked from commit 9769e1020b)

Fixes https://gitlab.com/kicad/code/kicad/issues/4143
2020-04-01 08:31:57 -07:00
Seth Hillbrand 72abcd5991 Correct cyrillic 'f' in newstroke
The lowercase greek phi had been used which did not match the cyrillic
f.  We use the variant of phi that includes the full strokes instead.

Fixes #3898 | https://gitlab.com/kicad/code/kicad/issues/3898

(cherry picked from commit 39a45f2a81)
2020-04-01 08:31:14 -07:00
jean-pierre charras 9c2bb85858 3D viewer: fix a minor problem: to many rotations when typing
Shift+z or Shift+y more than once.

From master, commit 00d9e77e
2020-03-31 17:48:50 +02:00
Jeff Young e9b059ee94 Re-implement change from cbef95256b
Fixes: lp:4103
* https://bugs.launchpad.net/kicad/+bug/4103
2020-03-30 20:24:08 +01:00
Ian McInerney 7a913844e2 Fix discrepancy between ASCII and CSV fp pos files
(based on 570ea62b64)

Fixes https://gitlab.com/kicad/code/kicad/issues/3897
2020-03-30 10:42:15 +01:00
jean-pierre charras f8be7e1f57 Gerber X2 format: Set default values to Enable X2 format 2020-03-29 15:37:36 +02:00
jean-pierre charras d5c43c4675 Gerber: fix a minor issue in OBLONG standard aperture: - incorrect (too big) bounding box. - HitTest did not test the exact shape. 2020-03-27 16:19:22 +01:00
jean-pierre charras 85fa6d8025 3D viewer: apply patch from master 04d6ea982.
The 3D viewer does not show the issue on solder paste layer having
negative clearance.
However the bug was here and not seen just because some draw code was different:
The code tried to draw outlines with segments having a negative thickness.
It happens mainly on solder paste layers.
2020-03-27 10:36:14 +01:00
Ian McInerney 6b2a8f54a1 Check for file writability before saving part
This is a 5.1 only fix for this crash. Fixing in master requires
a major refactor of the library writability detection code.

Fixes https://gitlab.com/kicad/code/kicad/issues/3864
2020-03-25 13:23:49 +00:00
jean-pierre charras bd1fb845b1 3D viewer: fix a minor issue in solder paste rect pads:
the solder paste mask clearance was no taken in account
for rect and trap shapes.
2020-03-25 13:47:48 +01:00
jean-pierre charras 9c64c9af5d Kicad manager: fix an issue on Windows when killing Kicad.
For some obscure reason, on Windows, when killing Kicad from the Windows task manager
if a editor frame (schematic, library, board editor or fp editor) is open and has
some edition to save, OnCloseWindow is run twice *at the same time*, creating race
conditions between OnCloseWindow() code.

Fixes #4072
https://gitlab.com/kicad/code/kicad/issues/4072
2020-03-25 09:51:12 +01:00
jean-pierre charras 1057eceb2f Gerber plotter: plot round rectangle pads using a region with arcs.
Previously, the region was a usual polygon with arc approximated by segment.
Using a region with arcs is a better way because it allows CAM tools to
identify this region as a round-rect pad.

Similar to master branch, commit 9cb3333d05.
2020-03-22 08:31:25 +01:00
Wayne Stambaugh 445bc75319 3D Viewer: fix broken check for write image permission check.
Fixes https://gitlab.com/kicad/code/kicad/issues/4081

(cherry picked from commit d8e99dc5be)
2020-03-21 17:20:04 -04:00
jean-pierre charras 4fb7ee02cd Kicad: unzip project: fix issues: - files with no extension were skipped. - subdirs were ignored. 2020-03-21 14:08:38 +01:00
Wayne Stambaugh ad11b7ebd0 3D viewer: fix double warning attempting to save screen shot file.
Fixes https://gitlab.com/kicad/code/kicad/issues/4028.

(cherry picked from commit fc20f9f0b2)
2020-03-16 13:09:02 -04:00
Seth Hillbrand 5d9bda6f97 Partial revert of 134a7ba85
The margin fix prevented some schematics from printing.  Reverting in
favor of transitioning to the Cairo print base in eeschema

(cherry picked from commit 9de7547c25)
2020-03-13 11:54:09 -07:00
jean-pierre charras 54be07c17d Pcbnew: Set default solder mask min size to 0.
When the solder mask min size is > 0, pads are no longer flashed or regions items.
Good Gerber files need pads flashed or regions items.

Non 0 solder mask min size is reserved to special cases (home made PCBs for instance)

From master branch.
2020-03-12 20:47:21 +01:00
jean-pierre charras 2c7ab3a28e Pcbnew, Gerber output: always generates Aperture Attributes.
Previously, for historical reasons, they were added only if
Include Netlist Attributes option was on.

But Aperture Attributes have nothing to do with Netlist Attributes, and good
Gerber files must include them.

From master branch
2020-03-12 17:00:55 +01:00
jean-pierre charras 3cc3c1bbd3 Zones: fix a crash when adding a zone cutout to a zone having already holes
From master branch
2020-03-12 14:49:36 +01:00
jean-pierre charras ddedf2e046 Annotate dialog: fix incorrect list of changes in complex hierarchies
Previously, to list changes, the Reference field was used in comparisons.
In complex hierarchies, this is incorrect: the Reference field contains
only the last displayed reference, not the reference of a given sheet.

The comparison uses now the sheet paths for ref and unit selection.

From a similar fix in master branch.
2020-03-09 18:28:39 +01:00
Seth Hillbrand a60c339f85 PCAD: Handle mirrored text
Mirrored text rotates clockwise in the mirror, so we need to invert the
sign for aligning mirrored PCAD text

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

(cherry picked from commit 058fb3afa1)
2020-03-05 15:29:47 -08:00
Michael Kavanagh ce2c5d6528 Remove empty choice in Via type dropdown
Fixes https://gitlab.com/kicad/code/kicad/issues/3968

(cherry picked from commit 265c1663f9)
2020-03-03 14:21:21 -08:00
Seth Hillbrand fd81f70355 Drop invalid arcs on footprint load
In the case where the footprint arc has a non-normal angle, we cannot
represent this in pcbnew and it corrupts the gerber output.  Therefore
we drop the invalid arc and continue to load the footprint/board.

Fixes #3918 | https://gitlab.com/kicad/code/kicad/issues/3918

(cherry picked from commit 3e0ff72720)
2020-03-02 15:59:35 -08:00
Seth Hillbrand 100bb7c6ca Set Module Editor flag for tools
The commit takes the module edit flag when resetting the tool.  All
tools should reset this flag when we setup the Module editor.

This is slightly different in master and v5, so  this is a rework of
7bdf71abc

Fixes #3973 | https://gitlab.com/kicad/code/kicad/issues/3973
2020-03-02 12:45:47 -08:00
Seth Hillbrand 1ffcedd9d4 libedit: Fix speed of lib check
The symbol check output the HTML message for each item.  This is _very_
slow and can lock the system reponsiveness.  Changing to a queue/flush
method is much faster

cherry-picked from 245b778454
2020-02-28 08:50:05 -08:00
Ben Dooks fc1f713106 Fix issue with DRC for through hole being applied to SMD pads
Commit d7272b7f5e fixed the use of
the eagle DRC to change the library pad shapes. This was also
applied incorrectly to SMD stacks.

Remove the references to m_rules in packageSMD() and the code
that deals with them. eagle 7.7 does not have any SMD pad options
other than rectangle with rounding.

(cherry picked from commit 070c6b8ce0)
2020-02-27 09:01:42 -08:00
Seth Hillbrand 83c3a78e6d pcbnew: Avoid wx scaling error
When drawing to a scaled DC, the window doesn't reflect the expected
size if scaled after.  This causes elements drawn on the edge to reflect
back into the drawing area instead of being cut off.

We can simply scale our own values to avoid this issue.

Fixes #3849 | https://gitlab.com/kicad/code/kicad/issues/3849

(cherry picked from commit 5b6a4d794f)
2020-02-27 09:01:18 -08:00
Ian McInerney e6a3e7024d Also verify that the .dcm is writable when saving library
Fixes https://gitlab.com/kicad/code/kicad/issues/3946

(cherry-picked from b2cc454878)
2020-02-26 19:38:30 +00:00
jean-pierre charras d62fde0d79 Pcbnew, Fix issue when trying to create a drawing (line,circle,arc,polygon):
Display a error message if no free graphic layer is enabled, to switch from
a copper layer.

Fixes #3916
https://gitlab.com/kicad/code/kicad/issues/3916
2020-02-24 19:59:07 +01:00
Jon Evans a70cf464d6 Check if scaling factor has changed when top-level window is moved
Fixes #2592

(cherry picked from commit 712ae5a953)
2020-02-23 15:55:05 -05:00
Jon Evans 546260348d Rework window size and position fixing code
Fixes #2624
Fixes #3888

(cherry picked from commit 96da45f12f)
2020-02-23 15:55:05 -05:00
jean-pierre charras 693aec949c Gerbview: Gerber attributes display: fix incorrect attributes deletion.
The Gerber attribute deletion command (%TD,xxx) always cleared all attributes,
instead of clearing xxx attribute.
Therefore some attributes were not always displayed.

From master branch, commit 7206b567
2020-02-23 10:05:00 +01:00
jean-pierre charras 5c7ac1bb7e ZONE_FILLER: fix incorrect thermal clearance of pads having "not in zone" option. Pads inside a zone of the same net having the "not in zone" option have a "antipad" clearance. The value in this case is the biggest between zone clearance and thermal clearance (the net clearance is 0 betwen items of the same net)
However a bug created a incorrect value, due to the fact the minimal zone width
was incorrectly taking in account in calculations.
2020-02-17 17:12:24 +01:00
jean-pierre charras 8862752523 Remove a fix committed in 6b78fdf by mistake. 2020-02-17 13:00:56 +01:00
jean-pierre charras 201c380925 QA tests: remove deprecated headers, already not used in master branch. 2020-02-17 12:58:04 +01:00
jean-pierre charras c7230a6f77 eeschema: fixes related to translated and not translated field names.
When searching for fields, the code was sometimes comparing
translated and not translated names. This is an issue for mandatory fields,
in non English languages.

From master branch.
2020-02-17 12:26:51 +01:00
jean-pierre charras 6b78fdf822 LOCALE_IO: replace the call to setlocale by a call to wxLocale to switch to "C" locale.
Previously we call only setlocale( xx, "C" ), but it was not enough on Windows.
Now we call wxLocale("C")
wxLocale calls setlocale, but also make some others initialization in wxWidgets.
It fixes some issues related to comma versus point as fp separator.
Especially wxWidgets warnings are no longer thrown, and a one case of incorrect
conversion is fixed.
However, wxLocale( "C" ) also switches the current translations to English, so
loading files can have a slightly different behavior
2020-02-17 09:14:18 +01:00
Jon Evans 3cb326e426 ADDED: Expose GetBuildVersion and GetBuildDate to Python
(cherry picked from commit 8fb72d8290)
2020-02-15 09:59:43 -05:00
jean-pierre charras d3f9332372 Kicad manager: Avoid crash when calling configure libraries from main menu,
when _eeschema.kiface or _pcbnew.kiface is not found.
Happen mainly when running Kicad from build tree.

From master branch.
2020-02-11 16:15:19 +01:00
jean-pierre charras be0f6a6af2 Fp editor: fix: Reference and Value default values aren't saved in Footprint Editor preferences
Fixes #3889
https://gitlab.com/kicad/code/kicad/issues/3889
2020-02-11 15:48:05 +01:00
Seth Hillbrand 25aa233cef eeschema: Temporary fix for GTK printing offset
The full fix will be Cairo printing in v6

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

(cherry picked from commit 134a7ba85d)
2020-02-10 09:07:21 -08:00
Jeff Young 5fdc424202 Don't report Eagle errors on the Unrouted layer.
Fixes https://gitlab.com/kicad/code/kicad/issues/3398
2020-02-05 22:20:16 +00:00
Jeff Young 9b74bb5c92 Remove preferred layer disambiguation for multiple modules.
The preferred list isn't actually in use anymore at this point, so
it currently has no effect other than to mess things up since we
aren't keeping track of which modules have been rejected when we
check the module count.

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

(cherry picked from commit d02c0da3ab)
2020-02-05 22:20:16 +00:00
Jeff Young 8bf8a649c8 Adjust justified text for mirroring and rotation.
Fixes https://gitlab.com/kicad/code/kicad/issues/3737

(cherry picked from commit 2507f985ad)
2020-02-05 22:20:16 +00:00
Ian McInerney 7ba8d8b608 Revert eeschema highlighting changes
This reverts commit 366d4d7b0b.
This reverts commit 8b3c0a941c.

Fixes https://gitlab.com/kicad/code/kicad/issues/3866
2020-02-05 11:51:46 +00:00
Drew Fustini e35328fece Update copyright year in About dialog to 2020
(Cherry-picked from f359892de3)
2020-02-04 21:42:23 +00:00
Ian McInerney 366d4d7b0b eeschema: Ignore the highlight flag when responding to dbl click
Fixes https://gitlab.com/kicad/code/kicad/issues/3855
2020-02-03 21:41:03 +00:00
jean-pierre charras 3af1e75084 Gerber plots: Add initial G01 command to the header,
to ensure linear interpolation mode.
To avoid issues, an interpolation mode must be set before first D01 command.

From master branch.
2020-02-03 17:56:02 +01:00
jean-pierre charras dabd80fe4c Dxf importer: fix issue when importing some "degenerated" splines.
(From master, commit 8f3e8cf)
Sometimes a dxf curve is a "degenerated" bezier curve having only 3 points.
(a control point is at same location as a end point)
This commit fix incorrect import of these curves.

Fixes #3845
https://gitlab.com/kicad/code/kicad/issues/3845
2020-02-03 12:49:45 +01:00
Ian McInerney cb711a648f Fix layout in color dialog on GTK
Don't initially set the minimum widget size, and instead let it be
computed at launch.

Fixes #2617

(Partial cherry-pick of 4f82939384)
2020-02-02 15:40:42 +00:00
Karl Zeilhofer 5b58dbc980 Fixes dangling ends and rotation when labels/texts are converted into each other
CHANGED: Eeschema: Preserve text justification when switching text types

Closes https://gitlab.com/kicad/code/kicad/-/merge_requests/86
2020-02-01 16:08:34 +00:00
easyw 8b3c0a941c Highlight eeschema symbol on left click
CHANGED: Highlight eeschema symbol on left click

Closes https://gitlab.com/kicad/code/kicad/-/merge_requests/83
2020-02-01 16:08:19 +00:00
Seth Hillbrand 3ce29a3d7e Eeschema: Add bit that was missing from commit 7ac83ac64
This part of the check removes recursive sheets from the schematic when
loading and notifies the user that their schematic has been repaired.

(cherry picked from commit 128ec782dd)
2020-01-27 09:43:07 -08:00
Seth Hillbrand dc3c6b2f39 Check recursion before appending
We need to ensure that the appended sheet does not already exist in the
parent hierarchy.  We do this for new sheets but need to check for
existing ones as well.

Fixes #3806 | https://gitlab.com/kicad/code/kicad/issues/3806

(cherry picked from commit 7ac83ac64d)
2020-01-27 06:31:16 -08:00
Ian McInerney 1cbee4c504 gerbview: Add default filename to export to pcbnew function
Some platforms (such as Linux) don't automatically append file
extensions, so we should ensure extensions are correct and the user is
prompted accordingly.

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

(Cherry-picked from 88e0ef548d)
2020-01-26 16:26:03 +00:00
qu1ck 798e4c288a Fix polygon shape move
Move vector should not affect start/end points as they are assumed to
always be 0,0. Polygon is defined by outline only.

(cherry-picked from 32674ef360)
2020-01-23 00:40:33 +00:00
Seth Hillbrand ac39e32bc9 Recognize subckt blocks in spice
Spice lines defining circuit elements are contained in a .subckt ..
.ends block.  The intervening lines should be exported to the netlist as
well as the control lines.

(cherry picked from commit d9eaff1c99f4c6664e23f8995062cf34f92dbc6c)
2020-01-17 18:58:27 -08:00
Seth Hillbrand 52da7f931b pcbnew: Check before reading/writing cache
The open/create calls can fail so we need to account for this before
using the result that assumes success.

(cherry picked from commit 88729de68553427c7f2ca2d32cad46f959b8cc3c)
2020-01-17 18:34:28 -08:00
Ian McInerney fcb6f814de Fix macos plist version string generation
Generate these resource files similar to how it is done one Linux.

Fixes mac-builder issue https://gitlab.com/kicad/packaging/kicad-mac-builder/issues/275

(Cherry-picked from 25a302758e)
2020-01-18 01:44:01 +00:00
Seth Hillbrand 9e6b56d783 PNS: Detect collisions including newline width
The new line collision search uses BBox() to check for colliding
objects.  BBox in the SHAPE_LINE_CHAIN did not include width as the
chains were assumed to be zero-width.  This is not the case for
PNS::LINE elements.

We mostly don't notice this because DRC checks for SEGMENT collisions
but it becomes obvious/annoying when we cannot place a track for unknown
reasons and the snap-back doesn't take line width into account.

Fixes #3776 | https://gitlab.com/kicad/code/kicad/issues/3776

(cherry picked from commit fe15511d38f2e6ffb293e2e708f8e3ed89c1a4d3)
2020-01-17 11:26:02 -08:00
Seth Hillbrand 923dad6ca8 PNS: Modify MarkObstacles logic to select shorter
When routing where we hit multiple obstacles, we choose the shortest
path to allow overlapping hits to choose the shorter path, thus giving a
better chance of returning true for the DRC-compliant path.

Fixes #3773 | https://gitlab.com/kicad/code/kicad/issues/3773

(cherry picked from commit 38f13ef481cd2e5cf560b921bcaabf9cdc7d00fb)
2020-01-16 19:58:19 -08:00
Ian McInerney 9f17d91b32 Fix return type in KIDIALOG
It was returned as a bool for some reason...

(Cherry-picked from 1f8611f1988f3165d49dc3039ad9b42947b57f01)
2020-01-15 18:30:24 +00:00
Mark Roszko 2bcb04a3b1 KIDIALOG should ignore "cancel" for the do not show again option.
CHANGED: Do not remember "do not show again" when cancel button is pressed

Fix #3734

(Cherry-picked from 3ae784d97fb50bc70cc49e27b9f424958e583257)
2020-01-15 18:26:20 +00:00
Ian McInerney a530b600b8 Smoothen rotation in 3D viewer when crossing the 0-2pi line
Rotating to 0 when above pi would result in the board spinning back
through pi to get there. This led to jarring motion.

Also fix an issue added in b6f64815 where the board would rotate
2pi when crossing over the 0-2pi boundary.

(Cherry-pick of 4fc9b4e5ab63fa192ec2a7d40574f614b318668c)
2020-01-15 18:10:46 +00:00
jean-pierre charras d494a2bee2 3D viewer: normalize rotation angles between -2_PI and 2_PI.
Fixes #3761
https://gitlab.com/kicad/code/kicad/issues/3761

(Cherry-pick of b6f64815f4)
2020-01-15 16:30:41 +00:00
Ian McInerney 6a027662ae Update Linux appdata file and CMake version strings
CHANGED: Update the Linux appdata file to include new tags

* Include version tags (and others) in the appdata file
* Refactor the version string generation to clean it up

Cherry-pick of:
3370e89967
e54c954aed
2020-01-15 16:23:22 +00:00
Ian McInerney 577bb7bf31 Update AUTHORS.txt with changes from master branch
Cherry-pick of:
8fcd59ebda
037e6bc006
0857a1f5dc
07c6cfdc38

Closes !64
2020-01-15 16:17:19 +00:00
Ian McInerney df664bd55f Don't tie generic validators to a specific field
(Partial cherry-pick of 15cd13ba6e)

Fixes #3667
2020-01-15 16:12:39 +00:00
Seth Hillbrand 8a2705f81f PNS: Assume the current line is a base before optimizing
We use the cost of the current line before trying to improve the pad
breakout cost when optimizing the smart pads

Fixes #3759 | https://gitlab.com/kicad/code/kicad/issues/3759

(cherry picked from commit 52bfdb9703)
2020-01-12 11:13:19 -08:00
Seth Hillbrand fcaf11422a Fix bitmap clipping
When printing (using DC context) the bitmap will clear the full screen
unless the clipping region is set to the image itself.

Addresses KSC ticket 126

Fixes #1877 | https://gitlab.com/kicad/code/kicad/issues/1877

(cherry picked from commit 195c3d074b)
2020-01-11 10:00:57 -08:00
Seth Hillbrand 3444409554 pcbnew: Fix polygon comparison () for end
This is a v5-only fix incorporating 2c5876e and 72da237 into the 5
branch to resolve a crash when parsing invalid polygons.

Fixes #3752 | https://gitlab.com/kicad/code/kicad/issues/3752
2020-01-09 17:15:48 -08:00
jean-pierre charras 683c01b301 SVG plotter: fix an issue with mirrored texts. Mirrored texts have a size < 0. Of course, the actual value for the plotter is the absolute value. 2020-01-09 18:24:15 +01:00
jean-pierre charras e2492f773d FILENAME_RESOLVER: fix missing conversion from UTF8 to wide chars.
Fixes #3742
https://gitlab.com/kicad/code/kicad/issues/3742
2020-01-08 10:47:14 +01:00
Ian McInerney 1f3a2dcd1d Fix cherry-pick error
Fixes https://gitlab.com/kicad/code/kicad/issues/3744
2020-01-08 09:41:01 +00:00
Mario Luzeiro 4205cb32c5 3d-viewer, make ortho projection zoom similar as prespective projection
Fixes #1843
Fixes reload of Raytracing when the projection button is pressed.

(cherry picked from commit 2c00540ad6)
2020-01-06 19:33:00 -08:00
Mario Luzeiro 6ab9bdb346 3d-viewer, ray-tracing, do not add coincident segments
Fixes #1946 (lp 1852970)

(cherry picked from commit 518c1df81b)
2020-01-06 13:56:25 -05:00
Mario Luzeiro a4aec1919c 3D-viewer: raytracing, implement multiple shape board.
Fixes #1879 (lp:1820099)
Fixes #2126 (lp:1764039)

(cherry picked from commit 37c3e34486)
2020-01-06 13:55:31 -05:00
Jon Evans 5b97d70d57 Use existing pcb filename for Save As where possible 2020-01-06 10:33:00 -05:00
Ian McInerney eeeb4596c3 Properly escape spaces when opening PDFs on windows
Fixes https://gitlab.com/kicad/code/kicad/issues/2625

(cherry-picked from 20e7fc8a0e)
2020-01-03 19:09:04 +00:00
jean-pierre charras 23853cae14 Try to fix SEG::PointCloserThan(), not working for quasi H or V segments.
Quasi H or V segments are segments having the same x value or y value
(with a + or -1 max diff) for end points coordinates.
The change is a workaround, not really a fix.

Fixes #3711
https://gitlab.com/kicad/code/kicad/issues/3711
2019-12-31 15:59:45 +01:00
jean-pierre charras 87f6f33b37 fix a minor wxWidgets alert. 2019-12-27 20:03:02 +01:00
jean-pierre charras 8c03d1bdde Gerber files: update unicode coding to the 2019 06 Gerber specifications.
In gbr files, not allowed chars are coded using a 16 bit (4 hexa digits)
unicode sequence.
Previously, it was \XXXX and now is \uXXXX escape sequence.

Changes from master branch.
2019-12-27 20:03:01 +01:00
Wayne Stambaugh 7f1c7d808d Eeschema: fix sheet file name case sensitivity test.
Fix overzealous test if the new file name is the same as an existing
file name.

Fix a potential comparison bug due to missing file extension.

(cherry picked from commit b66ecf141f)
2019-12-27 12:08:13 -05:00
Wayne Stambaugh be12aece5b Eeschema: fix sheet file name case sensitivity bug.
Apparently there are some issues with wxString::CmpNoCase() that was
causing the sheet file name case sensitivity test to incorrectly fail.
Converting the name strings to lower case before comparing resolved
the issue.

(cherry picked from commit 773f45aae3)
2019-12-27 12:07:15 -05:00
Wayne Stambaugh d7605f1449 Eeschema: fix multiple sheet file name bugs.
Add missing check for root sheet when searching sheet hierarchies for
already loaded schematics.  This prevents the root sheet from being
omitted when adding new sheets using the root sheet file name.

CHANGED: Make file name tests case sensitive so that schematic sheet
file names on non-Windows systems can be uses as expected.

Warn users when attempting to use schematic file names that only vary
by case sensitivity that doing so will result in a project that is not
portable to Windows.

Fixes lp:1843415

https://bugs.launchpad.net/kicad/+bug/1843415
(cherry picked from commit d4cea0f2b7)
2019-12-27 12:05:59 -05:00
Jon Evans ef80642dec LSET: Prevent assertion in MSW when size is not a multiple of 4
(cherry picked from commit 2ea565473f)
2019-12-26 10:01:44 -05:00
Jon Evans a5622c93d4 Don't try to write fp-info-cache to a read-only directory
Fixes #1890

(cherry picked from commit 80fb3bde56)
2019-12-25 18:48:21 -05:00
Ian McInerney b6f9bfe9a5 pcbnew: Fix cmake to work with no wxPython on macOS
(cherry-picked from bf5dba847c)
2019-12-25 23:23:31 +00:00
Ian McInerney 79954657e2 eeschema: Fix return ID check in annotate dialog
Fixes https://gitlab.com/kicad/code/kicad/issues/3708

(cherry-picked from e6e2cf47fd)
2019-12-25 23:18:31 +00:00
Mark Roszko 35d3f1f72a common: Remove out of bounds and erroenous array access
(cherry-picked from bf32122134)
2019-12-19 11:35:21 +00:00
jean-pierre charras 388d74faf4 Pcbnew: graphic polygon: display the points count, instead of length,
and coordinate origin.
Previously, the meaningless length (always 0) and begin and end (@0,0)
coordinates were always displayed.

From master branch.
2019-12-18 13:21:35 +01:00
jean-pierre charras 0f8747e194 Gerber plotter: modify G02 and G03 commands.
They are now in a specific block and no longer combined with an other
command.
(combining these commands with an other command (D01 or D02) is deprecated)

Fixes #3677 | https://gitlab.com/kicad/code/kicad/issues/3677
2019-12-18 12:30:28 +01:00
Ian McInerney 93f16ba9e3 Update about dialog link to GitLab
(cherry-picked from c31c99abd1)

Fixes #3687
2019-12-17 20:21:59 +00:00
jean-pierre charras bea2d42e8c Gerbview,export to pcbnew: avoid exporting not valid polygons.
Gerber regions are exported as polygons (they are filled polygon).
The fix ensure the polygons are simple and valid.
Invalid polygons crash Pcbnew.

From master branch, commit 25504319.
2019-12-15 14:24:11 +01:00
jean-pierre charras 68d644fd28 P&S router: length tuning tool: fix a crash after trying to tune a track.
It happens on Windows, and wxWidgets 3.1.3. It is created by
PNS_TUNE_STATUS_POPUP instance used in tool. I am pretty sure this crash is
created by the stack switching when managing events, due to some changes in
wxWidgets code.
The fix creates the instance on the heap, instead of on the stack.
This is not the first time I see this kind of issue.

From master, commit 21dd8db
2019-12-12 10:26:27 +01:00
jean-pierre charras f6e33450ff Gerber object attribute: avoid trying to guess if a SMD pad is a BGA pad.
Previously, if a SMD pad was round, itb was seen as BGA pad.
But this is not always true. so use always SMD PAD attribute,
until an explicit BGA pad attribute is added in Pcbnew
2019-12-11 08:55:44 +01:00
Seth Hillbrand 65008c5c0b Eeschema: Check twice before using GAL
The windows display may through an error which we need to catch when
starting GAL under windows.  This is a reimplementation of
e39586e15 which cannot be cherry-picked into v5

Fixes #2620 | https://gitlab.com/kicad/code/kicad/issues/2620
2019-12-10 16:01:59 -08:00
Seth Hillbrand dbfaf568fc Plot SVG embedded
ADDED: embedded image support for SVG files

Fixes #3643 | https://gitlab.com/kicad/code/kicad/issues/3643

(cherry picked from commit fa133f3f5c)
2019-12-08 08:59:01 -08:00
Fabien Corona 58fd6ac03e PCBnew: placing a blind/buried via sometimes incorrectly place a through via.
From master branch commit 36fba5bd7f
2019-12-08 13:31:21 +01:00
Seth Hillbrand 1e64524afb PNS: Allow snap to temp hidden
The IFACE for kicad refers to the board hidden state, not the
temporarily hidden state used by the router.  We allow snapping to items
that have been removed by the temporary router state to provide snapping
to original track location.

Fixes #1827 | https://gitlab.com/kicad/code/kicad/issues/1827
2019-12-07 09:49:59 -08:00
Seth Hillbrand 20a5d8effd pcbnew: Handle intermediate pad on route
The length calculation wanted to find start/end pads but this was
complicated for paths that had a via on the intermediate pad.  Instead
of warning, we calculate the longest path of the three possibilities

Fixes: lp:1838261
* https://bugs.launchpad.net/kicad/+bug/1838261

Fixes #2554 | https://gitlab.com/kicad/code/kicad/issues/2554
2019-12-04 13:46:09 -08:00
jean-pierre charras 8c7e0bcb0a DIALOG_DRC_CONTROL: fix a crash on wxWidgets 3.1.3
Happens when right clicking on an item in displayed lists.
The crash was due to a bug in wxWidgets, and the fix is only a workaround

From commit 5cd7f3fd in master branch.

Also remove duplicate code.
2019-12-03 09:47:42 +01:00
Jeff Young c69080f11e Fix some issues with the previous commit. 2019-12-02 23:33:45 +00:00
Jeff Young 5a48c800ee Make sure that libraries are always sorted consistently.
Fixes #1847481 | https://gitlab.com/kicad/code/kicad/issues/1847481
2019-12-02 21:55:31 +00:00
Jeff Young c6eff4d373 Update local coords when editing EDGE_MODULEs.
Fixes: lp:1853726
* https://bugs.launchpad.net/kicad/+bug/1853726
2019-12-02 20:01:11 +00:00
Seth Hillbrand 5c056c2a3e Fix compile error for old compilers 2019-12-02 09:19:13 -08:00
M.Scholz 61f593f350 Corrects IsDirWritable check
The check for IsDirWritable needs to reference the absolute path to
return correct values.

Fixes: lp:1853421
* https://bugs.launchpad.net/kicad/+bug/1853421

(cherry picked from commit dbb9b5f64f)
2019-11-21 17:25:48 -08:00
jean-pierre charras 6cc7dc7aaa Pcbnew: fix crash on Linux (when opening Edit Spice model in component properties)
It happens when the spice library model shown in dialog is a large file.
Looks like the wxTextCtrl used to displays the library content
creates the crash ( GKT bug?) for large texts.

The fix is to replace this wxTextCtrlt by a wxStyledTextCtrl.
It has advantages (does not crash... and much faster display) and
inconvenients (cannot disable editing).

Fixes: lp:1853161
https://bugs.launchpad.net/kicad/+bug/1853161
2019-11-21 13:15:14 +01:00
jean-pierre charras 239f040a98 Fix minor wxWidgets alert (wxWidgets 3.1.3) 2019-11-20 18:29:11 +01:00
jean-pierre charras 3827c16fde Fix a wxWidgets alert 2019-11-20 10:02:09 +01:00
Fabien Corona e299343807 Pad ratsnest settings initial value
Pad ratsnest settings set to global settings during initilization.

Fixes: lp:1848488
* https://bugs.launchpad.net/kicad/+bug/1848488

(cherry picked from commit 29ce76b4e4)
(slightly modified due to settings structure difference between
master and 5.1)
2019-11-18 22:34:21 +00:00
Fabien Corona 4130ce2b93 Ratsnest default value for tracks and vias
Fixes: lp:1851611
* https://bugs.launchpad.net/kicad/+bug/1851611

(cherry picked from commit 6182133a4e)
(slightly modified due to differences between master and 5.1)
2019-11-18 22:23:00 +00:00
Seth Hillbrand d6acb64514 CMake: Fix OCE/OCC swap
unset() needs to remove the cached variable to get rid of the implicit
version

(cherry picked from commit 365f9224e7)
2019-11-18 21:20:10 +00:00
jean-pierre charras 8e233e2591 Fix compil issue due to a small incompatibility from cherry-picked code. 2019-11-18 09:13:04 +01:00
jean-pierre charras 9cda16220e Gerbview: add parsing of optional Aperture Macro parameter. AMP_CIRCLE primitive has 4 or 5 parameters (last is optional) Reading the optional parameter was missing.
Fixes: lp:1852924
https://bugs.launchpad.net/kicad/+bug/1852924
2019-11-18 09:07:32 +01:00
jean-pierre charras 36acadbd52 DIALOG_PAD_PROPERTIES: fix incorrect pad type for Aperture option.
The aperture option created a Connector pad only on the paste layer.
This is incorrect: the SMD type only is acceptable.
Connector is *only* for edge card connectors.
Moreover, The dialog did not even accept the setting defined by this dialog...
2019-11-17 18:28:08 +01:00
jean-pierre charras 37b6552c42 FIX: add parameter to GAL::DrawCurve to control the curve to polyline
conversion.
Cairo supports curves, but not Opengl, that needs a conversion to polyline.
This control allows optimization in conversion
2019-11-17 18:22:13 +01:00
jean-pierre charras 1903052d79 Bezier curves: replace previous algorithm to convert the curve to segments.
In some cases it was not working well.
Opengl was using an other algo (using the curve properties to create segments)
Now only the OpenGL algo is used,
with optimization to reduce the number of segments.
2019-11-17 18:22:13 +01:00
jean-pierre charras 2b4cfd9a60 Footprint wizard frame: rebuild the parameter grid list after any parameter change. The python footprint wizard can modify other parameters than the one that was changed by user. So the parameter grid list must be updated after every parameter change.
Fixes: lp:1846404
https://bugs.launchpad.net/kicad/+bug/1846404
2019-11-17 18:22:13 +01:00
Fabien Corona decbb65f09 High contrast color for holes in microvias and buried bias
In high contrast mode, the holes of buried vias and microvias were no darkened when not on the active layer.
In high contrast mode, the outer circle of buried vias and microvias were alway darkened.

In high contrast mode, when the selected layer is non visible through-vias are now darkend.

Fixes: lp:1844982
* https://bugs.launchpad.net/kicad/+bug/1844982

(cherry picked from commit 04edc6ceff)
2019-11-15 12:02:47 -08:00
Seth Hillbrand 8e2ca37edc pcbnew: Prevent extra selection
We want to avoid selecting items that are disabled in the item list.
Our standard method is in the GetViewLOD() that performs both size and
visibility.  This extends the check to module text and via.

Fixes: lp:1851133
* https://bugs.launchpad.net/kicad/+bug/1851133
2019-11-14 09:50:39 -08:00
Wayne Stambaugh 8fb6bcc8b1 Begin version 5.1.6 development. 2019-11-14 12:14:16 -05:00
209 changed files with 4317 additions and 7816 deletions
@@ -386,9 +386,22 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
case PAD_SHAPE_RECT:
{
// see pcbnew/board_items_to_polygon_shape_transform.cpp
wxPoint corners[4];
aPad->BuildPadPolygon( corners, wxSize( 0, 0), aPad->GetOrientation() );
bool drawOutline;
// For aClearanceValue.x == aClearanceValue.y and > 0 we use the pad shape
// and draw outlines with thicknes = aClearanceValue.
// Otherwise we draw only the inflated/deflated shape
if( aClearanceValue.x > 0 && aClearanceValue.x == aClearanceValue.y )
{
drawOutline = true;
aPad->BuildPadPolygon( corners, wxSize( 0, 0 ), aPad->GetOrientation() );
}
else
{
drawOutline = false;
aPad->BuildPadPolygon( corners, aClearanceValue, aPad->GetOrientation() );
}
SFVEC2F corners3DU[4];
@@ -416,20 +429,23 @@ void CINFO3D_VISU::createNewPadWithClearance( const D_PAD* aPad,
// Add the PAD contours
// Round segments cannot have 0-length elements, so we approximate them
// as a small circle
for( int i = 1; i <= 4; i++ )
if( drawOutline )
{
if( Is_segment_a_circle( corners3DU[i - 1], corners3DU[i & 3] ) )
for( int i = 1; i <= 4; i++ )
{
aDstContainer->Add( new CFILLEDCIRCLE2D( corners3DU[i - 1],
aClearanceValue.x * m_biuTo3Dunits,
*aPad ) );
}
else
{
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[i - 1],
corners3DU[i & 3],
aClearanceValue.x * 2.0f * m_biuTo3Dunits,
*aPad ) );
if( Is_segment_a_circle( corners3DU[i - 1], corners3DU[i & 3] ) )
{
aDstContainer->Add( new CFILLEDCIRCLE2D( corners3DU[i - 1],
aClearanceValue.x * m_biuTo3Dunits,
*aPad ) );
}
else
{
aDstContainer->Add( new CROUNDSEGMENT2D( corners3DU[i - 1],
corners3DU[i & 3],
aClearanceValue.x * 2.0f * m_biuTo3Dunits,
*aPad ) );
}
}
}
}
+5 -2
View File
@@ -1085,7 +1085,10 @@ bool EDA_3D_CANVAS::SetView3D( int aKeycode )
m_settings.CameraGet().SetT0_and_T1_current_T();
m_settings.CameraGet().Reset_T1();
m_settings.CameraGet().RotateX_T1( glm::radians( -90.0f ) );
m_settings.CameraGet().RotateZ_T1( glm::radians( -180.0f ) );
// The rotation angle should be 180.
// We use 179.999 (180 - epsilon) to avoid a full 360 deg rotation when
// using 180 deg if the previous rotated position was already 180 deg
m_settings.CameraGet().RotateZ_T1( glm::radians( -179.999f ) );
request_start_moving_camera();
return true;
@@ -1101,7 +1104,7 @@ bool EDA_3D_CANVAS::SetView3D( int aKeycode )
m_settings.CameraGet().SetInterpolateMode( INTERPOLATION_BEZIER );
m_settings.CameraGet().SetT0_and_T1_current_T();
m_settings.CameraGet().Reset_T1();
m_settings.CameraGet().RotateY_T1( glm::radians( 180.0f ) );
m_settings.CameraGet().RotateY_T1( glm::radians( 179.999f ) ); // Rotation = 180-epsilon
request_start_moving_camera(
glm::min( glm::max( m_settings.CameraGet().ZoomGet(), 0.5f ), 1.125f ) );
return true;
@@ -286,7 +286,9 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
m_outlineBoard2dObjects = new CCONTAINER2D;
if( ((const SHAPE_POLY_SET &)m_settings.GetBoardPoly()).OutlineCount() == 1 )
const int outlineCount = m_settings.GetBoardPoly().OutlineCount();
if( outlineCount > 0 )
{
float divFactor = 0.0f;
@@ -299,12 +301,16 @@ void C3D_RENDER_RAYTRACING::reload( REPORTER *aStatusTextReporter )
SHAPE_POLY_SET boardPolyCopy = m_settings.GetBoardPoly();
boardPolyCopy.Fracture( SHAPE_POLY_SET::PM_FAST );
Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
boardPolyCopy,
*m_outlineBoard2dObjects,
m_settings.BiuTo3Dunits(),
divFactor,
(const BOARD_ITEM &)*m_settings.GetBoard() );
for( int iOutlinePolyIdx = 0; iOutlinePolyIdx < outlineCount; iOutlinePolyIdx++ )
{
Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
boardPolyCopy,
*m_outlineBoard2dObjects,
m_settings.BiuTo3Dunits(),
divFactor,
*dynamic_cast<const BOARD_ITEM*>( m_settings.GetBoard() ),
iOutlinePolyIdx );
}
if( m_settings.GetFlag( FL_SHOW_BOARD_BODY ) )
{
@@ -408,17 +408,16 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
CGENERICCONTAINER2D &aDstContainer,
float aBiuTo3DunitsScale,
float aDivFactor,
const BOARD_ITEM &aBoardItem )
const BOARD_ITEM &aBoardItem,
int aPolyIndex )
{
BOX2I pathBounds = aMainPath.BBox();
// Get the path
wxASSERT( aMainPath.OutlineCount() == 1 );
const SHAPE_POLY_SET::POLYGON& curr_polywithholes = aMainPath.CPolygon( 0 );
wxASSERT( aPolyIndex < aMainPath.OutlineCount() );
wxASSERT( curr_polywithholes.size() == 1 );
const SHAPE_LINE_CHAIN& path = curr_polywithholes[0]; // a simple polygon
const SHAPE_LINE_CHAIN& path = aMainPath.COutline( aPolyIndex );
BOX2I pathBounds = path.BBox();
// Convert the points to segments class
CBBOX2D bbox;
@@ -430,8 +429,10 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
// Contains a closed polygon used to calc if points are inside
SEGMENTS segments;
segments_and_normals.resize( path.PointCount() );
segments.resize( path.PointCount() );
segments_and_normals.reserve( path.PointCount() );
segments.reserve( path.PointCount() );
SFVEC2F prevPoint;
for( int i = 0; i < path.PointCount(); i++ )
{
@@ -440,9 +441,23 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
const SFVEC2F point ( (float)( a.x) * aBiuTo3DunitsScale,
(float)(-a.y) * aBiuTo3DunitsScale );
bbox.Union( point );
segments_and_normals[i].m_Start = point;
segments[i].m_Start = point;
// Only add points that are not coincident
if( (i == 0) ||
(fabs(prevPoint.x - point.x) > FLT_EPSILON) ||
(fabs(prevPoint.y - point.y) > FLT_EPSILON) )
{
prevPoint = point;
bbox.Union( point );
SEGMENT_WITH_NORMALS sn;
sn.m_Start = point;
segments_and_normals.push_back( sn );
POLYSEGMENT ps;
ps.m_Start = point;
segments.push_back( ps );
}
}
bbox.ScaleNextUp();
@@ -518,13 +533,13 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
segments_and_normals[i].m_Normals.m_Start = normalSeg;
else
segments_and_normals[i].m_Normals.m_Start =
glm::normalize( (((normalBeforeSeg * dotBefore ) + normalSeg) * 0.5f) );
glm::normalize( (normalBeforeSeg * dotBefore ) + normalSeg );
if( dotAfter < 0.7f )
segments_and_normals[i].m_Normals.m_End = normalSeg;
else
segments_and_normals[i].m_Normals.m_End =
glm::normalize( (((normalAfterSeg * dotAfter ) + normalSeg) * 0.5f) );
glm::normalize( (normalAfterSeg * dotAfter ) + normalSeg );
}
if( aDivFactor == 0.0f )
@@ -148,7 +148,8 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
CGENERICCONTAINER2D &aDstContainer,
float aBiuTo3DunitsScale,
float aDivFactor,
const BOARD_ITEM &aBoardItem );
const BOARD_ITEM &aBoardItem,
int aPolyIndex );
void Polygon2d_TestModule();
+38 -8
View File
@@ -31,6 +31,17 @@
#include <wx/log.h>
// A helper function to normalize aAngle between -2PI and +2PI
inline void normalise2PI( float& aAngle )
{
while( aAngle > 0.0 )
aAngle -= M_PI*2;
while( aAngle < 0.0 )
aAngle += M_PI*2;
}
/**
* Trace mask used to enable or disable the trace output of this class.
* The debug output can be turned on by setting the WXTRACE environment variable to
@@ -95,6 +106,20 @@ void CCAMERA::Reset_T1()
m_zoom_t1 = 1.0f;
m_rotate_aux_t1 = SFVEC3F( 0.0f );
m_lookat_pos_t1 = m_board_lookat_pos_init;
// Since 0 = 2pi, we want to reset the angle to be the closest
// one to where we currently are. That ensures that we rotate
// the board around the smallest distance getting there.
if( m_rotate_aux_t0.x > M_PI )
m_rotate_aux_t1.x = 2*M_PI;
if( m_rotate_aux_t0.y > M_PI )
m_rotate_aux_t1.y = 2*M_PI;
if( m_rotate_aux_t0.z > M_PI )
m_rotate_aux_t1.z = 2*M_PI;
}
@@ -111,14 +136,17 @@ void CCAMERA::updateRotationMatrix()
m_rotationMatrixAux = glm::rotate( glm::mat4( 1.0f ),
m_rotate_aux.x,
SFVEC3F( 1.0f, 0.0f, 0.0f ) );
normalise2PI( m_rotate_aux.x );
m_rotationMatrixAux = glm::rotate( m_rotationMatrixAux,
m_rotate_aux.y,
SFVEC3F( 0.0f, 1.0f, 0.0f ) );
normalise2PI( m_rotate_aux.y );
m_rotationMatrixAux = glm::rotate( m_rotationMatrixAux,
m_rotate_aux.z,
SFVEC3F( 0.0f, 0.0f, 1.0f ) );
normalise2PI( m_rotate_aux.z );
m_parametersChanged = true;
@@ -163,7 +191,7 @@ void CCAMERA::rebuildProjection()
m_projectionMatrixInv = glm::inverse( m_projectionMatrix );
m_frustum.tang = glm::tan( glm::radians( m_frustum.angle ) * 0.5f ) ;
m_frustum.tang = glm::tan( glm::radians( m_frustum.angle ) * 0.5f );
m_focalLen.x = ( (float)m_windowSize.y / (float)m_windowSize.x ) / m_frustum.tang;
m_focalLen.y = 1.0f / m_frustum.tang;
@@ -178,19 +206,21 @@ void CCAMERA::rebuildProjection()
m_frustum.nearD = -m_frustum.farD; // Use a symmetrical clip plane for ortho projection
const float orthoReductionFactor = m_zoom / 75.0f;
// This formula was found by trial and error
const float orthoReductionFactor = glm::length( m_camera_pos_init ) *
m_zoom * m_zoom * 0.5f;
// Initialize Projection Matrix for Ortographic View
m_projectionMatrix = glm::ortho( -m_windowSize.x * orthoReductionFactor,
m_windowSize.x * orthoReductionFactor,
-m_windowSize.y * orthoReductionFactor,
m_windowSize.y * orthoReductionFactor,
m_projectionMatrix = glm::ortho( -m_frustum.ratio * orthoReductionFactor,
m_frustum.ratio * orthoReductionFactor,
-orthoReductionFactor,
orthoReductionFactor,
m_frustum.nearD, m_frustum.farD );
m_projectionMatrixInv = glm::inverse( m_projectionMatrix );
m_frustum.nw = m_windowSize.x * orthoReductionFactor * 2.0f;
m_frustum.nh = m_windowSize.y * orthoReductionFactor * 2.0f;
m_frustum.nw = orthoReductionFactor * 2.0f * m_frustum.ratio;
m_frustum.nh = orthoReductionFactor * 2.0f;
m_frustum.fw = m_frustum.nw;
m_frustum.fh = m_frustum.nh;
+26 -9
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2020 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
@@ -22,11 +22,12 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file eda_3d_viewer.cpp
* @brief Implements a 3d viewer windows GUI
*/
#include <wx/colordlg.h>
#include <wx/colour.h>
#include <wx/filename.h>
#include <wx/string.h>
#include <wx/wupdlock.h>
#include <wx/clipbrd.h>
#include "eda_3d_viewer.h"
#include "../3d_viewer_id.h"
@@ -271,6 +272,7 @@ void EDA_3D_VIEWER::OnCloseWindow( wxCloseEvent &event )
event.Skip( true );
}
#define ROT_ANGLE 10.0
void EDA_3D_VIEWER::Process_Special_Functions( wxCommandEvent &event )
@@ -292,7 +294,7 @@ void EDA_3D_VIEWER::Process_Special_Functions( wxCommandEvent &event )
break;
case ID_ROTATE3D_X_POS:
m_settings.CameraGet().RotateX( glm::radians(ROT_ANGLE) );
m_settings.CameraGet().RotateX( glm::radians( ROT_ANGLE ) );
if( m_settings.RenderEngineGet() == RENDER_ENGINE_OPENGL_LEGACY )
m_canvas->Request_refresh();
@@ -302,7 +304,7 @@ void EDA_3D_VIEWER::Process_Special_Functions( wxCommandEvent &event )
break;
case ID_ROTATE3D_X_NEG:
m_settings.CameraGet().RotateX( -glm::radians(ROT_ANGLE) );
m_settings.CameraGet().RotateX( -glm::radians( ROT_ANGLE ) );
if( m_settings.RenderEngineGet() == RENDER_ENGINE_OPENGL_LEGACY )
m_canvas->Request_refresh();
@@ -369,7 +371,11 @@ void EDA_3D_VIEWER::Process_Special_Functions( wxCommandEvent &event )
case ID_ORTHO:
m_settings.CameraGet().ToggleProjection();
m_canvas->Request_refresh();
if( m_settings.RenderEngineGet() == RENDER_ENGINE_OPENGL_LEGACY )
m_canvas->Request_refresh();
else
m_canvas->RenderRaytracingRequest();
return;
case ID_TOOL_SCREENCOPY_TOCLIBBOARD:
@@ -985,6 +991,17 @@ void EDA_3D_VIEWER::takeScreenshot( wxCommandEvent& event )
fullFileName = m_defaultSaveScreenshotFileName.GetFullPath();
wxFileName fn = fullFileName;
if( !fn.IsDirWritable() )
{
wxString msg;
msg.Printf( _( "Insufficient permissions required to save file\n%s" ), fullFileName );
wxMessageBox( msg, _( "Error" ), wxOK | wxICON_ERROR, this );
return;
}
// Be sure the screen area destroyed by the file dialog is redrawn
// before making a screen copy.
// Without this call, under Linux the screen refresh is made to late.
+4 -2
View File
@@ -46,9 +46,10 @@ Russell Oliver <roliver8143[at]gmail-dot-com>
Seth Hillbrand <hillbrand[at]ucdavis-dot-edu>
Jeff Young <jeff[at]rokeby-dot-ie>
Kevin Cozens <kevin[at]ve3syb-dot-ca>
Ian McInerney <ian.s.mcinerney[at]ieee-dot-org>
See git repo on launchpad for contributors at
https://code.launchpad.net/~kicad-product-committers/kicad/+git/product-git/+ref/master.
See git repo on GitLab for contributors at
https://gitlab.com/kicad/code/kicad/-/graphs/master
== Document Writers
@@ -75,6 +76,7 @@ Spanish (ES) Pedro Martin del Valle <pkicad[at]yahoo-dot-es>
Spanish (ES) Iñigo Zuluaga <inigo_zuluaga[at]yahoo-dot-es>
German (DE) Rafael Sokolowski <Rafael.Sokolowski[at]web-dot-de
Japanese (JA) Kenta Yonekura <yoneken[at]kicad-dot-jp>
Simplified Chinese (zh_CN) taotieren <admin[at]taotieren-dot-com>
Remy Halvick, David Briscoe, Dominique Laigle, Paul Burke
+19 -3
View File
@@ -413,7 +413,7 @@ endif()
if( KICAD_USE_OCC )
add_definitions( -DKICAD_USE_OCC )
remove_definitions( -DKICAD_USE_OCE )
unset( KICAD_USE_OCE )
unset( KICAD_USE_OCE CACHE )
endif()
if( KICAD_USE_CUSTOM_PADS )
@@ -894,6 +894,16 @@ add_custom_target( uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" )
#################################################
# Generate platform metadata files
#################################################
if( APPLE )
include( ${CMAKE_MODULE_PATH}/WritePlatformMetadata_macos.cmake )
elseif( UNIX )
include( ${CMAKE_MODULE_PATH}/WritePlatformMetadata_linux.cmake )
endif()
#================================================
# Installation
#================================================
@@ -919,7 +929,7 @@ if( UNIX AND NOT APPLE )
set( UNIX_MIME_FILES ${UNIX_MIME_DIR}/mime )
set( UNIX_ICON_FILES ${UNIX_MIME_DIR}/icons )
set( UNIX_APPLICATIONS_FILES ${UNIX_MIME_DIR}/applications )
set( UNIX_APPDATA_FILES resources/linux/appdata )
set( UNIX_APPDATA_FILES ${PROJECT_BINARY_DIR}/resources/linux/appdata )
# Install Mime directory
install( DIRECTORY ${UNIX_ICON_FILES}
@@ -943,6 +953,9 @@ if( UNIX AND NOT APPLE )
install( DIRECTORY ${UNIX_APPDATA_FILES}
DESTINATION share
COMPONENT resources
FILES_MATCHING
PATTERN "*appdata.xml"
PATTERN "*.in" EXCLUDE
)
endif()
@@ -988,7 +1001,10 @@ add_subdirectory( plugins ) # 3D plugins must be built before kicad
add_subdirectory( kicad ) # should follow pcbnew, eeschema
add_subdirectory( tools )
add_subdirectory( utils )
add_subdirectory( qa )
if( KICAD_BUILD_QA_TESTS )
add_subdirectory( qa )
endif()
# Resources
if ( KICAD_INSTALL_DEMOS )
@@ -27,6 +27,8 @@ macro( create_git_version_header _git_src_path )
find_package( Git )
if( GIT_FOUND )
message( STATUS "Using Git to determine build version string." )
set( _Git_SAVED_LC_ALL "$ENV{LC_ALL}" )
set( ENV{LC_ALL} C )
+40
View File
@@ -0,0 +1,40 @@
#
# This program source code file is part of KICAD, a free EDA CAD application.
#
# Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
# Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, you may find one here:
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# or you may search the http://www.gnu.org website for the version 2 license,
# or you may write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
# This file will create the full KiCad version string. The base of this string
# will be either the git tag followed by the commit hash (if built inside a git
# repository), or the version from KiCadVersion.cmake. The user-provided
# KICAD_VERSION_EXTRA is then appended to the base version string.
# Use git to determine the version string if it's available.
include( ${CMAKE_MODULE_PATH}/CreateGitVersionHeader.cmake )
create_git_version_header( ${SRC_PATH} )
# $KICAD_VERSION is set in KiCadVersion.cmake or by git (if it is available).
set( KICAD_VERSION_FULL "${KICAD_VERSION}" )
# Optional user version information defined at configuration.
if( KICAD_VERSION_EXTRA )
set( KICAD_VERSION_FULL "${KICAD_VERSION_FULL}-${KICAD_VERSION_EXTRA}" )
endif()
+1 -1
View File
@@ -35,4 +35,4 @@
# be set after each version tag is added to the git repo. This will
# give developers a reasonable idea where which branch was used to build
# KiCad.
set( KICAD_VERSION "5.1.5" )
set( KICAD_VERSION "5.1.6" )
@@ -0,0 +1,46 @@
#
# This program source code file is part of KICAD, a free EDA CAD application.
#
# Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
# Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, you may find one here:
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# or you may search the http://www.gnu.org website for the version 2 license,
# or you may write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
# This file will configure the linux appdata.xml file to include the version
# and build date.
message( STATUS "Creating linux metadata" )
# Create the KiCad version strings
set( SRC_PATH ${PROJECT_SOURCE_DIR} )
include( ${CMAKE_MODULE_PATH}/KiCadVersion.cmake )
include( ${CMAKE_MODULE_PATH}/KiCadFullVersion.cmake )
# Create the date of the configure
string( TIMESTAMP KICAD_CONFIG_TIMESTAMP "%Y-%m-%d" )
# Configure the KiCad appdata file
configure_file( ${PROJECT_SOURCE_DIR}/resources/linux/appdata/kicad.appdata.xml.in
${PROJECT_BINARY_DIR}/resources/linux/appdata/kicad.appdata.xml
@ONLY )
# Ensure the file was configured successfully
if( NOT EXISTS ${PROJECT_BINARY_DIR}/resources/linux/appdata/kicad.appdata.xml )
message( FATAL_ERROR "Configuration failed to write file kicad.appdata.xml." )
endif()
@@ -0,0 +1,63 @@
#
# This program source code file is part of KICAD, a free EDA CAD application.
#
# Copyright (C) 2019 Ian McInerney <Ian.S.McInerney@ieee.org>
# Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, you may find one here:
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# or you may search the http://www.gnu.org website for the version 2 license,
# or you may write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
# This file will configure the MacOS info.plist files to include the version
# and build date.
message( STATUS "Creating MacOS metadata" )
# Create the KiCad version strings
set( SRC_PATH ${PROJECT_SOURCE_DIR} )
include( ${CMAKE_MODULE_PATH}/KiCadVersion.cmake )
include( ${CMAKE_MODULE_PATH}/KiCadFullVersion.cmake )
# Configure each plist file from the respurces directory and store it in the build directory
configure_file( ${PROJECT_SOURCE_DIR}/resources/macos/plist/bitmap2component.Info.plist.in
${PROJECT_BINARY_DIR}/bitmap2component/Info.plist
@ONLY )
configure_file( ${PROJECT_SOURCE_DIR}/resources/macos/plist/eeschema.Info.plist.in
${PROJECT_BINARY_DIR}/eeschema/Info.plist
@ONLY )
configure_file( ${PROJECT_SOURCE_DIR}/resources/macos/plist/gerbview.Info.plist.in
${PROJECT_BINARY_DIR}/gerbview/Info.plist
@ONLY )
configure_file( ${PROJECT_SOURCE_DIR}/resources/macos/plist/kicad.Info.plist.in
${PROJECT_BINARY_DIR}/kicad/Info.plist
@ONLY )
configure_file( ${PROJECT_SOURCE_DIR}/resources/macos/plist/pcb_calculator.Info.plist.in
${PROJECT_BINARY_DIR}/pcb_calculator/Info.plist
@ONLY )
configure_file( ${PROJECT_SOURCE_DIR}/resources/macos/plist/pcbnew.Info.plist.in
${PROJECT_BINARY_DIR}/pcbnew/Info.plist
@ONLY )
configure_file( ${PROJECT_SOURCE_DIR}/resources/macos/plist/pleditor.Info.plist.in
${PROJECT_BINARY_DIR}/pagelayout_editor/Info.plist
@ONLY )
+2 -18
View File
@@ -22,25 +22,9 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
# Automagically create version header file if the version string was
# not defined during the build configuration. If CreateGitVersionHeader
# cannot determine the current repo version, a version.h file is still
# created with KICAD_VERSION set in KiCadVersion.cmake.
# Create the KiCad version strings
include( ${CMAKE_MODULE_PATH}/KiCadVersion.cmake )
# Always use git if it's available to determine the version string.
message( STATUS "Using Git to determine build version string." )
include( ${CMAKE_MODULE_PATH}/CreateGitVersionHeader.cmake )
create_git_version_header( ${SRC_PATH} )
# $KICAD_VERSION will always be set to something. Even if it is the default
# value set in KiCadVersion.cmake
set( KICAD_VERSION_FULL "${KICAD_VERSION}" )
# Optional user version information defined at configuration.
if( KICAD_VERSION_EXTRA )
set( KICAD_VERSION_FULL "${KICAD_VERSION_FULL}-${KICAD_VERSION_EXTRA}" )
endif()
include( ${CMAKE_MODULE_PATH}/KiCadFullVersion.cmake )
set( _wvh_new_version_text
"/* Do not modify this file, it was automatically generated by CMake. */
+1 -1
View File
@@ -222,7 +222,7 @@ and can cause Pcbnew to crash if Python scripts create an invalid object state w
The KiCad version string is defined by the output of `git describe --dirty` when git is available
or the version string defined in CMakeModules/KiCadVersion.cmake with the value of
KICAD_VERSION_EXTRA appended to the former. If the KICAD_VERSION_EXTRA variable is not define,
KICAD_VERSION_EXTRA appended to the former. If the KICAD_VERSION_EXTRA variable is not defined,
it is not appended to the version string. If the KICAD_VERSION_EXTRA variable is defined it
is appended along with a leading '-' to the full version string as follows:
+1 -4
View File
@@ -54,11 +54,8 @@ target_link_libraries( bitmap2component
)
if( APPLE )
include( ${CMAKE_MODULE_PATH}/KiCadVersion.cmake )
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist @ONLY )
set_target_properties( bitmap2component PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
MACOSX_BUNDLE_INFO_PLIST ${PROJECT_BINARY_DIR}/bitmap2component/Info.plist
)
# put individual bundle outside of main bundle as a first step
-42
View File
@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDocumentTypes</key>
<array/>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>bitmap2component</string>
<key>CFBundleGetInfoString</key>
<string></string>
<key>CFBundleIconFile</key>
<string>bitmap2component.icns</string>
<key>CFBundleIdentifier</key>
<string>org.kicad-pcb.bitmap2component</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>@KICAD_VERSION_FULL@</string>
<key>CFBundleName</key>
<string>Bitmap 2 Component</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>@KICAD_VERSION@</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>@KICAD_VERSION_FULL@</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSRequiresCarbon</key>
<true/>
<key>NSRequiresAquaSystemAppearance</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>NSHighResolutionCapable</key>
<string>True</string>
</dict>
</plist>
+5 -6
View File
@@ -153,10 +153,10 @@ install( TARGETS lib_kicad
endif()
# KiCad build version string defaults to "no-vcs-found" which forces the build version header
# command to look for git to create the version string header when the .git path is found in
# the source path.
set( KICAD_BRANCH_NAME "" CACHE STRING "KiCad repository name." )
# The build version string defaults to the value in the KiCadVersion.cmake file.
# If being built inside a git repository, the git tag and commit hash are used to create
# a new version string instead. The user can supply an additional string to be appended
# to the end inside the KICAD_VERSION_EXTRA variable
set( KICAD_VERSION_EXTRA "" CACHE STRING
"User defined configuration string to append to KiCad version." )
@@ -164,8 +164,6 @@ set( KICAD_VERSION_EXTRA "" CACHE STRING
add_custom_target(
version_header ALL
COMMAND ${CMAKE_COMMAND}
-DKICAD_VERSION=${KICAD_VERSION}
-DKICAD_BRANCH_NAME=${KICAD_BRANCH_NAME}
-DKICAD_VERSION_EXTRA=${KICAD_VERSION_EXTRA}
-DOUTPUT_FILE=${CMAKE_BINARY_DIR}/kicad_build_version.h
-DSRC_PATH=${PROJECT_SOURCE_DIR}
@@ -278,6 +276,7 @@ set( COMMON_SRCS
${PLOTTERS_CONTROL_SRCS}
advanced_config.cpp
array_options.cpp
base64.cpp
base_struct.cpp
bezier_curves.cpp
bin_mod.cpp
+157
View File
@@ -0,0 +1,157 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Seth Hillbrand <seth@kipro-pcb.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <base64.h>
#include <cstdint>
#include <cstddef>
#include <limits>
#include <vector>
namespace {
static const uint8_t ENCODE_BASE64[64] = {
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F,
};
static const uint8_t E = -1;
static const uint8_t DECODE_BASE64[128] = {
/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xA 0xB 0xC 0xD 0xE 0xF */
E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,
E, E, E, E, E, E, E, E, E, E, E, 62, E, E, E, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, E, E, E, E, E, E,
E, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, E, E, E, E, E,
E, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, E, E, E, E, E,
};
} // namespace
namespace base64
{
size_t encode_length( size_t aInputLen )
{
return 4 * ( ( aInputLen + 2 ) / 3 ) + ( aInputLen + 2 ) % 3 - 2;
}
size_t decode_length( size_t aInputLen )
{
if( aInputLen % 4 == 1 )
return 0;
else
return 3 * ( ( aInputLen + 2 ) / 4 ) + ( aInputLen + 2 ) % 4 - 2;
}
void encode( const std::vector<uint8_t>& aInput, std::vector<uint8_t>& aOutput )
{
size_t end = ( aInput.size() / 3 ) * 3;
aOutput.reserve( encode_length( aInput.size() ) );
for( size_t i = 0; i < end; i += 3 )
{
unsigned value = ( aInput[i] << 16 ) | ( aInput[i + 1] << 8 ) | aInput[i + 2] ;
aOutput.emplace_back( ENCODE_BASE64[( value >> 18 ) & 0x3F] );
aOutput.emplace_back( ENCODE_BASE64[( value >> 12 ) & 0x3F] );
aOutput.emplace_back( ENCODE_BASE64[( value >> 6 ) & 0x3F] );
aOutput.emplace_back( ENCODE_BASE64[value & 0x3F] );
}
size_t remainder = aInput.size() - end;
if( remainder )
{
unsigned value = aInput[end];
if( remainder == 2 )
{
value = ( value << 10 ) | ( aInput[end + 1] << 2 );
aOutput.emplace_back( ENCODE_BASE64[( value >> 12 ) & 0x3F] );
}
else
{
value <<= 4;
}
aOutput.emplace_back( ENCODE_BASE64[( value >> 6 ) & 0x3F] );
aOutput.emplace_back( ENCODE_BASE64[value & 0x3F] );
}
}
void decode(const std::vector<uint8_t>& aInput, std::vector<uint8_t>& aOutput )
{
size_t end = ( aInput.size() / 4 ) * 4;
size_t decode_size = decode_length( aInput.size() );
if( !decode_size )
return;
aOutput.reserve( decode_size );
for( size_t i = 0; i < end; i++ )
{
unsigned value = ( DECODE_BASE64[aInput[i] & 0x7F] << 18 ) |
( DECODE_BASE64[aInput[i + 1] & 0x7F] << 12 ) |
( DECODE_BASE64[aInput[i + 2] & 0x7F] << 6 ) |
DECODE_BASE64[aInput[i + 3] & 0x7F];
aOutput.emplace_back( ( value >> 16 ) & 0xff );
aOutput.emplace_back( ( value >> 8 ) & 0xff );
aOutput.emplace_back( value & 0xff );
}
size_t remainder = aInput.size() - end;
if( remainder )
{
unsigned value = ( ( DECODE_BASE64[aInput[end] & 0x7F] ) << 6 ) |
( DECODE_BASE64[aInput[end + 1] & 0x7F] );
if( remainder == 3 )
{
value = ( value << 6 ) | ( DECODE_BASE64[aInput[end + 2] & 0x7F] );
value >>= 2;
aOutput.emplace_back( ( value >> 8 ) & 0xff );
}
else
{
value >>= 4;
}
aOutput[0] = value & 0xff ;
}
}
} // base64
+42 -336
View File
@@ -1,8 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2014-2017 KiCad Developers, see CHANGELOG.TXT for contributors.
* Copyright (C) 2014-2019 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
@@ -26,362 +25,69 @@
/* routines to handle bezier curves */
/************************************/
#include <fctsys.h>
#include <bezier_curves.h>
static inline double calc_sq_distance( int x1, int y1, int x2, int y2 )
BEZIER_POLY::BEZIER_POLY( const std::vector<wxPoint>& aControlPoints )
{
int dx = x2 - x1;
int dy = y2 - y1;
for( unsigned ii = 0; ii < aControlPoints.size(); ++ii )
m_ctrlPts.emplace_back( VECTOR2D( aControlPoints[ii] ) );
return (double)dx * dx + (double)dy * dy;
}
static inline double sqrt_len( int dx, int dy )
{
return ((double)dx * dx) + ((double)dy * dy);
m_minSegLen = 0.0;
}
void BEZIER_POLY::GetPoly( std::vector<wxPoint>& aOutput, int aMinSegLen )
{
wxCHECK( !m_ctrlPts.empty(), /* void */ );
m_minSegLen = std::max( 1, aMinSegLen );
m_output = &aOutput;
m_output->clear();
m_output->push_back( wxPoint( m_ctrlPts.front() ) );
aOutput.clear();
std::vector<VECTOR2D> buffer;
GetPoly( buffer, double( aMinSegLen ) );
// Only quadratic and cubic Bezier curves are handled
if( m_ctrlPts.size() == 3 )
recursiveBezier( m_ctrlPts[0].x, m_ctrlPts[0].y,
m_ctrlPts[1].x, m_ctrlPts[1].y,
m_ctrlPts[2].x, m_ctrlPts[2].y, 0 );
else if( m_ctrlPts.size() == 4 )
recursiveBezier( m_ctrlPts[0].x, m_ctrlPts[0].y,
m_ctrlPts[1].x, m_ctrlPts[1].y,
m_ctrlPts[2].x, m_ctrlPts[2].y,
m_ctrlPts[3].x, m_ctrlPts[3].y, 0 );
m_output->push_back( wxPoint( m_ctrlPts.back() ) );
for( unsigned ii = 0; ii < buffer.size(); ++ii )
aOutput.emplace_back( wxPoint( int( buffer[ii].x ), int( buffer[ii].y ) ) );
}
void BEZIER_POLY::recursiveBezier( int x1, int y1, int x2, int y2,
int x3, int y3, unsigned int level )
void BEZIER_POLY::GetPoly( std::vector<VECTOR2D>& aOutput, double aMinSegLen )
{
if( level > recursion_limit )
return;
wxASSERT( m_ctrlPts.size() == 4 );
// FIXME Brute force method, use a better (recursive?) algorithm
// with a max error value.
// to optimize the number of segments
#define CURVE_POINTS 32
double dt = 1.0 / CURVE_POINTS;
// Calculate all the mid-points of the line segments
//----------------------
int x12 = (x1 + x2) / 2;
int y12 = (y1 + y2) / 2;
int x23 = (x2 + x3) / 2;
int y23 = (y2 + y3) / 2;
int x123 = (x12 + x23) / 2;
int y123 = (y12 + y23) / 2;
aOutput.clear();
aOutput.push_back( m_ctrlPts[0] );
int dx = x3 - x1;
int dy = y3 - y1;
double d = fabs( ((double) (x2 - x3) * dy) - ((double) (y2 - y3) * dx ) );
double da;
// If the Bezier curve is degenerated (straight line), skip intermediate points:
bool degenerated = m_ctrlPts[0] == m_ctrlPts[1] && m_ctrlPts[2] == m_ctrlPts[3];
if( d > curve_collinearity_epsilon )
if( !degenerated )
{
// Regular case
//-----------------
if( d * d <= distance_tolerance_square * (dx * dx + dy * dy) )
for( int ii = 1; ii < CURVE_POINTS; ii++ )
{
// If the curvature doesn't exceed the distance_tolerance value
// we tend to finish subdivisions.
//----------------------
if( angle_tolerance < curve_angle_tolerance_epsilon )
{
addSegment( wxPoint( x123, y123 ) );
return;
}
double t = dt * ii;
double omt = 1.0 - t;
double omt2 = omt * omt;
double omt3 = omt * omt2;
double t2 = t * t;
double t3 = t * t2;
// Angle & Cusp Condition
//----------------------
da = fabs( atan2( (double) ( y3 - y2 ), (double) ( x3 - x2 ) ) -
atan2( (double) ( y2 - y1 ), (double) ( x2 - x1 ) ) );
if( da >=M_PI )
da = 2 * M_PI - da;
VECTOR2D vertex = omt3 * m_ctrlPts[0]
+ 3.0 * t * omt2 * m_ctrlPts[1]
+ 3.0 * t2 * omt * m_ctrlPts[2]
+ t3 * m_ctrlPts[3];
if( da < angle_tolerance )
{
// Finally we can stop the recursion
//----------------------
addSegment( wxPoint( x123, y123 ) );
return;
}
}
}
else
{
// Collinear case
//------------------
da = sqrt_len(dx, dy);
if( da == 0 )
{
d = calc_sq_distance( x1, y1, x2, y2 );
}
else
{
d = ( (double)(x2 - x1) * dx + (double)(y2 - y1) * dy ) / da;
if( d > 0 && d < 1 )
{
// Simple collinear case, 1---2---3
// We can leave just two endpoints
return;
}
if( d <= 0 )
d = calc_sq_distance( x2, y2, x1, y1 );
else if( d >= 1 )
d = calc_sq_distance( x2, y2, x3, y3 );
else
d = calc_sq_distance( x2, y2, x1 + (int) d * dx,
y1 + (int) d * dy );
}
if( d < distance_tolerance_square )
{
addSegment( wxPoint( x2, y2 ) );
return;
// a minimal filter on the lenght of the segment being created:
// The offset from last point:
VECTOR2D delta = vertex - aOutput.back();
double dist = delta.EuclideanNorm();
if( dist > aMinSegLen )
aOutput.push_back( vertex );
}
}
// Continue subdivision
//----------------------
recursiveBezier( x1, y1, x12, y12, x123, y123, level + 1 );
recursiveBezier( x123, y123, x23, y23, x3, y3, level + 1 );
}
void BEZIER_POLY::recursiveBezier( int x1, int y1, int x2, int y2,
int x3, int y3, int x4, int y4, unsigned int level )
{
if( level > recursion_limit )
return;
// Calculate all the mid-points of the line segments
//----------------------
int x12 = (x1 + x2) / 2;
int y12 = (y1 + y2) / 2;
int x23 = (x2 + x3) / 2;
int y23 = (y2 + y3) / 2;
int x34 = (x3 + x4) / 2;
int y34 = (y3 + y4) / 2;
int x123 = (x12 + x23) / 2;
int y123 = (y12 + y23) / 2;
int x234 = (x23 + x34) / 2;
int y234 = (y23 + y34) / 2;
int x1234 = (x123 + x234) / 2;
int y1234 = (y123 + y234) / 2;
// Try to approximate the full cubic curve by a single straight line
//------------------
int dx = x4 - x1;
int dy = y4 - y1;
double d2 = fabs( (double) ( (x2 - x4) * dy - (y2 - y4) * dx ) );
double d3 = fabs( (double) ( (x3 - x4) * dy - (y3 - y4) * dx ) );
double da1, da2, k;
switch( (int(d2 > curve_collinearity_epsilon) << 1) +
int(d3 > curve_collinearity_epsilon) )
{
case 0:
// All collinear OR p1==p4
//----------------------
k = dx * dx + dy * dy;
if( k == 0 )
{
d2 = calc_sq_distance( x1, y1, x2, y2 );
d3 = calc_sq_distance( x4, y4, x3, y3 );
}
else
{
k = 1 / k;
da1 = x2 - x1;
da2 = y2 - y1;
d2 = k * (da1 * dx + da2 * dy);
da1 = x3 - x1;
da2 = y3 - y1;
d3 = k * (da1 * dx + da2 * dy);
if( d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1 )
{
// Simple collinear case, 1---2---3---4
// We can leave just two endpoints
return;
}
if( d2 <= 0 )
d2 = calc_sq_distance( x2, y2, x1, y1 );
else if( d2 >= 1 )
d2 = calc_sq_distance( x2, y2, x4, y4 );
else
d2 = calc_sq_distance( x2, y2, x1 + (int) d2 * dx,
y1 + (int) d2 * dy );
if( d3 <= 0 )
d3 = calc_sq_distance( x3, y3, x1, y1 );
else if( d3 >= 1 )
d3 = calc_sq_distance( x3, y3, x4, y4 );
else
d3 = calc_sq_distance( x3, y3, x1 + (int) d3 * dx,
y1 + (int) d3 * dy );
}
if( d2 > d3 )
{
if( d2 < distance_tolerance_square )
{
addSegment( wxPoint( x2, y2 ) );
return;
}
}
else
{
if( d3 < distance_tolerance_square )
{
addSegment( wxPoint( x3, y3 ) );
return;
}
}
break;
case 1:
// p1,p2,p4 are collinear, p3 is significant
//----------------------
if( d3 * d3 <= distance_tolerance_square * sqrt_len(dx, dy) )
{
if( angle_tolerance < curve_angle_tolerance_epsilon )
{
addSegment( wxPoint( x23, y23 ) );
return;
}
// Angle Condition
//----------------------
da1 = fabs( atan2( (double) ( y4 - y3 ), (double) ( x4 - x3 ) ) -
atan2( (double) ( y3 - y2 ), (double) ( x3 - x2 ) ) );
if( da1 >= M_PI )
da1 = 2 * M_PI - da1;
if( da1 < angle_tolerance )
{
addSegment( wxPoint( x2, y2 ) );
addSegment( wxPoint( x3, y3 ) );
return;
}
if( cusp_limit != 0.0 )
{
if( da1 > cusp_limit )
{
addSegment( wxPoint( x3, y3 ) );
return;
}
}
}
break;
case 2:
// p1,p3,p4 are collinear, p2 is significant
//----------------------
if( d2 * d2 <= distance_tolerance_square * sqrt_len(dx, dy) )
{
if( angle_tolerance < curve_angle_tolerance_epsilon )
{
addSegment( wxPoint( x23, y23 ) );
return;
}
// Angle Condition
//----------------------
da1 = fabs( atan2( (double) ( y3 - y2 ), (double) ( x3 - x2 ) ) -
atan2( (double) ( y2 - y1 ), (double) ( x2 - x1 ) ) );
if( da1 >= M_PI )
da1 = 2 * M_PI - da1;
if( da1 < angle_tolerance )
{
addSegment( wxPoint( x2, y2 ) );
addSegment( wxPoint( x3, y3 ) );
return;
}
if( cusp_limit != 0.0 )
{
if( da1 > cusp_limit )
{
addSegment( wxPoint( x2, y2 ) );
return;
}
}
}
break;
case 3:
// Regular case
//-----------------
if( (d2 + d3) * (d2 + d3) <= distance_tolerance_square * sqrt_len(dx, dy) )
{
// If the curvature doesn't exceed the distance_tolerance value
// we tend to finish subdivisions.
//----------------------
if( angle_tolerance < curve_angle_tolerance_epsilon )
{
addSegment( wxPoint( x23, y23 ) );
return;
}
// Angle & Cusp Condition
//----------------------
k = atan2( (double) ( y3 - y2 ), (double) ( x3 - x2 ) );
da1 = fabs( k - atan2( (double) ( y2 - y1 ),
(double) ( x2 - x1 ) ) );
da2 = fabs( atan2( (double) ( y4 - y3 ),
(double) ( x4 - x3 ) ) - k );
if( da1 >= M_PI )
da1 = 2 * M_PI - da1;
if( da2 >= M_PI )
da2 = 2 * M_PI - da2;
if( da1 + da2 < angle_tolerance )
{
// Finally we can stop the recursion
//----------------------
addSegment( wxPoint( x23, y23 ) );
return;
}
if( cusp_limit != 0.0 )
{
if( da1 > cusp_limit )
{
addSegment( wxPoint( x2, y2 ) );
return;
}
if( da2 > cusp_limit )
{
addSegment( wxPoint( x3, y3 ) );
return;
}
}
}
break;
}
// Continue subdivision
//----------------------
recursiveBezier( x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1 );
recursiveBezier( x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1 );
if( aOutput.back() != m_ctrlPts[3] )
aOutput.push_back( m_ctrlPts[3] );
}
+9 -4
View File
@@ -240,18 +240,23 @@ void BITMAP_BASE::DrawBitmap( wxDC* aDC, const wxPoint& aPos )
aDC->SetLogicalOrigin( logicalOriginX / GetScalingFactor(),
logicalOriginY / GetScalingFactor() );
pos.x = KiROUND( pos.x / GetScalingFactor() );
pos.y = KiROUND( pos.y / GetScalingFactor() );
size.x = KiROUND( size.x / GetScalingFactor() );
size.y = KiROUND( size.y / GetScalingFactor() );
aDC->SetClippingRegion( pos, size );
if( GetGRForceBlackPenState() )
{
wxBitmap result( m_bitmap->ConvertToImage().ConvertToGreyscale() );
aDC->DrawBitmap( result, KiROUND( pos.x / GetScalingFactor() ),
KiROUND( pos.y / GetScalingFactor() ), true );
aDC->DrawBitmap( result, pos.x, pos.y, true );
}
else
{
aDC->DrawBitmap( *m_bitmap, KiROUND( pos.x / GetScalingFactor() ),
KiROUND( pos.y / GetScalingFactor() ), true );
aDC->DrawBitmap( *m_bitmap, pos.x, pos.y, true );
}
aDC->DestroyClippingRegion();
aDC->SetUserScale( scale, scale );
aDC->SetLogicalOrigin( logicalOriginX, logicalOriginY );
}
+32 -13
View File
@@ -57,33 +57,46 @@ using KIGFX::COLOR4D;
COLOR4D g_GhostColor;
// When reading/writing files, we need to swtich to setlocale( LC_NUMERIC, "C" ).
// Works fine to read/write files with floating point numbers.
// We can call setlocale( LC_NUMERIC, "C" ) of wxLocale( "C", "C", "C", false )
// wxWidgets discourage a direct call to setlocale
// However, for us, calling wxLocale( "C", "C", "C", false ) has a unwanted effect:
// The I18N translations are no longer active, because the English dixtionary is selected.
// To read files, this is not a major issues, but the resul can differ
// from using setlocale(xx, "C").
// Previouly, we called setlocale( LC_NUMERIC, "C" )
// The old code will be removed when calling wxLocale( "C", "C", "C", false )
// is fully tested, and all issues fixed
#define USE_WXLOCALE 1 /* 0 to call setlocale, 1 to call wxLocale */
// On Windows, when using setlocale, a wx alert is generated
// in some cases (reading a bitmap for instance)
// So we disable alerts during the time a file is read or written
#if !USE_WXLOCALE
#if defined( _WIN32 ) && defined( DEBUG )
// a wxAssertHandler_t function to filter wxWidgets alert messages when reading/writing a file
// when switching the locale to LC_NUMERIC, "C"
// It is used in class LOCALE_IO to hide a useless (in kicad) wxWidgets alert message
void KiAssertFilter( const wxString &file, int line,
const wxString &func, const wxString &cond,
const wxString &msg)
const wxString &func, const wxString &cond,
const wxString &msg)
{
if( !msg.Contains( "Decimal separator mismatch" ) )
wxTheApp->OnAssertFailure( file, line, func, cond, msg );
wxTheApp->OnAssertFailure( file.c_str(), line, func.c_str(), cond.c_str(), msg.c_str() );
}
#endif
#endif
std::atomic<unsigned int> LOCALE_IO::m_c_count( 0 );
// Note on Windows, setlocale( LC_NUMERIC, "C" ) works fine to read/write
// files with floating point numbers, but generates a overzealous wx alert
// in some cases (reading a bitmap for instance)
// So we disable alerts during the time a file is read or written
LOCALE_IO::LOCALE_IO()
LOCALE_IO::LOCALE_IO() : m_wxLocale( nullptr )
{
// use thread safe, atomic operation
if( m_c_count++ == 0 )
{
#if USE_WXLOCALE
m_wxLocale = new wxLocale( "C", "C", "C", false );
#else
// Store the user locale name, to restore this locale later, in dtor
m_user_locale = setlocale( LC_NUMERIC, nullptr );
#if defined( _WIN32 ) && defined( DEBUG )
@@ -92,6 +105,7 @@ LOCALE_IO::LOCALE_IO()
#endif
// Switch the locale to C locale, to read/write files with fp numbers
setlocale( LC_NUMERIC, "C" );
#endif
}
}
@@ -102,10 +116,15 @@ LOCALE_IO::~LOCALE_IO()
if( --m_c_count == 0 )
{
// revert to the user locale
#if USE_WXLOCALE
delete m_wxLocale; // Deleting m_wxLocale restored previous locale
m_wxLocale = nullptr;
#else
setlocale( LC_NUMERIC, m_user_locale.c_str() );
#if defined( _WIN32 ) && defined( DEBUG )
// Enable wxWidgets alerts
wxSetDefaultAssertHandler();
#endif
#endif
}
}
@@ -425,7 +444,7 @@ wxString KIwxExpandEnvVars(const wxString& str)
if( !expanded )
strResult << (wxChar)bracket;
str_m = str[++m];
m++;
}
}
+4 -4
View File
@@ -89,10 +89,10 @@ bool KIDIALOG::Show( bool aShow )
return it->second;
}
bool ret = wxRichMessageDialog::Show( aShow );
int ret = wxRichMessageDialog::Show( aShow );
// Has the user asked not to show the dialog again
if( IsCheckBoxChecked() )
// Has the user asked not to show the dialog again and it was confirmed
if( IsCheckBoxChecked() && ret != wxID_CANCEL )
doNotShowAgainDlgs[m_hash] = ret;
return ret;
@@ -110,7 +110,7 @@ int KIDIALOG::ShowModal()
int ret = wxRichMessageDialog::ShowModal();
// Has the user asked not to show the dialog again
if( IsCheckBoxChecked() )
if( IsCheckBoxChecked() && ret != wxID_CANCEL )
doNotShowAgainDlgs[m_hash] = ret;
return ret;
+2 -3
View File
@@ -64,7 +64,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
aInfo.SetAppName( Pgm().App().GetAppName() );
/* Copyright information */
aInfo.SetCopyright( "(C) 1992-2019 KiCad Developers Team" );
aInfo.SetCopyright( "(C) 1992-2020 KiCad Developers Team" );
/* KiCad build version */
wxString version;
@@ -152,8 +152,7 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
description << "<ul>";
description << "<li>"
<< _( "Report or examine bugs - " )
<< HtmlHyperlink( "https://bugs.launchpad.net/kicad/+bugs?orderby=-id&start=0",
"https://bugs.launchpad.net/kicad" )
<< HtmlHyperlink( "https://gitlab.com/kicad/code/kicad/issues" )
<< "</li>";
description << "</ul></p>";
+19
View File
@@ -23,6 +23,18 @@
#define ALPHA_MAX 100 // the max value returned by the alpha (opacity) slider
// Configure the spin controls contained inside the dialog
void configureSpinCtrl( wxSpinCtrl* aCtrl )
{
wxSize textLength = aCtrl->GetTextExtent( "999" );
wxSize ctrlSize = aCtrl->GetSizeFromTextSize( textLength );
aCtrl->SetMinSize( ctrlSize );
aCtrl->SetSize( ctrlSize );
}
DIALOG_COLOR_PICKER::DIALOG_COLOR_PICKER( wxWindow* aParent, KIGFX::COLOR4D& aCurrentColor,
bool aAllowOpacityControl, CUSTOM_COLORS_LIST* aUserColors )
: DIALOG_COLOR_PICKER_BASE( aParent )
@@ -131,6 +143,13 @@ bool DIALOG_COLOR_PICKER::TransferDataToWindow()
SetEditVals( ALL_CHANGED );
drawAll();
// Configure the spin control sizes
configureSpinCtrl( m_spinCtrlGreen );
configureSpinCtrl( m_spinCtrlBlue );
configureSpinCtrl( m_spinCtrlRed );
configureSpinCtrl( m_spinCtrlHue );
configureSpinCtrl( m_spinCtrlSaturation );
m_notebook->GetPage( 0 )->Layout();
m_notebook->GetPage( 1 )->Layout();
+1 -11
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Mar 28 2019)
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -56,18 +56,12 @@ DIALOG_COLOR_PICKER_BASE::DIALOG_COLOR_PICKER_BASE( wxWindow* parent, wxWindowID
fgSizerRGB->Add( m_staticTextB, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_spinCtrlRed = new wxSpinCtrl( sbSizerViewRGB->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 128 );
m_spinCtrlRed->SetMinSize( wxSize( 80,-1 ) );
fgSizerRGB->Add( m_spinCtrlRed, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_spinCtrlGreen = new wxSpinCtrl( sbSizerViewRGB->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 128 );
m_spinCtrlGreen->SetMinSize( wxSize( 80,-1 ) );
fgSizerRGB->Add( m_spinCtrlGreen, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_spinCtrlBlue = new wxSpinCtrl( sbSizerViewRGB->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 128 );
m_spinCtrlBlue->SetMinSize( wxSize( 80,-1 ) );
fgSizerRGB->Add( m_spinCtrlBlue, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
@@ -103,13 +97,9 @@ DIALOG_COLOR_PICKER_BASE::DIALOG_COLOR_PICKER_BASE( wxWindow* parent, wxWindowID
fgSizerHSV->Add( m_staticTextSat, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_spinCtrlHue = new wxSpinCtrl( sbSizerViewHSV->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, 0, 359, 0 );
m_spinCtrlHue->SetMinSize( wxSize( 80,-1 ) );
fgSizerHSV->Add( m_spinCtrlHue, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_spinCtrlSaturation = new wxSpinCtrl( sbSizerViewHSV->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 128 );
m_spinCtrlSaturation->SetMinSize( wxSize( 80,-1 ) );
fgSizerHSV->Add( m_spinCtrlSaturation, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
+5 -7
View File
@@ -14,7 +14,6 @@
<property name="file">dialog_color_picker_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">DIALOG_COLOR_PICKER_BASE</property>
@@ -26,7 +25,6 @@
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
@@ -506,7 +504,7 @@
<property name="min">0</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">80,-1</property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_spinCtrlRed</property>
<property name="pane_border">1</property>
@@ -569,7 +567,7 @@
<property name="min">0</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">80,-1</property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_spinCtrlGreen</property>
<property name="pane_border">1</property>
@@ -632,7 +630,7 @@
<property name="min">0</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">80,-1</property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_spinCtrlBlue</property>
<property name="pane_border">1</property>
@@ -918,7 +916,7 @@
<property name="min">0</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">80,-1</property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_spinCtrlHue</property>
<property name="pane_border">1</property>
@@ -981,7 +979,7 @@
<property name="min">0</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">80,-1</property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_spinCtrlSaturation</property>
<property name="pane_border">1</property>
+1 -1
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Mar 28 2019)
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
+5 -21
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2019 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
@@ -23,10 +23,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file displlst.cpp
*/
#include <fctsys.h>
#include <macros.h>
#include <draw_frame.h>
@@ -46,11 +42,9 @@ EDA_LIST_DIALOG::EDA_LIST_DIALOG( EDA_DRAW_FRAME* aParent, const wxString& aTitl
const std::vector<wxArrayString>& aItemList,
const wxString& aSelection,
void( *aCallBackFunction )( wxString&, void* ),
void* aCallBackFunctionData,
bool aSortList, bool aShowHeaders ) :
void* aCallBackFunctionData ) :
EDA_LIST_DIALOG_BASE( aParent, wxID_ANY, aTitle )
{
m_sortList = aSortList;
m_cb_func = aCallBackFunction;
m_cb_data = aCallBackFunctionData;
m_itemsListCp = &aItemList;
@@ -59,9 +53,6 @@ EDA_LIST_DIALOG::EDA_LIST_DIALOG( EDA_DRAW_FRAME* aParent, const wxString& aTitl
initDialog( aItemHeaders, aSelection );
if( !aShowHeaders )
m_listBox->SetSingleStyle( wxLC_NO_HEADER, true );
// DIALOG_SHIM needs a unique hash_key because classname is not sufficient
// because so many dialogs share this same class, with different numbers of
// columns, different column names, and column widths.
@@ -111,15 +102,10 @@ void EDA_LIST_DIALOG::initDialog( const wxArrayString& aItemHeaders, const wxStr
}
void EDA_LIST_DIALOG::SetFilterHint( const wxString& aHint )
{
m_filterBox->SetHint( aHint );
}
void EDA_LIST_DIALOG::SetListLabel( const wxString& aLabel )
{
m_listLabel->SetLabel( aLabel );
m_listBox->SetSingleStyle( wxLC_NO_HEADER, true );
}
@@ -148,8 +134,7 @@ void EDA_LIST_DIALOG::textChangeInFilterBox( wxCommandEvent& event )
}
}
if( m_sortList )
sortList();
sortList();
}
@@ -219,8 +204,7 @@ void EDA_LIST_DIALOG::InsertItems( const std::vector< wxArrayString >& itemList,
}
}
if( m_sortList )
sortList();
sortList();
}
+37 -10
View File
@@ -68,6 +68,12 @@ static const wxString entrySizeX = "Size_x"; ///< Width of frame, in pixels (suf
static const wxString entryMaximized = "Maximized"; ///< Nonzero iff frame is maximized (suffix)
///@}
BEGIN_EVENT_TABLE( EDA_BASE_FRAME, wxFrame )
EVT_MOVE( EDA_BASE_FRAME::OnMove )
END_EVENT_TABLE()
EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType,
const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
long aStyle, const wxString& aFrameName ) :
@@ -279,18 +285,34 @@ void EDA_BASE_FRAME::LoadSettings( wxConfigBase* aCfg )
aCfg->Read( text, &m_autoSaveInterval, DEFAULT_AUTO_SAVE_INTERVAL );
}
// Ensure the window is on a connected display, and is visible.
// (at least a corner of the frame must be visible on screen)
// Sometimes, if a window was moved on an auxiliary display, and when this
// display is no more available, it is not the case.
wxRect rect( m_FramePos, m_FrameSize );
// Ensure window isn't bigger than can be displayed
int displayIndex = wxDisplay::GetFromPoint( m_FramePos );
if( wxDisplay::GetFromPoint( rect.GetTopLeft() ) == wxNOT_FOUND &&
wxDisplay::GetFromPoint( rect.GetTopRight() ) == wxNOT_FOUND &&
wxDisplay::GetFromPoint( rect.GetBottomLeft() ) == wxNOT_FOUND &&
wxDisplay::GetFromPoint( rect.GetBottomRight() ) == wxNOT_FOUND )
{
if( displayIndex == wxNOT_FOUND )
displayIndex = 0;
wxDisplay display( displayIndex );
wxRect clientSize = display.GetClientArea();
// The window may have been saved on a display that is no longer present.
// First, check the window origin and move it if it's off the chosen display
if( m_FramePos.x >= clientSize.x + clientSize.width ||
m_FramePos.y >= clientSize.y + clientSize.height )
m_FramePos = wxDefaultPosition;
// Now, fix up the size if needed
if( m_FrameSize.x + m_FramePos.x > clientSize.x + clientSize.width )
{
m_FrameSize.x = clientSize.width;
m_FramePos.x = 0;
}
if( m_FrameSize.y + m_FramePos.y > clientSize.y + clientSize.height )
{
m_FrameSize.y = clientSize.height;
m_FramePos.y = 0;
}
// Ensure Window title bar is visible
@@ -302,7 +324,12 @@ void EDA_BASE_FRAME::LoadSettings( wxConfigBase* aCfg )
int Ypos_min = 0;
#endif
if( m_FramePos.y < Ypos_min )
{
if( m_FrameSize.y + ( Ypos_min - m_FramePos.y ) > clientSize.height)
m_FrameSize.y = clientSize.height - Ypos_min;
m_FramePos.y = Ypos_min;
}
if( maximized )
Maximize();
+10 -12
View File
@@ -185,9 +185,9 @@ bool FILENAME_RESOLVER::createPathList()
if( GetKicadPaths( epaths ) )
{
for( const auto& i : epaths )
for( const wxString& curr_path : epaths )
{
wxString pathVal = ExpandEnvVarSubstitutions( i );
wxString pathVal = ExpandEnvVarSubstitutions( curr_path );
if( pathVal.empty() )
{
@@ -200,8 +200,8 @@ bool FILENAME_RESOLVER::createPathList()
lpath.m_pathexp = fndummy.GetFullPath();
}
lpath.m_alias = i;
lpath.m_pathvar = i;
lpath.m_alias = curr_path;
lpath.m_pathvar = curr_path;
if( !lpath.m_pathexp.empty() && psep == *lpath.m_pathexp.rbegin() )
lpath.m_pathexp.erase( --lpath.m_pathexp.end() );
@@ -219,9 +219,8 @@ bool FILENAME_RESOLVER::createPathList()
#ifdef DEBUG
wxLogTrace( MASK_3D_RESOLVER, " * [3D model] search paths:\n" );
std::list< SEARCH_PATH >::const_iterator sPL = m_Paths.begin();
std::list< SEARCH_PATH >::const_iterator ePL = m_Paths.end();
while( sPL != ePL )
while( sPL != m_Paths.end() )
{
wxLogTrace( MASK_3D_RESOLVER, " + %s : '%s'\n", (*sPL).m_alias.GetData(),
(*sPL).m_pathexp.GetData() );
@@ -636,9 +635,9 @@ bool FILENAME_RESOLVER::writePathList()
// skip all ${ENV_VAR} alias names
std::list< SEARCH_PATH >::const_iterator sPL = m_Paths.begin();
std::list< SEARCH_PATH >::const_iterator ePL = m_Paths.end();
while( sPL != ePL && ( sPL->m_alias.StartsWith( "${" ) || sPL->m_alias.StartsWith( "$(" ) ) )
while( sPL != m_Paths.end() &&
( sPL->m_alias.StartsWith( "${" ) || sPL->m_alias.StartsWith( "$(" ) ) )
++sPL;
wxFileName cfgpath( m_ConfigDir, RESOLVER_CONFIG );
@@ -662,7 +661,7 @@ bool FILENAME_RESOLVER::writePathList()
cfgFile << "#V" << CFGFILE_VERSION << "\n";
std::string tstr;
while( sPL != ePL )
while( sPL != m_Paths.end() )
{
tstr = sPL->m_alias.ToUTF8();
cfgFile << "\"" << tstr.size() << ":" << tstr << "\",";
@@ -762,10 +761,9 @@ wxString FILENAME_RESOLVER::ShortenPath( const wxString& aFullPathName )
wxCriticalSectionLocker lock( lock_resolver );
std::list< SEARCH_PATH >::const_iterator sL = m_Paths.begin();
std::list< SEARCH_PATH >::const_iterator eL = m_Paths.end();
size_t idx;
while( sL != eL )
while( sL != m_Paths.end() )
{
// undefined paths do not participate in the
// file name shortening procedure
@@ -949,7 +947,7 @@ static bool getHollerith( const std::string& aString, size_t& aIndex, wxString&
if( nchars > 0 )
{
aResult = aString.substr( i2, nchars );
aResult = wxString::FromUTF8( aString.substr( i2, nchars ).c_str() );
i2 += nchars;
}
+21 -5
View File
@@ -78,6 +78,9 @@ CAIRO_GAL_BASE::~CAIRO_GAL_BASE()
if( context )
cairo_destroy( context );
for( auto imageSurface : imageSurfaces )
cairo_surface_destroy( imageSurface );
}
@@ -424,8 +427,11 @@ void CAIRO_GAL_BASE::DrawPolygon( const SHAPE_LINE_CHAIN& aPolygon )
void CAIRO_GAL_BASE::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControlPointA,
const VECTOR2D& aControlPointB, const VECTOR2D& aEndPoint )
const VECTOR2D& aControlPointB, const VECTOR2D& aEndPoint,
double aFilterValue )
{
// Note: aFilterValue is not used because the cubic Bezier curve is
// supported by Cairo.
syncLineWidth();
const auto sp = roundp( xform( aStartPoint ) );
@@ -499,7 +505,9 @@ void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap )
cairo_surface_mark_dirty( image );
cairo_set_source_surface( currentContext, image, 0, 0 );
cairo_paint( currentContext );
cairo_surface_destroy( image );
// store the image handle so it can be destroyed later
imageSurfaces.push_back( image );
isElementAdded = true;
@@ -920,6 +928,11 @@ void CAIRO_GAL_BASE::EnableDepthTest( bool aEnabled )
void CAIRO_GAL_BASE::resetContext()
{
for( auto imageSurface : imageSurfaces )
cairo_surface_destroy( imageSurface );
imageSurfaces.clear();
ClearScreen();
// Compute the world <-> screen transformations
@@ -1256,10 +1269,13 @@ void CAIRO_GAL::endDrawing()
// Now translate the raw context data from the format stored
// by cairo into a format understood by wxImage.
pixman_image_t* dstImg = pixman_image_create_bits( PIXMAN_r8g8b8,
pixman_image_t* dstImg = pixman_image_create_bits(
wxPlatformInfo::Get().GetEndianness() == wxENDIAN_LITTLE ? PIXMAN_b8g8r8 :
PIXMAN_r8g8b8,
screenSize.x, screenSize.y, (uint32_t*) wxOutput, wxBufferWidth * 3 );
pixman_image_t* srcImg = pixman_image_create_bits( PIXMAN_a8b8g8r8,
screenSize.x, screenSize.y, (uint32_t*) bitmapBuffer, wxBufferWidth * 4 );
pixman_image_t* srcImg = pixman_image_create_bits( PIXMAN_a8r8g8b8, screenSize.x, screenSize.y,
(uint32_t*) bitmapBuffer, wxBufferWidth * 4 );
pixman_image_composite( PIXMAN_OP_SRC, srcImg, NULL, dstImg,
0, 0, 0, 0, 0, 0, screenSize.x, screenSize.y );
+11 -5
View File
@@ -64,6 +64,7 @@ static const wxChar* traceGalDispOpts = wxT( "KICAD_GAL_DISPLAY_OPTIONS" );
GAL_DISPLAY_OPTIONS::GAL_DISPLAY_OPTIONS()
: gl_antialiasing_mode( OPENGL_ANTIALIASING_MODE::NONE ),
cairo_antialiasing_mode( CAIRO_ANTIALIASING_MODE::NONE ),
m_dpi( nullptr, nullptr ),
m_gridStyle( GRID_STYLE::DOTS ),
m_gridLineWidth( 1.0 ),
m_gridMinSpacing( 10.0 ),
@@ -109,12 +110,10 @@ void GAL_DISPLAY_OPTIONS::ReadCommonConfig( wxConfigBase& aCommonConfig, wxWindo
CAIRO_ANTIALIASING_MODE_KEY, &temp, (int) KIGFX::CAIRO_ANTIALIASING_MODE::NONE );
cairo_antialiasing_mode = (KIGFX::CAIRO_ANTIALIASING_MODE) temp;
{
const DPI_SCALING dpi{ &aCommonConfig, aWindow };
m_scaleFactor = dpi.GetScaleFactor();
}
m_dpi = DPI_SCALING( &aCommonConfig, aWindow );
NotifyChanged();
// Also calls NotifyChanged
UpdateScaleFactor();
}
@@ -146,6 +145,13 @@ void GAL_DISPLAY_OPTIONS::WriteConfig( wxConfigBase& aCfg, const wxString& aBase
}
void GAL_DISPLAY_OPTIONS::UpdateScaleFactor()
{
m_scaleFactor = m_dpi.GetScaleFactor();
NotifyChanged();
}
void GAL_DISPLAY_OPTIONS::NotifyChanged()
{
wxLogTrace( traceGalDispOpts, "Change notification" );
+12 -24
View File
@@ -33,6 +33,7 @@
#include <geometry/shape_poly_set.h>
#include <text_utils.h>
#include <bitmap_base.h>
#include <bezier_curves.h>
#include <macros.h>
@@ -1034,34 +1035,21 @@ void OPENGL_GAL::DrawPolygon( const SHAPE_LINE_CHAIN& aPolygon )
void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControlPointA,
const VECTOR2D& aControlPointB, const VECTOR2D& aEndPoint )
const VECTOR2D& aControlPointB, const VECTOR2D& aEndPoint,
double aFilterValue )
{
// FIXME The drawing quality needs to be improved
// FIXME Perhaps choose a quad/triangle strip instead?
// FIXME Brute force method, use a better (recursive?) algorithm
std::vector<VECTOR2D> output;
std::vector<VECTOR2D> pointCtrl;
std::deque<VECTOR2D> pointList;
pointCtrl.push_back( aStartPoint );
pointCtrl.push_back( aControlPointA );
pointCtrl.push_back( aControlPointB );
pointCtrl.push_back( aEndPoint );
double t = 0.0;
double dt = 1.0 / (double) CURVE_POINTS;
BEZIER_POLY converter( pointCtrl );
converter.GetPoly( output, aFilterValue );
for( int i = 0; i <= CURVE_POINTS; i++ )
{
double omt = 1.0 - t;
double omt2 = omt * omt;
double omt3 = omt * omt2;
double t2 = t * t;
double t3 = t * t2;
VECTOR2D vertex = omt3 * aStartPoint + 3.0 * t * omt2 * aControlPointA
+ 3.0 * t2 * omt * aControlPointB + t3 * aEndPoint;
pointList.push_back( vertex );
t += dt;
}
DrawPolyline( pointList );
DrawPolyline( &output[0], output.size() );
}
+54 -11
View File
@@ -268,33 +268,78 @@ std::string GBR_APERTURE_METADATA::FormatAttribute( GBR_APERTURE_ATTRIB aAttribu
return full_attribute_string;
}
// Helper function to convert a ascii hex char to its integer value
// If the char is not a hexa char, return -1
int char2Hex( unsigned aCode )
{
if( aCode >= '0' && aCode <= '9' )
return aCode - '0';
if( aCode >= 'A' && aCode <= 'F' )
return aCode - 'A' + 10;
if( aCode >= 'a' && aCode <= 'f' )
return aCode - 'a' + 10;
return -1;
}
wxString FormatStringFromGerber( const wxString& aString )
{
// make the inverse conversion of formatStringToGerber()
// It converts a "normalized" gerber string and convert it to a 16 bits sequence unicode
// and return a wxString (unicode 16) from the gerber string
// Note the initial gerber string can already contain unicode chars.
wxString txt;
for( unsigned ii = 0; ii < aString.Length(); ++ii )
unsigned count = aString.Length();
for( unsigned ii = 0; ii < count; ++ii )
{
unsigned code = aString[ii];
if( code == '\\' )
if( code == '\\' && ii < count-5 && aString[ii+1] == 'u' )
{
// Convert 4 hexadecimal digits to a 16 bit unicode
// Note the latest Gerber X2 spec (2019 06) uses \uXXXX to encode
// the unicode XXXX hexadecimal value
// If 4 chars next to 'u' are hexadecimal chars,
// convert these 4 hexadecimal digits to a 16 bit unicode
// (Gerber allows only 4 hexadecimal digits)
// If an error occurs, the escape sequence is not translated,
// and used "as this"
long value = 0;
bool error = false;
for( int jj = 0; jj < 4; jj++ )
{
value <<= 4;
code = aString[++ii];
// Very basic conversion, but it expects a valid gerber file
int hexa = (code <= '9' ? code - '0' : code - 'A' + 10) & 0xF;
value += hexa;
code = aString[ii+jj+2];
int hexa = char2Hex( code );
if( hexa >= 0 )
value += hexa;
else
{
error = true;
break;
}
}
txt.Append( wxChar( value ) );
if( !error )
{
if( value >= ' ' ) // Is a valid wxChar ?
txt.Append( wxChar( value ) );
ii += 5;
}
else
{
txt.Append( aString[ii] );
continue;
}
}
else
txt.Append( aString[ii] );
@@ -334,12 +379,10 @@ std::string formatStringToGerber( const wxString& aString )
if( convert || code > 0x7F )
{
txt += '\\';
// Convert code to 4 hexadecimal digit
// (Gerber allows only 4 hexadecimal digit)
char hexa[32];
sprintf( hexa,"%4.4X", code & 0xFFFF);
sprintf( hexa,"\\u%4.4X", code & 0xFFFF);
txt += hexa;
}
else
+11 -2
View File
@@ -33,6 +33,7 @@ int sgn( T aVal )
bool SEG::PointCloserThan( const VECTOR2I& aP, int aDist ) const
{
// See http://geomalgorithms.com/a02-_lines.html for some explanations and ideas.
VECTOR2I d = B - A;
ecoord dist_sq = (ecoord) aDist * aDist;
@@ -44,9 +45,17 @@ bool SEG::PointCloserThan( const VECTOR2I& aP, int aDist ) const
else if( t >= l_squared )
return ( aP - B ).SquaredEuclideanNorm() < dist_sq;
int dxdy = abs( d.x ) - abs( d.y );
// JPC: This code is not trivial and is not commented
// and does not work for d.x or d.y = -1...1
// I am guessing it is here for calculation time optimization.
// if someone can understand it, please fix it.
// It can be tested with a segment having d.x or d.y value
// is -1 or +1 ("this" is a quasi vertical or horizontal segment)
int dxdy = std::abs( d.x ) - std::abs( d.y );
if( ( dxdy >= -1 && dxdy <= 1 ) || abs( d.x ) <= 1 || abs( d.y ) <= 1 )
if( ( dxdy >= -1 && dxdy <= 1 ) // quasi 45 deg segment
/*|| std::abs( d.x ) <= 1 // quasi horizontal segment
|| std::abs( d.y ) <= 1 // quasi vertical segment */ )
{
int ca = -sgn( d.y );
int cb = sgn( d.x );
+2
View File
@@ -458,6 +458,8 @@ int SHAPE_POLY_SET::AddHole( const SHAPE_LINE_CHAIN& aHole, int aOutline )
POLYGON& poly = m_polys[aOutline];
assert( aOutline < (int)m_polys.size() );
assert( poly.size() );
poly.push_back( aHole );
+5
View File
@@ -351,7 +351,12 @@ bool OpenPDF( const wxString& file )
if( !Pgm().UseSystemPdfBrowser() ) // Run the preferred PDF Browser
{
#ifdef __WXMSW__
// Windows requires double quotes around the filename to handle spaces
command = Pgm().GetPdfBrowserName() + wxT( " \"" ) + filename + wxT( "\"" );
#else
command = Pgm().GetPdfBrowserName() + wxT( " '" ) + filename + wxT( "'" );
#endif
}
else
{
+7 -36
View File
@@ -1148,45 +1148,16 @@ void ClipAndDrawPoly( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aPoints[], int n )
}
void GRBezier( EDA_RECT* ClipBox,
wxDC* DC,
int x1,
int y1,
int x2,
int y2,
int x3,
int y3,
int width,
COLOR4D Color )
void GRBezier( EDA_RECT* aClipBox, wxDC* aDC,
std::vector<wxPoint>& aPoint,
int aWidth, COLOR4D aColor )
{
std::vector<wxPoint> points;
std::vector<wxPoint> output;
BEZIER_POLY converter( x1, y1, x2, y2, x3, y3 );
converter.GetPoly( points );
BEZIER_POLY converter( aPoint );
converter.GetPoly( output, aWidth );
GRPoly( ClipBox, DC, points.size(), &points[0], false, width, Color, Color );
}
void GRBezier( EDA_RECT* ClipBox,
wxDC* DC,
int x1,
int y1,
int x2,
int y2,
int x3,
int y3,
int x4,
int y4,
int width,
COLOR4D Color )
{
std::vector<wxPoint> points;
BEZIER_POLY converter( x1, y1, x2, y2, x3, y3, x4, y4 );
converter.GetPoly( points );
GRPoly( ClipBox, DC, points.size(), &points[0], false, width, Color, Color );
GRPoly( aClipBox, aDC, output.size(), &output[0], false, aWidth, aColor, aColor );
}
+1 -1
View File
@@ -500,7 +500,7 @@ void GRID_TRICKS::onUpdateUI( wxUpdateUIEvent& event )
}
}
if( !cursorInSelectedRow )
if( !cursorInSelectedRow && cursorRow >= 0 )
m_grid->SelectRow( cursorRow );
}
}
+17
View File
@@ -672,6 +672,23 @@ void EDA_DRAW_FRAME::OnSize( wxSizeEvent& SizeEv )
}
void EDA_DRAW_FRAME::OnMove( wxMoveEvent& aEvent )
{
// If the window is moved to a different display, the scaling factor may change
double oldFactor = m_galDisplayOptions.m_scaleFactor;
m_galDisplayOptions.UpdateScaleFactor();
if( oldFactor != m_galDisplayOptions.m_scaleFactor )
{
wxSize clientSize = GetClientSize();
GetGalCanvas()->GetGAL()->ResizeScreen( clientSize.x, clientSize.y );
GetGalCanvas()->GetView()->MarkDirty();
}
aEvent.Skip();
}
void EDA_DRAW_FRAME::SetToolID( int aId, int aCursor, const wxString& aToolMsg )
{
// Keep default cursor in toolbars
+6
View File
@@ -687,6 +687,12 @@ void EDA_DRAW_FRAME::OnSize( wxSizeEvent& SizeEv )
}
void EDA_DRAW_FRAME::OnMove( wxMoveEvent& aEvent )
{
aEvent.Skip();
}
void EDA_DRAW_FRAME::SetToolID( int aId, int aCursor, const wxString& aToolMsg )
{
// Keep default cursor in toolbars
+8 -5
View File
@@ -286,17 +286,20 @@ std::string LSET::FmtHex() const
static const char hex[] = "0123456789abcdef";
int nibble_count = ( size() + 3 ) / 4;
unsigned nibble_count = ( size() + 3 ) / 4;
for( int nibble=0; nibble<nibble_count; ++nibble )
for( unsigned nibble = 0; nibble < nibble_count; ++nibble )
{
unsigned ndx = 0;
// test 4 consecutive bits and set ndx to 0-15:
for( int nibble_bit=0; nibble_bit<4; ++nibble_bit )
for( unsigned nibble_bit = 0; nibble_bit < 4; ++nibble_bit )
{
if( (*this)[nibble_bit + nibble*4] )
ndx |= (1 << nibble_bit);
if( ( nibble_bit + nibble * 4 ) >= size() )
break;
if( (*this)[nibble_bit + nibble * 4] )
ndx |= ( 1 << nibble_bit );
}
if( nibble && !( nibble % 8 ) )
+199 -54
View File
@@ -1,8 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2020 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
@@ -217,6 +217,10 @@ bool GERBER_PLOTTER::StartPlot()
// Be sure the usual dark polarity is selected:
fputs( "%LPD*%\n", outputFile );
// Set initial interpolation mode: always G01 (linear):
fputs( "G01*\n", outputFile );
// Set aperture list starting point:
fputs( "G04 APERTURE LIST*\n", outputFile );
return true;
@@ -327,10 +331,7 @@ void GERBER_PLOTTER::selectAperture( const wxSize& aSize,
( currentAperture->m_Type != aType ) ||
( currentAperture->m_Size != aSize );
if( !m_useNetAttributes )
aApertureAttribute = 0;
else
change = change || ( currentAperture->m_ApertureAttribute != aApertureAttribute );
change = change || ( currentAperture->m_ApertureAttribute != aApertureAttribute );
if( change )
{
@@ -474,21 +475,34 @@ void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAn
{
SetCurrentLineWidth( aWidth );
// aFill is not used here.
plotArc( aCenter, aStAngle, aEndAngle, aRadius, false );
}
void GERBER_PLOTTER::plotArc( const wxPoint& aCenter, double aStAngle, double aEndAngle,
int aRadius, bool aPlotInRegion )
{
wxPoint start, end;
start.x = aCenter.x + KiROUND( cosdecideg( aRadius, aStAngle ) );
start.y = aCenter.y - KiROUND( sindecideg( aRadius, aStAngle ) );
MoveTo( start );
if( !aPlotInRegion )
MoveTo( start );
else
LineTo( start );
end.x = aCenter.x + KiROUND( cosdecideg( aRadius, aEndAngle ) );
end.y = aCenter.y - KiROUND( sindecideg( aRadius, aEndAngle ) );
DPOINT devEnd = userToDeviceCoordinates( end );
DPOINT devCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start );
fprintf( outputFile, "G75*\n" ); // Multiquadrant (360 degrees) mode
fprintf( outputFile, "G75*\n" ); // Multiquadrant (360 degrees) mode
if( aStAngle < aEndAngle )
fprintf( outputFile, "G03" );
fprintf( outputFile, "G03*\n" ); // Active circular interpolation, CCW
else
fprintf( outputFile, "G02" );
fprintf( outputFile, "G02*\n" ); // Active circular interpolation, CW
fprintf( outputFile, "X%dY%dI%dJ%dD01*\n",
KiROUND( devEnd.x ), KiROUND( devEnd.y ),
@@ -736,33 +750,28 @@ void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, doub
else // Plot pad as region.
// Only regions and flashed items accept a object attribute TO.P for the pin name
{
if( size.x > size.y )
{
std::swap( size.x, size.y );
if( orient < 2700 )
orient += 900;
else
orient -= 2700;
}
if( trace_mode == FILLED )
{
// TODO: use an aperture macro to declare the rotated pad
// to be able to flash the shape
// For now, the pad is drawn as segment
// The pad is reduced to an segment with dy > dx
int delta = size.y - size.x;
wxPoint p0( 0, -delta / 2 );
wxPoint p1( 0, delta / 2 );
RotatePoint( &p0.x, &p0.y, orient );
RotatePoint( &p1.x, &p1.y, orient );
ThickSegment( pos + p0, pos + p1, size.x, trace_mode, gbr_metadata );
// Draw the oval as round rect pad with a radius = 50% min size)
// In gerber file, it will be drawn as a region with arcs, and can be
// detected as pads (similar to a flashed pad)
FlashPadRoundRect( pos, aSize, std::min( aSize.x, aSize.y ) /2,
orient, FILLED, aData );
}
else
else // Non filled shape: plot outlines:
{
if( size.x > size.y )
{
std::swap( size.x, size.y );
if( orient < 2700 )
orient += 900;
else
orient -= 2700;
}
sketchOval( pos, size, orient, -1 );
}
}
}
@@ -840,36 +849,172 @@ void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
EDA_DRAW_MODE_T aTraceMode, void* aData )
{
GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
// Currently, a Pad RoundRect is plotted as polygon.
// TODO: use Aperture macro and flash it
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 64;
TransformRoundRectToPolygon( outline, aPadPos, aSize, aOrient,
aCornerRadius, segmentToCircleCount );
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
if( aTraceMode != FILLED )
{
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 64;
TransformRoundRectToPolygon( outline, aPadPos, aSize, aOrient,
aCornerRadius, segmentToCircleCount );
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &gbr_metadata );
outline.Inflate( -GetCurrentLineWidth()/2, 16 );
std::vector< wxPoint > cornerList;
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
cornerList.reserve( poly.PointCount() + 1 );
for( int ii = 0; ii < poly.PointCount(); ++ii )
cornerList.emplace_back( poly.CPoint( ii ).x, poly.CPoint( ii ).y );
// Close polygon
cornerList.push_back( cornerList[0] );
// plot outlines
PlotPoly( cornerList, NO_FILL, GetCurrentLineWidth(), gbr_metadata );
}
else
{
// A Pad RoundRect is plotted as a Gerber region.
// Initialize region metadata:
bool clearTA_AperFunction = false; // true if a TA.AperFunction is used
if( gbr_metadata )
{
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
std::string attrib = gbr_metadata->m_ApertureMetadata.FormatAttribute( !m_useX2format );
if( !attrib.empty() )
{
fputs( attrib.c_str(), outputFile );
clearTA_AperFunction = true;
}
}
// Plot the region using arcs in corners.
plotRoundRectAsRegion( aPadPos, aSize, aCornerRadius, aOrient );
// Clear the TA attribute, to avoid the next item to inherit it:
if( clearTA_AperFunction )
{
if( m_useX2format )
{
fputs( "%TD.AperFunction*%\n", outputFile );
}
else
{
fputs( "G04 #@! TD.AperFunction*\n", outputFile );
}
}
}
}
void GERBER_PLOTTER::plotRoundRectAsRegion( const wxPoint& aRectCenter, const wxSize& aSize,
int aCornerRadius, double aOrient )
{
// The region outline is generated by 4 sides and 4 90 deg arcs
// 1 --- 2
// | c |
// 4 --- 3
// Note also in user coordinates the Y axis is from top to bottom
// for historical reasons.
// A helper structure to handle outlines coordinates (segments and arcs)
// in user coordinates
struct RR_EDGE
{
wxPoint m_start;
wxPoint m_end;
wxPoint m_center;
// in decidegrees: angle start. angle end = m_arc_angle_start+arc_angle
double m_arc_angle_start;
};
const double arc_angle = -900.0; // in decidegrees
int hsizeX = aSize.x/2;
int hsizeY = aSize.y/2;
RR_EDGE curr_edge;
std::vector<RR_EDGE> rr_outline;
// Build outline coordinates, relative to rectangle center, rotation 0:
// Top left corner 1 (and 4 to 1 left vertical side @ x=-hsizeX)
curr_edge.m_start.x = -hsizeX;
curr_edge.m_start.y = hsizeY - aCornerRadius;
curr_edge.m_end.x = curr_edge.m_start.x;
curr_edge.m_end.y = -hsizeY + aCornerRadius;
curr_edge.m_center.x = -hsizeX + aCornerRadius;
curr_edge.m_center.y = curr_edge.m_end.y;
curr_edge.m_arc_angle_start = aOrient + 1800.0; // En decidegree
rr_outline.push_back( curr_edge );
// Top right corner 2 (and 1 to 2 top horizontal side @ y=-hsizeY)
curr_edge.m_start.x = -hsizeX + aCornerRadius;
curr_edge.m_start.y = -hsizeY;
curr_edge.m_end.x = hsizeX - aCornerRadius;
curr_edge.m_end.y = curr_edge.m_start.y;
curr_edge.m_center.x = curr_edge.m_end.x;
curr_edge.m_center.y = -hsizeY + aCornerRadius;
curr_edge.m_arc_angle_start = aOrient + 900.0; // En decidegree
rr_outline.push_back( curr_edge );
// bottom right corner 3 (and 2 to 3 right vertical side @ x=hsizeX)
curr_edge.m_start.x = hsizeX;
curr_edge.m_start.y = -hsizeY + aCornerRadius;
curr_edge.m_end.x = curr_edge.m_start.x;
curr_edge.m_end.y = hsizeY - aCornerRadius;
curr_edge.m_center.x = hsizeX - aCornerRadius;
curr_edge.m_center.y = curr_edge.m_end.y;
curr_edge.m_arc_angle_start = aOrient + 0.0; // En decidegree
rr_outline.push_back( curr_edge );
// bottom left corner 4 (and 3 to 4 bottom horizontal side @ y=hsizeY)
curr_edge.m_start.x = hsizeX - aCornerRadius;
curr_edge.m_start.y = hsizeY;
curr_edge.m_end.x = -hsizeX + aCornerRadius;
curr_edge.m_end.y = curr_edge.m_start.y;
curr_edge.m_center.x = curr_edge.m_end.x;
curr_edge.m_center.y = hsizeY - aCornerRadius;
curr_edge.m_arc_angle_start = aOrient - 900.0; // En decidegree
rr_outline.push_back( curr_edge );
// Move relative coordinates to the actual location and rotation:
for( RR_EDGE& rr_edge: rr_outline )
{
RotatePoint( &rr_edge.m_start, aOrient );
RotatePoint( &rr_edge.m_end, aOrient );
RotatePoint( &rr_edge.m_center, aOrient );
rr_edge.m_start += aRectCenter;
rr_edge.m_end += aRectCenter;
rr_edge.m_center += aRectCenter;
}
std::vector< wxPoint > cornerList;
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
cornerList.reserve( poly.PointCount() + 1 );
fputs( "G36*\n", outputFile ); // Start region
fputs( "G01*\n", outputFile ); // Set linear interpolation.
MoveTo( rr_outline[0].m_start ); // Start point of region
for( int ii = 0; ii < poly.PointCount(); ++ii )
cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
for( RR_EDGE& rr_edge: rr_outline )
{
if( aCornerRadius ) // Guard: ensure we do not create arcs with radius = 0
{
// LineTo( rr_edge.m_end ); // made in plotArc()
plotArc( rr_edge.m_center, rr_edge.m_arc_angle_start, rr_edge.m_arc_angle_start+arc_angle,
aCornerRadius, true );
}
else
LineTo( rr_edge.m_end );
}
// Close polygon
cornerList.push_back( cornerList[0] );
if( aTraceMode == SKETCH )
PlotPoly( cornerList, NO_FILL, GetCurrentLineWidth(), gbr_metadata );
else
PlotGerberRegion( cornerList, gbr_metadata );
fputs( "G37*\n", outputFile ); // Close region
}
+62 -13
View File
@@ -6,8 +6,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2020 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
@@ -90,6 +90,8 @@
* flag_sweep : 0 = CCW, 1 = CW
* The center of ellipse is automatically calculated.
*/
#include <base64.h>
#include <fctsys.h>
#include <trigo.h>
#include <eda_base_frame.h>
@@ -100,6 +102,8 @@
#include <macros.h>
#include <kicad_string.h>
#include <cstdint>
#include <wx/mstream.h>
/**
@@ -499,7 +503,7 @@ void SVG_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i
setFillMode( NO_FILL );
SetCurrentLineWidth( width );
fprintf( outputFile, "<path d=\"M%g %g A%g %g 0.0 %d %d %g %g \" />\n",
fprintf( outputFile, "<path d=\"M%g %g A%g %g 0.0 %d %d %g %g\" />\n",
start.x, start.y, radius_dev, radius_dev,
flg_arc, flg_sweep,
end.x, end.y );
@@ -554,12 +558,51 @@ void SVG_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
void SVG_PLOTTER::PlotImage( const wxImage& aImage, const wxPoint& aPos,
double aScaleFactor )
{
// in svg file we must insert a link to a png image file to plot an image
// the image itself is not included in the svg file.
// So we prefer skip the image, and just draw a rectangle,
// like other plotters which do not support images
wxSize pix_size( aImage.GetWidth(), aImage.GetHeight() );
// Requested size (in IUs)
DPOINT drawsize( aScaleFactor * pix_size.x,
aScaleFactor * pix_size.y );
// calculate the bitmap start position
wxPoint start( aPos.x - drawsize.x / 2,
aPos.y - drawsize.y / 2);
// Rectangles having a 0 size value for height or width are just not drawn on Inscape,
// so use a line when happens.
if( drawsize.x == 0.0 || drawsize.y == 0.0 ) // Draw a line
{
PLOTTER::PlotImage( aImage, aPos, aScaleFactor );
}
else
{
wxMemoryOutputStream img_stream;
aImage.SaveFile( img_stream, wxBITMAP_TYPE_PNG );
size_t input_len = img_stream.GetOutputStreamBuffer()->GetBufferSize();
std::vector<uint8_t> buffer( input_len );
std::vector<uint8_t> encoded;
img_stream.CopyTo( buffer.data(), buffer.size() );
base64::encode( buffer, encoded );
fprintf( outputFile,
"<image x=\"%g\" y=\"%g\" xlink:href=\"data:image/png;base64,",
userToDeviceSize( start.x ), userToDeviceSize( start.y )
);
for( size_t i = 0; i < encoded.size(); i++ )
{
fprintf( outputFile, "%c", static_cast<char>( encoded[i] ) );
if( ( i % 64 ) == 63 )
fprintf( outputFile, "\n" );
}
fprintf( outputFile, "\"\npreserveAspectRatio=\"none\" width=\"%g\" height=\"%g\" />",
userToDeviceSize( drawsize.x ), userToDeviceSize( drawsize.y ) );
}
PLOTTER::PlotImage( aImage, aPos, aScaleFactor );
}
@@ -620,7 +663,11 @@ bool SVG_PLOTTER::StartPlot()
"<?xml version=\"1.0\" standalone=\"no\"?>\n",
" <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> \n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" \n",
"<svg\n"
" xmlns:svg=\"http://www.w3.org/2000/svg\"\n"
" xmlns=\"http://www.w3.org/2000/svg\"\n",
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n",
" version=\"1.1\"\n",
NULL
};
@@ -633,7 +680,7 @@ bool SVG_PLOTTER::StartPlot()
// Write viewport pos and size
wxPoint origin; // TODO set to actual value
fprintf( outputFile,
" width=\"%gcm\" height=\"%gcm\" viewBox=\"%d %d %d %d \">\n",
" width=\"%fcm\" height=\"%fcm\" viewBox=\"%d %d %d %d\">\n",
(double) paperSize.x / m_IUsPerDecimil * 2.54 / 10000,
(double) paperSize.y / m_IUsPerDecimil * 2.54 / 10000,
origin.x, origin.y,
@@ -660,7 +707,7 @@ bool SVG_PLOTTER::StartPlot()
m_brush_rgb_color, opacity, m_pen_rgb_color, opacity );
// output the pen cap and line joint
fputs( "stroke-linecap:round; stroke-linejoin:round; \"\n", outputFile );
fputs( "stroke-linecap:round; stroke-linejoin:round;\"\n", outputFile );
fputs( " transform=\"translate(0 0) scale(1 1)\">\n", outputFile );
return true;
}
@@ -734,8 +781,10 @@ void SVG_PLOTTER::Text( const wxPoint& aPos,
}
wxSize text_size;
text_size.x = GraphicTextWidth( aText, aSize, aItalic, width );
text_size.y = aSize.x * 4/3; // Hershey font height to em size conversion
// aSize.x or aSize.y is < 0 for mirrored texts.
// The actual text size value is the absolue value
text_size.x = std::abs( GraphicTextWidth( aText, aSize, aItalic, width ) );
text_size.y = std::abs( aSize.x * 4/3 ); // Hershey font height to em size conversion
DPOINT anchor_pos_dev = userToDeviceCoordinates( aPos );
DPOINT text_pos_dev = userToDeviceCoordinates( text_pos );
DPOINT sz_dev = userToDeviceSize( text_size );
+2
View File
@@ -96,6 +96,7 @@ principle should be easily implemented by adapting the current STL containers.
#include <marker_base.h>
#include <eda_text.h>
#include <convert_to_biu.h>
#include <build_version.h>
%}
// all the wx wrappers for wxString, wxPoint, wxRect, wxChar ..
@@ -116,6 +117,7 @@ principle should be easily implemented by adapting the current STL containers.
%include colors_design_settings.h
%include marker_base.h
%include eda_text.h
%include build_version.h
// Cast time_t to known type for Python
typedef long time_t;
-56
View File
@@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFile</key>
<string>cvpcb_doc.icns</string>
<key>CFBundleTypeExtensions</key>
<array>
<string>net</string>
<string>cmp</string>
</array>
<key>CFBundleTypeName</key>
<string>cvpcb document</string>
<key>LSHandlerRank</key>
<string>Owner</string>
</dict>
</array>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>cvpcb</string>
<key>CFBundleGetInfoString</key>
<string></string>
<key>CFBundleIconFile</key>
<string>cvpcb.icns</string>
<key>CFBundleIdentifier</key>
<string>org.kicad-pcb.cvpcb</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>@KICAD_VERSION_FULL@</string>
<key>CFBundleName</key>
<string>CvPcb</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>@KICAD_VERSION@</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>@KICAD_VERSION_FULL@</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSRequiresCarbon</key>
<true/>
<key>NSRequiresAquaSystemAppearance</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>NSHighResolutionCapable</key>
<string>True</string>
</dict>
</plist>
+1 -4
View File
@@ -394,11 +394,8 @@ endif()
# these 2 binaries are a matched set, keep them together:
if( APPLE )
include( ${CMAKE_MODULE_PATH}/KiCadVersion.cmake )
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist @ONLY )
set_target_properties( eeschema PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
MACOSX_BUNDLE_INFO_PLIST ${PROJECT_BINARY_DIR}/eeschema/Info.plist
)
# puts binaries into the *.app bundle while linking
+34 -17
View File
@@ -38,7 +38,7 @@
#include <class_library.h>
void mapExistingAnnotation( std::map<timestamp_t, wxString>& aMap )
void mapExistingAnnotation( std::map<wxString, wxString>& aMap )
{
SCH_SHEET_LIST sheets( g_RootSheet );
SCH_REFERENCE_LIST references;
@@ -48,10 +48,19 @@ void mapExistingAnnotation( std::map<timestamp_t, wxString>& aMap )
for( size_t i = 0; i < references.GetCount(); i++ )
{
SCH_COMPONENT* comp = references[ i ].GetComp();
wxString ref = comp->GetField( REFERENCE )->GetFullyQualifiedText();
const SCH_SHEET_PATH* curr_sheetpath = &references[ i ].GetSheetPath();
wxString full_path = curr_sheetpath->Path();
full_path += wxString::Format( wxT( "/%8.8lX" ),
(unsigned long) comp->GetTimeStamp() );
wxString ref = comp->GetRef( (SCH_SHEET_PATH*)curr_sheetpath );
if( comp->GetUnitCount() > 1 )
ref << LIB_PART::SubReference( comp->GetUnitSelection( curr_sheetpath ) );
if( !ref.Contains( wxT( "?" ) ) )
aMap[ comp->GetTimeStamp() ] = ref;
aMap[ full_path ] = ref;
}
}
@@ -99,7 +108,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents;
// Map of previous annotation for building info messages
std::map<timestamp_t, wxString> previousAnnotation;
std::map<wxString, wxString> previousAnnotation;
// Test for and replace duplicate time stamps in components and sheets. Duplicate
// time stamps can happen with old schematics, schematic conversions, or manual
@@ -191,9 +200,19 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
for( size_t i = 0; i < references.GetCount(); i++ )
{
SCH_COMPONENT* comp = references[ i ].GetComp();
wxString prevRef = previousAnnotation[ comp->GetTimeStamp() ];
wxString newRef = comp->GetField( REFERENCE )->GetFullyQualifiedText();
wxString msg;
const SCH_SHEET_PATH* curr_sheetpath = &references[ i ].GetSheetPath();
wxString curr_full_path = curr_sheetpath->Path();
curr_full_path += wxString::Format( wxT( "/%8.8lX" ),
(unsigned long) comp->GetTimeStamp() );
wxString prevRef = previousAnnotation[ curr_full_path ];
wxString newRef = comp->GetRef( curr_sheetpath );
if( comp->GetUnitCount() > 1 )
newRef << LIB_PART::SubReference( comp->GetUnitSelection( curr_sheetpath ) );
wxString msg;
if( prevRef.Length() )
{
@@ -202,27 +221,25 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
if( comp->GetUnitCount() > 1 )
msg.Printf( _( "Updated %s (unit %s) from %s to %s" ),
GetChars( comp->GetField( VALUE )->GetShownText() ),
comp->GetField( VALUE )->GetShownText(),
LIB_PART::SubReference( comp->GetUnit(), false ),
GetChars( prevRef ),
GetChars( newRef ) );
prevRef, newRef );
else
msg.Printf( _( "Updated %s from %s to %s" ),
GetChars( comp->GetField( VALUE )->GetShownText() ),
GetChars( prevRef ),
GetChars( newRef ) );
comp->GetField( VALUE )->GetShownText(),
prevRef, newRef );
}
else
{
if( comp->GetUnitCount() > 1 )
msg.Printf( _( "Annotated %s (unit %s) as %s" ),
GetChars( comp->GetField( VALUE )->GetShownText() ),
comp->GetField( VALUE )->GetShownText(),
LIB_PART::SubReference( comp->GetUnit(), false ),
GetChars( newRef ) );
newRef );
else
msg.Printf( _( "Annotated %s as %s" ),
GetChars( comp->GetField( VALUE )->GetShownText() ),
GetChars( newRef ) );
comp->GetField( VALUE )->GetShownText(),
newRef );
}
aReporter.Report( msg, REPORTER::RPT_ACTION );
+12 -3
View File
@@ -595,8 +595,7 @@ void LIB_PART::RemoveDrawItem( LIB_ITEM* aItem, EDA_DRAW_PANEL* aPanel, wxDC* aD
{
wxLogWarning( _(
"An attempt was made to remove the %s field from component %s in library %s." ),
GetChars( field->GetName() ), GetChars( GetName() ),
GetChars( GetLibraryName() ) );
field->GetName( TRANSLATE_FIELD_NAME ), GetName(), GetLibraryName() );
return;
}
}
@@ -716,6 +715,15 @@ bool LIB_PART::PinsConflictWith( LIB_PART& aOtherPart, bool aTestNums, bool aTes
for( LIB_PIN* eachOtherPin : otherPinList )
{
wxASSERT( eachOtherPin );
// Same unit?
if( eachThisPin->GetUnit() != eachOtherPin->GetUnit() )
continue;
// Same body stype?
if( eachThisPin->GetConvert() != eachOtherPin->GetConvert() )
continue;
// Same position?
if( eachThisPin->GetPosition() != eachOtherPin->GetPosition() )
continue;
@@ -741,6 +749,7 @@ bool LIB_PART::PinsConflictWith( LIB_PART& aOtherPart, bool aTestNums, bool aTes
continue;
foundMatch = true;
break; // Match found so seach is complete.
}
if( !foundMatch )
@@ -894,7 +903,7 @@ LIB_FIELD* LIB_PART::FindField( const wxString& aFieldName )
{
LIB_FIELD* field = ( LIB_FIELD* ) &item;
if( field->GetName() == aFieldName )
if( field->GetName( NATIVE_FIELD_NAME ) == aFieldName )
return field;
}
+2 -1
View File
@@ -403,7 +403,8 @@ public:
void GetFields( LIB_FIELDS& aList );
/**
* Findd a field within this part matching \a aFieldName and returns it or NULL if not found.
* Find a field within this part matching \a aFieldName and returns it
* or NULL if not found.
*/
LIB_FIELD* FindField( const wxString& aFieldName );
+1 -1
View File
@@ -217,7 +217,7 @@ void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event )
dlg.SetOKLabel( _( "Clear and Annotate" ) );
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
if( dlg.ShowModal() == wxCANCEL )
if( dlg.ShowModal() == wxID_CANCEL )
return;
}
@@ -484,7 +484,6 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow()
// parts.
if( m_cmp->GetUnitCount() > 1 )
{
const LIB_ID thisLibId = m_cmp->GetLibId();
const wxString thisRef = m_cmp->GetRef( &( GetParent()->GetCurrentSheet() ) );
int thisUnit = m_cmp->GetUnit();
@@ -495,9 +494,7 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataFromWindow()
{
SCH_REFERENCE component = components[i];
if( component.GetLibPart()->GetLibId() == thisLibId
&& component.GetRef() == thisRef
&& component.GetUnit() != thisUnit )
if( component.GetRef() == thisRef && component.GetUnit() != thisUnit )
{
SCH_COMPONENT* otherUnit = component.GetComp();
GetParent()->SaveCopyInUndoList( otherUnit, UR_CHANGED, true /* append */);
+31 -7
View File
@@ -34,6 +34,7 @@
#include <confirm.h>
#include <kicad_string.h>
#include <sch_base_frame.h>
#include <sch_edit_frame.h>
#include <sch_component.h>
#include <class_libentry.h>
#include <lib_field.h>
@@ -43,7 +44,7 @@
#include <sch_validators.h>
#include <dialog_edit_one_field.h>
#include <sch_reference_list.h>
// These should probably moved into some other file as helpers.
EDA_TEXT_HJUSTIFY_T IntToEdaTextHorizJustify( int aHorizJustify )
@@ -275,12 +276,13 @@ DIALOG_SCH_EDIT_ONE_FIELD::DIALOG_SCH_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent,
void DIALOG_SCH_EDIT_ONE_FIELD::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH* aSheetPath )
{
SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( aField->GetParent() );
int fieldType = aField->GetId();
if( aField->GetId() == REFERENCE )
{
wxASSERT( aSheetPath );
SCH_COMPONENT* component = dynamic_cast< SCH_COMPONENT* >( aField->GetParent() );
wxASSERT( component );
if( component )
@@ -304,9 +306,31 @@ void DIALOG_SCH_EDIT_ONE_FIELD::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH*
aField->SetText( m_text );
updateText( aField );
if( positioningModified )
// The value, footprint and datasheet fields should be kept in sync in multi-unit
// parts.
if( editFrame && component && component->GetUnitCount() > 1
&& ( fieldType == VALUE || fieldType == FOOTPRINT || fieldType == DATASHEET ) )
{
auto component = static_cast< SCH_COMPONENT* >( aField->GetParent() );
component->ClearFieldsAutoplaced();
const wxString thisRef = component->GetRef( &( editFrame->GetCurrentSheet() ) );
int thisUnit = component->GetUnit();
SCH_REFERENCE_LIST components;
editFrame->GetCurrentSheet().GetComponents( components );
for( unsigned i = 0; i < components.GetCount(); i++ )
{
SCH_REFERENCE componentRef = components[i];
if( componentRef.GetRef() == thisRef && componentRef.GetUnit() != thisUnit )
{
SCH_COMPONENT* otherUnit = componentRef.GetComp();
editFrame->SaveCopyInUndoList( otherUnit, UR_CHANGED, true /* append */);
otherUnit->GetField( fieldType )->SetText( m_text );
editFrame->RefreshItem( otherUnit );
}
}
}
if( component && positioningModified )
component->ClearFieldsAutoplaced();
}
@@ -868,10 +868,13 @@ void DIALOG_FIELDS_EDITOR_GLOBAL::LoadFieldNames()
// Force References to always be shown
m_config->Write( "SymbolFieldEditor/Show/Reference", true );
AddField( _( "Reference" ), true, true );
AddField( _( "Value" ), true, true );
AddField( _( "Footprint" ), true, true );
AddField( _( "Datasheet" ), true, false );
// *DO NOT* use translated mandatory field names:
// They are also used as keyword to find fields in component list.
// Changing that is not a basic change
AddField( "Reference", true, true );
AddField( "Value", true, true );
AddField( "Footprint", true, true );
AddField( "Datasheet", true, false );
for( auto fieldName : userFieldNames )
AddField( fieldName, true, false );
@@ -324,10 +324,10 @@ public:
void SortRows( int aSortCol, bool ascending )
{
std::sort( m_rows.begin(), m_rows.end(),
[ aSortCol, ascending, this ]( LIB_PINS& lhs, LIB_PINS& rhs ) -> bool
{
return compare( lhs, rhs, aSortCol, ascending, m_userUnits );
} );
[ aSortCol, ascending, this ]( const LIB_PINS& lhs, const LIB_PINS& rhs ) -> bool
{
return compare( lhs, rhs, aSortCol, ascending, m_userUnits );
} );
}
void SortPins( LIB_PINS& aRow )
@@ -399,6 +399,7 @@ void SCH_PRINTOUT::DrawPage( SCH_SCREEN* aScreen )
pageSizeIU = aScreen->GetPageSettings().GetSizeIU();
FitThisSizeToPaper( pageSizeIU );
fitRect = GetLogicalPaperRect();
wxLogDebug( wxT( "Fit rectangle: x = %d, y = %d, w = %d, h = %d" ),
+8 -3
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 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
@@ -245,8 +245,13 @@ void DIALOG_RESCUE_EACH::displayItemsInConflict()
else
{
RESCUE_CANDIDATE& selected_part = m_Rescuer->m_all_candidates[row];
m_previewOldWidget->DisplayPart( selected_part.GetCacheCandidate(), 0 );
m_previewNewWidget->DisplayPart( selected_part.GetLibCandidate(), 0 );
m_previewOldWidget->DisplayPart( selected_part.GetCacheCandidate(),
selected_part.GetUnit(),
selected_part.GetConvert() );
m_previewNewWidget->DisplayPart( selected_part.GetLibCandidate(),
selected_part.GetUnit(),
selected_part.GetConvert() );
}
}
+11 -5
View File
@@ -244,7 +244,8 @@ bool DIALOG_SPICE_MODEL::TransferDataFromWindow()
[&]( const SCH_FIELD& f ) { return f.GetName() == spiceField; } ), m_schfields->end() );
else
m_libfields->erase( std::remove_if( m_libfields->begin(), m_libfields->end(),
[&]( const LIB_FIELD& f ) { return f.GetName() == spiceField; } ), m_libfields->end() );
[&]( const LIB_FIELD& f ) { return f.GetName( NATIVE_FIELD_NAME ) == spiceField; } ),
m_libfields->end() );
}
}
@@ -281,7 +282,7 @@ bool DIALOG_SPICE_MODEL::TransferDataToWindow()
// TODO: There must be a good way to template out these repetitive calls
for( auto field : *m_libfields )
{
if( field.GetName() == spiceField && !field.GetText().IsEmpty() )
if( field.GetName( NATIVE_FIELD_NAME ) == spiceField && !field.GetText().IsEmpty() )
{
m_fieldsTmp[idx] = field.GetText();
break;
@@ -677,12 +678,14 @@ void DIALOG_SPICE_MODEL::loadLibrary( const wxString& aFilePath )
file.Open( filePath.GetFullPath() );
int line_nr = 0;
// Stores the libray content. It will be displayed after reading the full library
wxString fullText;
// Process the file, looking for components
while( !file.Eof() )
{
const wxString& line = line_nr == 0 ? file.GetFirstLine() : file.GetNextLine();
m_libraryContents->AppendText( line );
m_libraryContents->AppendText( "\n" );
fullText << line << '\n';
wxStringTokenizer tokenizer( line );
@@ -729,6 +732,9 @@ void DIALOG_SPICE_MODEL::loadLibrary( const wxString& aFilePath )
++line_nr;
}
// display the full library content:
m_libraryContents->AppendText( fullText );
wxArrayString modelsList;
// Refresh the model name combobox values
@@ -773,7 +779,7 @@ LIB_FIELD& DIALOG_SPICE_MODEL::getLibField( int aFieldType )
const wxString& spiceField = NETLIST_EXPORTER_PSPICE::GetSpiceFieldName( (SPICE_FIELD) aFieldType );
auto fieldIt = std::find_if( m_libfields->begin(), m_libfields->end(), [&]( const LIB_FIELD& f ) {
return f.GetName() == spiceField;
return f.GetName( NATIVE_FIELD_NAME ) == spiceField;
} );
// Found one, so return it
+235 -209
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jul 11 2018)
// C++ code generated with wxFormBuilder (version Jul 10 2019)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -12,187 +12,187 @@
DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
wxBoxSizer* bSizer1;
bSizer1 = new wxBoxSizer( wxVERTICAL );
m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_passive = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer41;
bSizer41 = new wxBoxSizer( wxVERTICAL );
wxFlexGridSizer* fgSizer1;
fgSizer1 = new wxFlexGridSizer( 0, 3, 0, 0 );
fgSizer1->AddGrowableCol( 1 );
fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticTextPtype = new wxStaticText( m_passive, wxID_ANY, _("Type:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextPtype->Wrap( -1 );
fgSizer1->Add( m_staticTextPtype, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pasType = new wxComboBox( m_passive, wxID_ANY, _("Resistor"), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
m_pasType->Append( _("Resistor") );
m_pasType->Append( _("Capacitor") );
m_pasType->Append( _("Inductor") );
m_pasType->SetSelection( 0 );
fgSizer1->Add( m_pasType, 0, wxALL|wxEXPAND, 5 );
m_staticText62 = new wxStaticText( m_passive, wxID_ANY, _("Passive type"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText62->Wrap( -1 );
fgSizer1->Add( m_staticText62, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_staticTextPvalue = new wxStaticText( m_passive, wxID_ANY, _("Value:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextPvalue->Wrap( -1 );
fgSizer1->Add( m_staticTextPvalue, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pasValue = new wxTextCtrl( m_passive, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_pasValue->SetMinSize( wxSize( 200,-1 ) );
fgSizer1->Add( m_pasValue, 0, wxALL|wxEXPAND, 5 );
m_staticTextSpVal = new wxStaticText( m_passive, wxID_ANY, _("Spice value in simulation"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextSpVal->Wrap( -1 );
fgSizer1->Add( m_staticTextSpVal, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
bSizer41->Add( fgSizer1, 0, wxEXPAND|wxALL, 5 );
m_staticline1 = new wxStaticLine( m_passive, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizer41->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
wxBoxSizer* bSizerUnits;
bSizerUnits = new wxBoxSizer( wxVERTICAL );
m_staticText32 = new wxStaticText( m_passive, wxID_ANY, _("In Spice values,the decimal separator is the point.\nValues can use Spice unit symbols."), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText32->Wrap( -1 );
bSizerUnits->Add( m_staticText32, 0, wxALL, 5 );
m_staticText321 = new wxStaticText( m_passive, wxID_ANY, _("Spice unit symbols in values (case insensitive):"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText321->Wrap( -1 );
bSizerUnits->Add( m_staticText321, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
wxFlexGridSizer* fgSizerUnitSymbols;
fgSizerUnitSymbols = new wxFlexGridSizer( 0, 3, 0, 0 );
fgSizerUnitSymbols->AddGrowableCol( 1 );
fgSizerUnitSymbols->SetFlexibleDirection( wxBOTH );
fgSizerUnitSymbols->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText341 = new wxStaticText( m_passive, wxID_ANY, _("f"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText341->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText341, 0, wxALL, 5 );
m_staticText_femto = new wxStaticText( m_passive, wxID_ANY, _("femto"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText_femto->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText_femto, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText36 = new wxStaticText( m_passive, wxID_ANY, _("1e-15"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText36->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText36, 0, wxALL, 5 );
m_staticText37 = new wxStaticText( m_passive, wxID_ANY, _("p"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText37->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText37, 0, wxALL, 5 );
m_staticText38 = new wxStaticText( m_passive, wxID_ANY, _("pico"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText38->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText38, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText39 = new wxStaticText( m_passive, wxID_ANY, _("1e-12"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText39->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText39, 0, wxALL, 5 );
m_staticText40 = new wxStaticText( m_passive, wxID_ANY, _("n"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText40->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText40, 0, wxALL, 5 );
m_staticText41 = new wxStaticText( m_passive, wxID_ANY, _("nano"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText41->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText41, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText42 = new wxStaticText( m_passive, wxID_ANY, _("1e-9"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText42->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText42, 0, wxALL, 5 );
m_staticText43 = new wxStaticText( m_passive, wxID_ANY, _("u"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText43->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText43, 0, wxALL, 5 );
m_staticText44 = new wxStaticText( m_passive, wxID_ANY, _("micro"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText44->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText44, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText46 = new wxStaticText( m_passive, wxID_ANY, _("1e-6"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText46->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText46, 0, wxALL, 5 );
m_staticText47 = new wxStaticText( m_passive, wxID_ANY, _("m"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText47->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText47, 0, wxALL, 5 );
m_staticText48 = new wxStaticText( m_passive, wxID_ANY, _("milli"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText48->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText48, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText45 = new wxStaticText( m_passive, wxID_ANY, _("1e-3"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText45->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText45, 0, wxALL, 5 );
m_staticText49 = new wxStaticText( m_passive, wxID_ANY, _("k"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText49->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText49, 0, wxALL, 5 );
m_staticText50 = new wxStaticText( m_passive, wxID_ANY, _("kilo"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText50->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText50, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText51 = new wxStaticText( m_passive, wxID_ANY, _("1e3"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText51->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText51, 0, wxALL, 5 );
m_staticText52 = new wxStaticText( m_passive, wxID_ANY, _("meg"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText52->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText52, 0, wxALL, 5 );
m_staticText53 = new wxStaticText( m_passive, wxID_ANY, _("mega"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText53->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText53, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText54 = new wxStaticText( m_passive, wxID_ANY, _("1e6"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText54->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText54, 0, wxALL, 5 );
m_staticText55 = new wxStaticText( m_passive, wxID_ANY, _("g"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText55->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText55, 0, wxALL, 5 );
m_staticText56 = new wxStaticText( m_passive, wxID_ANY, _("giga"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText56->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText56, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText57 = new wxStaticText( m_passive, wxID_ANY, _("1e9"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText57->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText57, 0, wxALL, 5 );
m_staticText58 = new wxStaticText( m_passive, wxID_ANY, _("t"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText58->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText58, 0, wxALL, 5 );
m_staticText59 = new wxStaticText( m_passive, wxID_ANY, _("tera"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText59->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText59, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText60 = new wxStaticText( m_passive, wxID_ANY, _("1e12"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText60->Wrap( -1 );
fgSizerUnitSymbols->Add( m_staticText60, 0, wxALL, 5 );
bSizerUnits->Add( fgSizerUnitSymbols, 1, wxEXPAND, 5 );
bSizer41->Add( bSizerUnits, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
m_passive->SetSizer( bSizer41 );
m_passive->Layout();
bSizer41->Fit( m_passive );
@@ -200,129 +200,156 @@ DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID i
m_model = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer6;
bSizer6 = new wxBoxSizer( wxVERTICAL );
wxFlexGridSizer* fgSizer3;
fgSizer3 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer3->AddGrowableCol( 1 );
fgSizer3->SetFlexibleDirection( wxBOTH );
fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText7 = new wxStaticText( m_model, wxID_ANY, _("Library:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText7->Wrap( -1 );
fgSizer3->Add( m_staticText7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
wxBoxSizer* bSizer7;
bSizer7 = new wxBoxSizer( wxHORIZONTAL );
m_modelLibrary = new wxTextCtrl( m_model, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
bSizer7->Add( m_modelLibrary, 1, wxALL|wxEXPAND, 5 );
m_selectLibrary = new wxButton( m_model, wxID_ANY, _("Select file..."), wxDefaultPosition, wxDefaultSize, 0 );
bSizer7->Add( m_selectLibrary, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
fgSizer3->Add( bSizer7, 1, wxEXPAND, 5 );
m_staticText5 = new wxStaticText( m_model, wxID_ANY, _("Model:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText5->Wrap( -1 );
fgSizer3->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_modelName = new wxComboBox( m_model, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_SORT );
m_modelName = new wxComboBox( m_model, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_SORT );
fgSizer3->Add( m_modelName, 0, wxALL|wxEXPAND, 5 );
m_staticText4 = new wxStaticText( m_model, wxID_ANY, _("Type:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText4->Wrap( -1 );
fgSizer3->Add( m_staticText4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_modelType = new wxComboBox( m_model, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
m_modelType = new wxComboBox( m_model, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
fgSizer3->Add( m_modelType, 0, wxALL|wxEXPAND, 5 );
bSizer6->Add( fgSizer3, 0, wxEXPAND, 5 );
m_libraryContents = new wxTextCtrl( m_model, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_DONTWRAP|wxTE_MULTILINE|wxTE_READONLY );
m_libraryContents->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
bSizer6->Add( m_libraryContents, 1, wxALL|wxEXPAND, 5 );
m_libraryContents = new wxStyledTextCtrl( m_model, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString );
m_libraryContents->SetUseTabs( false );
m_libraryContents->SetTabWidth( 4 );
m_libraryContents->SetIndent( 4 );
m_libraryContents->SetTabIndents( true );
m_libraryContents->SetBackSpaceUnIndents( true );
m_libraryContents->SetViewEOL( false );
m_libraryContents->SetViewWhiteSpace( false );
m_libraryContents->SetMarginWidth( 2, 0 );
m_libraryContents->SetIndentationGuides( false );
m_libraryContents->SetMarginWidth( 1, 0 );
m_libraryContents->SetMarginType( 0, wxSTC_MARGIN_NUMBER );
m_libraryContents->SetMarginWidth( 0, m_libraryContents->TextWidth( wxSTC_STYLE_LINENUMBER, wxT("_99999") ) );
m_libraryContents->MarkerDefine( wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUS );
m_libraryContents->MarkerSetBackground( wxSTC_MARKNUM_FOLDER, wxColour( wxT("BLACK") ) );
m_libraryContents->MarkerSetForeground( wxSTC_MARKNUM_FOLDER, wxColour( wxT("WHITE") ) );
m_libraryContents->MarkerDefine( wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_BOXMINUS );
m_libraryContents->MarkerSetBackground( wxSTC_MARKNUM_FOLDEROPEN, wxColour( wxT("BLACK") ) );
m_libraryContents->MarkerSetForeground( wxSTC_MARKNUM_FOLDEROPEN, wxColour( wxT("WHITE") ) );
m_libraryContents->MarkerDefine( wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_EMPTY );
m_libraryContents->MarkerDefine( wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_BOXPLUS );
m_libraryContents->MarkerSetBackground( wxSTC_MARKNUM_FOLDEREND, wxColour( wxT("BLACK") ) );
m_libraryContents->MarkerSetForeground( wxSTC_MARKNUM_FOLDEREND, wxColour( wxT("WHITE") ) );
m_libraryContents->MarkerDefine( wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BOXMINUS );
m_libraryContents->MarkerSetBackground( wxSTC_MARKNUM_FOLDEROPENMID, wxColour( wxT("BLACK") ) );
m_libraryContents->MarkerSetForeground( wxSTC_MARKNUM_FOLDEROPENMID, wxColour( wxT("WHITE") ) );
m_libraryContents->MarkerDefine( wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_EMPTY );
m_libraryContents->MarkerDefine( wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_EMPTY );
m_libraryContents->SetSelBackground( true, wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
m_libraryContents->SetSelForeground( true, wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
bSizer6->Add( m_libraryContents, 1, wxEXPAND | wxALL, 5 );
m_model->SetSizer( bSizer6 );
m_model->Layout();
bSizer6->Fit( m_model );
m_notebook->AddPage( m_model, _("Model"), false );
m_power = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_power->SetMinSize( wxSize( 650,-1 ) );
wxBoxSizer* bSizer4;
bSizer4 = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* sbSizer1;
sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( m_power, wxID_ANY, _("DC/AC analysis:") ), wxVERTICAL );
wxFlexGridSizer* fgSizer6;
fgSizer6 = new wxFlexGridSizer( 0, 6, 0, 0 );
fgSizer6->AddGrowableCol( 1 );
fgSizer6->AddGrowableCol( 3 );
fgSizer6->SetFlexibleDirection( wxBOTH );
fgSizer6->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText10 = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("DC:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText10->Wrap( -1 );
fgSizer6->Add( m_staticText10, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_genDc = new wxTextCtrl( sbSizer1->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_genDc->SetMinSize( wxSize( 60,-1 ) );
fgSizer6->Add( m_genDc, 0, wxALL|wxEXPAND, 5 );
m_staticText113 = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("Volts/Amps"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText113->Wrap( -1 );
fgSizer6->Add( m_staticText113, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
fgSizer6->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizer6->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizer6->Add( 0, 0, 1, wxEXPAND, 5 );
m_staticText11 = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("AC magnitude:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText11->Wrap( -1 );
fgSizer6->Add( m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_genAcMag = new wxTextCtrl( sbSizer1->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_genAcMag->SetMinSize( wxSize( 60,-1 ) );
fgSizer6->Add( m_genAcMag, 0, wxALL|wxEXPAND, 5 );
m_staticText111 = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("Volts/Amps"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText111->Wrap( -1 );
fgSizer6->Add( m_staticText111, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText12 = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("AC phase:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText12->Wrap( -1 );
fgSizer6->Add( m_staticText12, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
m_genAcPhase = new wxTextCtrl( sbSizer1->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_genAcPhase->SetMinSize( wxSize( 60,-1 ) );
fgSizer6->Add( m_genAcPhase, 0, wxALL|wxEXPAND, 5 );
m_staticText112 = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("radians"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText112->Wrap( -1 );
fgSizer6->Add( m_staticText112, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
sbSizer1->Add( fgSizer6, 1, wxEXPAND, 5 );
bSizer4->Add( sbSizer1, 0, wxALL|wxEXPAND, 5 );
wxStaticBoxSizer* sbSizer3;
sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( m_power, wxID_ANY, _("Transient analysis:") ), wxVERTICAL );
m_powerNotebook = new wxNotebook( sbSizer3->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_pwrPulse = new wxPanel( m_powerNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxFlexGridSizer* fgSizer7;
@@ -330,87 +357,87 @@ DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID i
fgSizer7->AddGrowableCol( 1 );
fgSizer7->SetFlexibleDirection( wxBOTH );
fgSizer7->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText13 = new wxStaticText( m_pwrPulse, wxID_ANY, _("Initial value:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText13->Wrap( -1 );
fgSizer7->Add( m_staticText13, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pulseInit = new wxTextCtrl( m_pwrPulse, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_pulseInit->SetMinSize( wxSize( 100,-1 ) );
fgSizer7->Add( m_pulseInit, 0, wxALL|wxEXPAND, 5 );
m_staticText131 = new wxStaticText( m_pwrPulse, wxID_ANY, _("Volts/Amps"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText131->Wrap( -1 );
fgSizer7->Add( m_staticText131, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText14 = new wxStaticText( m_pwrPulse, wxID_ANY, _("Pulsed value:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText14->Wrap( -1 );
fgSizer7->Add( m_staticText14, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pulseNominal = new wxTextCtrl( m_pwrPulse, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer7->Add( m_pulseNominal, 0, wxALL|wxEXPAND, 5 );
m_staticText132 = new wxStaticText( m_pwrPulse, wxID_ANY, _("Volts/Amps"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText132->Wrap( -1 );
fgSizer7->Add( m_staticText132, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText15 = new wxStaticText( m_pwrPulse, wxID_ANY, _("Delay time:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText15->Wrap( -1 );
fgSizer7->Add( m_staticText15, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pulseDelay = new wxTextCtrl( m_pwrPulse, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer7->Add( m_pulseDelay, 0, wxALL|wxEXPAND, 5 );
m_staticText133 = new wxStaticText( m_pwrPulse, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText133->Wrap( -1 );
fgSizer7->Add( m_staticText133, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText16 = new wxStaticText( m_pwrPulse, wxID_ANY, _("Rise time:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText16->Wrap( -1 );
fgSizer7->Add( m_staticText16, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pulseRise = new wxTextCtrl( m_pwrPulse, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer7->Add( m_pulseRise, 0, wxALL|wxEXPAND, 5 );
m_staticText134 = new wxStaticText( m_pwrPulse, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText134->Wrap( -1 );
fgSizer7->Add( m_staticText134, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText17 = new wxStaticText( m_pwrPulse, wxID_ANY, _("Fall time:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText17->Wrap( -1 );
fgSizer7->Add( m_staticText17, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pulseFall = new wxTextCtrl( m_pwrPulse, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer7->Add( m_pulseFall, 0, wxALL|wxEXPAND, 5 );
m_staticText135 = new wxStaticText( m_pwrPulse, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText135->Wrap( -1 );
fgSizer7->Add( m_staticText135, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText18 = new wxStaticText( m_pwrPulse, wxID_ANY, _("Pulse width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText18->Wrap( -1 );
fgSizer7->Add( m_staticText18, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pulseWidth = new wxTextCtrl( m_pwrPulse, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer7->Add( m_pulseWidth, 0, wxALL|wxEXPAND, 5 );
m_staticText136 = new wxStaticText( m_pwrPulse, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText136->Wrap( -1 );
fgSizer7->Add( m_staticText136, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText20 = new wxStaticText( m_pwrPulse, wxID_ANY, _("Period:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText20->Wrap( -1 );
fgSizer7->Add( m_staticText20, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pulsePeriod = new wxTextCtrl( m_pwrPulse, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer7->Add( m_pulsePeriod, 0, wxALL|wxEXPAND, 5 );
m_staticText137 = new wxStaticText( m_pwrPulse, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText137->Wrap( -1 );
fgSizer7->Add( m_staticText137, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_pwrPulse->SetSizer( fgSizer7 );
m_pwrPulse->Layout();
fgSizer7->Fit( m_pwrPulse );
@@ -421,65 +448,65 @@ DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID i
fgSizer8->AddGrowableCol( 1 );
fgSizer8->SetFlexibleDirection( wxBOTH );
fgSizer8->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText21 = new wxStaticText( m_pwrSin, wxID_ANY, _("DC offset:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText21->Wrap( -1 );
fgSizer8->Add( m_staticText21, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_sinOffset = new wxTextCtrl( m_pwrSin, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_sinOffset->SetMinSize( wxSize( 100,-1 ) );
fgSizer8->Add( m_sinOffset, 0, wxALL|wxEXPAND, 5 );
m_staticText211 = new wxStaticText( m_pwrSin, wxID_ANY, _("Volts/Amps"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText211->Wrap( -1 );
fgSizer8->Add( m_staticText211, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText22 = new wxStaticText( m_pwrSin, wxID_ANY, _("Amplitude:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText22->Wrap( -1 );
fgSizer8->Add( m_staticText22, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_sinAmplitude = new wxTextCtrl( m_pwrSin, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer8->Add( m_sinAmplitude, 0, wxALL|wxEXPAND, 5 );
m_staticText212 = new wxStaticText( m_pwrSin, wxID_ANY, _("Volts/Amps"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText212->Wrap( -1 );
fgSizer8->Add( m_staticText212, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText23 = new wxStaticText( m_pwrSin, wxID_ANY, _("Frequency:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText23->Wrap( -1 );
fgSizer8->Add( m_staticText23, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_sinFreq = new wxTextCtrl( m_pwrSin, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer8->Add( m_sinFreq, 0, wxALL|wxEXPAND, 5 );
m_staticText213 = new wxStaticText( m_pwrSin, wxID_ANY, _("Hz"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText213->Wrap( -1 );
fgSizer8->Add( m_staticText213, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText24 = new wxStaticText( m_pwrSin, wxID_ANY, _("Delay:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText24->Wrap( -1 );
fgSizer8->Add( m_staticText24, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_sinDelay = new wxTextCtrl( m_pwrSin, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer8->Add( m_sinDelay, 0, wxALL|wxEXPAND, 5 );
m_staticText214 = new wxStaticText( m_pwrSin, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText214->Wrap( -1 );
fgSizer8->Add( m_staticText214, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText25 = new wxStaticText( m_pwrSin, wxID_ANY, _("Damping factor:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText25->Wrap( -1 );
fgSizer8->Add( m_staticText25, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_sinDampFactor = new wxTextCtrl( m_pwrSin, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer8->Add( m_sinDampFactor, 0, wxALL|wxEXPAND, 5 );
m_staticText215 = new wxStaticText( m_pwrSin, wxID_ANY, _("1/seconds"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText215->Wrap( -1 );
fgSizer8->Add( m_staticText215, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_pwrSin->SetSizer( fgSizer8 );
m_pwrSin->Layout();
fgSizer8->Fit( m_pwrSin );
@@ -490,218 +517,217 @@ DIALOG_SPICE_MODEL_BASE::DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID i
fgSizer9->AddGrowableCol( 1 );
fgSizer9->SetFlexibleDirection( wxBOTH );
fgSizer9->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText26 = new wxStaticText( m_pwrExp, wxID_ANY, _("Initial value:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText26->Wrap( -1 );
fgSizer9->Add( m_staticText26, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_expInit = new wxTextCtrl( m_pwrExp, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_expInit->SetMinSize( wxSize( 100,-1 ) );
fgSizer9->Add( m_expInit, 0, wxALL|wxEXPAND, 5 );
m_staticText261 = new wxStaticText( m_pwrExp, wxID_ANY, _("Volts/Amps"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText261->Wrap( -1 );
fgSizer9->Add( m_staticText261, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText27 = new wxStaticText( m_pwrExp, wxID_ANY, _("Pulsed value:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText27->Wrap( -1 );
fgSizer9->Add( m_staticText27, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_expPulsed = new wxTextCtrl( m_pwrExp, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer9->Add( m_expPulsed, 0, wxALL|wxEXPAND, 5 );
m_staticText262 = new wxStaticText( m_pwrExp, wxID_ANY, _("Volts/Amps"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText262->Wrap( -1 );
fgSizer9->Add( m_staticText262, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText28 = new wxStaticText( m_pwrExp, wxID_ANY, _("Rise delay time:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText28->Wrap( -1 );
fgSizer9->Add( m_staticText28, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_expRiseDelay = new wxTextCtrl( m_pwrExp, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer9->Add( m_expRiseDelay, 0, wxALL|wxEXPAND, 5 );
m_staticText263 = new wxStaticText( m_pwrExp, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText263->Wrap( -1 );
fgSizer9->Add( m_staticText263, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText29 = new wxStaticText( m_pwrExp, wxID_ANY, _("Rise time constant:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText29->Wrap( -1 );
fgSizer9->Add( m_staticText29, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_expRiseConst = new wxTextCtrl( m_pwrExp, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer9->Add( m_expRiseConst, 0, wxALL|wxEXPAND, 5 );
m_staticText264 = new wxStaticText( m_pwrExp, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText264->Wrap( -1 );
fgSizer9->Add( m_staticText264, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText30 = new wxStaticText( m_pwrExp, wxID_ANY, _("Fall delay time:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText30->Wrap( -1 );
fgSizer9->Add( m_staticText30, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_expFallDelay = new wxTextCtrl( m_pwrExp, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer9->Add( m_expFallDelay, 0, wxALL|wxEXPAND, 5 );
m_staticText265 = new wxStaticText( m_pwrExp, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText265->Wrap( -1 );
fgSizer9->Add( m_staticText265, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText31 = new wxStaticText( m_pwrExp, wxID_ANY, _("Fall time constant:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText31->Wrap( -1 );
fgSizer9->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_expFallConst = new wxTextCtrl( m_pwrExp, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer9->Add( m_expFallConst, 0, wxALL|wxEXPAND, 5 );
m_staticText266 = new wxStaticText( m_pwrExp, wxID_ANY, _("seconds"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText266->Wrap( -1 );
fgSizer9->Add( m_staticText266, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_pwrExp->SetSizer( fgSizer9 );
m_pwrExp->Layout();
fgSizer9->Fit( m_pwrExp );
m_powerNotebook->AddPage( m_pwrExp, _("Exponential"), false );
m_pwrPwl = new wxPanel( m_powerNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_pwrPwl->SetToolTip( _("Piece-wise linear") );
wxFlexGridSizer* fgSizer15;
fgSizer15 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer15->AddGrowableCol( 0 );
fgSizer15->AddGrowableRow( 1 );
fgSizer15->SetFlexibleDirection( wxBOTH );
fgSizer15->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
wxFlexGridSizer* fgSizer10;
fgSizer10 = new wxFlexGridSizer( 0, 3, 0, 0 );
fgSizer10->AddGrowableCol( 1 );
fgSizer10->SetFlexibleDirection( wxBOTH );
fgSizer10->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText34 = new wxStaticText( m_pwrPwl, wxID_ANY, _("Time:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText34->Wrap( -1 );
fgSizer10->Add( m_staticText34, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pwlTime = new wxTextCtrl( m_pwrPwl, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_pwlTime->SetMinSize( wxSize( 100,-1 ) );
fgSizer10->Add( m_pwlTime, 0, wxALL|wxEXPAND, 5 );
m_staticText342 = new wxStaticText( m_pwrPwl, wxID_ANY, _("second"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText342->Wrap( -1 );
fgSizer10->Add( m_staticText342, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
m_staticText35 = new wxStaticText( m_pwrPwl, wxID_ANY, _("Value:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText35->Wrap( -1 );
fgSizer10->Add( m_staticText35, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pwlValue = new wxTextCtrl( m_pwrPwl, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer10->Add( m_pwlValue, 0, wxALL|wxEXPAND, 5 );
m_staticText343 = new wxStaticText( m_pwrPwl, wxID_ANY, _("Volts/Amps"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText343->Wrap( -1 );
fgSizer10->Add( m_staticText343, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT, 5 );
fgSizer15->Add( fgSizer10, 1, wxEXPAND, 5 );
m_pwlAddButton = new wxButton( m_pwrPwl, wxID_ANY, _("Add"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer15->Add( m_pwlAddButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pwlValList = new wxListCtrl( m_pwrPwl, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL );
m_pwlValList->SetMinSize( wxSize( 200,-1 ) );
fgSizer15->Add( m_pwlValList, 0, wxALL|wxEXPAND, 5 );
m_pwlRemoveBtn = new wxButton( m_pwrPwl, wxID_ANY, _("Remove"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer15->Add( m_pwlRemoveBtn, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_pwrPwl->SetSizer( fgSizer15 );
m_pwrPwl->Layout();
fgSizer15->Fit( m_pwrPwl );
m_powerNotebook->AddPage( m_pwrPwl, _("Piece-wise Linear"), false );
m_pwrFm = new wxPanel( m_powerNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_pwrFm->Hide();
m_powerNotebook->AddPage( m_pwrFm, _("FM"), false );
m_pwrAm = new wxPanel( m_powerNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_pwrAm->Hide();
m_powerNotebook->AddPage( m_pwrAm, _("AM"), false );
m_pwrTransNoise = new wxPanel( m_powerNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_pwrTransNoise->Hide();
m_powerNotebook->AddPage( m_pwrTransNoise, _("Transient noise"), false );
m_pwrRandom = new wxPanel( m_powerNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_pwrRandom->Hide();
m_powerNotebook->AddPage( m_pwrRandom, _("Random"), false );
m_pwrExtData = new wxPanel( m_powerNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_pwrExtData->Hide();
m_powerNotebook->AddPage( m_pwrExtData, _("External data"), false );
sbSizer3->Add( m_powerNotebook, 0, wxEXPAND | wxALL, 5 );
bSizer4->Add( sbSizer3, 0, wxALL|wxEXPAND, 5 );
wxString m_pwrTypeChoices[] = { _("Voltage"), _("Current") };
int m_pwrTypeNChoices = sizeof( m_pwrTypeChoices ) / sizeof( wxString );
m_pwrType = new wxRadioBox( m_power, wxID_ANY, _("Source type:"), wxDefaultPosition, wxDefaultSize, m_pwrTypeNChoices, m_pwrTypeChoices, 1, wxRA_SPECIFY_ROWS );
m_pwrType->SetSelection( 1 );
bSizer4->Add( m_pwrType, 0, wxALL|wxEXPAND, 5 );
m_power->SetSizer( bSizer4 );
m_power->Layout();
bSizer4->Fit( m_power );
m_notebook->AddPage( m_power, _("Source"), false );
bSizer1->Add( m_notebook, 1, wxEXPAND | wxALL, 5 );
m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizer1->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 );
m_disabled = new wxCheckBox( this, wxID_ANY, _("Disable symbol for simulation"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer1->Add( m_disabled, 0, wxALL, 5 );
wxBoxSizer* bSizer2;
bSizer2 = new wxBoxSizer( wxHORIZONTAL );
m_nodeSeqCheck = new wxCheckBox( this, wxID_ANY, _("Alternate node sequence:"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer2->Add( m_nodeSeqCheck, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_nodeSeqVal = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_nodeSeqVal->SetMinSize( wxSize( 200,-1 ) );
bSizer2->Add( m_nodeSeqVal, 1, wxALL, 5 );
bSizer1->Add( bSizer2, 0, wxEXPAND, 5 );
m_staticline3 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizer1->Add( m_staticline3, 0, wxEXPAND | wxALL, 5 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bSizer1->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 );
this->SetSizer( bSizer1 );
this->Layout();
bSizer1->Fit( this );
this->Centre( wxBOTH );
// Connect Events
this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_SPICE_MODEL_BASE::onInitDlg ) );
m_selectLibrary->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onSelectLibrary ), NULL, this );
@@ -720,5 +746,5 @@ DIALOG_SPICE_MODEL_BASE::~DIALOG_SPICE_MODEL_BASE()
m_modelName->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onModelSelected ), NULL, this );
m_pwlAddButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onPwlAdd ), NULL, this );
m_pwlRemoveBtn->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SPICE_MODEL_BASE::onPwlRemove ), NULL, this );
}
File diff suppressed because it is too large Load Diff
+11 -12
View File
@@ -1,12 +1,11 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jul 11 2018)
// C++ code generated with wxFormBuilder (version Jul 10 2019)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __DIALOG_SPICE_MODEL_BASE_H__
#define __DIALOG_SPICE_MODEL_BASE_H__
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
@@ -27,6 +26,7 @@
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/stc/stc.h>
#include <wx/statbox.h>
#include <wx/listctrl.h>
#include <wx/notebook.h>
@@ -43,7 +43,7 @@
class DIALOG_SPICE_MODEL_BASE : public DIALOG_SHIM
{
private:
protected:
wxNotebook* m_notebook;
wxPanel* m_passive;
@@ -91,7 +91,7 @@ class DIALOG_SPICE_MODEL_BASE : public DIALOG_SHIM
wxComboBox* m_modelName;
wxStaticText* m_staticText4;
wxComboBox* m_modelType;
wxTextCtrl* m_libraryContents;
wxStyledTextCtrl* m_libraryContents;
wxPanel* m_power;
wxStaticText* m_staticText10;
wxTextCtrl* m_genDc;
@@ -184,20 +184,19 @@ class DIALOG_SPICE_MODEL_BASE : public DIALOG_SHIM
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
// Virtual event handlers, overide them in your derived class
virtual void onInitDlg( wxInitDialogEvent& event ) { event.Skip(); }
virtual void onSelectLibrary( wxCommandEvent& event ) { event.Skip(); }
virtual void onModelSelected( wxCommandEvent& event ) { event.Skip(); }
virtual void onPwlAdd( wxCommandEvent& event ) { event.Skip(); }
virtual void onPwlRemove( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Spice Model Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_SPICE_MODEL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Spice Model Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 494,604 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_SPICE_MODEL_BASE();
};
#endif //__DIALOG_SPICE_MODEL_BASE_H__
+29
View File
@@ -34,6 +34,7 @@
#include <sch_draw_panel.h>
#include <confirm.h>
#include <sch_edit_frame.h>
#include <sch_view.h>
#include <kicad_device_context.h>
#include <general.h>
@@ -238,6 +239,34 @@ void SCH_EDIT_FRAME::OnConvertTextType( wxCommandEvent& aEvent )
if( screen->GetCurItem() == text )
screen->SetCurItem( newtext );
// handle dangling end for the different label/text types
if( type == SCH_TEXT_T )
{
if( newtext->IsDangling() )
{
newtext->SetIsDangling( false );
GetCanvas()->GetView()->Update( newtext, KIGFX::REPAINT );
}
}
else
{
newtext->SetIsDangling( true );
}
TestDanglingEnds();
// fix rotation of the converted label, only needed for horizontal labels:
bool newTypeIsBig = newtext->Type() == SCH_GLOBAL_LABEL_T ||
newtext->Type() == SCH_HIERARCHICAL_LABEL_T;
bool oldTypeIsBig = text->Type() == SCH_GLOBAL_LABEL_T ||
text->Type() == SCH_HIERARCHICAL_LABEL_T;
if ( ( newTypeIsBig && !oldTypeIsBig ) ||
( !newTypeIsBig && oldTypeIsBig ) )
{
newtext->MirrorY( newtext->GetPosition().x );
}
if( text->IsNew() )
{
// if the previous text is new, no undo command to prepare here
+5 -1
View File
@@ -357,6 +357,7 @@ static const wxString RepeatStepXEntry = "RepeatStepX";
static const wxString RepeatStepYEntry = "RepeatStepY";
static const wxString RepeatLabelIncrementEntry = "RepeatLabelIncrement";
static const wxString ShowIllegalSymboLibDialog = "ShowIllegalSymbolLibDialog";
static const wxString showSheetFileNameCaseSensitivityDlg = "ShowSheetFileNameCaseSensitivityDlg";
// Library editor wxConfig entry names.
static const wxChar defaultLibWidthEntry[] = wxT( "LibeditLibWidth" );
@@ -401,7 +402,9 @@ PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetConfigurationSettings()
-10, +10 ) );
m_configSettings.push_back( new PARAM_CFG_BOOL( true, ShowIllegalSymboLibDialog,
&m_showIllegalSymbolLibDialog, true ) );
m_configSettings.push_back( new PARAM_CFG_BOOL( true, showSheetFileNameCaseSensitivityDlg,
&m_showSheetFileNameCaseSensitivityDlg,
true ) );
return m_configSettings;
}
@@ -547,6 +550,7 @@ void SCH_EDIT_FRAME::SaveSettings( wxConfigBase* aCfg )
record.Replace( wxT(" "), wxT(" "), true ); // double space to single
aCfg->Write( FieldNamesEntry, record );
aCfg->Write( showSheetFileNameCaseSensitivityDlg, m_showSheetFileNameCaseSensitivityDlg );
}
+2 -2
View File
@@ -82,13 +82,13 @@ FIELDS_GRID_TABLE<T>::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* a
m_urlAttr = new wxGridCellAttr;
GRID_CELL_URL_EDITOR* urlEditor = new GRID_CELL_URL_EDITOR( aDialog );
urlEditor->SetValidator( SCH_FIELD_VALIDATOR( aFrame->IsType( FRAME_SCH_LIB_EDITOR ),
DATASHEET ) );
FIELD_VALUE ) );
m_urlAttr->SetEditor( urlEditor );
m_nonUrlAttr = new wxGridCellAttr;
wxGridCellTextEditor* nonUrlEditor = new wxGridCellTextEditor();
nonUrlEditor->SetValidator( SCH_FIELD_VALIDATOR( aFrame->IsType( FRAME_SCH_LIB_EDITOR ),
DATASHEET ) );
FIELD_VALUE ) );
m_nonUrlAttr->SetEditor( nonUrlEditor );
m_boolAttr = new wxGridCellAttr;
+1 -1
View File
@@ -160,7 +160,7 @@ protected:
wxString GetHtmlFieldRow( LIB_FIELD const & aField )
{
wxString name = aField.GetName();
wxString name = aField.GetName( NATIVE_FIELD_NAME );
wxString text = aField.GetFullText( m_unit > 0 ? m_unit : 1 );
wxString fieldhtml = FieldFormat;
+3 -2
View File
@@ -538,7 +538,8 @@ void LIB_FIELD::SetText( const wxString& aText )
wxString LIB_FIELD::GetSelectMenuText( EDA_UNITS_T aUnits ) const
{
return wxString::Format( _( "Field %s \"%s\"" ), GetName(), ShortenedShownText() );
return wxString::Format( _( "Field %s \"%s\"" ), GetName( TRANSLATE_FIELD_NAME ),
ShortenedShownText() );
}
@@ -623,7 +624,7 @@ void LIB_FIELD::GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList )
aList.push_back( MSG_PANEL_ITEM( _( "Height" ), msg, BLUE ) );
// Display field name (ref, value ...)
aList.push_back( MSG_PANEL_ITEM( _( "Field" ), GetName(), BROWN ) );
aList.push_back( MSG_PANEL_ITEM( _( "Field" ), GetName( TRANSLATE_FIELD_NAME ), BROWN ) );
// Display field text:
aList.push_back( MSG_PANEL_ITEM( _( "Value" ), GetShownText(), BROWN ) );
+10 -6
View File
@@ -119,12 +119,16 @@ public:
* names. The user definable fields will return FieldN where N is the ID of the field
* when the m_name member is empty.
*
* @param aTranslate True to return translated field name (default). False to return
* the english name (useful when the name is used as keyword in
* netlists ...)
* @return Name of the field.
*/
wxString GetName( bool aTranslate = true ) const;
* @param aTranslate true to return translated field name.
* note: has meaning mainly for mandatory fields or to return a default field name.
* Should be used only in messages (never when trying to find a field by name)
* false to return the english name.
* Normal option when the name is used as keyword in netlists.
* @return Name of the field.
*/
#define TRANSLATE_FIELD_NAME true
#define NATIVE_FIELD_NAME false
wxString GetName( bool aTranslate ) const;
/**
* Set a user definable field name to \a aName.
+94 -1
View File
@@ -144,39 +144,132 @@ void LIB_TEXT::Move( const wxPoint& newPosition )
}
void LIB_TEXT::NormalizeJustification( bool inverse )
{
wxPoint delta( 0, 0 );
EDA_RECT bbox = GetTextBox( -1 );
if( GetTextAngle() == 0.0 )
{
if( GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT )
delta.x = bbox.GetWidth() / 2;
else if( GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT )
delta.x = - bbox.GetWidth() / 2;
if( GetVertJustify() == GR_TEXT_VJUSTIFY_TOP )
delta.y = - bbox.GetHeight() / 2;
else if( GetVertJustify() == GR_TEXT_VJUSTIFY_BOTTOM )
delta.y = bbox.GetHeight() / 2;
}
else
{
if( GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT )
delta.y = bbox.GetWidth() / 2;
else if( GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT )
delta.y = - bbox.GetWidth() / 2;
if( GetVertJustify() == GR_TEXT_VJUSTIFY_TOP )
delta.x = + bbox.GetHeight() / 2;
else if( GetVertJustify() == GR_TEXT_VJUSTIFY_BOTTOM )
delta.x = - bbox.GetHeight() / 2;
}
if( inverse )
SetTextPos( GetTextPos() - delta );
else
SetTextPos( GetTextPos() + delta );
}
void LIB_TEXT::MirrorHorizontal( const wxPoint& center )
{
NormalizeJustification( false );
int x = GetTextPos().x;
x -= center.x;
x *= -1;
x += center.x;
if( GetTextAngle() == 0.0 )
{
if( GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT )
SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
else if( GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT )
SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
}
else
{
if( GetVertJustify() == GR_TEXT_VJUSTIFY_TOP )
SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
else if( GetVertJustify() == GR_TEXT_VJUSTIFY_BOTTOM )
SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
}
SetTextX( x );
NormalizeJustification( true );
}
void LIB_TEXT::MirrorVertical( const wxPoint& center )
{
NormalizeJustification( false );
int y = GetTextPos().y;
y -= center.y;
y *= -1;
y += center.y;
if( GetTextAngle() == 0.0 )
{
if( GetVertJustify() == GR_TEXT_VJUSTIFY_TOP )
SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
else if( GetVertJustify() == GR_TEXT_VJUSTIFY_BOTTOM )
SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
}
else
{
if( GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT )
SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
else if( GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT )
SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
}
SetTextY( y );
NormalizeJustification( true );
}
void LIB_TEXT::Rotate( const wxPoint& center, bool aRotateCCW )
{
NormalizeJustification( false );
int rot_angle = aRotateCCW ? -900 : 900;
wxPoint pt = GetTextPos();
RotatePoint( &pt, center, rot_angle );
SetTextPos( pt );
SetTextAngle( GetTextAngle() != 0.0 ? 0 : 900 );
if( GetTextAngle() == 0.0 )
{
SetTextAngle( 900 );
}
else
{
// 180º of rotation is a mirror
if( GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT )
SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
else if( GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT )
SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
if( GetVertJustify() == GR_TEXT_VJUSTIFY_TOP )
SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
else if( GetVertJustify() == GR_TEXT_VJUSTIFY_BOTTOM )
SetVertJustify( GR_TEXT_VJUSTIFY_TOP );
SetTextAngle( 0 );
}
NormalizeJustification( true );
}
+2
View File
@@ -122,6 +122,8 @@ public:
void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
void NormalizeJustification( bool inverse );
void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
const TRANSFORM& aTransform ) override;
+1 -1
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2004 Jean-Pierre Charras, jp.charras ar wanadoo.fr
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-2020 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
+13 -6
View File
@@ -373,6 +373,14 @@ void LIB_EDIT_FRAME::OnSave( wxCommandEvent& aEvent )
}
else
{
wxFileName fn = Prj().SchSymbolLibTable()->GetFullURI( libName );
wxFileName docFileName = fn;
docFileName.SetExt( DOC_EXT );
// Verify the user has write privileges before attempting to save the library file.
if( !IsWritable( fn ) || !IsWritable( docFileName ) )
return;
// Save Part
if( m_libMgr->FlushPart( partName, libName ) )
m_libMgr->ClearPartModified( partName, libName );
@@ -424,8 +432,7 @@ void LIB_EDIT_FRAME::savePartAs()
itemsToDisplay.push_back( item );
}
EDA_LIST_DIALOG dlg( this, _( "Save Copy of Symbol" ), headers, itemsToDisplay, old_lib,
nullptr, nullptr, /* sort */ false, /* show headers */ false );
EDA_LIST_DIALOG dlg( this, _( "Save Copy of Symbol" ), headers, itemsToDisplay, old_lib );
dlg.SetListLabel( _( "Save in library:" ) );
dlg.SetOKLabel( _( "Save" ) );
@@ -727,8 +734,11 @@ bool LIB_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
fn = prj.SchSymbolLibTable()->GetFullURI( aLibrary );
}
wxFileName docFileName = fn;
docFileName.SetExt( DOC_EXT );
// Verify the user has write privileges before attempting to save the library file.
if( !IsWritable( fn ) )
if( !IsWritable( fn ) || !IsWritable( docFileName ) )
return false;
ClearMsgPanel();
@@ -737,9 +747,6 @@ bool LIB_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
if( !backupFile( fn, "bak" ) )
return false;
wxFileName docFileName = fn;
docFileName.SetExt( DOC_EXT );
// Copy .dcm file to .bck.
if( !backupFile( docFileName, "bck" ) )
return false;
+1 -1
View File
@@ -55,7 +55,7 @@ void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField )
if( aField->GetId() == VALUE )
caption = _( "Edit Component Name" );
else
caption.Printf( _( "Edit %s Field" ), GetChars( aField->GetName() ) );
caption.Printf( _( "Edit %s Field" ), aField->GetName( TRANSLATE_FIELD_NAME ) );
DIALOG_LIB_EDIT_ONE_FIELD dlg( this, caption, aField );
+18 -2
View File
@@ -619,6 +619,8 @@ void LIB_EDIT_FRAME::OnCheckComponent( wxCommandEvent& event )
wxDefaultPosition,
wxSize( 750, 600 ) );
std::vector<wxString> messages;
int dup_error = 0;
for( unsigned ii = 1; ii < pinList.size(); ii++ )
@@ -665,7 +667,7 @@ void LIB_EDIT_FRAME::OnCheckComponent( wxCommandEvent& event )
msg += wxT( ".<br>" );
error_display.m_htmlWindow->AppendToPage( msg );
messages.push_back( msg );
}
// Test for off grid pins:
@@ -705,11 +707,25 @@ void LIB_EDIT_FRAME::OnCheckComponent( wxCommandEvent& event )
msg += wxT( ".<br>" );
error_display.m_htmlWindow->AppendToPage( msg );
messages.push_back( msg );
}
if( !dup_error && !offgrid_error )
DisplayInfoMessage( this, _( "No off grid or duplicate pins were found." ) );
else
{
wxColour bgcolor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
wxColour fgcolor = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
wxString outmsg = wxString::Format( "<html><body bgcolor='%s' text='%s'>",
bgcolor.GetAsString( wxC2S_HTML_SYNTAX ),
fgcolor.GetAsString( wxC2S_HTML_SYNTAX ) );
for( auto& msg : messages )
outmsg += msg;
outmsg += "</body></html>";
error_display.m_htmlWindow->SetPage( outmsg );
error_display.ShowModal();
}
}
@@ -382,6 +382,7 @@ void NETLIST_EXPORTER_PSPICE::UpdateDirectives( unsigned aCtl )
m_directives.clear();
bool controlBlock = false;
bool circuitBlock = false;
for( unsigned i = 0; i < sheetList.size(); i++ )
{
@@ -437,20 +438,9 @@ void NETLIST_EXPORTER_PSPICE::UpdateDirectives( unsigned aCtl )
m_title = line.AfterFirst( ' ' );
}
// Handle .control .. .endc blocks
else if( lowercaseline.IsSameAs( ".control" ) && ( !controlBlock ) )
{
controlBlock = true;
m_directives.push_back( line );
}
else if( lowercaseline.IsSameAs( ".endc" ) && controlBlock )
{
controlBlock = false;
m_directives.push_back( line );
}
else if( line.StartsWith( '.' ) // one-line directives
|| controlBlock // .control .. .endc block
|| circuitBlock // .subckt .. .ends block
|| couplingK.Matches( line ) // K## L## L## coupling constant
|| ( directiveStarted && line.StartsWith( '+' ) ) ) // multiline directives
{
@@ -459,6 +449,21 @@ void NETLIST_EXPORTER_PSPICE::UpdateDirectives( unsigned aCtl )
m_directives.emplace_back( line + " " );
}
// Handle .control .. .endc blocks
if( lowercaseline.IsSameAs( ".control" ) && ( !controlBlock ) )
controlBlock = true;
if( lowercaseline.IsSameAs( ".endc" ) && controlBlock )
controlBlock = false;
// Handle .subckt .. .ends blocks
if( lowercaseline.StartsWith( ".subckt" ) && ( !circuitBlock ) )
circuitBlock = true;
if( lowercaseline.IsSameAs( ".ends" ) && circuitBlock )
circuitBlock = false;
// Mark directive as started or continued in case it is a multi-line one
directiveStarted = line.StartsWith( '.' )
|| ( directiveStarted && line.StartsWith( '+' ) );
+25 -7
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Chris Pavlina <pavlina.chris@gmail.com>
* Copyright (C) 2015-2019 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2015-2020 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
@@ -125,11 +125,15 @@ static wxFileName GetRescueLibraryFileName()
RESCUE_CASE_CANDIDATE::RESCUE_CASE_CANDIDATE( const wxString& aRequestedName,
const wxString& aNewName,
LIB_PART* aLibCandidate )
LIB_PART* aLibCandidate,
int aUnit,
int aConvert )
{
m_requested_name = aRequestedName;
m_new_name = aNewName;
m_lib_candidate = aLibCandidate;
m_unit = aUnit;
m_convert = aConvert;
}
@@ -170,7 +174,9 @@ void RESCUE_CASE_CANDIDATE::FindRescues( RESCUER& aRescuer,
continue;
RESCUE_CASE_CANDIDATE candidate( part_name, case_insensitive_matches[0]->GetName(),
case_insensitive_matches[0]->GetPart() );
case_insensitive_matches[0]->GetPart(),
each_component->GetUnit(),
each_component->GetConvert() );
candidate_map[part_name] = candidate;
}
@@ -213,12 +219,16 @@ bool RESCUE_CASE_CANDIDATE::PerformAction( RESCUER* aRescuer )
RESCUE_CACHE_CANDIDATE::RESCUE_CACHE_CANDIDATE( const wxString& aRequestedName,
const wxString& aNewName,
LIB_PART* aCacheCandidate,
LIB_PART* aLibCandidate )
LIB_PART* aLibCandidate,
int aUnit,
int aConvert )
{
m_requested_name = aRequestedName;
m_new_name = aNewName;
m_cache_candidate = aCacheCandidate;
m_lib_candidate = aLibCandidate;
m_unit = aUnit;
m_convert = aConvert;
}
@@ -271,7 +281,9 @@ void RESCUE_CACHE_CANDIDATE::FindRescues( RESCUER& aRescuer,
// Check if the symbol has already been rescued.
wxString new_name = LIB_ID::FixIllegalChars( part_name, LIB_ID::ID_SCH );
RESCUE_CACHE_CANDIDATE candidate( part_name, new_name, cache_match, lib_match );
RESCUE_CACHE_CANDIDATE candidate( part_name, new_name, cache_match, lib_match,
each_component->GetUnit(),
each_component->GetConvert() );
candidate_map[part_name] = candidate;
}
@@ -335,13 +347,17 @@ RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::RESCUE_SYMBOL_LIB_TABLE_CANDIDATE(
const LIB_ID& aRequestedId,
const LIB_ID& aNewId,
LIB_PART* aCacheCandidate,
LIB_PART* aLibCandidate ) : RESCUE_CANDIDATE()
LIB_PART* aLibCandidate,
int aUnit,
int aConvert ) : RESCUE_CANDIDATE()
{
m_requested_id = aRequestedId;
m_requested_name = aRequestedId.Format();
m_new_id = aNewId;
m_lib_candidate = aLibCandidate;
m_cache_candidate = aCacheCandidate;
m_unit = aUnit;
m_convert = aConvert;
}
@@ -406,7 +422,9 @@ void RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues(
libNickname.Replace( " ", "-" );
LIB_ID new_id( libNickname, new_name + "-" + part_id.GetLibNickname().wx_str() );
RESCUE_SYMBOL_LIB_TABLE_CANDIDATE candidate( part_id, new_id, cache_match, lib_match );
RESCUE_SYMBOL_LIB_TABLE_CANDIDATE candidate( part_id, new_id, cache_match, lib_match,
each_component->GetUnit(),
each_component->GetConvert() );
candidate_map[part_id] = candidate;
}
+18 -4
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Chris Pavlina <pavlina.chris@gmail.com>
* Copyright (C) 2015-2019 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2015-2020 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
@@ -69,6 +69,8 @@ protected:
wxString m_requested_name;
wxString m_new_name;
LIB_PART* m_lib_candidate;
int m_unit;
int m_convert;
public:
virtual ~RESCUE_CANDIDATE() {}
@@ -95,6 +97,10 @@ public:
*/
virtual LIB_PART* GetLibCandidate() const { return m_lib_candidate; }
int GetUnit() const { return m_unit; }
int GetConvert() const { return m_convert; }
/**
* Get a description of the action proposed, for displaying in the UI.
*/
@@ -125,9 +131,11 @@ public:
* @param aRequestedName - the name the schematic asks for
* @param aNewName - the name we want to change it to
* @param aLibCandidate - the part that will give us
* @param aUnit The unit of the rescued symbol.
* @param aConvert The body style of the rescued symbol.
*/
RESCUE_CASE_CANDIDATE( const wxString& aRequestedName, const wxString& aNewName,
LIB_PART* aLibCandidate );
LIB_PART* aLibCandidate, int aUnit = 0, int aConvert = 0 );
RESCUE_CASE_CANDIDATE() { m_lib_candidate = NULL; }
@@ -156,9 +164,12 @@ public:
* @param aNewName - the name we want to change it to
* @param aCacheCandidate - the part from the cache
* @param aLibCandidate - the part that would be loaded from the library
* @param aUnit The unit of the rescued symbol.
* @param aConvert The body style of the rescued symbol.
*/
RESCUE_CACHE_CANDIDATE( const wxString& aRequestedName, const wxString& aNewName,
LIB_PART* aCacheCandidate, LIB_PART* aLibCandidate );
LIB_PART* aCacheCandidate, LIB_PART* aLibCandidate,
int aUnit = 0, int aConvert = 0 );
RESCUE_CACHE_CANDIDATE();
@@ -191,9 +202,12 @@ public:
* @param aNewName - the name we want to change it to
* @param aCacheCandidate - the part from the cache
* @param aLibCandidate - the part that would be loaded from the library
* @param aUnit The unit of the rescued symbol.
* @param aConvert The body style of the rescued symbol.
*/
RESCUE_SYMBOL_LIB_TABLE_CANDIDATE( const LIB_ID& aRequestedId, const LIB_ID& aNewId,
LIB_PART* aCacheCandidate, LIB_PART* aLibCandidate);
LIB_PART* aCacheCandidate, LIB_PART* aLibCandidate,
int aUnit = 0, int aConvert = 0 );
RESCUE_SYMBOL_LIB_TABLE_CANDIDATE();
+13 -8
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2015-2017 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2015-2020 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
@@ -45,17 +45,22 @@
LIB_ALIAS* SchGetLibAlias( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable, PART_LIB* aCacheLib,
wxWindow* aParent, bool aShowErrorMsg )
{
// wxCHECK_MSG( aLibId.IsValid(), NULL, "LIB_ID is not valid." );
wxCHECK_MSG( aLibTable, NULL, "Invalid symbol library table." );
wxCHECK_MSG( aLibTable, nullptr, "Invalid symbol library table." );
LIB_ALIAS* alias = NULL;
LIB_ALIAS* symbol = nullptr;
try
{
alias = aLibTable->LoadSymbol( aLibId );
symbol = aLibTable->LoadSymbol( aLibId );
if( !alias && aCacheLib )
alias = aCacheLib->FindAlias( aLibId );
if( !symbol && aCacheLib )
{
wxCHECK_MSG( aCacheLib->IsCache(), nullptr, "Invalid cache library." );
wxString cacheName = aLibId.GetLibNickname().wx_str();
cacheName += "_" + aLibId.GetLibItemName();
symbol = aCacheLib->FindAlias( cacheName );
}
}
catch( const IO_ERROR& ioe )
{
@@ -69,7 +74,7 @@ LIB_ALIAS* SchGetLibAlias( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable, PA
}
}
return alias;
return symbol;
}
+5 -4
View File
@@ -837,7 +837,7 @@ void SCH_COMPONENT::SetTimeStamp( timestamp_t aNewTimeStamp )
}
int SCH_COMPONENT::GetUnitSelection( SCH_SHEET_PATH* aSheet )
int SCH_COMPONENT::GetUnitSelection( const SCH_SHEET_PATH* aSheet )
{
wxString path = GetPath( aSheet );
wxString h_path, h_multi;
@@ -988,7 +988,7 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
{
// Can no longer insert an empty name, since names are now keys. The
// field index is not used beyond the first MANDATORY_FIELDS
if( field.GetName().IsEmpty() )
if( field.GetName( NATIVE_FIELD_NAME ).IsEmpty() )
continue;
// See if field already exists (mandatory fields always exist).
@@ -1005,11 +1005,12 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
if( (unsigned) idx < MANDATORY_FIELDS )
schField = GetField( idx );
else
schField = FindField( field.GetName() );
schField = FindField( field.GetName( NATIVE_FIELD_NAME ) );
if( !schField )
{
SCH_FIELD newField( wxPoint( 0, 0 ), GetFieldCount(), this, field.GetName() );
SCH_FIELD newField( wxPoint( 0, 0 ), GetFieldCount(), this,
field.GetName( NATIVE_FIELD_NAME ) );
schField = AddField( newField );
}
+1 -1
View File
@@ -546,7 +546,7 @@ public:
int aMulti );
// returns the unit selection, for the given sheet path.
int GetUnitSelection( SCH_SHEET_PATH* aSheet );
int GetUnitSelection( const SCH_SHEET_PATH* aSheet );
// Set the unit selection, for the given sheet path.
void SetUnitSelection( SCH_SHEET_PATH* aSheet, int aUnitSelection );
+15 -4
View File
@@ -23,10 +23,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <functional>
#include <view/wx_view_controls.h>
#include <worksheet_viewitem.h>
#include <confirm.h>
#include <gal/graphics_abstraction_layer.h>
#include <sch_draw_panel.h>
#include <sch_view.h>
@@ -34,8 +35,6 @@
#include <sch_edit_frame.h>
#include <preview_items/selection_area.h>
#include <functional>
#include <sch_sheet.h>
#include <pgm_base.h>
@@ -174,7 +173,19 @@ void SCH_DRAW_PANEL::DisplaySheet( const SCH_SCREEN *aScreen )
void SCH_DRAW_PANEL::OnShow()
{
//m_view->RecacheAllItems();
SCH_BASE_FRAME* frame = dynamic_cast<SCH_BASE_FRAME*>( GetParent() );
try
{
// Check if the current rendering backend can be properly initialized
m_view->UpdateItems();
}
catch( const std::runtime_error& e )
{
// Fallback to software renderer
DisplayInfoMessage( frame, e.what() );
SwitchBackend( GAL_TYPE_CAIRO );
}
}
+1
View File
@@ -387,6 +387,7 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ):
m_undoItem = NULL;
m_hasAutoSave = true;
m_showIllegalSymbolLibDialog = true;
m_showSheetFileNameCaseSensitivityDlg = true;
m_FrameSize = ConvertDialogToPixels( wxSize( 500, 350 ) ); // default in case of no prefs
m_AboutTitle = "Eeschema";
+14
View File
@@ -151,6 +151,7 @@ private:
bool m_autoplaceAlign; ///< align autoplaced fields to the grid
bool m_footprintPreview; ///< whether to show footprint previews
bool m_showIllegalSymbolLibDialog;
bool m_showSheetFileNameCaseSensitivityDlg;
/// An index to the last find item in the found items list #m_foundItems.
int m_foundItemIndex;
@@ -985,6 +986,19 @@ private:
*/
bool importFile( const wxString& aFileName, int aFileType );
/**
* Check \a aSchematicFileName for a potential file name case sensitivity clashes.
*
* On platforms where file names are case sensitive, it is possible to schematic sheet
* file names that would cause issues on platforms where file name are case insensitive.
* File names foo.sch and Foo.sch are unique files on Linux and MacOS but on Windows
* this would result in a broken schematic.
*
* @param aSchematicFileName is the absolute path and file name of the file to test.
* @return true if the user accepts the potential file name clase risk.
*/
bool allowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName );
public:
/**
* Command event handler to change a text type to another one.
+27
View File
@@ -1619,6 +1619,33 @@ bool SCH_SCREENS::HasSchematic( const wxString& aSchematicFileName )
}
bool SCH_SCREENS::CanCauseCaseSensitivityIssue( const wxString& aSchematicFileName ) const
{
wxString lhsLower;
wxString rhsLower;
wxFileName lhs;
wxFileName rhs = aSchematicFileName;
wxCHECK( rhs.IsAbsolute(), false );
for( const SCH_SCREEN* screen : m_screens )
{
lhs = screen->GetFileName();
if( lhs.GetPath() != rhs.GetPath() )
continue;
lhsLower = lhs.GetFullName().Lower();
rhsLower = rhs.GetFullName().Lower();
if( lhsLower == rhsLower && lhs.GetFullName() != rhs.GetFullName() )
return true;
}
return false;
}
void SCH_SCREENS::BuildClientSheetPathList()
{
SCH_SHEET_LIST sheetList( g_RootSheet );
+13
View File
@@ -639,6 +639,19 @@ public:
void BuildClientSheetPathList();
/**
* Check \a aSchematicFileName for a potential file name case sensitivity issue.
*
* On platforms where file names are case sensitive, it is possible to schematic sheet
* file names that would cause issues on platforms where file name are case insensitive.
* File names foo.sch and Foo.sch are unique files on Linux and MacOS but on Windows
* this would result in a broken schematic.
*
* @param aSchematicFileName is the absolute path and file name of the file to test.
* @return true if \a aSchematicFileName would cause an issue.
*/
bool CanCauseCaseSensitivityIssue( const wxString& aSchematicFileName ) const;
private:
void addScreenToList( SCH_SCREEN* aScreen );
void buildScreenList( SCH_SHEET* aSheet);
+21 -3
View File
@@ -578,18 +578,36 @@ int SCH_SHEET::ComponentCount()
bool SCH_SHEET::SearchHierarchy( const wxString& aFilename, SCH_SCREEN** aScreen )
{
SCH_SHEET* sheet = nullptr;
SCH_SCREEN* screen = nullptr;
if( m_screen )
{
// Only check the root sheet once and don't recurse.
if( !GetParent() )
{
sheet = this;
screen = m_screen;
if( screen && screen->GetFileName().Cmp( aFilename ) == 0 )
{
*aScreen = screen;
return true;
}
}
EDA_ITEM* item = m_screen->GetDrawItems();
while( item )
{
if( item->Type() == SCH_SHEET_T )
{
SCH_SHEET* sheet = (SCH_SHEET*) item;
// Must use the screen's path (which is always absolute) rather than the
// sheet's (which could be relative).
sheet = static_cast< SCH_SHEET* >( item );
screen = sheet->m_screen;
if( sheet->m_screen
&& sheet->m_screen->GetFileName().CmpNoCase( aFilename ) == 0 )
if( screen && screen->GetFileName().Cmp( aFilename ) == 0 )
{
*aScreen = sheet->m_screen;
return true;
+15 -1
View File
@@ -455,6 +455,8 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet )
{
wxCHECK_RET( aSheet != NULL, wxT( "Cannot build sheet list from undefined sheet." ) );
std::vector<SCH_SHEET*> badSheets;
if( aSheet == g_RootSheet )
m_isRootSheet = true;
@@ -477,11 +479,23 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet )
if( item->Type() == SCH_SHEET_T )
{
SCH_SHEET* sheet = (SCH_SHEET*) item;
BuildSheetList( sheet );
if( !m_currentSheetPath.TestForRecursion(
sheet->GetFileName(), aSheet->GetFileName() ) )
BuildSheetList( sheet );
else
badSheets.push_back( sheet );
}
item = item->Next();
}
for( auto sheet : badSheets )
{
aSheet->GetScreen()->Remove( sheet );
aSheet->GetScreen()->SetModify();
}
}
m_currentSheetPath.pop_back();
+7 -6
View File
@@ -82,12 +82,13 @@ bool SCH_FIELD_VALIDATOR::Validate( wxWindow *aParent )
switch( m_fieldId )
{
case FIELD_NAME: fieldName = _( "field name" ); break;
case REFERENCE: fieldName = _( "reference field" ); break;
case VALUE: fieldName = _( "value field" ); break;
case FOOTPRINT: fieldName = _( "footprint field" ); break;
case DATASHEET: fieldName = _( "datasheet field" ); break;
default: fieldName = _( "user defined field" ); break;
case FIELD_NAME: fieldName = _( "field name" ); break;
case FIELD_VALUE: fieldName = _( "field value" ); break;
case REFERENCE: fieldName = _( "reference field" ); break;
case VALUE: fieldName = _( "value field" ); break;
case FOOTPRINT: fieldName = _( "footprint field" ); break;
case DATASHEET: fieldName = _( "datasheet field" ); break;
default: fieldName = _( "user defined field" ); break;
};
wxString msg;
+1
View File
@@ -34,6 +34,7 @@
#define FIELD_NAME -1
#define FIELD_VALUE -2
/**
+43 -2
View File
@@ -574,6 +574,9 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy,
if( aSheet->GetScreen() == NULL ) // New sheet.
{
if( !allowCaseSensitiveFileNameClashes( newFilename ) )
return false;
if( useScreen || loadFromFile ) // Load from existing file.
{
clearAnnotation = true;
@@ -605,6 +608,9 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy,
isExistingSheet = true;
if( !allowCaseSensitiveFileNameClashes( newFilename ) )
return false;
// Changing the filename of a sheet can modify the full hierarchy structure
// and can be not always undoable.
// So prepare messages for user notifications:
@@ -627,7 +633,7 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy,
wxString oldFilename = aSheet->GetScreen()->GetFileName();
oldFilename.Replace( wxT( "\\" ), wxT( "/" ) );
if( newFilename.CmpNoCase( oldFilename ) != 0 )
if( newFilename.Cmp( oldFilename ) != 0 )
{
// Sheet file name changes cannot be undone.
isUndoable = false;
@@ -731,7 +737,8 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy,
aHierarchy->LastScreen()->Remove( aSheet );
}
if( !LoadSheetFromFile( aSheet, aHierarchy, newFilename ) )
if( !LoadSheetFromFile( aSheet, aHierarchy, newFilename )
|| checkSheetForRecursion( aSheet, aHierarchy ) )
{
if( restoreSheet )
aHierarchy->LastScreen()->Append( aSheet );
@@ -974,3 +981,37 @@ void SCH_EDIT_FRAME::MirrorSheet( SCH_SHEET* aSheet, bool aFromXaxis )
GetCanvas()->GetView()->Update( aSheet );
OnModify();
}
bool SCH_EDIT_FRAME::allowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName )
{
wxString msg;
SCH_SCREENS screens;
wxFileName fn = aSchematicFileName;
wxCHECK( fn.IsAbsolute(), false );
if( m_showSheetFileNameCaseSensitivityDlg
&& screens.CanCauseCaseSensitivityIssue( aSchematicFileName ) )
{
msg.Printf( _( "The file name \"%s\" can cause issues with an existing file name\n"
"already defined in the schematic on systems that support case\n"
"insensitive file names. This will cause issues if you copy this\n"
"project to an operating system that supports case insensitive file\n"
"names.\n\nDo you wish to continue?" ),
fn.GetName() );
wxRichMessageDialog dlg( this, msg, _( "Warning" ),
wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
dlg.ShowCheckBox( _( "Do not show this message again." ) );
dlg.SetYesNoLabels( wxMessageDialog::ButtonLabel( _( "Create New Sheet" ) ),
wxMessageDialog::ButtonLabel( _( "Discard New Sheet" ) ) );
if( dlg.ShowModal() == wxID_NO )
return false;
m_showSheetFileNameCaseSensitivityDlg = !dlg.IsCheckBoxChecked();
}
return true;
}
+12
View File
@@ -621,6 +621,12 @@ void LIB_VIEW_FRAME::ClickOnLibList( wxCommandEvent& event )
m_selection_changed = true;
SetSelectedLibrary( m_libList->GetString( ii ) );
// The m_libList has now the focus, in order to be able to use arrow keys
// to navigate inside the list.
// the gal canvas must not steal the focus to allow navigation
GetGalCanvas()->SetStealsFocus( false );
m_libList->SetFocus();
}
@@ -651,6 +657,12 @@ void LIB_VIEW_FRAME::ClickOnCmpList( wxCommandEvent& event )
m_selection_changed = true;
SetSelectedComponent( m_cmpList->GetString( ii ) );
// The m_cmpList has now the focus, in order to be able to use arrow keys
// to navigate inside the list.
// the gal canvas must not steal the focus to allow navigation
GetGalCanvas()->SetStealsFocus( false );
m_cmpList->SetFocus();
}
+18 -18
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2018-2020 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
@@ -57,7 +57,8 @@ SYMBOL_PREVIEW_WIDGET::SYMBOL_PREVIEW_WIDGET( wxWindow* aParent, KIWAY& aKiway,
// Do not display the grid: the look is not good for a small canvas area.
// But mainly, due to some strange bug I (JPC) was unable to fix, the grid creates
// strange artifacts on Windows when eeschema is run from Kicad manager (but not in stand alone...).
// strange artifacts on Windows when eeschema is run from Kicad manager (but not in
// stand alone...).
m_preview->GetGAL()->SetGridVisibility( false );
// Early initialization of the canvas background color,
@@ -141,7 +142,7 @@ void SYMBOL_PREVIEW_WIDGET::fitOnDrawArea()
}
void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit )
void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit, int aConvert )
{
KIGFX::VIEW* view = m_preview->GetView();
auto settings = static_cast<KIGFX::SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
@@ -172,19 +173,16 @@ void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit )
// If unit isn't specified for a multi-unit part, pick the first. (Otherwise we'll
// draw all of them.)
if( part->IsMulti() && aUnit == 0 )
aUnit = 1;
settings->m_ShowUnit = aUnit;
settings->m_ShowUnit = ( part->IsMulti() && aUnit == 0 ) ? 1 : aUnit;
// For symbols having a De Morgan body style, use the first style
settings->m_ShowConvert = part->HasConversion() ? 1 : 0;
settings->m_ShowConvert =
( part->HasConversion() && aConvert == 0 ) ? 1 : aConvert;
m_previewItem = new LIB_ALIAS( *alias, part );
view->Add( m_previewItem );
// Get the symbole size, in internal units
m_itemBBox = part->GetUnitBoundingBox( aUnit, 0 );
m_itemBBox = part->GetUnitBoundingBox( settings->m_ShowUnit, settings->m_ShowConvert );
if( !m_preview->IsShown() )
{
@@ -201,7 +199,7 @@ void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit )
}
void SYMBOL_PREVIEW_WIDGET::DisplayPart( LIB_PART* aPart, int aUnit )
void SYMBOL_PREVIEW_WIDGET::DisplayPart( LIB_PART* aPart, int aUnit, int aConvert )
{
KIGFX::VIEW* view = m_preview->GetView();
@@ -214,19 +212,21 @@ void SYMBOL_PREVIEW_WIDGET::DisplayPart( LIB_PART* aPart, int aUnit )
if( aPart )
{
// If unit isn't specified for a multi-unit part, pick the first. (Otherwise we'll
// draw all of them.)
if( aPart->IsMulti() && aUnit == 0 )
aUnit = 1;
m_previewItem = new LIB_PART( *aPart );
// For symbols having a De Morgan body style, use the first style
auto settings = static_cast<KIGFX::SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
settings->m_ShowConvert = aPart->HasConversion() ? 1 : 0;
m_previewItem = new LIB_PART( *aPart );
// If unit isn't specified for a multi-unit part, pick the first. (Otherwise we'll
// draw all of them.)
settings->m_ShowUnit = ( aPart->IsMulti() && aUnit == 0 ) ? 1 : aUnit;
settings->m_ShowConvert =
( aPart->HasConversion() && aConvert == 0 ) ? 1 : aConvert;
view->Add( m_previewItem );
// Get the symbole size, in internal units
m_itemBBox = aPart->GetUnitBoundingBox( aUnit, 0 );
m_itemBBox = aPart->GetUnitBoundingBox( settings->m_ShowUnit, settings->m_ShowConvert );
// Calculate the draw scale to fit the drawing area
fitOnDrawArea();
+3 -3
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2018-2020 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
@@ -58,9 +58,9 @@ public:
/**
* Set the currently displayed symbol.
*/
void DisplaySymbol( const LIB_ID& aSymbolID, int aUnit );
void DisplaySymbol( const LIB_ID& aSymbolID, int aUnit, int aConvert = 0 );
void DisplayPart( LIB_PART* aPart, int aUnit );
void DisplayPart( LIB_PART* aPart, int aUnit, int aConvert = 0 );
private:
void onSize( wxSizeEvent& aEvent );
+1 -4
View File
@@ -168,11 +168,8 @@ add_dependencies( gerbview gerbview_kiface )
# these 2 binaries are a matched set, keep them together
if( APPLE )
include( ${CMAKE_MODULE_PATH}/KiCadVersion.cmake )
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist @ONLY )
set_target_properties( gerbview PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
MACOSX_BUNDLE_INFO_PLIST ${PROJECT_BINARY_DIR}/gerbview/Info.plist
)
# puts binaries into the *.app bundle while linking
+5 -8
View File
@@ -226,14 +226,14 @@ void D_CODE::DrawFlashedShape( GERBER_DRAW_ITEM* aParent,
int delta = (m_Size.x - m_Size.y) / 2;
start.x -= delta;
end.x += delta;
radius = m_Size.y;
radius = m_Size.y; // Width in fact
}
else // horizontal oval
else // vertical oval
{
int delta = (m_Size.y - m_Size.x) / 2;
start.y -= delta;
end.y += delta;
radius = m_Size.x;
radius = m_Size.x; // Width in fact
}
start = aParent->GetABPosition( start );
@@ -374,13 +374,10 @@ void D_CODE::ConvertShapeToPolygon()
m_Polygon.Append( VECTOR2I( currpos ) );
}
m_Polygon.Append( VECTOR2I( initialpos ) ); // close outline
m_Polygon.Append( VECTOR2I( initialpos ) ); // close outline
if( m_Size.y > m_Size.x ) // vertical oval, rotate polygon.
{
for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
it->Rotate( -M_PI / 2 );
}
m_Polygon.Rotate( -M_PI / 2, VECTOR2I( 0, 0 ) );
addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
}
+21 -7
View File
@@ -185,17 +185,17 @@ void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event )
return;
}
wxString fileName;
wxString fileDialogName( wxT( "noname." ) + KiCadPcbFileExtension );
wxString path = m_mruPath;
wxFileDialog filedlg( this, _( "Board File Name" ),
path, fileName, PcbFileWildcard(),
path, fileDialogName, PcbFileWildcard(),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
if( filedlg.ShowModal() == wxID_CANCEL )
return;
fileName = filedlg.GetPath();
wxFileName fileName = filedlg.GetPath();
/* Install a dialog frame to choose the mapping
* between gerber layers and Pcbnew layers
@@ -207,9 +207,13 @@ void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event )
if( ok != wxID_OK )
return;
m_mruPath = wxFileName( fileName ).GetPath();
// If no extension was entered, then force the extension to be a KiCad PCB file
if( !fileName.HasExt() )
fileName.SetExt( KiCadPcbFileExtension );
GBR_TO_PCB_EXPORTER gbr_exporter( this, fileName );
m_mruPath = fileName.GetPath();
GBR_TO_PCB_EXPORTER gbr_exporter( this, fileName.GetFullPath() );
gbr_exporter.ExportPcb( layerdlg->GetLayersLookUpTable(), layerdlg->GetCopperLayersCount() );
}
@@ -536,11 +540,21 @@ void GBR_TO_PCB_EXPORTER::writePcbLineItem( bool aIsArc, wxPoint& aStart, wxPoin
void GBR_TO_PCB_EXPORTER::writePcbPolygonItem( GERBER_DRAW_ITEM* aGbrItem, LAYER_NUM aLayer )
{
fprintf( m_fp, "(gr_poly (pts " );
SHAPE_POLY_SET polys = aGbrItem->m_Polygon;
// Cleanup the polygon
polys.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
// Ensure the polygon is valid:
if( polys.OutlineCount() == 0 )
return;
polys.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
SHAPE_LINE_CHAIN& poly = polys.Outline( 0 );
fprintf( m_fp, "(gr_poly (pts " );
#define MAX_COORD_CNT 4
int jj = MAX_COORD_CNT;
int cnt_max = poly.PointCount() -1;
+32 -1
View File
@@ -339,7 +339,7 @@ const EDA_RECT GERBER_DRAW_ITEM::GetBoundingBox() const
case GBR_SPOT_OVAL:
{
if( code )
bbox.Inflate( code->m_Size.x, code->m_Size.y );
bbox.Inflate( code->m_Size.x /2, code->m_Size.y / 2 );
break;
}
@@ -828,6 +828,37 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) const
case GBR_SPOT_RECT:
return GetBoundingBox().Contains( aRefPos );
case GBR_SPOT_OVAL:
{
EDA_RECT bbox = GetBoundingBox();
if( ! bbox.Contains( aRefPos ) )
return false;
// This is similar to a segment with thickness = min( m_Size.x, m_Size.y )
int radius = std::min( m_Size.x, m_Size.y )/2;
wxPoint start, end;
if( m_Size.x > m_Size.y ) // Horizontal oval
{
int len = m_Size.y - m_Size.x;
start.x = -len/2;
end.x = len/2;
}
else // Vertical oval
{
int len = m_Size.x - m_Size.y;
start.y = -len/2;
end.y = len/2;
}
start += bbox.Centre();
end += bbox.Centre();
if( radius < MIN_HIT_TEST_RADIUS )
radius = MIN_HIT_TEST_RADIUS;
return TestSegmentHit( aRefPos, start, end, radius );
}
case GBR_ARC:
{
double radius = GetLineLength( m_Start, m_ArcCentre );
+5 -4
View File
@@ -211,8 +211,8 @@ void GERBER_FILE_IMAGE::ResetDefaultValues()
m_FmtLen.x = m_FmtLen.y = 3 + 4; // Initialize default format len = 3+4
m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // Linear, 90 arc, Circ.
m_360Arc_enbl = false; // 360 deg circular
// interpolation disable
m_360Arc_enbl = false; // 360 deg circular interpolation disable
m_AsArcG74G75Cmd = false; // false until a G74 or G75 command is found
m_Current_Tool = 0; // Current Dcode selected
m_CommandState = 0; // State of the current command
m_CurrentPos.x = m_CurrentPos.y = 0; // current specified coord
@@ -385,9 +385,10 @@ void GERBER_FILE_IMAGE::RemoveAttribute( X2_ATTRIBUTE& aAttribute )
* if a attribute name is specified (for instance %TD.CN*%) is specified,
* only this attribute is cleared
*/
m_NetAttributeDict.ClearAttribute( &aAttribute.GetPrm( 1 ) );
wxString cmd = aAttribute.GetPrm( 0 );
m_NetAttributeDict.ClearAttribute( &cmd );
if( aAttribute.GetPrm( 1 ).IsEmpty() || aAttribute.GetPrm( 1 ) == ".AperFunction" )
if( cmd.IsEmpty() || cmd == ".AperFunction" )
m_AperFunction.Clear();
}
+2
View File
@@ -163,6 +163,8 @@ public:
bool m_Has_DCode; // true = DCodes in file
// (false = no DCode -> separate DCode file
bool m_360Arc_enbl; // Enbl 360 deg circular interpolation
bool m_AsArcG74G75Cmd; // Set to true when a circular interpolation command
// type is found. Mandatory before drawing an arc.
bool m_PolygonFillMode; // Enable polygon mode (read coord as a polygon descr)
int m_PolygonFillModeState; // In polygon mode: 0 = first segm, 1 = next segm

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