Compare commits
95 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4c14d7ef5a | |||
| 8234c20e28 | |||
| 52e272954f | |||
| 77caf50265 | |||
| 2ab8751fd4 | |||
| 54589c0828 | |||
| 1fdb247167 | |||
| 49cc47afd1 | |||
| 673677c831 | |||
| c30dc04571 | |||
| f58de79ceb | |||
| 8d9bb7a63e | |||
| 18490162f7 | |||
| bf71a4e012 | |||
| d29edf6381 | |||
| b087b7743e | |||
| 8ee1a7f67f | |||
| 475385d876 | |||
| 1b967a07e5 | |||
| 1088d613d5 | |||
| 1b2d4d6522 | |||
| 0fd1214dea | |||
| 00547b7aac | |||
| 621bfe36a8 | |||
| c1849f7e00 | |||
| b23db7c4cb | |||
| b3525bc642 | |||
| 589951eaea | |||
| 74adbbcc5d | |||
| bab61dd249 | |||
| 5c3bcb09fa | |||
| f0b94dd0d4 | |||
| ba5ab99a03 | |||
| 9bc3028eb7 | |||
| 5ef9db6d67 | |||
| 86a710e175 | |||
| 1797a9c61a | |||
| fd49bc5d8d | |||
| de4c6c6fab | |||
| 78a7dd3269 | |||
| 0cf53da0fe | |||
| 13b8708e58 | |||
| b6d91bd28a | |||
| 5bdc78e3ba | |||
| bce8fb31ab | |||
| 77d7d21130 | |||
| fed1520a8e | |||
| 284d5861dd | |||
| ee6154c842 | |||
| 709197c294 | |||
| fd55b7b4ed | |||
| 5bca5e2d77 | |||
| ee96937fd4 | |||
| a370d69542 | |||
| 24aad2eed4 | |||
| 910605cc7d | |||
| 7194e25bba | |||
| 7f287cb8f9 | |||
| a0ce1491d9 | |||
| 26035d23fe | |||
| 835debe75e | |||
| b482deb8b0 | |||
| 76fd1e6f5a | |||
| abb45fbe45 | |||
| 567ce48cc1 | |||
| 56a17b4e68 | |||
| c027e72439 | |||
| 25b8da8e3b | |||
| 5b47d1a910 | |||
| a844c3043c | |||
| e099a82d15 | |||
| b681af4556 | |||
| 78d66a9ac3 | |||
| bfe4d9f3f4 | |||
| a02ee3719c | |||
| 542f713678 | |||
| 2395c6fdaa | |||
| c7f02d5e51 | |||
| 55a726e933 | |||
| 601633347c | |||
| 182973c0ee | |||
| a16e9ac76a | |||
| 66f70e5da6 | |||
| 5a187c6ca8 | |||
| c6042100f9 | |||
| fde7ae4d19 | |||
| e37e13e700 | |||
| d22003578e | |||
| 52139cf0c4 | |||
| 37b723d8ae | |||
| aec3649524 | |||
| 36d716bb50 | |||
| f61c692929 | |||
| 3f717f3baf | |||
| ffc95090aa |
@@ -44,7 +44,7 @@ if( APPLE )
|
||||
endif()
|
||||
|
||||
find_file( S3DSG_VERSION_FILE sg_version.h
|
||||
PATHS ${CMAKE_SOURCE_DIR}/include/plugins/3dapi NO_DEFAULT_PATH )
|
||||
PATHS ${CMAKE_SOURCE_DIR}/include/plugins/3dapi NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
|
||||
|
||||
if( NOT ${S3DSG_VERSION_FILE} STREQUAL "S3DSG_VERSION_FILE-NOTFOUND" )
|
||||
|
||||
|
||||
@@ -272,13 +272,9 @@ void CINFO3D_VISU::InitSettings( REPORTER *aStatusTextReporter )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "CINFO3D_VISU::InitSettings" ) );
|
||||
|
||||
// Calculates the board bounding box
|
||||
// First, use only the board outlines
|
||||
EDA_RECT bbbox = m_board->ComputeBoundingBox( true );
|
||||
|
||||
// If no outlines, use the board with items
|
||||
if( ( bbbox.GetWidth() == 0 ) && ( bbbox.GetHeight() == 0 ) )
|
||||
bbbox = m_board->ComputeBoundingBox( false );
|
||||
// Calculates the board bounding box (board outlines + items)
|
||||
// to ensure any item, even outside the board outlines can be seen
|
||||
EDA_RECT bbbox = m_board->ComputeBoundingBox( false );
|
||||
|
||||
// Gives a non null size to avoid issues in zoom / scale calculations
|
||||
if( ( bbbox.GetWidth() == 0 ) && ( bbbox.GetHeight() == 0 ) )
|
||||
|
||||
@@ -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
|
||||
@@ -57,6 +57,9 @@ const wxChar * EDA_3D_CANVAS::m_logTrace = wxT( "KI_TRACE_EDA_3D_CANVAS" );
|
||||
|
||||
const float EDA_3D_CANVAS::m_delta_move_step_factor = 0.7f;
|
||||
|
||||
// A custom event, used to call DoRePaint during an idle time
|
||||
wxDEFINE_EVENT( wxEVT_REFRESH_CUSTOM_COMMAND, wxEvent);
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( EDA_3D_CANVAS, wxGLCanvas )
|
||||
EVT_PAINT( EDA_3D_CANVAS::OnPaint )
|
||||
@@ -78,6 +81,7 @@ BEGIN_EVENT_TABLE( EDA_3D_CANVAS, wxGLCanvas )
|
||||
|
||||
// other events
|
||||
EVT_ERASE_BACKGROUND( EDA_3D_CANVAS::OnEraseBackground )
|
||||
EVT_CUSTOM(wxEVT_REFRESH_CUSTOM_COMMAND, ID_CUSTOM_EVENT_1, EDA_3D_CANVAS::OnRefreshRequest )
|
||||
EVT_MENU_RANGE( ID_POPUP_3D_VIEW_START,
|
||||
ID_POPUP_3D_VIEW_END, EDA_3D_CANVAS::OnPopUpMenu )
|
||||
|
||||
@@ -312,17 +316,22 @@ void EDA_3D_CANVAS::DisplayStatus()
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
|
||||
void EDA_3D_CANVAS::OnPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
// Please have a look at:
|
||||
// https://lists.launchpad.net/kicad-developers/msg25149.html
|
||||
// wxPaintDC( this );
|
||||
// event.Skip( false );
|
||||
// aEvent.Skip( false );
|
||||
DoRePaint();
|
||||
}
|
||||
|
||||
|
||||
void EDA_3D_CANVAS::DoRePaint()
|
||||
{
|
||||
// SwapBuffer requires the window to be shown before calling
|
||||
if( !IsShownOnScreen() )
|
||||
{
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::OnPaint !IsShown" );
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::DoRePaint !IsShown" );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -856,13 +865,13 @@ void EDA_3D_CANVAS::restart_editingTimeOut_Timer()
|
||||
|
||||
void EDA_3D_CANVAS::OnTimerTimeout_Redraw( wxTimerEvent &event )
|
||||
{
|
||||
(void)event;
|
||||
Request_refresh( true );
|
||||
}
|
||||
|
||||
//Refresh();
|
||||
//Update();
|
||||
|
||||
wxPaintEvent redrawEvent;
|
||||
wxPostEvent( this, redrawEvent );
|
||||
void EDA_3D_CANVAS::OnRefreshRequest( wxEvent& aEvent )
|
||||
{
|
||||
DoRePaint();
|
||||
}
|
||||
|
||||
|
||||
@@ -870,22 +879,12 @@ void EDA_3D_CANVAS::Request_refresh( bool aRedrawImmediately )
|
||||
{
|
||||
if( aRedrawImmediately )
|
||||
{
|
||||
// On some systems, just calling Refresh does not work always
|
||||
// (Issue experienced on Win7 MSYS2)
|
||||
//Refresh();
|
||||
//Update();
|
||||
|
||||
// Using PostEvent will take priority to other events, like
|
||||
// mouse movements, keys, etc.
|
||||
wxPaintEvent redrawEvent;
|
||||
// Just calling Refresh() does not work always
|
||||
// Using an event to call DoRepaint ensure the repaint code will be executed,
|
||||
// and PostEvent will take priority to other events like mouse movements, keys, etc.
|
||||
// and is executed during the next idle time
|
||||
wxCommandEvent redrawEvent( wxEVT_REFRESH_CUSTOM_COMMAND, ID_CUSTOM_EVENT_1 );
|
||||
wxPostEvent( this, redrawEvent );
|
||||
|
||||
// This behaves the same
|
||||
// wxQueueEvent( this,
|
||||
// From wxWidget documentation: "The heap-allocated and
|
||||
// non-NULL event to queue, the function takes ownership of it."
|
||||
// new wxPaintEvent()
|
||||
// );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -135,10 +135,21 @@ class EDA_3D_CANVAS : public HIDPI_GL_CANVAS
|
||||
|
||||
private:
|
||||
|
||||
void OnPaint( wxPaintEvent &event );
|
||||
/** Called by a wxPaintEvent event
|
||||
*/
|
||||
void OnPaint( wxPaintEvent& aEvent );
|
||||
|
||||
/**
|
||||
* The actual function to repaint the canvas.
|
||||
* It is usually called by OnPaint() but because it does not use a wxPaintDC
|
||||
* it can be called outside a wxPaintEvent
|
||||
*/
|
||||
void DoRePaint();
|
||||
|
||||
void OnEraseBackground( wxEraseEvent &event );
|
||||
|
||||
void OnRefreshRequest( wxEvent& aEvent );
|
||||
|
||||
void OnMouseWheel( wxMouseEvent &event );
|
||||
|
||||
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
|
||||
|
||||
@@ -103,6 +103,8 @@ enum id_3dview_frm
|
||||
|
||||
ID_DISABLE_RAY_TRACING,
|
||||
|
||||
ID_CUSTOM_EVENT_1, // A id for a custom event (canvas refresh request)
|
||||
|
||||
ID_POPUP_3D_VIEW_START,
|
||||
ID_POPUP_ZOOMIN,
|
||||
ID_POPUP_ZOOMOUT,
|
||||
|
||||
+1
-26
@@ -21,14 +21,7 @@
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
#
|
||||
|
||||
cmake_minimum_required( VERSION 2.8.12 FATAL_ERROR )
|
||||
# because of http://public.kitware.com/Bug/view.php?id=10395
|
||||
|
||||
# See https://gitlab.kitware.com/cmake/cmake/issues/15943
|
||||
# Remove as soon as 3.1 is minimum required version
|
||||
if(POLICY CMP0025)
|
||||
cmake_policy(SET CMP0025 NEW) # CMake 3.0
|
||||
endif()
|
||||
cmake_minimum_required( VERSION 3.2 FATAL_ERROR )
|
||||
|
||||
# Default to CMAKE_BUILD_TYPE = Release unless overridden on command line
|
||||
# http://www.cmake.org/pipermail/cmake/2008-September/023808.html
|
||||
@@ -200,24 +193,6 @@ include( PerformFeatureChecks )
|
||||
perform_feature_checks()
|
||||
|
||||
|
||||
# Workaround: CMake < 3.1 does not support CMAKE_CXX_STANDARD
|
||||
if( NOT CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 3.1 )
|
||||
message( FATAL_ERROR "Remove compatibility code" )
|
||||
endif()
|
||||
|
||||
if( CMAKE_VERSION VERSION_LESS 3.1 AND ( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) )
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
|
||||
|
||||
if(COMPILER_SUPPORTS_CXX11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
else()
|
||||
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# Warn about missing override specifiers, if supported
|
||||
if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
@@ -44,7 +44,7 @@ cmake_find_frameworks(Python)
|
||||
|
||||
set(_PYTHON1_VERSIONS 1.6 1.5)
|
||||
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
|
||||
set(_PYTHON3_VERSIONS 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
set(_PYTHON3_VERSIONS 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
|
||||
if(PythonLibs_FIND_VERSION)
|
||||
if(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
find_program(SWIG_EXECUTABLE NAMES swig3.0 swig2.0 swig)
|
||||
find_program(SWIG_EXECUTABLE NAMES swig4.0 swig3.0 swig2.0 swig)
|
||||
|
||||
if(SWIG_EXECUTABLE)
|
||||
execute_process(COMMAND ${SWIG_EXECUTABLE} -swiglib
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# CMake script for finding libngspice
|
||||
|
||||
# Copyright (C) 2016 CERN
|
||||
# Copyright (C) 2020 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
#
|
||||
# Author: Maciej Suminski <maciej.suminski@cern.ch>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
@@ -20,21 +22,103 @@
|
||||
# or you may write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# ngspice uses pkg-config to gather the configuration information so the pkg-config
|
||||
# information is used to populate the CMake find_* commands. When pkg-config is not
|
||||
# available, the fallback is the default platform search paths set up by CMake. The
|
||||
# default search paths can be overridden by user. The order of precedence is as
|
||||
# follows:
|
||||
#
|
||||
# User defined root path NGSPICE_ROOT_DIR on CMake command line.
|
||||
# User defined root path environment variable NGSPICE_ROOT_DIR.
|
||||
# Paths generated by pkg-config.
|
||||
# The default system paths configured by CMake
|
||||
#
|
||||
# For a specific ngspice include path not defined above set NGSPICE_INCLUDE_PATH.
|
||||
#
|
||||
# For a specific ngspice library path not defined above set NGSPICE_LIBRARY_PATH.
|
||||
|
||||
# Use pkg-config if it's available.
|
||||
find_package(PkgConfig)
|
||||
|
||||
if( PKG_CONFIG_FOUND )
|
||||
pkg_check_modules( _NGSPICE ngspice )
|
||||
|
||||
if( _NGSPICE_FOUND )
|
||||
set( NGSPICE_BUILD_VERSION "${_NGSPICE_VERSION}" CACHE STRING
|
||||
"ngspice version returned by pkg-config" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
find_path( NGSPICE_INCLUDE_DIR ngspice/sharedspice.h
|
||||
PATHS ${NGSPICE_ROOT_DIR} $ENV{NGSPICE_ROOT_DIR} ${NGSPICE_INCLUDE_PATH}
|
||||
${NGSPICE_ROOT_DIR}/include
|
||||
PATH_SUFFIXES src/include share/ngspice/include share/ngspice/include/ngspice
|
||||
PATHS
|
||||
${NGSPICE_ROOT_DIR}
|
||||
$ENV{NGSPICE_ROOT_DIR}
|
||||
${NGSPICE_INCLUDE_PATH}
|
||||
${_NGSPICE_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
src/include
|
||||
share/ngspice/include
|
||||
share/ngspice/include/ngspice
|
||||
)
|
||||
|
||||
find_library( NGSPICE_LIBRARY ngspice
|
||||
PATHS ${NGSPICE_ROOT_DIR} $ENV{NGSPICE_ROOT_DIR} ${NGSPICE_LIBRARY_PATH}
|
||||
PATH_SUFFIXES src/.libs lib
|
||||
PATHS
|
||||
${NGSPICE_ROOT_DIR}
|
||||
$ENV{NGSPICE_ROOT_DIR}
|
||||
${NGSPICE_LIBRARY_PATH}
|
||||
${_NGSPICE_LIBRARY_DIRS}
|
||||
PATH_SUFFIXES
|
||||
src/.libs
|
||||
lib
|
||||
)
|
||||
|
||||
# If the ngspice version is not set by pkg-config, see if ngspice/config.h is available.
|
||||
if( NOT NGSPICE_BUILD_VERSION )
|
||||
find_file( NGSPICE_CONFIG_H ngspice/config.h
|
||||
PATHS
|
||||
${NGSPICE_ROOT_DIR}
|
||||
$ENV{NGSPICE_ROOT_DIR}
|
||||
${NGSPICE_INCLUDE_PATH}
|
||||
${_NGSPICE_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
src/include
|
||||
share/ngspice/include
|
||||
share/ngspice/include/ngspice
|
||||
)
|
||||
|
||||
if( NOT NGSPICE_CONFIG_H-NOTFOUND )
|
||||
message( STATUS "ngspice configuration file ${NGSPICE_CONFIG_H} found." )
|
||||
set( NGSPICE_HAVE_CONFIG_H "1" CACHE STRING "ngspice/config.h header found." )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if( WIN32 AND MSYS )
|
||||
# NGSPICE_LIBRARY points to libngspice.dll.a on Windows,
|
||||
# but the goal is to find out the DLL name.
|
||||
find_library( NGSPICE_DLL NAMES libngspice-0.dll libngspice-1.dll )
|
||||
|
||||
# Some msys versions do not find xxx.dll lib files, only xxx.dll.a files
|
||||
# so try a find_file in exec paths
|
||||
if( NGSPICE_DLL STREQUAL "NGSPICE_DLL-NOTFOUND" )
|
||||
find_file( NGSPICE_DLL NAMES libngspice-0.dll libngspice-1.dll
|
||||
PATHS
|
||||
${NGSPICE_ROOT_DIR}
|
||||
PATH_SUFFIXES
|
||||
bin
|
||||
lib
|
||||
)
|
||||
endif()
|
||||
|
||||
if( NGSPICE_DLL STREQUAL "NGSPICE_DLL-NOTFOUND" )
|
||||
message( ERROR ":\n***** libngspice-x.dll not found in any executable path *****\n\n" )
|
||||
else()
|
||||
message( STATUS ": libngspice shared lib found: ${NGSPICE_DLL}\n" )
|
||||
endif()
|
||||
else()
|
||||
set( NGSPICE_DLL "${NGSPICE_LIBRARY}" )
|
||||
endif()
|
||||
@@ -62,4 +146,6 @@ mark_as_advanced(
|
||||
NGSPICE_INCLUDE_DIR
|
||||
NGSPICE_LIBRARY
|
||||
NGSPICE_DLL
|
||||
NGSPICE_BUILD_VERSION
|
||||
NGSPIC_HAVE_CONFIG_H
|
||||
)
|
||||
|
||||
@@ -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.6" )
|
||||
set( KICAD_VERSION "5.1.7" )
|
||||
|
||||
@@ -75,4 +75,10 @@
|
||||
/// Allows scripts install directory to be referenced by the program code.
|
||||
#define PYTHON_DEST "@PYTHON_DEST@"
|
||||
|
||||
/// ngspice version string detected by pkg-config when available.
|
||||
#cmakedefine NGSPICE_BUILD_VERSION "@NGSPICE_BUILD_VERSION@"
|
||||
|
||||
/// When pkg-config config is not available for ngspice, use ngspice/config.h for version.
|
||||
#cmakedefine NGSPICE_HAVE_CONFIG_H
|
||||
|
||||
#endif // CONFIG_H_
|
||||
|
||||
@@ -170,6 +170,7 @@ add_custom_target(
|
||||
-DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}
|
||||
-P ${CMAKE_MODULE_PATH}/WriteVersionHeader.cmake
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/kicad_build_version.h
|
||||
COMMENT "Generating version string header"
|
||||
)
|
||||
|
||||
|
||||
@@ -469,6 +469,11 @@ wxString KIwxExpandEnvVars(const wxString& str)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
if( strResult.StartsWith( "~" ) )
|
||||
strResult.Replace( "~", wxGetHomeDir(), false );
|
||||
#endif // __WINDOWS__
|
||||
|
||||
return strResult;
|
||||
}
|
||||
|
||||
|
||||
@@ -221,14 +221,17 @@ bool DIALOG_CONFIGURE_PATHS::TransferDataFromWindow()
|
||||
|
||||
for( int row = 0; row < m_EnvVars->GetNumberRows(); ++row )
|
||||
{
|
||||
wxString name = m_EnvVars->GetCellValue( row, EV_NAME_COL );
|
||||
wxString path = m_EnvVars->GetCellValue( row, EV_PATH_COL );
|
||||
wxString external = m_EnvVars->GetCellValue( row, EV_FLAG_COL );
|
||||
wxString name = m_EnvVars->GetCellValue( row, EV_NAME_COL );
|
||||
wxString path = m_EnvVars->GetCellValue( row, EV_PATH_COL );
|
||||
wxString external = m_EnvVars->GetCellValue( row, EV_FLAG_COL );
|
||||
ENV_VAR_ITEM var( path );
|
||||
|
||||
if( external.Length() )
|
||||
continue;
|
||||
|
||||
if( name.IsEmpty() )
|
||||
{
|
||||
// Don't check for consistency on external variables, just use them as-is
|
||||
var.SetDefinedExternally( true );
|
||||
}
|
||||
else if( name.IsEmpty() )
|
||||
{
|
||||
m_errorGrid = m_EnvVars;
|
||||
m_errorRow = row;
|
||||
@@ -245,7 +248,7 @@ bool DIALOG_CONFIGURE_PATHS::TransferDataFromWindow()
|
||||
return false;
|
||||
}
|
||||
|
||||
envVarMap[ name ] = ENV_VAR_ITEM( path );
|
||||
envVarMap[ name ] = var;
|
||||
}
|
||||
|
||||
Pgm().SetLocalEnvVariables( envVarMap );
|
||||
|
||||
@@ -174,6 +174,7 @@ bool PANEL_COMMON_SETTINGS::TransferDataFromWindow()
|
||||
void PANEL_COMMON_SETTINGS::OnScaleSlider( wxScrollEvent& aEvent )
|
||||
{
|
||||
m_iconScaleAuto->SetValue( false );
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <gal/color4d.h>
|
||||
#include <wx/clipbrd.h>
|
||||
#include <kicad_string.h>
|
||||
|
||||
WX_HTML_REPORT_PANEL::WX_HTML_REPORT_PANEL( wxWindow* parent,
|
||||
wxWindowID id,
|
||||
@@ -402,7 +403,10 @@ void WX_HTML_REPORT_PANEL::onBtnSaveToFile( wxCommandEvent& event )
|
||||
|
||||
for( const REPORT_LINE& l : m_report )
|
||||
{
|
||||
f.Write( generatePlainText( l ) );
|
||||
wxString s = generatePlainText( l );
|
||||
|
||||
ConvertSmartQuotesAndDashes( &s );
|
||||
f.Write( s );
|
||||
}
|
||||
|
||||
f.Close();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013-2017 CERN
|
||||
* Copyright (C) 2013-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2013-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
@@ -148,6 +148,16 @@ void EDA_DRAW_PANEL_GAL::SetFocus()
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
|
||||
{
|
||||
DoRePaint();
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::DoRePaint()
|
||||
{
|
||||
// Repaint the canvas, and fix scrollbar cursors
|
||||
// Usually called by a OnPaint event, but because it does not use a wxPaintDC,
|
||||
// it can be called outside a wxPaintEvent.
|
||||
|
||||
// Update current zoom settings if the canvas is managed by a EDA frame
|
||||
// (i.e. not by a preview panel in a dialog)
|
||||
if( GetParentEDAFrame() && GetParentEDAFrame()->GetScreen() )
|
||||
@@ -231,7 +241,7 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
totalRealTime.Stop();
|
||||
wxLogTrace( "GAL_PROFILE", "EDA_DRAW_PANEL_GAL::onPaint(): %.1f ms", totalRealTime.msecs() );
|
||||
wxLogTrace( "GAL_PROFILE", "EDA_DRAW_PANEL_GAL::DoRePaint(): %.1f ms", totalRealTime.msecs() );
|
||||
#endif /* PROFILE */
|
||||
|
||||
m_lastRefresh = wxGetLocalTimeMillis();
|
||||
@@ -284,8 +294,9 @@ void EDA_DRAW_PANEL_GAL::Refresh( bool aEraseBackground, const wxRect* aRect )
|
||||
|
||||
void EDA_DRAW_PANEL_GAL::ForceRefresh()
|
||||
{
|
||||
wxPaintEvent redrawEvent;
|
||||
wxPostEvent( this, redrawEvent );
|
||||
//wxPaintEvent redrawEvent;
|
||||
//wxPostEvent( this, redrawEvent );
|
||||
DoRePaint();
|
||||
}
|
||||
|
||||
|
||||
@@ -495,8 +506,9 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
|
||||
}
|
||||
}
|
||||
|
||||
wxPaintEvent redrawEvent;
|
||||
wxPostEvent( this, redrawEvent );
|
||||
//wxPaintEvent redrawEvent;
|
||||
//wxPostEvent( this, redrawEvent );
|
||||
DoRePaint();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1297,6 +1297,16 @@ void CAIRO_GAL::endDrawing()
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::PostPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
// posts an event to m_paint_listener to ask for redraw the canvas.
|
||||
if( paintListener )
|
||||
{
|
||||
wxPostEvent( paintListener, aEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::ResizeScreen( int aWidth, int aHeight )
|
||||
{
|
||||
CAIRO_GAL_BASE::ResizeScreen( aWidth, aHeight );
|
||||
@@ -1502,9 +1512,9 @@ void CAIRO_GAL::setCompositor()
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
|
||||
void CAIRO_GAL::onPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
PostPaint();
|
||||
PostPaint( aEvent );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -135,14 +135,6 @@ CAIRO_PRINT_GAL::CAIRO_PRINT_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions,
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_PRINT_GAL::SetLineWidth( float aLineWidth )
|
||||
{
|
||||
storePath();
|
||||
lineWidth = aLineWidth;
|
||||
cairo_set_line_width( currentContext, aLineWidth );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_PRINT_GAL::ComputeWorldScreenMatrix()
|
||||
{
|
||||
worldScale = screenDPI * worldUnitLength * zoomFactor;
|
||||
|
||||
@@ -282,7 +282,6 @@ const float SHADER_FILLED_CIRCLE = 2.0;
|
||||
const float SHADER_STROKED_CIRCLE = 3.0;
|
||||
const float SHADER_FONT = 4.0;
|
||||
const float SHADER_LINE_A = 5.0;
|
||||
const float SHADER_LINE_B = 6.0;
|
||||
|
||||
varying vec4 shaderParams;
|
||||
varying vec2 circleCoords;
|
||||
@@ -302,12 +301,6 @@ void filledCircle( vec2 aCoord )
|
||||
|
||||
float pixelSegDistance( vec2 aCoord )
|
||||
{
|
||||
if( shaderParams[0] == SHADER_LINE_B )
|
||||
{
|
||||
gl_FragColor = gl_Color;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
float aspect = shaderParams[1];
|
||||
float dist;
|
||||
vec2 v = vec2( 1.0 - ( aspect - abs( aCoord.s ) ), aCoord.t );
|
||||
@@ -361,19 +354,23 @@ float median( vec3 v )
|
||||
|
||||
void main()
|
||||
{
|
||||
if( shaderParams[0] == SHADER_LINE_A )
|
||||
// VS to FS pipeline does math that means we can't rely on the mode
|
||||
// parameter being bit-exact without rounding it first.
|
||||
float mode = floor( shaderParams[0] + 0.5 );
|
||||
|
||||
if( mode == SHADER_LINE_A )
|
||||
{
|
||||
drawLine( gl_TexCoord[0].st );
|
||||
}
|
||||
else if( shaderParams[0] == SHADER_FILLED_CIRCLE )
|
||||
else if( mode == SHADER_FILLED_CIRCLE )
|
||||
{
|
||||
filledCircle( circleCoords );
|
||||
}
|
||||
else if( shaderParams[0] == SHADER_STROKED_CIRCLE )
|
||||
else if( mode == SHADER_STROKED_CIRCLE )
|
||||
{
|
||||
strokedCircle( circleCoords, shaderParams[2], shaderParams[3] );
|
||||
}
|
||||
else if( shaderParams[0] == SHADER_FONT )
|
||||
else if( mode == SHADER_FONT )
|
||||
{
|
||||
vec2 tex = shaderParams.yz;
|
||||
|
||||
|
||||
@@ -326,6 +326,16 @@ OPENGL_GAL::~OPENGL_GAL()
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::PostPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
// posts an event to m_paint_listener to ask for redraw the canvas.
|
||||
if( paintListener )
|
||||
{
|
||||
wxPostEvent( paintListener, aEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool OPENGL_GAL::updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions )
|
||||
{
|
||||
bool refresh = false;
|
||||
@@ -603,7 +613,12 @@ void OPENGL_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoin
|
||||
void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint,
|
||||
double aWidth )
|
||||
{
|
||||
if( aStartPoint == aEndPoint ) // 0 length segments are just a circle.
|
||||
VECTOR2D startEndVector = aEndPoint - aStartPoint;
|
||||
double lineLength = startEndVector.EuclideanNorm();
|
||||
|
||||
// segments having a length <= 1 are just a circle.
|
||||
// Moreover trying to draw them as a segment does not work fine.
|
||||
if( lineLength <= 1 )
|
||||
{
|
||||
DrawCircle( aStartPoint, aWidth/2 );
|
||||
return;
|
||||
@@ -618,10 +633,8 @@ void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP
|
||||
}
|
||||
else
|
||||
{
|
||||
auto startEndVector = aEndPoint - aStartPoint;
|
||||
auto lineAngle = startEndVector.Angle();
|
||||
// Outlined tracks
|
||||
double lineLength = startEndVector.EuclideanNorm();
|
||||
|
||||
SetLineWidth( 1.0 );
|
||||
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
@@ -1911,9 +1924,9 @@ std::pair<VECTOR2D, float> OPENGL_GAL::computeBitmapTextSize( const UTF8& aText
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
|
||||
void OPENGL_GAL::onPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
PostPaint();
|
||||
PostPaint( aEvent );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* 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
|
||||
@@ -54,6 +54,25 @@ int GetArcToSegmentCount( int aRadius, int aErrorMax, double aArcAngleDegree )
|
||||
}
|
||||
|
||||
|
||||
// When creating polygons to create a clearance polygonal area, the polygon must
|
||||
// be same or bigger than the original shape.
|
||||
// Polygons are bigger if the original shape has arcs (round rectangles, ovals, circles...)
|
||||
// In some cases (in fact only one: when building layer solder mask) modifying
|
||||
// shapes when converting them to polygons is not acceptable (the modification
|
||||
// can break calculations)
|
||||
// so one can disable the shape expansion by calling KeepPolyInsideShape( true )
|
||||
// Important: calling KeepPolyInsideShape( false ) after calculations is
|
||||
// mandatory to break oher calculations
|
||||
static bool s_disable_arc_correction = false;
|
||||
|
||||
// Enable (aInside = false) or disable (aInside = true) polygonal shape expansion
|
||||
// when converting pads shapes and other items shapes to polygons:
|
||||
void DisableArcRadiusCorrection( bool aDisable )
|
||||
{
|
||||
s_disable_arc_correction = aDisable;
|
||||
}
|
||||
|
||||
|
||||
double GetCircletoPolyCorrectionFactor( int aSegCountforCircle )
|
||||
{
|
||||
/* calculates the coeff to compensate radius reduction of circle
|
||||
@@ -66,7 +85,7 @@ double GetCircletoPolyCorrectionFactor( int aSegCountforCircle )
|
||||
if( aSegCountforCircle < MIN_SEGCOUNT_FOR_CIRCLE )
|
||||
aSegCountforCircle = MIN_SEGCOUNT_FOR_CIRCLE;
|
||||
|
||||
return 1.0 / cos( M_PI / aSegCountforCircle );
|
||||
return s_disable_arc_correction ? 1.0 : 1.0 / cos( M_PI / aSegCountforCircle );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -268,6 +268,7 @@ bool EDA_DRAW_FRAME::LockFile( const wxString& aFileName )
|
||||
|
||||
void EDA_DRAW_FRAME::unitsChangeRefresh()
|
||||
{
|
||||
ReCreateAuxiliaryToolbar();
|
||||
UpdateStatusBar();
|
||||
UpdateMsgPanel();
|
||||
}
|
||||
@@ -298,6 +299,8 @@ void EDA_DRAW_FRAME::CommonSettingsChanged()
|
||||
m_canvas->SetEnableAutoPan( option );
|
||||
|
||||
m_galDisplayOptions.ReadCommonConfig( *settings, this );
|
||||
|
||||
ReCreateAuxiliaryToolbar();
|
||||
}
|
||||
|
||||
|
||||
@@ -428,6 +431,7 @@ void EDA_DRAW_FRAME::OnUpdateUnits( wxUpdateUIEvent& aEvent )
|
||||
|
||||
aEvent.Check( enable );
|
||||
DisplayUnitsMsg();
|
||||
ReCreateAuxiliaryToolbar();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -271,6 +271,7 @@ bool EDA_DRAW_FRAME::LockFile( const wxString& aFileName )
|
||||
|
||||
void EDA_DRAW_FRAME::unitsChangeRefresh()
|
||||
{
|
||||
ReCreateAuxiliaryToolbar();
|
||||
UpdateStatusBar();
|
||||
UpdateMsgPanel();
|
||||
}
|
||||
@@ -300,6 +301,8 @@ void EDA_DRAW_FRAME::CommonSettingsChanged()
|
||||
m_canvas->SetEnableAutoPan( option );
|
||||
|
||||
m_galDisplayOptions.ReadCommonConfig( *settings, this );
|
||||
|
||||
ReCreateAuxiliaryToolbar();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <lib_tree_model.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <eda_pattern_match.h>
|
||||
#include <lib_tree_item.h>
|
||||
#include <make_unique.h>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
|
||||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
|
||||
* Copyright (C) 2014-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2014-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
|
||||
@@ -155,6 +155,7 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( wxString const& aSearch )
|
||||
{
|
||||
wxWindowUpdateLocker updateLock( m_widget );
|
||||
|
||||
Freeze();
|
||||
// Even with the updateLock, wxWidgets sometimes ties its knickers in
|
||||
// a knot when trying to run a wxdataview_selection_changed_callback()
|
||||
// on a row that has been deleted.
|
||||
@@ -162,7 +163,11 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( wxString const& aSearch )
|
||||
m_widget->UnselectAll();
|
||||
|
||||
Cleared();
|
||||
#ifndef __WINDOWS__
|
||||
Thaw();
|
||||
|
||||
// This was fixed in wxWidgets 3.0.5 and 3.1.3.
|
||||
#if defined( __WXGTK__ ) && ( (wxVERSION_NUMBER < 030005 ) || \
|
||||
( ( wxVERSION_NUMBER >= 030100 ) && ( wxVERSION_NUMBER < 030103 ) ) )
|
||||
// The fastest method to update wxDataViewCtrl is to rebuild from
|
||||
// scratch by calling Cleared(). Linux requires to reassociate model to
|
||||
// display data, but Windows will create multiple associations.
|
||||
@@ -310,6 +315,9 @@ bool LIB_TREE_MODEL_ADAPTER::IsContainer( wxDataViewItem const& aItem ) const
|
||||
|
||||
wxDataViewItem LIB_TREE_MODEL_ADAPTER::GetParent( wxDataViewItem const& aItem ) const
|
||||
{
|
||||
if( m_freeze )
|
||||
return ToItem( nullptr );
|
||||
|
||||
auto node = ToNode( aItem );
|
||||
auto parent = node ? node->Parent : nullptr;
|
||||
|
||||
@@ -451,7 +459,7 @@ LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowResults()
|
||||
[]( LIB_TREE_NODE const* n )
|
||||
{
|
||||
// return leaf nodes with some level of matching
|
||||
return n->Children.size() == 0 && n->Score > 1;
|
||||
return n->Type == LIB_TREE_NODE::TYPE::LIBID && n->Score > 1;
|
||||
},
|
||||
&highScore );
|
||||
|
||||
|
||||
@@ -170,9 +170,8 @@ bool GERBER_PLOTTER::StartPlot()
|
||||
|
||||
finalFile = outputFile; // the actual gerber file will be created later
|
||||
|
||||
// Create a temporary filename to store gerber file
|
||||
// note tmpfile() does not work under Vista and W7 in user mode
|
||||
m_workFilename = filename + wxT(".tmp");
|
||||
// Create a temp file in system temp to avoid potential network share buffer issues for the final read and save
|
||||
m_workFilename = wxFileName::CreateTempFileName( "" );
|
||||
workFile = wxFopen( m_workFilename, wxT( "wt" ));
|
||||
outputFile = workFile;
|
||||
wxASSERT( outputFile );
|
||||
@@ -988,6 +987,9 @@ void GERBER_PLOTTER::plotRoundRectAsRegion( const wxPoint& aRectCenter, const wx
|
||||
rr_outline.push_back( curr_edge );
|
||||
|
||||
// Move relative coordinates to the actual location and rotation:
|
||||
wxPoint arc_last_center;
|
||||
int arc_last_angle = curr_edge.m_arc_angle_start+arc_angle;
|
||||
|
||||
for( RR_EDGE& rr_edge: rr_outline )
|
||||
{
|
||||
RotatePoint( &rr_edge.m_start, aOrient );
|
||||
@@ -996,19 +998,38 @@ void GERBER_PLOTTER::plotRoundRectAsRegion( const wxPoint& aRectCenter, const wx
|
||||
rr_edge.m_start += aRectCenter;
|
||||
rr_edge.m_end += aRectCenter;
|
||||
rr_edge.m_center += aRectCenter;
|
||||
arc_last_center = rr_edge.m_center;
|
||||
}
|
||||
|
||||
fputs( "G36*\n", outputFile ); // Start region
|
||||
fputs( "G01*\n", outputFile ); // Set linear interpolation.
|
||||
MoveTo( rr_outline[0].m_start ); // Start point of region
|
||||
// Ensure the region is a closed polygon, i.e. the end point of last segment
|
||||
// (end of arc) is the same as the first point. Rounding issues can create a
|
||||
// small difference, mainly for rotated pads.
|
||||
// calculate last point (end of last arc):
|
||||
wxPoint last_pt;
|
||||
last_pt.x = arc_last_center.x + KiROUND( cosdecideg( aCornerRadius, arc_last_angle ) );
|
||||
last_pt.y = arc_last_center.y - KiROUND( sindecideg( aCornerRadius, arc_last_angle ) );
|
||||
|
||||
wxPoint first_pt = rr_outline[0].m_start;
|
||||
|
||||
#if 0 // For test only:
|
||||
if( last_pt != first_pt )
|
||||
wxLogMessage( "first pt %d %d last pt %d %d",
|
||||
first_pt.x, first_pt.y, last_pt.x, last_pt.y );
|
||||
#endif
|
||||
|
||||
fputs( "G36*\n", outputFile ); // Start region
|
||||
fputs( "G01*\n", outputFile ); // Set linear interpolation.
|
||||
first_pt = last_pt;
|
||||
MoveTo( first_pt ); // Start point of region, must be same as end point
|
||||
|
||||
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 );
|
||||
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 );
|
||||
|
||||
@@ -495,7 +495,7 @@ int PDF_PLOTTER::startPdfStream(int handle)
|
||||
"stream\n", handle + 1 );
|
||||
|
||||
// Open a temporary file to accumulate the stream
|
||||
workFilename = filename + wxT(".tmp");
|
||||
workFilename = wxFileName::CreateTempFileName( "" );
|
||||
workFile = wxFopen( workFilename, wxT( "w+b" ));
|
||||
wxASSERT( workFile );
|
||||
return handle;
|
||||
|
||||
@@ -796,10 +796,15 @@ void SVG_PLOTTER::Text( const wxPoint& aPos,
|
||||
}
|
||||
|
||||
fprintf( outputFile,
|
||||
"<text x=\"%g\" y=\"%g\"\n"
|
||||
"<text x=\"%g\" y=\"%g\"\n", text_pos_dev.x, text_pos_dev.y );
|
||||
|
||||
/// If the text is mirrored, we should also mirror the hidden text to match
|
||||
if( aSize.x < 0 )
|
||||
fprintf( outputFile, "transform=\"scale(-1 1) translate(%f 0)\"\n", -2 * text_pos_dev.x );
|
||||
|
||||
fprintf( outputFile,
|
||||
"textLength=\"%g\" font-size=\"%g\" lengthAdjust=\"spacingAndGlyphs\"\n"
|
||||
"text-anchor=\"%s\" opacity=\"0\">%s</text>\n",
|
||||
text_pos_dev.x, text_pos_dev.y,
|
||||
sz_dev.x, sz_dev.y,
|
||||
hjust, TO_UTF8( XmlEsc( aText ) ) );
|
||||
|
||||
|
||||
@@ -478,9 +478,16 @@ void PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, int width,
|
||||
{
|
||||
if( tracemode == FILLED )
|
||||
{
|
||||
SetCurrentLineWidth( width );
|
||||
MoveTo( start );
|
||||
FinishTo( end );
|
||||
if( start == end )
|
||||
{
|
||||
Circle( start, width, FILLED_SHAPE, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCurrentLineWidth( width );
|
||||
MoveTo( start );
|
||||
FinishTo( end );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
using namespace KIGFX::PREVIEW;
|
||||
|
||||
const double POLYGON_ITEM::POLY_LINE_WIDTH = 150000.0;
|
||||
const double POLYGON_ITEM::POLY_LINE_WIDTH = 1;
|
||||
|
||||
POLYGON_ITEM::POLYGON_ITEM():
|
||||
SIMPLE_OVERLAY_ITEM()
|
||||
@@ -61,7 +61,7 @@ void POLYGON_ITEM::drawPreviewShape( KIGFX::VIEW* aView ) const
|
||||
auto& gal = *aView->GetGAL();
|
||||
auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
|
||||
|
||||
gal.SetLineWidth( POLY_LINE_WIDTH );
|
||||
gal.SetLineWidth( (float) aView->ToWorld( POLY_LINE_WIDTH ) );
|
||||
gal.DrawPolyline( m_lockedChain );
|
||||
|
||||
// draw the leader line in a different color
|
||||
|
||||
@@ -40,6 +40,40 @@
|
||||
static const char illegalFileNameChars[] = "\\/:\"<>|";
|
||||
|
||||
|
||||
bool ConvertSmartQuotesAndDashes( wxString* aString )
|
||||
{
|
||||
bool retVal = false;
|
||||
|
||||
for( wxString::iterator ii = aString->begin(); ii != aString->end(); ++ii )
|
||||
{
|
||||
if( *ii == L'\u0060' || *ii == L'\u00B4' || *ii == L'\u2018' || *ii == L'\u2019' )
|
||||
{
|
||||
*ii = '\'';
|
||||
retVal = true;
|
||||
}
|
||||
if( *ii == L'\u201C' || *ii == L'\u201D' )
|
||||
{
|
||||
*ii = '"';
|
||||
retVal = true;
|
||||
}
|
||||
if( *ii == L'\u2013' || *ii == L'\u2014' )
|
||||
{
|
||||
*ii = '-';
|
||||
retVal = true;
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* These Escape/Unescape routines use HTML-entity-reference-style encoding to handle
|
||||
* characters which are:
|
||||
* (a) not legal in filenames
|
||||
* (b) used as control characters in LIB_IDs
|
||||
* (c) used to delineate hierarchical paths
|
||||
*/
|
||||
wxString EscapeString( const wxString& aSource )
|
||||
{
|
||||
#if 1
|
||||
|
||||
@@ -79,6 +79,10 @@ void GRID_CELL_COMBOBOX::BeginEdit( int aRow, int aCol, wxGrid* aGrid )
|
||||
// Don't immediately end if we get a kill focus event within BeginEdit
|
||||
evtHandler->SetInSetFocus( true );
|
||||
|
||||
// These event handlers are needed to properly dismiss the editor when the popup is closed
|
||||
m_control->Bind(wxEVT_COMBOBOX_DROPDOWN, &GRID_CELL_COMBOBOX::onComboDropDown, this);
|
||||
m_control->Bind(wxEVT_COMBOBOX_CLOSEUP, &GRID_CELL_COMBOBOX::onComboCloseUp, this);
|
||||
|
||||
m_value = aGrid->GetTable()->GetValue( aRow, aCol );
|
||||
|
||||
Combo()->SetFocus();
|
||||
@@ -126,3 +130,24 @@ void GRID_CELL_COMBOBOX::Reset()
|
||||
}
|
||||
|
||||
|
||||
void GRID_CELL_COMBOBOX::onComboDropDown( wxCommandEvent& aEvent )
|
||||
{
|
||||
auto evtHandler = static_cast<wxGridCellEditorEvtHandler*>( m_control->GetEventHandler() );
|
||||
|
||||
// Once the combobox is dropped, reset the flag to allow the focus-loss handler
|
||||
// to function and close the editor.
|
||||
evtHandler->SetInSetFocus( false );
|
||||
}
|
||||
|
||||
|
||||
void GRID_CELL_COMBOBOX::onComboCloseUp( wxCommandEvent& aEvent )
|
||||
{
|
||||
auto evtHandler = static_cast<wxGridCellEditorEvtHandler*>( m_control->GetEventHandler() );
|
||||
|
||||
// Forward the combobox close up event to the cell event handler as a focus kill event
|
||||
// so that the grid editor is dismissed when the combox closes, otherwise it leaves the
|
||||
// dropdown arrow visible in the cell.
|
||||
wxFocusEvent event( wxEVT_KILL_FOCUS, m_control->GetId() );
|
||||
event.SetEventObject( m_control );
|
||||
evtHandler->ProcessEvent( event );
|
||||
}
|
||||
|
||||
@@ -124,8 +124,10 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, LIB_TABLE* aLibTable, LIB_TREE_MODEL_ADAP
|
||||
{
|
||||
m_query_ctrl->SetHint( _( "Filter" ) );
|
||||
m_query_ctrl->SetFocus();
|
||||
m_query_ctrl->SetValue( wxEmptyString ); // SetValue() is required here to kick off
|
||||
// initial sorting and pre-selection.
|
||||
m_query_ctrl->SetValue( wxEmptyString );
|
||||
|
||||
// Force an update of the adapter with the empty text to ensure preselect is done
|
||||
Regenerate( false );
|
||||
}
|
||||
|
||||
// There may be a part preselected in the model. Make sure it is displayed.
|
||||
|
||||
+39
-23
@@ -696,9 +696,20 @@ void mpFXY::Plot( wxDC& dc, mpWindow& w )
|
||||
}
|
||||
else
|
||||
{
|
||||
wxCoord x0, y0;
|
||||
bool first = true;
|
||||
int count = 0;
|
||||
int x0=0; // X position of merged current vertical line
|
||||
int ymin0=0; // y min coord of merged current vertical line
|
||||
int ymax0=0; // y max coord of merged current vertical line
|
||||
int dupx0 = 0; // count of currently merged vertical lines
|
||||
wxPoint line_start; // starting point of the current line to draw
|
||||
|
||||
// Note: we do not use dc.DrawLines(), because at least on Windows
|
||||
// dc.DrawLine() is faster, and dc.DrawLines() can hang for a lot
|
||||
// (> 10000 points) (can happens when a lot of points is calculated)
|
||||
// To avoid long draw time (and perhaps hanging) one plot only not redundant lines.
|
||||
// To avoid artifacts when skipping points to the same x coordinate, for each
|
||||
// group of points at a give, x coordinate we also draw a vertical line at this coord,
|
||||
// from the ymin to the ymax vertical coordinates of skipped points
|
||||
while( GetNextXY( x, y ) )
|
||||
{
|
||||
double px = m_scaleX->TransformToPlot( x );
|
||||
@@ -707,29 +718,34 @@ void mpFXY::Plot( wxDC& dc, mpWindow& w )
|
||||
wxCoord x1 = w.x2p( px );
|
||||
wxCoord y1 = w.y2p( py );
|
||||
|
||||
if( first )
|
||||
// Plot only points on the drawing area, to speed up the drawing time
|
||||
if( x1 >= startPx && x1 <= endPx )
|
||||
{
|
||||
first = false;
|
||||
x0 = x1;
|
||||
y0 = y1;
|
||||
continue;
|
||||
if( !count || line_start.x != x1 )
|
||||
{
|
||||
if( dupx0 > 1 ) // Vertical points are merged,
|
||||
// draw the pending vertical line
|
||||
dc.DrawLine( x0, ymin0, x0, ymax0 );
|
||||
|
||||
x0 = x1;
|
||||
ymin0 = ymax0 = y1;
|
||||
dupx0 = 0;
|
||||
|
||||
if( count )
|
||||
dc.DrawLine( line_start, wxPoint( x1, y1 ) );
|
||||
|
||||
line_start.x = x1;
|
||||
line_start.y = y1;
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// "Merge" points on a vertical line at x0:
|
||||
ymin0 = std::min( ymin0, y1 );
|
||||
ymax0 = std::max( ymax0, y1 );
|
||||
dupx0++;
|
||||
}
|
||||
}
|
||||
|
||||
// This gives disastrous results with very high-frequency plots where the
|
||||
// X coordinate may not increment until several waves later
|
||||
//
|
||||
// if( x0 == x1 ) // continue until a new X coordinate is reached
|
||||
// continue;
|
||||
|
||||
bool outDown = ( y0 > maxYpx ) && ( y1 > maxYpx );
|
||||
bool outUp = ( y0 < minYpx ) && ( y1 < minYpx );
|
||||
bool outLeft = ( x1 < startPx ) && ( x0 < startPx );
|
||||
bool outRight = ( x1 > endPx ) && ( x0 > endPx );
|
||||
if( !( outUp || outDown || outLeft || outRight ) )
|
||||
dc.DrawLine( x0, y0, x1, y1 );
|
||||
|
||||
x0 = x1;
|
||||
y0 = y1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,77 +60,6 @@ else()
|
||||
endif()
|
||||
|
||||
|
||||
if( false )
|
||||
# setup bundle
|
||||
set( CVPCB_RESOURCES cvpcb.icns cvpcb_doc.icns )
|
||||
set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/cvpcb.icns" PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Resources
|
||||
)
|
||||
set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/cvpcb_doc.icns" PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Resources
|
||||
)
|
||||
set( MACOSX_BUNDLE_ICON_FILE cvpcb.icns )
|
||||
set( MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-pcb.kicad )
|
||||
set( MACOSX_BUNDLE_NAME cvpcb )
|
||||
endif()
|
||||
|
||||
|
||||
if( false ) # no CVPCB exe any more, only the *.kiface
|
||||
add_executable( cvpcb WIN32 MACOSX_BUNDLE
|
||||
../common/single_top.cpp
|
||||
../common/pgm_base.cpp
|
||||
${CVPCB_RESOURCES}
|
||||
)
|
||||
set_source_files_properties( ../common/single_top.cpp PROPERTIES
|
||||
COMPILE_DEFINITIONS "TOP_FRAME=FRAME_CVPCB;PGM_DATA_FILE_EXT=\"net\";BUILD_KIWAY_DLL"
|
||||
)
|
||||
target_link_libraries( cvpcb
|
||||
#singletop # replaces common, giving us restrictive control and link warnings.
|
||||
# There's way too much crap coming in from common yet.
|
||||
common
|
||||
${wxWidgets_LIBRARIES}
|
||||
)
|
||||
if( MAKE_LINK_MAPS )
|
||||
set_target_properties( cvpcb PROPERTIES
|
||||
LINK_FLAGS "${TO_LINKER},-cref ${TO_LINKER},-Map=cvpcb.map" )
|
||||
endif()
|
||||
|
||||
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( cvpcb PROPERTIES
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
|
||||
)
|
||||
|
||||
# put individual bundle outside of main bundle as a first step
|
||||
# will be pulled into the main bundle when creating main bundle
|
||||
install( TARGETS cvpcb
|
||||
DESTINATION ${KICAD_BIN}
|
||||
COMPONENT binary
|
||||
)
|
||||
install( CODE "
|
||||
# override default embedded path settings
|
||||
${OSX_BUNDLE_OVERRIDE_PATHS}
|
||||
|
||||
# do all the work
|
||||
include( BundleUtilities )
|
||||
fixup_bundle( ${KICAD_BIN}/cvpcb.app/Contents/MacOS/cvpcb
|
||||
\"\"
|
||||
\"\"
|
||||
)
|
||||
" COMPONENT Runtime
|
||||
)
|
||||
else()
|
||||
install( TARGETS cvpcb
|
||||
DESTINATION ${KICAD_BIN}
|
||||
COMPONENT binary
|
||||
)
|
||||
endif()
|
||||
|
||||
endif() # no CVPCB exe
|
||||
|
||||
|
||||
# the main cvpcb program, in DSO form.
|
||||
add_library( cvpcb_kiface MODULE
|
||||
cvpcb.cpp
|
||||
|
||||
@@ -83,7 +83,10 @@ public:
|
||||
{
|
||||
href.Printf( wxT( "href='%d'" ), ii );
|
||||
marker_text = m_MarkerListReferences[ii]->GetReporter().ShowHtml( aUnits );
|
||||
marker_text.Replace( wxT( "href=''"), href );
|
||||
marker_text.Replace( wxT( "href=''"), href, false );
|
||||
|
||||
href.Printf( wxT( "href='%d'" ), -ii );
|
||||
marker_text.Replace( wxT( "href=''"), href, false );
|
||||
htmlpage += marker_text;
|
||||
}
|
||||
|
||||
|
||||
@@ -393,6 +393,25 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnGridCellChanging( wxGridEvent& event )
|
||||
m_delayedFocusColumn = event.GetCol();
|
||||
m_delayedFocusPage = 0;
|
||||
}
|
||||
else if( event.GetCol() == FDC_NAME )
|
||||
{
|
||||
wxString newName = event.GetString();
|
||||
|
||||
for( int i = 0; i < m_grid->GetNumberRows(); ++i )
|
||||
{
|
||||
if( i == event.GetRow() )
|
||||
continue;
|
||||
|
||||
if( newName.CmpNoCase( m_grid->GetCellValue( i, FDC_NAME ) ) == 0 )
|
||||
{
|
||||
DisplayError( this, wxString::Format( _( "The name '%s' is already in use." ),
|
||||
newName ) );
|
||||
event.Veto();
|
||||
m_delayedFocusRow = event.GetRow();
|
||||
m_delayedFocusColumn = event.GetCol();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( event.GetRow() == VALUE && event.GetCol() == FDC_VALUE )
|
||||
m_SymbolNameCtrl->ChangeValue( event.GetString() );
|
||||
|
||||
|
||||
@@ -526,6 +526,25 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnGridCellChanging( wxGridEvent& event
|
||||
m_delayedFocusRow = event.GetRow();
|
||||
m_delayedFocusColumn = event.GetCol();
|
||||
}
|
||||
else if( event.GetCol() == FDC_NAME )
|
||||
{
|
||||
wxString newName = event.GetString();
|
||||
|
||||
for( int i = 0; i < m_grid->GetNumberRows(); ++i )
|
||||
{
|
||||
if( i == event.GetRow() )
|
||||
continue;
|
||||
|
||||
if( newName.CmpNoCase( m_grid->GetCellValue( i, FDC_NAME ) ) == 0 )
|
||||
{
|
||||
DisplayError( this, wxString::Format( _( "The name '%s' is already in use." ),
|
||||
newName ) );
|
||||
event.Veto();
|
||||
m_delayedFocusRow = event.GetRow();
|
||||
m_delayedFocusColumn = event.GetCol();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor->DecRef();
|
||||
}
|
||||
|
||||
@@ -312,21 +312,24 @@ void DIALOG_SCH_EDIT_ONE_FIELD::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH*
|
||||
&& ( fieldType == VALUE || fieldType == FOOTPRINT || fieldType == DATASHEET ) )
|
||||
{
|
||||
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++ )
|
||||
if( thisRef.Last() != '?' ) // Obvioulsy, the component must be annotated
|
||||
{
|
||||
SCH_REFERENCE componentRef = components[i];
|
||||
int thisUnit = component->GetUnit();
|
||||
SCH_REFERENCE_LIST components;
|
||||
editFrame->GetCurrentSheet().GetComponents( components );
|
||||
|
||||
if( componentRef.GetRef() == thisRef && componentRef.GetUnit() != thisUnit )
|
||||
for( unsigned i = 0; i < components.GetCount(); i++ )
|
||||
{
|
||||
SCH_COMPONENT* otherUnit = componentRef.GetComp();
|
||||
editFrame->SaveCopyInUndoList( otherUnit, UR_CHANGED, true /* append */);
|
||||
otherUnit->GetField( fieldType )->SetText( m_text );
|
||||
editFrame->RefreshItem( otherUnit );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,10 +213,17 @@ void DIALOG_ERC::OnLeftClickMarkersList( wxHtmlLinkEvent& event )
|
||||
m_lastMarkerFound = NULL;
|
||||
|
||||
long index;
|
||||
bool secondItem = false;
|
||||
|
||||
if( !link.ToLong( &index ) )
|
||||
return;
|
||||
|
||||
if( index < 0 )
|
||||
{
|
||||
secondItem = true;
|
||||
index = -index;
|
||||
}
|
||||
|
||||
const SCH_MARKER* marker = m_MarkersList->GetItem( index );
|
||||
|
||||
if( marker == NULL )
|
||||
@@ -262,8 +269,18 @@ void DIALOG_ERC::OnLeftClickMarkersList( wxHtmlLinkEvent& event )
|
||||
}
|
||||
|
||||
m_lastMarkerFound = marker;
|
||||
m_parent->FocusOnLocation( marker->m_Pos, false, true );
|
||||
m_parent->SetCrossHairPosition( marker->m_Pos );
|
||||
|
||||
if( secondItem )
|
||||
{
|
||||
m_parent->FocusOnLocation( marker->GetReporter().GetPointB() );
|
||||
m_parent->SetCrossHairPosition( marker->GetReporter().GetPointB() );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_parent->FocusOnLocation( marker->m_Pos, false, true );
|
||||
m_parent->SetCrossHairPosition( marker->m_Pos );
|
||||
}
|
||||
|
||||
RedrawDrawPanel();
|
||||
}
|
||||
|
||||
|
||||
@@ -820,13 +820,14 @@ bool DIALOG_FIELDS_EDITOR_GLOBAL::TransferDataFromWindow()
|
||||
SCH_SHEET_PATH currentSheet = m_parent->GetCurrentSheet();
|
||||
|
||||
m_dataModel->ApplyData();
|
||||
m_parent->SyncView();
|
||||
m_parent->OnModify();
|
||||
|
||||
// Reset the view to where we left the user
|
||||
m_parent->SetCurrentSheet( currentSheet );
|
||||
m_parent->SyncView();
|
||||
m_parent->Refresh();
|
||||
|
||||
m_parent->OnModify();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,13 +86,15 @@ bool DIALOG_LIB_EDIT_PIN::TransferDataToWindow()
|
||||
if( !DIALOG_SHIM::TransferDataToWindow() )
|
||||
return false;
|
||||
|
||||
m_origPos = m_pin->GetPosition();
|
||||
|
||||
m_choiceOrientation->SetSelection( LIB_PIN::GetOrientationIndex( m_pin->GetOrientation() ) );
|
||||
m_choiceStyle->SetSelection( m_pin->GetShape() );
|
||||
m_choiceElectricalType->SetSelection( m_pin->GetType() );
|
||||
m_textPinName->SetValue( m_pin->GetName() );
|
||||
m_nameSize.SetValue( m_pin->GetNameTextSize() );
|
||||
m_posX.SetValue( m_pin->GetPosition().x );
|
||||
m_posY.SetValue( -m_pin->GetPosition().y );
|
||||
m_posX.SetValue( m_origPos.x );
|
||||
m_posY.SetValue( -m_origPos.y );
|
||||
m_textPinNumber->SetValue( m_pin->GetNumber() );
|
||||
m_numberSize.SetValue( m_pin->GetNumberTextSize() );
|
||||
m_pinLength.SetValue( m_pin->GetLength() );
|
||||
@@ -111,9 +113,13 @@ bool DIALOG_LIB_EDIT_PIN::TransferDataFromWindow()
|
||||
if( !DIALOG_SHIM::TransferDataFromWindow() )
|
||||
return false;
|
||||
|
||||
wxPoint newPos( m_posX.GetValue(), -m_posY.GetValue() );
|
||||
|
||||
const int acceptable_mingrid = 50;
|
||||
|
||||
if( ( m_posX.GetValue() % acceptable_mingrid ) || ( m_posY.GetValue() % acceptable_mingrid ) )
|
||||
// Only show the warning if the position has been changed
|
||||
if( ( m_origPos != newPos )
|
||||
&& ( ( m_posX.GetValue() % acceptable_mingrid ) || ( m_posY.GetValue() % acceptable_mingrid ) ) )
|
||||
{
|
||||
auto msg = wxString::Format( _( "This pin is not on a %d mils grid which will make it\n"
|
||||
"difficult to connect to in the schematic.\n"
|
||||
@@ -132,7 +138,7 @@ bool DIALOG_LIB_EDIT_PIN::TransferDataFromWindow()
|
||||
m_pin->SetNumberTextSize( m_numberSize.GetValue() );
|
||||
m_pin->SetOrientation( LIB_PIN::GetOrientationCode( m_choiceOrientation->GetSelection() ) );
|
||||
m_pin->SetLength( m_pinLength.GetValue() );
|
||||
m_pin->SetPinPosition( wxPoint( m_posX.GetValue(), -m_posY.GetValue() ) );
|
||||
m_pin->SetPinPosition( newPos );
|
||||
m_pin->SetType( m_choiceElectricalType->GetPinTypeSelection() );
|
||||
m_pin->SetShape( m_choiceStyle->GetPinShapeSelection() );
|
||||
m_pin->SetConversion( m_checkApplyToAllConversions->GetValue() ? 0 : m_frame->GetConvert() );
|
||||
|
||||
@@ -47,6 +47,8 @@ class DIALOG_LIB_EDIT_PIN : public DIALOG_LIB_EDIT_PIN_BASE
|
||||
UNIT_BINDER m_nameSize;
|
||||
UNIT_BINDER m_numberSize;
|
||||
|
||||
wxPoint m_origPos;
|
||||
|
||||
public:
|
||||
/** Constructor */
|
||||
DIALOG_LIB_EDIT_PIN( LIB_EDIT_FRAME* parent, LIB_PIN* aPin );
|
||||
|
||||
@@ -507,7 +507,8 @@ void PANEL_SYM_LIB_TABLE::deleteRowHandler( wxCommandEvent& event )
|
||||
}
|
||||
}
|
||||
|
||||
m_cur_grid->SetGridCursor( std::min( curRow, m_cur_grid->GetNumberRows() - 1 ), curCol );
|
||||
if( m_cur_grid->GetNumberRows() > 0 && curRow >= 0 )
|
||||
m_cur_grid->SetGridCursor( std::min( curRow, m_cur_grid->GetNumberRows() - 1 ), curCol );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -104,17 +104,21 @@ wxString DRC_ITEM::ShowHtml( EDA_UNITS_T aUnits ) const
|
||||
|
||||
// an html fragment for the entire message in the listbox. feel free
|
||||
// to add color if you want:
|
||||
return wxString::Format( "<p><b>%s</b><br> <font color='%s'><a href=''>%s</a></font>: %s<br> %s: %s",
|
||||
return wxString::Format( "<p><b>%s</b><br>"
|
||||
" <font color='%s'><a href=''>%s</a></font>: %s<br>"
|
||||
" <font color='%s'><a href=''>%s</a></font>: %s",
|
||||
errText,
|
||||
hrefColour.GetAsString( wxC2S_HTML_SYNTAX ),
|
||||
ShowCoord( aUnits, m_MainPosition ),
|
||||
mainText,
|
||||
hrefColour.GetAsString( wxC2S_HTML_SYNTAX ),
|
||||
ShowCoord( aUnits, m_AuxiliaryPosition ),
|
||||
auxText );
|
||||
}
|
||||
else
|
||||
{
|
||||
return wxString::Format( "<p><b>%s</b><br> <font color='%s'><a href=''>%s</a></font>: %s",
|
||||
return wxString::Format( "<p><b>%s</b><br>"
|
||||
" <font color='%s'><a href=''>%s</a></font>: %s",
|
||||
errText,
|
||||
hrefColour.GetAsString( wxC2S_HTML_SYNTAX ),
|
||||
ShowCoord( aUnits, m_MainPosition ),
|
||||
|
||||
@@ -442,8 +442,8 @@ void FIELDS_GRID_TABLE<T>::SetValue( int aRow, int aCol, const wxString &aValue
|
||||
break;
|
||||
|
||||
case FDC_TEXT_SIZE:
|
||||
field.SetTextSize( wxSize( ValueFromString( m_userUnits, aValue ),
|
||||
ValueFromString( m_userUnits, aValue ) ) );
|
||||
field.SetTextSize( wxSize( ValueFromString( m_userUnits, aValue, true ),
|
||||
ValueFromString( m_userUnits, aValue, true ) ) );
|
||||
break;
|
||||
|
||||
case FDC_ORIENTATION:
|
||||
|
||||
@@ -284,14 +284,14 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
}
|
||||
else
|
||||
{
|
||||
// This will rename the file if there is an autosave and the user want to recover
|
||||
CheckForAutoSaveFile( fullFileName );
|
||||
|
||||
SetScreen( nullptr );
|
||||
delete g_RootSheet; // Delete the current project.
|
||||
g_RootSheet = NULL; // Force CreateScreens() to build new empty project on load failure.
|
||||
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
|
||||
|
||||
// This will rename the file if there is an autosave and the user want to recover
|
||||
CheckForAutoSaveFile( fullFileName );
|
||||
|
||||
try
|
||||
{
|
||||
g_RootSheet = pi->Load( fullFileName, &Kiway() );
|
||||
|
||||
@@ -201,6 +201,7 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||
SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_LIB_EDITOR, _( "Library Editor" ),
|
||||
wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, LIB_EDIT_FRAME_NAME )
|
||||
{
|
||||
m_partSelectBox = nullptr;
|
||||
m_showAxis = true; // true to draw axis
|
||||
SetShowDeMorgan( false );
|
||||
m_drawSpecificConvert = true;
|
||||
@@ -1652,23 +1653,18 @@ void LIB_EDIT_FRAME::SyncLibraries( bool aShowProgress )
|
||||
{
|
||||
wxDataViewItem found;
|
||||
|
||||
m_treePane->GetLibTree()->Unselect();
|
||||
m_treePane->Regenerate();
|
||||
|
||||
if( selected.IsValid() )
|
||||
{
|
||||
// Check if the previously selected item is still valid,
|
||||
// if not - it has to be unselected to prevent crash
|
||||
found = m_libMgr->GetAdapter()->FindItem( selected );
|
||||
|
||||
if( !found )
|
||||
m_treePane->GetLibTree()->Unselect();
|
||||
}
|
||||
|
||||
m_treePane->Regenerate();
|
||||
|
||||
// Try to select the parent library, in case the part is not found
|
||||
if( !found && selected.IsValid() )
|
||||
{
|
||||
selected.SetLibItemName( "" );
|
||||
found = m_libMgr->GetAdapter()->FindItem( selected );
|
||||
{
|
||||
selected.SetLibItemName( "" );
|
||||
found = m_libMgr->GetAdapter()->FindItem( selected );
|
||||
}
|
||||
|
||||
if( found )
|
||||
m_treePane->GetLibTree()->SelectLibId( selected );
|
||||
|
||||
@@ -177,12 +177,12 @@ void LIB_EDIT_FRAME::ReCreateHToolbar()
|
||||
|
||||
KiScaledSeparator( m_mainToolBar, this );
|
||||
|
||||
m_partSelectBox = new wxComboBox( m_mainToolBar,
|
||||
ID_LIBEDIT_SELECT_PART_NUMBER,
|
||||
wxEmptyString,
|
||||
wxDefaultPosition,
|
||||
wxSize( LISTBOX_WIDTH, -1 ),
|
||||
0, nullptr, wxCB_READONLY );
|
||||
if( m_partSelectBox == nullptr )
|
||||
m_partSelectBox = new wxComboBox( m_mainToolBar, ID_LIBEDIT_SELECT_PART_NUMBER,
|
||||
wxEmptyString,
|
||||
wxDefaultPosition, wxSize( LISTBOX_WIDTH, -1 ),
|
||||
0, nullptr, wxCB_READONLY );
|
||||
|
||||
m_mainToolBar->AddControl( m_partSelectBox );
|
||||
|
||||
KiScaledSeparator( m_mainToolBar, this );
|
||||
|
||||
@@ -21,6 +21,7 @@ import sys
|
||||
import xml.sax as sax
|
||||
import re
|
||||
import pdb
|
||||
import string
|
||||
|
||||
#-----<Configure>----------------------------------------------------------------
|
||||
|
||||
@@ -335,7 +336,8 @@ class comp():
|
||||
result = False
|
||||
if self.getValue() == other.getValue():
|
||||
if self.getFootprint() == other.getFootprint():
|
||||
result = True
|
||||
if self.getRef().rstrip(string.digits) == other.getRef().rstrip(string.digits):
|
||||
result = True
|
||||
return result
|
||||
|
||||
def setLibPart(self, part):
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<!-- list of all references -->
|
||||
<xsl:for-each select="key('partTypeByValueAndFootprint', concat(footprint, '-', value))">
|
||||
<!-- strip non-digits from reference and sort based on remaining number -->
|
||||
<xsl:sort select="translate(@ref, translate(@ref, digits, ''), '')" data-type="number" />
|
||||
<xsl:sort select="translate(@ref, translate(@ref, $digits, ''), '')" data-type="number" />
|
||||
<xsl:value-of select="@ref"/><xsl:text> </xsl:text>
|
||||
</xsl:for-each><xsl:text>,</xsl:text>
|
||||
<!-- quantity of parts with same footprint and value -->
|
||||
|
||||
@@ -577,7 +577,7 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
|
||||
SCH_SCREEN* screen = new SCH_SCREEN( m_kiway );
|
||||
|
||||
sheet->SetTimeStamp( GetNewTimeStamp() - i ); // minus the sheet index to make it unique.
|
||||
sheet->SetParent( m_rootSheet->GetScreen() );
|
||||
sheet->SetParent( m_rootSheet );
|
||||
sheet->SetScreen( screen );
|
||||
sheet->GetScreen()->SetFileName( sheet->GetFileName() );
|
||||
|
||||
|
||||
@@ -223,3 +223,22 @@ BITMAP_DEF SCH_JUNCTION::GetMenuImage() const
|
||||
{
|
||||
return add_junction_xpm;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_JUNCTION::operator <( const SCH_ITEM& aItem ) const
|
||||
{
|
||||
if( Type() != aItem.Type() )
|
||||
return Type() < aItem.Type();
|
||||
|
||||
if( GetLayer() != aItem.GetLayer() )
|
||||
return GetLayer() < aItem.GetLayer();
|
||||
|
||||
auto junction = static_cast<const SCH_JUNCTION*>( &aItem );
|
||||
|
||||
if( GetPosition().x != junction->GetPosition().x )
|
||||
return GetPosition().x < junction->GetPosition().x;
|
||||
|
||||
return GetPosition().y < junction->GetPosition().y;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -113,6 +113,8 @@ public:
|
||||
|
||||
EDA_ITEM* Clone() const override;
|
||||
|
||||
virtual bool operator <( const SCH_ITEM& aItem ) const override;
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const override;
|
||||
#endif
|
||||
|
||||
@@ -687,28 +687,6 @@ void SCH_LEGACY_PLUGIN::loadHierarchy( SCH_SHEET* aSheet )
|
||||
try
|
||||
{
|
||||
loadFile( fileName.GetFullPath(), aSheet->GetScreen() );
|
||||
|
||||
EDA_ITEM* item = aSheet->GetScreen()->GetDrawItems();
|
||||
|
||||
while( item )
|
||||
{
|
||||
if( item->Type() == SCH_SHEET_T )
|
||||
{
|
||||
SCH_SHEET* sheet = (SCH_SHEET*) item;
|
||||
|
||||
// Set the parent to aSheet. This effectively creates a method to find
|
||||
// the root sheet from any sheet so a pointer to the root sheet does not
|
||||
// need to be stored globally. Note: this is not the same as a hierarchy.
|
||||
// Complex hierarchies can have multiple copies of a sheet. This only
|
||||
// provides a simple tree to find the root sheet.
|
||||
sheet->SetParent( aSheet );
|
||||
|
||||
// Recursion starts here.
|
||||
loadHierarchy( sheet );
|
||||
}
|
||||
|
||||
item = item->Next();
|
||||
}
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
@@ -722,6 +700,28 @@ void SCH_LEGACY_PLUGIN::loadHierarchy( SCH_SHEET* aSheet )
|
||||
|
||||
m_error += ioe.What();
|
||||
}
|
||||
|
||||
EDA_ITEM* item = aSheet->GetScreen()->GetDrawItems();
|
||||
|
||||
while( item )
|
||||
{
|
||||
if( item->Type() == SCH_SHEET_T )
|
||||
{
|
||||
SCH_SHEET* sheet = (SCH_SHEET*) item;
|
||||
|
||||
// Set the parent to aSheet. This effectively creates a method to find
|
||||
// the root sheet from any sheet so a pointer to the root sheet does not
|
||||
// need to be stored globally. Note: this is not the same as a hierarchy.
|
||||
// Complex hierarchies can have multiple copies of a sheet. This only
|
||||
// provides a simple tree to find the root sheet.
|
||||
sheet->SetParent( aSheet );
|
||||
|
||||
// Recursion starts here.
|
||||
loadHierarchy( sheet );
|
||||
}
|
||||
|
||||
item = item->Next();
|
||||
}
|
||||
}
|
||||
|
||||
m_currentPath.pop();
|
||||
|
||||
@@ -57,6 +57,9 @@ SCH_PREVIEW_PANEL::SCH_PREVIEW_PANEL( wxWindow* aParentWindow, wxWindowID aWindo
|
||||
m_view->SetScaleLimits( 20000.0, 0.002 );
|
||||
m_view->SetMirror( false, false );
|
||||
|
||||
ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_NEVER );
|
||||
EnableScrolling( false, false );
|
||||
|
||||
setDefaultLayerOrder();
|
||||
setDefaultLayerDeps();
|
||||
|
||||
|
||||
+20
-2
@@ -101,6 +101,19 @@ EDA_ITEM* SCH_SHEET::Clone() const
|
||||
}
|
||||
|
||||
|
||||
void SCH_SHEET::SetParent( EDA_ITEM* aSheet )
|
||||
{
|
||||
m_Parent = nullptr;
|
||||
|
||||
if( aSheet )
|
||||
{
|
||||
// Parent must be another SCH_SHEET object or nullptr
|
||||
wxCHECK( aSheet->Type() == SCH_SHEET_T, /* void */ );
|
||||
m_Parent = aSheet;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_SHEET::SetScreen( SCH_SCREEN* aScreen )
|
||||
{
|
||||
if( aScreen == m_screen )
|
||||
@@ -135,11 +148,16 @@ int SCH_SHEET::GetScreenCount() const
|
||||
|
||||
SCH_SHEET* SCH_SHEET::GetRootSheet()
|
||||
{
|
||||
SCH_SHEET* sheet = dynamic_cast< SCH_SHEET* >( GetParent() );
|
||||
EDA_ITEM* item = GetParent();
|
||||
|
||||
if( sheet == NULL )
|
||||
if( item == nullptr )
|
||||
return this;
|
||||
|
||||
SCH_SHEET* sheet = dynamic_cast< SCH_SHEET* >( item );
|
||||
|
||||
// The parent must be a SCH_SHEET object.
|
||||
wxCHECK( sheet, nullptr );
|
||||
|
||||
// Recurse until a sheet is found with no parent which is the root sheet.
|
||||
return sheet->GetRootSheet();
|
||||
}
|
||||
|
||||
@@ -253,6 +253,8 @@ public:
|
||||
return wxT( "SCH_SHEET" );
|
||||
}
|
||||
|
||||
virtual void SetParent( EDA_ITEM* aSheet ) override;
|
||||
|
||||
/**
|
||||
* Return true for items which are moved with the anchor point at mouse cursor
|
||||
* and false for items moved with no reference to anchor.
|
||||
|
||||
@@ -1057,7 +1057,7 @@ void SCH_EDIT_FRAME::OnEditItem( wxCommandEvent& aEvent )
|
||||
|
||||
case SCH_SHEET_T:
|
||||
{
|
||||
bool doClearAnnotation;
|
||||
bool doClearAnnotation = false;
|
||||
bool doRefresh = false;
|
||||
// Keep trace of existing sheet paths. EditSheet() can modify this list
|
||||
SCH_SHEET_LIST initial_sheetpathList( g_RootSheet );
|
||||
|
||||
+3
-4
@@ -170,8 +170,7 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
|
||||
|
||||
// If the loaded schematic is in a different folder from the current project and
|
||||
// it contains hierarchical sheets, the hierarchical sheet paths need to be updated.
|
||||
if( fileName.GetPath( wxPATH_GET_SEPARATOR ) != Prj().GetProjectPath()
|
||||
&& newSheet->CountSheets() )
|
||||
if( fileName.GetPathWithSep() != Prj().GetProjectPath() && newSheet->CountSheets() )
|
||||
{
|
||||
// Give the user the option to choose relative path if possible.
|
||||
if( tmp.MakeRelativeTo( Prj().GetProjectPath() ) )
|
||||
@@ -227,7 +226,7 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
|
||||
wxMessageDialog::ButtonLabel okButtonLabel( _( "Continue Load" ) );
|
||||
wxMessageDialog::ButtonLabel cancelButtonLabel( _( "Cancel Load" ) );
|
||||
|
||||
if( fileName.GetPath( wxPATH_GET_SEPARATOR ) == Prj().GetProjectPath()
|
||||
if( fileName.GetPathWithSep() == Prj().GetProjectPath()
|
||||
&& !prjScreens.HasSchematic( fullFilename ) )
|
||||
{
|
||||
// A schematic in the current project path that isn't part of the current project.
|
||||
@@ -254,7 +253,7 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if( fileName.GetPath( wxPATH_GET_SEPARATOR ) != Prj().GetProjectPath() )
|
||||
else if( fileName.GetPathWithSep() != Prj().GetProjectPath() )
|
||||
{
|
||||
// A schematic loaded from a path other than the current project path.
|
||||
|
||||
|
||||
@@ -294,13 +294,14 @@ void NGSPICE::init_dll()
|
||||
#endif /* __WINDOWS__ */
|
||||
#ifdef __WXMAC__
|
||||
wxFileName dllFile( "", NGSPICE_DLL_FILE );
|
||||
const vector<string> dllPaths = {
|
||||
GetOSXKicadUserDataDir() + "/PlugIns/ngspice",
|
||||
GetOSXKicadMachineDataDir() + "/PlugIns/ngspice",
|
||||
const vector<string> dllPaths =
|
||||
{
|
||||
GetOSXKicadUserDataDir().ToStdString() + "/PlugIns/ngspice",
|
||||
GetOSXKicadMachineDataDir().ToStdString() + "/PlugIns/ngspice",
|
||||
// when running kicad.app
|
||||
stdPaths.GetPluginsDir() + "/sim",
|
||||
stdPaths.GetPluginsDir().ToStdString() + "/sim",
|
||||
// when running eeschema.app
|
||||
wxFileName( stdPaths.GetExecutablePath() ).GetPath() + "/../../../../../Contents/PlugIns/sim"
|
||||
wxFileName( stdPaths.GetExecutablePath() ).GetPath().ToStdString() + "/../../../../../Contents/PlugIns/sim"
|
||||
};
|
||||
#endif /* __WXMAC__ */
|
||||
|
||||
@@ -357,8 +358,8 @@ void NGSPICE::init_dll()
|
||||
{
|
||||
".",
|
||||
#ifdef __WXMAC__
|
||||
stdPaths.GetPluginsDir() + "/sim/ngspice/scripts",
|
||||
wxFileName( stdPaths.GetExecutablePath() ).GetPath() + "/../../../../../Contents/PlugIns/sim/ngspice/scripts"
|
||||
stdPaths.GetPluginsDir().ToStdString() + "/sim/ngspice/scripts",
|
||||
wxFileName( stdPaths.GetExecutablePath() ).GetPath().ToStdString() + "/../../../../../Contents/PlugIns/sim/ngspice/scripts"
|
||||
#endif /* __WXMAC__ */
|
||||
"../share/kicad",
|
||||
"../share",
|
||||
@@ -422,8 +423,8 @@ string NGSPICE::findCmPath() const
|
||||
#ifdef __WXMAC__
|
||||
"/Applications/ngspice/lib/ngspice",
|
||||
"Contents/Frameworks",
|
||||
wxStandardPaths::Get().GetPluginsDir() + "/sim/ngspice",
|
||||
wxFileName( wxStandardPaths::Get().GetExecutablePath() ).GetPath() + "/../../../../../Contents/PlugIns/sim/ngspice",
|
||||
wxStandardPaths::Get().GetPluginsDir().ToStdString() + "/sim/ngspice",
|
||||
wxFileName( wxStandardPaths::Get().GetExecutablePath() ).GetPath().ToStdString() + "/../../../../../Contents/PlugIns/sim/ngspice",
|
||||
"../Plugins/sim/ngspice",
|
||||
#endif /* __WXMAC__ */
|
||||
"../lib/ngspice",
|
||||
|
||||
@@ -528,7 +528,7 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
|
||||
|
||||
trace->SetData( std::vector<double>( aX, aX + aPoints ), tmp );
|
||||
|
||||
if( aFlags & SPT_AC_PHASE || aFlags & SPT_CURRENT )
|
||||
if( ( aFlags & SPT_AC_PHASE ) || ( aFlags & SPT_CURRENT ) )
|
||||
trace->SetScale( m_axis_x, m_axis_y2 );
|
||||
else
|
||||
trace->SetScale( m_axis_x, m_axis_y1 );
|
||||
|
||||
@@ -90,12 +90,18 @@ void SPICE_VALUE::Normalize()
|
||||
{
|
||||
m_base *= 0.001;
|
||||
m_prefix = (UNIT_PREFIX)( m_prefix + 3 );
|
||||
|
||||
if( m_prefix == PFX_TERA ) // this is the biggest unit available
|
||||
break;
|
||||
}
|
||||
|
||||
while( m_base != 0.0 && std::fabs( m_base ) < 1.000 )
|
||||
{
|
||||
m_base *= 1000.0;
|
||||
m_prefix = (UNIT_PREFIX)( m_prefix - 3 );
|
||||
|
||||
if( m_prefix == PFX_FEMTO ) // this is the smallest unit available
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,8 +95,10 @@ void LIB_VIEW_FRAME::ReCreateHToolbar()
|
||||
|
||||
m_mainToolBar->AddSeparator();
|
||||
|
||||
m_unitChoice = new wxChoice( m_mainToolBar, ID_LIBVIEW_SELECT_PART_NUMBER,
|
||||
wxDefaultPosition, wxSize( 150, -1 ) );
|
||||
if( m_unitChoice == nullptr )
|
||||
m_unitChoice = new wxChoice( m_mainToolBar, ID_LIBVIEW_SELECT_PART_NUMBER,
|
||||
wxDefaultPosition, wxSize( 150, -1 ) );
|
||||
|
||||
m_mainToolBar->AddControl( m_unitChoice );
|
||||
|
||||
m_mainToolBar->AddSeparator();
|
||||
|
||||
@@ -107,6 +107,7 @@ LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
aFrameType == FRAME_SCH_VIEWER_MODAL ? LIB_VIEW_STYLE_MODAL : LIB_VIEW_STYLE,
|
||||
aFrameType == FRAME_SCH_VIEWER_MODAL ? LIB_VIEW_NAME_MODAL : LIB_VIEW_NAME ),
|
||||
m_unitChoice( nullptr ),
|
||||
m_libList( nullptr ),
|
||||
m_cmpList( nullptr ),
|
||||
m_previewItem( nullptr )
|
||||
|
||||
@@ -65,24 +65,36 @@ SYMBOL_PREVIEW_WIDGET::SYMBOL_PREVIEW_WIDGET( wxWindow* aParent, KIWAY& aKiway,
|
||||
// before any OnPaint event is fired for the canvas using a wrong bg color
|
||||
KIGFX::VIEW* view = m_preview->GetView();
|
||||
auto settings = static_cast<KIGFX::SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
|
||||
m_preview->GetGAL()->SetClearColor( settings->GetBackgroundColor() );
|
||||
|
||||
SetBackgroundColour( *wxWHITE );
|
||||
SetForegroundColour( *wxBLACK );
|
||||
const COLOR4D& backgroundColor = settings->GetBackgroundColor();
|
||||
const COLOR4D& foregroundColor = settings->GetCursorColor();
|
||||
|
||||
m_status = new wxStaticText( this, wxID_ANY, wxEmptyString );
|
||||
m_preview->GetGAL()->SetClearColor( backgroundColor );
|
||||
|
||||
m_statusPanel = new wxPanel( this );
|
||||
m_status = new wxStaticText( m_statusPanel, wxID_ANY, wxEmptyString );
|
||||
m_statusSizer = new wxBoxSizer( wxVERTICAL );
|
||||
m_statusSizer->Add( 0, 0, 1 ); // add a spacer
|
||||
m_statusSizer->Add( m_status, 0, wxALIGN_CENTER );
|
||||
m_statusSizer->Add( 0, 0, 1 ); // add a spacer
|
||||
m_statusPanel->SetSizer( m_statusSizer );
|
||||
|
||||
auto outer_sizer = new wxBoxSizer( wxVERTICAL );
|
||||
outer_sizer->Add( m_preview, 1, wxTOP | wxEXPAND, 5 );
|
||||
outer_sizer->Add( m_statusSizer, 1, wxALIGN_CENTER );
|
||||
// Give the status panel the same color scheme as the canvas so it isn't jarring when switched to
|
||||
m_statusPanel->SetBackgroundColour( backgroundColor.ToColour() );
|
||||
m_statusPanel->SetForegroundColour( foregroundColor.ToColour() );
|
||||
|
||||
m_statusSizer->ShowItems( false );
|
||||
// Give the preview panel a small top border to align its top with the status panel,
|
||||
// and give the status panel a small bottom border to align its bottom with the preview
|
||||
// panel.
|
||||
m_outerSizer = new wxBoxSizer( wxVERTICAL );
|
||||
m_outerSizer->Add( m_preview, 1, wxTOP | wxEXPAND, 5 );
|
||||
m_outerSizer->Add( m_statusPanel, 1, wxBOTTOM | wxEXPAND, 5 );
|
||||
|
||||
SetSizer( outer_sizer );
|
||||
// Hide the status panel to start
|
||||
m_statusPanel->Hide();
|
||||
|
||||
SetSizer( m_outerSizer );
|
||||
Layout();
|
||||
|
||||
Connect( wxEVT_SIZE, wxSizeEventHandler( SYMBOL_PREVIEW_WIDGET::onSize ), NULL, this );
|
||||
}
|
||||
@@ -100,8 +112,8 @@ SYMBOL_PREVIEW_WIDGET::~SYMBOL_PREVIEW_WIDGET()
|
||||
void SYMBOL_PREVIEW_WIDGET::SetStatusText( wxString const& aText )
|
||||
{
|
||||
m_status->SetLabel( aText );
|
||||
m_statusSizer->ShowItems( true );
|
||||
m_preview->Hide();
|
||||
m_statusPanel->Show();
|
||||
Layout();
|
||||
}
|
||||
|
||||
@@ -187,7 +199,7 @@ void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit, i
|
||||
if( !m_preview->IsShown() )
|
||||
{
|
||||
m_preview->Show();
|
||||
m_statusSizer->ShowItems( false );
|
||||
m_statusPanel->Hide();
|
||||
Layout(); // Ensure panel size is up to date.
|
||||
}
|
||||
|
||||
@@ -235,5 +247,6 @@ void SYMBOL_PREVIEW_WIDGET::DisplayPart( LIB_PART* aPart, int aUnit, int aConver
|
||||
m_preview->ForceRefresh();
|
||||
|
||||
m_preview->Show();
|
||||
m_statusSizer->ShowItems( false );
|
||||
m_statusPanel->Hide();
|
||||
Layout();
|
||||
}
|
||||
|
||||
@@ -73,7 +73,9 @@ private:
|
||||
EDA_DRAW_PANEL_GAL* m_preview;
|
||||
|
||||
wxStaticText* m_status;
|
||||
wxPanel* m_statusPanel;
|
||||
wxSizer* m_statusSizer;
|
||||
wxSizer* m_outerSizer;
|
||||
|
||||
/** a local copy of the LIB_ALIAS or the LIB_PART to display on the canvas
|
||||
*/
|
||||
|
||||
+23
-1
@@ -322,7 +322,17 @@ bool GERBVIEW_FRAME::loadListOfGerberAndDrillFiles( const wxString& aPath,
|
||||
}
|
||||
else
|
||||
{
|
||||
if( Read_GERBER_File( filename.GetFullPath() ) )
|
||||
if( filename.GetExt() == GerberJobFileExtension.c_str() )
|
||||
{
|
||||
//We cannot read a gerber job file as a gerber plot file: skip it
|
||||
wxString txt;
|
||||
txt.Printf(
|
||||
_( "<b>A gerber job file cannot be loaded as a plot file</b> <i>%s</i>" ),
|
||||
filename.GetFullName() );
|
||||
success = false;
|
||||
reporter.Report( txt, REPORTER::RPT_WARNING );
|
||||
}
|
||||
else if( Read_GERBER_File( filename.GetFullPath() ) )
|
||||
{
|
||||
UpdateFileHistory( m_lastFileName );
|
||||
|
||||
@@ -552,6 +562,18 @@ bool GERBVIEW_FRAME::unarchiveFiles( const wxString& aFullFileName, REPORTER* aR
|
||||
continue;
|
||||
}
|
||||
|
||||
if( curr_ext == GerberJobFileExtension.c_str() )
|
||||
{
|
||||
//We cannot read a gerber job file as a gerber plot file: skip it
|
||||
if( aReporter )
|
||||
{
|
||||
msg.Printf( _( "Info: skip file \"%s\" (gerber job file)\n" ), entry->GetName() );
|
||||
aReporter->Report( msg, REPORTER::RPT_WARNING );
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
int layer = GetActiveLayer();
|
||||
|
||||
if( layer == NO_AVAILABLE_LAYERS )
|
||||
|
||||
@@ -666,17 +666,18 @@ void GERBER_DRAW_ITEM::DrawGbrPoly( EDA_RECT* aClipBox,
|
||||
const wxPoint& aOffset,
|
||||
bool aFilledShape )
|
||||
{
|
||||
std::vector<wxPoint> points;
|
||||
SHAPE_LINE_CHAIN& poly = m_Polygon.Outline( 0 );
|
||||
int pointCount = poly.PointCount() - 1;
|
||||
|
||||
std::vector<wxPoint> points;
|
||||
points.reserve( pointCount );
|
||||
|
||||
for( int ii = 0; ii < pointCount; ii++ )
|
||||
{
|
||||
wxPoint p( poly.Point( ii ).x, poly.Point( ii ).y );
|
||||
points[ii] = p + aOffset;
|
||||
points[ii] = GetABPosition( points[ii] );
|
||||
p = p + aOffset;
|
||||
p = GetABPosition( p );
|
||||
points.push_back( p );
|
||||
}
|
||||
|
||||
GRClosedPoly( aClipBox, aDC, pointCount, &points[0], aFilledShape, aColor, aColor );
|
||||
|
||||
@@ -360,11 +360,16 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer )
|
||||
|
||||
// TODO(JE) Refactor this to allow const aItem
|
||||
D_CODE* code = aItem->GetDcodeDescr();
|
||||
|
||||
if( code && code->m_Shape == APT_RECT )
|
||||
{
|
||||
if( aItem->m_Polygon.OutlineCount() == 0 )
|
||||
aItem->ConvertSegmentToPolygon();
|
||||
drawPolygon( aItem, aItem->m_Polygon, isFilled );
|
||||
|
||||
// Warning: drawPolygon modify the polygon to draw, so use a copy
|
||||
// of aItem->m_Polygon
|
||||
SHAPE_POLY_SET poly = aItem->m_Polygon;
|
||||
drawPolygon( aItem, poly, isFilled );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -54,20 +54,23 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
|
||||
|
||||
// Open Gerber file(s)
|
||||
AddMenuItem( fileMenu, wxID_FILE,
|
||||
_( "Open &Gerber File(s)..." ),
|
||||
_( "Open Gerber file(s) on the current layer. Previous data will be deleted" ),
|
||||
_( "Open &Gerber Plot File(s)..." ),
|
||||
_( "Open Gerber plot file(s) on the current layer."
|
||||
" Previous data will be deleted" ),
|
||||
KiBitmap( load_gerber_xpm ) );
|
||||
|
||||
// Open Excellon drill file(s)
|
||||
AddMenuItem( fileMenu, ID_GERBVIEW_LOAD_DRILL_FILE,
|
||||
_( "Open &Excellon Drill File(s)..." ),
|
||||
_( "Open Excellon drill file(s) on the current layer. Previous data will be deleted" ),
|
||||
_( "Open Excellon drill file(s) on the current layer."
|
||||
" Previous data will be deleted" ),
|
||||
KiBitmap( gerbview_drill_file_xpm ) );
|
||||
|
||||
// Open Gerber job files
|
||||
AddMenuItem( fileMenu, ID_GERBVIEW_LOAD_JOB_FILE,
|
||||
_( "Open Gerber &Job File..." ),
|
||||
_( "Open a Gerber job file, and it's associated gerber files depending on the job" ),
|
||||
_( "Open a Gerber job file, and it's associated gerber plot"
|
||||
" files depending on the job" ),
|
||||
KiBitmap( gerber_job_file_xpm ) );
|
||||
|
||||
// Open Zip archive files
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 2013-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2008-2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 2004-2018 KiCad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2004-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
|
||||
@@ -213,8 +213,8 @@ public:
|
||||
|
||||
void SetNext( EDA_ITEM* aNext ) { Pnext = aNext; }
|
||||
void SetBack( EDA_ITEM* aBack ) { Pback = aBack; }
|
||||
void SetParent( EDA_ITEM* aParent ) { m_Parent = aParent; }
|
||||
void SetList( DHEAD* aList ) { m_List = aList; }
|
||||
virtual void SetParent( EDA_ITEM* aParent ) { m_Parent = aParent; }
|
||||
|
||||
inline bool IsNew() const { return m_Flags & IS_NEW; }
|
||||
inline bool IsModified() const { return m_Flags & IS_CHANGED; }
|
||||
|
||||
@@ -49,7 +49,10 @@
|
||||
|
||||
#define DEFAULT_PCB_EDGE_THICKNESS 0.15
|
||||
|
||||
#define DEFAULT_SOLDERMASK_CLEARANCE 0.05 // soldermask to pad clearance
|
||||
// soldermask to pad clearance. The default is 0 because usually board houses
|
||||
// create a clearance depending on their fab process:
|
||||
// mask material, color, price ...
|
||||
#define DEFAULT_SOLDERMASK_CLEARANCE 0.0
|
||||
|
||||
// DEFAULT_SOLDERMASK_MIN_WIDTH is only used in Gerber files: soldermask minimum size.
|
||||
// Set to 0, because using non 0 value creates an annoying issue in Gerber files:
|
||||
|
||||
@@ -67,14 +67,10 @@ enum STROKE_T
|
||||
*/
|
||||
class BOARD_ITEM : public EDA_ITEM
|
||||
{
|
||||
|
||||
protected:
|
||||
PCB_LAYER_ID m_Layer;
|
||||
|
||||
static int getNextNumberInSequence( const std::set<int>& aSeq, bool aFillSequenceGaps );
|
||||
|
||||
public:
|
||||
|
||||
BOARD_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) :
|
||||
EDA_ITEM( aParent, idtype ), m_Layer( F_Cu )
|
||||
{
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013-2018 CERN
|
||||
* Copyright (C) 2013-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
@@ -240,7 +242,15 @@ public:
|
||||
*/
|
||||
void OnEvent( wxEvent& aEvent );
|
||||
|
||||
/**
|
||||
* Repaint the canvas, and fix scrollbar cursors
|
||||
* Usually called by a OnPaint event, but because it do not use a wxPaintDC,
|
||||
* it can be called outside a wxPaintEvent.
|
||||
*/
|
||||
void DoRePaint();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void onPaint( wxPaintEvent& WXUNUSED( aEvent ) );
|
||||
void onSize( wxSizeEvent& aEvent );
|
||||
void onEnter( wxEvent& aEvent );
|
||||
|
||||
@@ -292,7 +292,6 @@ protected:
|
||||
unsigned int groupCounter; ///< Counter used for generating keys for groups
|
||||
GROUP* currentGroup; ///< Currently used group
|
||||
|
||||
double lineWidth;
|
||||
double linePixelWidth;
|
||||
double lineWidthInPixels;
|
||||
bool lineWidthIsOdd;
|
||||
@@ -390,16 +389,10 @@ public:
|
||||
/**
|
||||
* Function PostPaint
|
||||
* posts an event to m_paint_listener. A post is used so that the actual drawing
|
||||
* function can use a device context type that is not specific to the wxEVT_PAINT event.
|
||||
* function can use a device context type that is not specific to the wxEVT_PAINT event,
|
||||
* just by changing the PostPaint code.
|
||||
*/
|
||||
void PostPaint()
|
||||
{
|
||||
if( paintListener )
|
||||
{
|
||||
wxPaintEvent redrawEvent;
|
||||
wxPostEvent( paintListener, redrawEvent );
|
||||
}
|
||||
}
|
||||
void PostPaint( wxPaintEvent& aEvent );
|
||||
|
||||
void SetMouseListener( wxEvtHandler* aMouseListener )
|
||||
{
|
||||
|
||||
@@ -82,8 +82,6 @@ public:
|
||||
CAIRO_PRINT_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions,
|
||||
std::unique_ptr<CAIRO_PRINT_CTX> aContext );
|
||||
|
||||
void SetLineWidth( float aLineWidth ) override;
|
||||
|
||||
void ComputeWorldScreenMatrix() override;
|
||||
|
||||
GAL* GetGAL() override
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2020 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2013-2017 CERN
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
@@ -249,16 +249,10 @@ public:
|
||||
/**
|
||||
* @brief Function PostPaint
|
||||
* posts an event to m_paint_listener. A post is used so that the actual drawing
|
||||
* function can use a device context type that is not specific to the wxEVT_PAINT event.
|
||||
* function can use a device context type that is not specific to the wxEVT_PAINT event,
|
||||
* just by changing the PostPaint code.
|
||||
*/
|
||||
void PostPaint()
|
||||
{
|
||||
if( paintListener )
|
||||
{
|
||||
wxPaintEvent redrawEvent;
|
||||
wxPostEvent( paintListener, redrawEvent );
|
||||
}
|
||||
}
|
||||
void PostPaint( wxPaintEvent& aEvent );
|
||||
|
||||
void SetMouseListener( wxEvtHandler* aMouseListener )
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 1992-2018 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
|
||||
@@ -45,8 +45,25 @@ class EDA_RECT;
|
||||
*/
|
||||
int GetArcToSegmentCount( int aRadius, int aErrorMax, double aArcAngleDegree );
|
||||
|
||||
/** When creating polygons to create a clearance polygonal area, the polygon must
|
||||
* be same or bigger than the original shape.
|
||||
* Polygons are bigger if the original shape has arcs (round rectangles, ovals, circles...)
|
||||
* In some cases (in fact only one: when building layer solder mask) modifying
|
||||
* shapes when converting them to polygons is not acceptable (the modification
|
||||
* can break calculations)
|
||||
* so one can disable the shape expansion by calling KeepPolyInsideShape( true )
|
||||
* Important: calling DisableArcRadiusCorrection( false ) after calculations is
|
||||
* mandatory to break oher calculations
|
||||
* @param aDisable = false to create polygons same or outside the original shape
|
||||
* = true to create polygons same or inside the original shape and minimize
|
||||
* shape geometric changes
|
||||
*/
|
||||
void DisableArcRadiusCorrection( bool aDisable );
|
||||
|
||||
|
||||
/**
|
||||
* @return the correction factor to approximate a circle by segments
|
||||
* @return the correction factor to approximate a circle by segments or 1.0
|
||||
* depending on the last call to DisableArcRadiusCorrection()
|
||||
* @param aSegCountforCircle is the number of segments to approximate the circle
|
||||
*
|
||||
* When creating a polygon from a circle, the polygon is inside the circle.
|
||||
|
||||
@@ -36,6 +36,13 @@
|
||||
#include <wx/filename.h>
|
||||
|
||||
|
||||
/**
|
||||
* Converts curly quotes and em/en dashes to straight quotes and dashes.
|
||||
* @param aString
|
||||
* @return true if any characters required conversion.
|
||||
*/
|
||||
bool ConvertSmartQuotesAndDashes( wxString* aString );
|
||||
|
||||
/**
|
||||
* These Escape/Unescape routines use HTML-entity-reference-style encoding to handle
|
||||
* characters which are:
|
||||
|
||||
+1
-2
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2016-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-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
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <math/box2.h>
|
||||
#include <draw_graphic_text.h>
|
||||
#include <page_info.h>
|
||||
#include <eda_text.h> // FILL_T
|
||||
|
||||
class SHAPE_POLY_SET;
|
||||
class SHAPE_LINE_CHAIN;
|
||||
|
||||
@@ -52,8 +52,11 @@ public:
|
||||
protected:
|
||||
wxComboBox* Combo() const { return static_cast<wxComboBox*>( m_control ); }
|
||||
|
||||
const wxArrayString& m_names;
|
||||
wxString m_value;
|
||||
void onComboCloseUp( wxCommandEvent& aEvent );
|
||||
void onComboDropDown( wxCommandEvent& aEvent );
|
||||
|
||||
wxArrayString m_names;
|
||||
wxString m_value;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS( GRID_CELL_COMBOBOX );
|
||||
};
|
||||
|
||||
+21
-1
@@ -95,17 +95,31 @@ if( APPLE )
|
||||
set( SCRIPTING_HELPER "0" )
|
||||
endif()
|
||||
|
||||
if( KICAD_SPICE )
|
||||
set( SPICE_HELPER "1" )
|
||||
else()
|
||||
set( SPICE_HELPER "0" )
|
||||
endif()
|
||||
|
||||
if( KICAD_USE_OCC )
|
||||
set( KICAD_BUNDLE_LIBS ${OCC_LIBRARY_DIR} )
|
||||
endif()
|
||||
|
||||
# make main bundle relocatable
|
||||
install( CODE "
|
||||
# find all libs and modules
|
||||
# find all kicad libs and modules
|
||||
file( GLOB PLUGINS_KIFACE ${OSX_BUNDLE_INSTALL_KIFACE_DIR}/*.kiface )
|
||||
file( GLOB_RECURSE PLUGINS_SO ${OSX_BUNDLE_INSTALL_PLUGIN_DIR}/*.so )
|
||||
file( GLOB_RECURSE PLUGINS_3D ${OSX_BUNDLE_INSTALL_PLUGIN_DIR}/3d/*.dylib )
|
||||
set( BUNDLE_FIX_LIBS \${PLUGINS_KIFACE} \${PLUGINS_SO} \${PLUGINS_3D} )
|
||||
|
||||
# Find ngspice if it is being packaged
|
||||
if( ${SPICE_HELPER} )
|
||||
file( GLOB_RECURSE PLUGINS_NGSPICE ${OSX_BUNDLE_INSTALL_PLUGIN_DIR}/sim/*.dylib )
|
||||
set( BUNDLE_FIX_LIBS \${BUNDLE_FIX_LIBS} \${PLUGINS_NGSPICE} )
|
||||
endif()
|
||||
|
||||
# Find python if it is requested
|
||||
if( ${SCRIPTING_HELPER} )
|
||||
file( GLOB WXPYTHON_DIR RELATIVE ${OSX_BUNDLE_INSTALL_LIB_DIR}/${PYTHON_LIB_DIR} ${OSX_BUNDLE_INSTALL_LIB_DIR}/${PYTHON_LIB_DIR}/wx-?.?-osx_cocoa )
|
||||
file( GLOB PYTHON_SCRIPTING_SO ${OSX_BUNDLE_INSTALL_LIB_DIR}/${PYTHON_LIB_DIR}/*.so )
|
||||
@@ -124,6 +138,12 @@ if( APPLE )
|
||||
\"\${BUNDLE_FIX_LIBS}\"
|
||||
\" ${KICAD_BUNDLE_LIBS}\"
|
||||
)
|
||||
|
||||
if( ${SPICE_HELPER} )
|
||||
execute_process( COMMAND install_name_tool -id @executable_path/../PlugIns/sim/libngspice.0.dylib libngspice.0.dylib
|
||||
WORKING_DIRECTORY ${OSX_BUNDLE_INSTALL_PLUGIN_DIR}/sim )
|
||||
endif()
|
||||
|
||||
" COMPONENT Runtime
|
||||
)
|
||||
|
||||
|
||||
+2
-3
@@ -139,10 +139,9 @@ bool PGM_KICAD::OnPgmInit()
|
||||
wxString projToLoad;
|
||||
|
||||
if( App().argc > 1 )
|
||||
{
|
||||
projToLoad = App().argv[1];
|
||||
}
|
||||
else if( GetFileHistory().GetCount() )
|
||||
|
||||
if( projToLoad.IsEmpty() && GetFileHistory().GetCount() )
|
||||
{
|
||||
wxString last_pro = GetFileHistory().GetHistoryFile( 0 );
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <id.h>
|
||||
#include <eda_base_frame.h>
|
||||
#include <kiway_player.h>
|
||||
#include <mutex>
|
||||
|
||||
#define KICAD_MANAGER_FRAME_NAME wxT( "KicadFrame" )
|
||||
|
||||
@@ -304,6 +305,9 @@ private:
|
||||
void language_change( wxCommandEvent& event );
|
||||
|
||||
bool m_active_project;
|
||||
|
||||
// Mutex to allow only a single KiFace to load at one time (released when loaded)
|
||||
std::mutex m_loading;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -316,6 +316,9 @@ void KICAD_MANAGER_FRAME::RunEeschema( const wxString& aProjectSchematicFileName
|
||||
{
|
||||
KIWAY_PLAYER* frame;
|
||||
|
||||
// Prevent multiple KiFace loading at one time
|
||||
const std::lock_guard<std::mutex> lock( m_loading );
|
||||
|
||||
try
|
||||
{
|
||||
frame = Kiway().Player( FRAME_SCH, true );
|
||||
@@ -361,6 +364,9 @@ void KICAD_MANAGER_FRAME::OnRunSchLibEditor( wxCommandEvent& event )
|
||||
{
|
||||
KIWAY_PLAYER* frame;
|
||||
|
||||
// Prevent multiple KiFace loading at one time
|
||||
const std::lock_guard<std::mutex> lock( m_loading );
|
||||
|
||||
try
|
||||
{
|
||||
frame = Kiway().Player( FRAME_SCH_LIB_EDITOR, true );
|
||||
@@ -387,6 +393,9 @@ void KICAD_MANAGER_FRAME::RunPcbNew( const wxString& aProjectBoardFileName )
|
||||
{
|
||||
KIWAY_PLAYER* frame;
|
||||
|
||||
// Prevent multiple KiFace loading at one time
|
||||
const std::lock_guard<std::mutex> lock( m_loading );
|
||||
|
||||
try
|
||||
{
|
||||
frame = Kiway().Player( FRAME_PCB, true );
|
||||
@@ -430,6 +439,9 @@ void KICAD_MANAGER_FRAME::OnRunPcbFpEditor( wxCommandEvent& event )
|
||||
{
|
||||
KIWAY_PLAYER* frame;
|
||||
|
||||
// Prevent multiple KiFace loading at one time
|
||||
const std::lock_guard<std::mutex> lock( m_loading );
|
||||
|
||||
try
|
||||
{
|
||||
frame = Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
|
||||
|
||||
@@ -449,7 +449,7 @@ if( KICAD_SCRIPTING ) # Generate pcbnew.py and pcbnew_wrap.cxx using swig
|
||||
# We deliberately do not use the CMake support for swig here,
|
||||
# i.e. swig_add_footprint()) because we want full control.
|
||||
|
||||
set( SWIG_OPTS -python -c++ -outdir ${CMAKE_CURRENT_BINARY_DIR} ${SWIG_FLAGS} )
|
||||
set( SWIG_OPTS -python -c++ -nothreads -outdir ${CMAKE_CURRENT_BINARY_DIR} ${SWIG_FLAGS} )
|
||||
|
||||
if( EXISTS ${CMAKE_CURRENT_BINARY_DIR}/doxygen-xml )
|
||||
set( SWIG_OPTS ${SWIG_OPTS} -DENABLE_DOCSTRINGS_FROM_DOXYGEN )
|
||||
|
||||
@@ -106,7 +106,7 @@ void ARRAY_CREATOR::Invoke()
|
||||
{
|
||||
// Don't bother incrementing pads: the module won't update
|
||||
// until commit, so we can only do this once
|
||||
new_item.reset( module->Duplicate( item, false ) );
|
||||
new_item.reset( module->Duplicate( item ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -53,7 +53,9 @@
|
||||
#include <class_edge_mod.h>
|
||||
|
||||
#include <dialogs/dialog_move_exact.h>
|
||||
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/footprint_editor_tools.h>
|
||||
#include <pad_naming.h>
|
||||
|
||||
#define BLOCK_COLOR BROWN
|
||||
|
||||
@@ -72,7 +74,6 @@ static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wx
|
||||
static int MarkItemsInBloc( MODULE* module, EDA_RECT& Rect );
|
||||
|
||||
static void ClearMarkItems( MODULE* module );
|
||||
static void CopyMarkedItems( MODULE* module, wxPoint offset, bool aIncrement );
|
||||
static void MoveMarkedItems( MODULE* module, wxPoint offset );
|
||||
static void DeleteMarkedItems( MODULE* module );
|
||||
|
||||
@@ -452,7 +453,7 @@ static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wx
|
||||
|
||||
/* Copy marked items, at new position = old position + offset
|
||||
*/
|
||||
void CopyMarkedItems( MODULE* module, wxPoint offset, bool aIncrement )
|
||||
void FOOTPRINT_EDIT_FRAME::CopyMarkedItems( MODULE* module, wxPoint offset, bool aIncrement )
|
||||
{
|
||||
if( module == NULL )
|
||||
return;
|
||||
@@ -473,8 +474,14 @@ void CopyMarkedItems( MODULE* module, wxPoint offset, bool aIncrement )
|
||||
NewPad->SetFlags( SELECTED );
|
||||
module->PadsList().PushFront( NewPad );
|
||||
|
||||
if( aIncrement )
|
||||
NewPad->IncrementPadName( true, true );
|
||||
if( aIncrement && PAD_NAMING::PadCanHaveName( *NewPad ) )
|
||||
{
|
||||
MODULE_EDITOR_TOOLS* modEdit = m_toolManager->GetTool<MODULE_EDITOR_TOOLS>();
|
||||
wxString padName = modEdit->GetLastPadName();
|
||||
padName = module->GetNextPadName( padName );
|
||||
modEdit->SetLastPadName( padName );
|
||||
NewPad->SetName( padName );
|
||||
}
|
||||
}
|
||||
|
||||
BOARD_ITEM* newItem;
|
||||
|
||||
@@ -102,7 +102,7 @@ public:
|
||||
*/
|
||||
int GetNetCode() const
|
||||
{
|
||||
return m_netinfo->GetNet();
|
||||
return m_netinfo ? m_netinfo->GetNet() : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -95,35 +95,6 @@ void BOARD_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
}
|
||||
|
||||
|
||||
int BOARD_ITEM::getNextNumberInSequence( const std::set<int>& aSeq, bool aFillSequenceGaps)
|
||||
{
|
||||
if( aSeq.empty() )
|
||||
return 1;
|
||||
|
||||
// By default go to the end of the sequence
|
||||
int candidate = *aSeq.rbegin();
|
||||
|
||||
// Filling in gaps in pad numbering
|
||||
if( aFillSequenceGaps )
|
||||
{
|
||||
// start at the beginning
|
||||
candidate = *aSeq.begin();
|
||||
|
||||
for( auto it : aSeq )
|
||||
{
|
||||
if( it - candidate > 1 )
|
||||
break;
|
||||
|
||||
candidate = it;
|
||||
}
|
||||
}
|
||||
|
||||
++candidate;
|
||||
|
||||
return candidate;
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ITEM::DeleteStructure()
|
||||
{
|
||||
auto parent = GetParent();
|
||||
|
||||
+11
-16
@@ -1244,9 +1244,8 @@ void MODULE::SetOrientation( double newangle )
|
||||
CalculateBoundingBox();
|
||||
}
|
||||
|
||||
BOARD_ITEM* MODULE::Duplicate( const BOARD_ITEM* aItem,
|
||||
bool aIncrementPadNumbers,
|
||||
bool aAddToModule )
|
||||
|
||||
BOARD_ITEM* MODULE::Duplicate( const BOARD_ITEM* aItem, bool aAddToModule )
|
||||
{
|
||||
BOARD_ITEM* new_item = NULL;
|
||||
D_PAD* new_pad = NULL;
|
||||
@@ -1305,29 +1304,25 @@ BOARD_ITEM* MODULE::Duplicate( const BOARD_ITEM* aItem,
|
||||
break;
|
||||
}
|
||||
|
||||
if( aIncrementPadNumbers && new_pad && !new_pad->IsAperturePad() )
|
||||
{
|
||||
new_pad->IncrementPadName( true, true );
|
||||
}
|
||||
|
||||
return new_item;
|
||||
}
|
||||
|
||||
|
||||
wxString MODULE::GetNextPadName( bool aFillSequenceGaps ) const
|
||||
wxString MODULE::GetNextPadName( const wxString& aLastPadName ) const
|
||||
{
|
||||
std::set<int> usedNumbers;
|
||||
std::set<wxString> usedNames;
|
||||
|
||||
// Create a set of used pad numbers
|
||||
for( D_PAD* pad = PadsList(); pad; pad = pad->Next() )
|
||||
{
|
||||
int padNumber = GetTrailingInt( pad->GetName() );
|
||||
usedNumbers.insert( padNumber );
|
||||
}
|
||||
usedNames.insert( pad->GetName() );
|
||||
|
||||
const int nextNum = getNextNumberInSequence( usedNumbers, aFillSequenceGaps );
|
||||
wxString prefix = UTIL::GetReferencePrefix( aLastPadName );
|
||||
int num = GetTrailingInt( aLastPadName );
|
||||
|
||||
return wxString::Format( wxT( "%i" ), nextNum );
|
||||
while( usedNames.count( wxString::Format( "%s%d", prefix, num ) ) )
|
||||
num++;
|
||||
|
||||
return wxString::Format( "%s%d", prefix, num );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -555,12 +555,8 @@ public:
|
||||
/**
|
||||
* Function GetNextPadName
|
||||
* returns the next available pad name in the module
|
||||
*
|
||||
* @param aFillSequenceGaps true if the numbering should "fill in" gaps in
|
||||
* the sequence, else return the highest value + 1
|
||||
* @return the next available pad name
|
||||
*/
|
||||
wxString GetNextPadName( bool aFillSequenceGaps ) const;
|
||||
wxString GetNextPadName( const wxString& aLastPadName ) const;
|
||||
|
||||
double GetArea( int aPadding = 0 ) const;
|
||||
|
||||
@@ -578,9 +574,7 @@ public:
|
||||
* Duplicate a given item within the module, without adding to the board
|
||||
* @return the new item, or NULL if the item could not be duplicated
|
||||
*/
|
||||
BOARD_ITEM* Duplicate( const BOARD_ITEM* aItem,
|
||||
bool aIncrementPadNumbers,
|
||||
bool aAddToModule = false );
|
||||
BOARD_ITEM* Duplicate( const BOARD_ITEM* aItem, bool aAddToModule = false );
|
||||
|
||||
/**
|
||||
* Function Add3DModel
|
||||
|
||||
@@ -562,17 +562,6 @@ wxPoint D_PAD::ShapePos() const
|
||||
}
|
||||
|
||||
|
||||
bool D_PAD::IncrementPadName( bool aSkipUnconnectable, bool aFillSequenceGaps )
|
||||
{
|
||||
bool skip = aSkipUnconnectable && ( GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED );
|
||||
|
||||
if( !skip )
|
||||
SetName( GetParent()->GetNextPadName( aFillSequenceGaps ) );
|
||||
|
||||
return !skip;
|
||||
}
|
||||
|
||||
|
||||
void D_PAD::CopyNetlistSettings( D_PAD* aPad, bool aCopyLocalSettings )
|
||||
{
|
||||
// Don't do anything foolish like trying to copy to yourself.
|
||||
|
||||
@@ -192,18 +192,6 @@ public:
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function IncrementPadName
|
||||
*
|
||||
* Increments the pad name to the next available name in the module.
|
||||
*
|
||||
* @param aSkipUnconnectable skips any pads that are not connectable (for example NPTH)
|
||||
* @param aFillSequenceGaps if true, the next reference in a sequence
|
||||
* like A1,A3,A4 will be A2. If false, it will be A5.
|
||||
* @return pad name incremented
|
||||
*/
|
||||
bool IncrementPadName( bool aSkipUnconnectable, bool aFillSequenceGaps );
|
||||
|
||||
bool PadNameEqual( const D_PAD* other ) const
|
||||
{
|
||||
return m_name == other->m_name; // hide tricks behind sensible API
|
||||
|
||||
@@ -176,6 +176,13 @@ void TEXTE_PCB::Flip( const wxPoint& aCentre )
|
||||
SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
|
||||
SetMirrored( !IsMirrored() );
|
||||
|
||||
double text_angle = GetTextAngle();
|
||||
if( text_angle < 1800 )
|
||||
text_angle = 1800 - text_angle;
|
||||
else
|
||||
text_angle = 3600 - text_angle + 1800;
|
||||
SetTextAngle( text_angle );
|
||||
|
||||
// adjust justified text for mirroring
|
||||
if( GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT || GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT )
|
||||
{
|
||||
|
||||
@@ -42,7 +42,8 @@ CONNECTIVITY_DATA::CONNECTIVITY_DATA()
|
||||
}
|
||||
|
||||
|
||||
CONNECTIVITY_DATA::CONNECTIVITY_DATA( const std::vector<BOARD_ITEM*>& aItems )
|
||||
CONNECTIVITY_DATA::CONNECTIVITY_DATA( const std::vector<BOARD_ITEM*>& aItems, bool aSkipRatsnest )
|
||||
: m_skipRatsnest( aSkipRatsnest )
|
||||
{
|
||||
Build( aItems );
|
||||
m_progressReporter = nullptr;
|
||||
@@ -187,7 +188,8 @@ void CONNECTIVITY_DATA::RecalculateRatsnest( BOARD_COMMIT* aCommit )
|
||||
|
||||
m_connAlgo->ClearDirtyFlags();
|
||||
|
||||
updateRatsnest();
|
||||
if( !m_skipRatsnest )
|
||||
updateRatsnest();
|
||||
}
|
||||
|
||||
|
||||
@@ -204,7 +206,8 @@ void CONNECTIVITY_DATA::BlockRatsnestItems( const std::vector<BOARD_ITEM*>& aIte
|
||||
}
|
||||
else
|
||||
{
|
||||
citems.push_back( static_cast<BOARD_CONNECTED_ITEM*>(item) );
|
||||
if( auto citem = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
|
||||
citems.push_back( citem );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +257,7 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>&
|
||||
return ;
|
||||
}
|
||||
|
||||
CONNECTIVITY_DATA connData( aItems );
|
||||
CONNECTIVITY_DATA connData( aItems, true );
|
||||
BlockRatsnestItems( aItems );
|
||||
|
||||
for( unsigned int nc = 1; nc < connData.m_nets.size(); nc++ )
|
||||
@@ -278,27 +281,19 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>&
|
||||
}
|
||||
}
|
||||
|
||||
for( auto net : connData.m_nets )
|
||||
const auto& edges = GetRatsnestForItems( aItems );
|
||||
|
||||
for( const auto& edge : edges )
|
||||
{
|
||||
if( !net )
|
||||
continue;
|
||||
const auto& nodeA = edge.GetSourceNode();
|
||||
const auto& nodeB = edge.GetTargetNode();
|
||||
RN_DYNAMIC_LINE l;
|
||||
|
||||
const auto& edges = net->GetUnconnected();
|
||||
|
||||
if( edges.empty() )
|
||||
continue;
|
||||
|
||||
for( const auto& edge : edges )
|
||||
{
|
||||
const auto& nodeA = edge.GetSourceNode();
|
||||
const auto& nodeB = edge.GetTargetNode();
|
||||
RN_DYNAMIC_LINE l;
|
||||
|
||||
l.a = nodeA->Pos();
|
||||
l.b = nodeB->Pos();
|
||||
l.netCode = 0;
|
||||
m_dynamicRatsnest.push_back( l );
|
||||
}
|
||||
// Use the parents' positions
|
||||
l.a = nodeA->Parent()->GetPosition();
|
||||
l.b = nodeB->Parent()->GetPosition();
|
||||
l.netCode = 0;
|
||||
m_dynamicRatsnest.push_back( l );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,6 +658,55 @@ void CONNECTIVITY_DATA::SetProgressReporter( PROGRESS_REPORTER* aReporter )
|
||||
}
|
||||
|
||||
|
||||
const std::vector<CN_EDGE> CONNECTIVITY_DATA::GetRatsnestForItems( std::vector<BOARD_ITEM*> aItems )
|
||||
{
|
||||
std::set<int> nets;
|
||||
std::vector<CN_EDGE> edges;
|
||||
std::set<BOARD_ITEM*> item_set( aItems.begin(), aItems.end() );
|
||||
|
||||
for( auto item : aItems )
|
||||
{
|
||||
if( item->Type() == PCB_MODULE_T )
|
||||
{
|
||||
auto component = static_cast<MODULE*>( item );
|
||||
|
||||
for( auto pad : component->Pads() )
|
||||
{
|
||||
nets.insert( pad->GetNetCode() );
|
||||
item_set.insert( pad );
|
||||
}
|
||||
}
|
||||
else if( auto conn_item = dyn_cast<BOARD_CONNECTED_ITEM*>( item ) )
|
||||
{
|
||||
item_set.insert( conn_item );
|
||||
nets.insert( conn_item->GetNetCode() );
|
||||
}
|
||||
}
|
||||
|
||||
for( const auto& netcode : nets )
|
||||
{
|
||||
const auto& net = GetRatsnestForNet( netcode );
|
||||
|
||||
for( const auto& edge : net->GetEdges() )
|
||||
{
|
||||
auto srcNode = edge.GetSourceNode();
|
||||
auto dstNode = edge.GetTargetNode();
|
||||
|
||||
auto srcParent = static_cast<BOARD_ITEM*>( srcNode->Parent() );
|
||||
auto dstParent = static_cast<BOARD_ITEM*>( dstNode->Parent() );
|
||||
|
||||
bool srcFound = ( item_set.find(srcParent) != item_set.end() );
|
||||
bool dstFound = ( item_set.find(dstParent) != item_set.end() );
|
||||
|
||||
if ( srcFound && dstFound )
|
||||
edges.push_back( edge );
|
||||
}
|
||||
}
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
||||
|
||||
const std::vector<CN_EDGE> CONNECTIVITY_DATA::GetRatsnestForComponent( MODULE* aComponent, bool aSkipInternalConnections )
|
||||
{
|
||||
std::set<int> nets;
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
CONNECTIVITY_DATA();
|
||||
~CONNECTIVITY_DATA();
|
||||
|
||||
CONNECTIVITY_DATA( const std::vector<BOARD_ITEM*>& aItems );
|
||||
CONNECTIVITY_DATA( const std::vector<BOARD_ITEM*>& aItems, bool aSkipItems = false );
|
||||
|
||||
/**
|
||||
* Function Build()
|
||||
@@ -244,6 +244,8 @@ public:
|
||||
void SetProgressReporter( PROGRESS_REPORTER* aReporter );
|
||||
|
||||
#ifndef SWIG
|
||||
const std::vector<CN_EDGE> GetRatsnestForItems( const std::vector<BOARD_ITEM*> aItems );
|
||||
|
||||
const std::vector<CN_EDGE> GetRatsnestForComponent( MODULE* aComponent, bool aSkipInternalConnections = false );
|
||||
#endif
|
||||
|
||||
@@ -259,6 +261,8 @@ private:
|
||||
|
||||
PROGRESS_REPORTER* m_progressReporter;
|
||||
|
||||
bool m_skipRatsnest = false;
|
||||
|
||||
std::mutex m_lock;
|
||||
};
|
||||
|
||||
|
||||
@@ -598,20 +598,27 @@ bool DIALOG_FOOTPRINT_FP_EDITOR::TransferDataFromWindow()
|
||||
m_footprint->Value() = m_texts->at( 1 );
|
||||
|
||||
size_t i = 2;
|
||||
std::vector<TEXTE_MODULE*> items_to_remove;
|
||||
|
||||
for( BOARD_ITEM* item = m_footprint->GraphicalItemsList().GetFirst(); item; item = item->Next() )
|
||||
{
|
||||
TEXTE_MODULE* textModule = dyn_cast<TEXTE_MODULE*>( item );
|
||||
TEXTE_MODULE* textModule = dynamic_cast<TEXTE_MODULE*>( item );
|
||||
|
||||
if( textModule )
|
||||
{
|
||||
// copy grid table entries till we run out, then delete any remaining texts
|
||||
if( i < m_texts->size() )
|
||||
*textModule = m_texts->at( i++ );
|
||||
else
|
||||
textModule->DeleteStructure();
|
||||
else // store this item to remove and delete it later,
|
||||
// after the graphic list is explored:
|
||||
items_to_remove.push_back( textModule );
|
||||
}
|
||||
}
|
||||
|
||||
// Remove items from m_footprint graphic list:
|
||||
for( TEXTE_MODULE* item: items_to_remove )
|
||||
item->DeleteStructure();
|
||||
|
||||
// if there are still grid table entries, create new texts for them
|
||||
while( i < m_texts->size() )
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user