Compare commits
241 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ad43570ec0 | |||
| 5dd4718db0 | |||
| ea70d8cf4c | |||
| cd2879880a | |||
| b51c8c1b3d | |||
| 5db1ee930f | |||
| 695dd57477 | |||
| 224c989072 | |||
| 80db7ff8cf | |||
| 6e6d3e9b03 | |||
| c08dd172d6 | |||
| 7972805d07 | |||
| a86147b4b1 | |||
| 335bb8792f | |||
| c8f7887cf8 | |||
| 2fe5c28787 | |||
| 64365de9de | |||
| a950d55cb2 | |||
| 3748a10ed5 | |||
| 227bb76909 | |||
| a20a6bb2a3 | |||
| 7c17aa5974 | |||
| 59795c81c5 | |||
| 84d00a7887 | |||
| 3774e31db8 | |||
| 69ac570658 | |||
| 46ecb22ef5 | |||
| ff7ea6eae0 | |||
| 2f70ac171f | |||
| 360011e563 | |||
| 2a0785d188 | |||
| a480b1a5ba | |||
| 6f31e306a1 | |||
| 5983815415 | |||
| 288050b6ec | |||
| 6d36363403 | |||
| 720c7d9fc4 | |||
| e009afd4a1 | |||
| 9e13ff25d0 | |||
| af1899ddc3 | |||
| beb30dd881 | |||
| 6d09293b11 | |||
| ca7378924c | |||
| 74316a62d3 | |||
| 3150f467bb | |||
| c033c364d4 | |||
| 37c14a65ed | |||
| dbf64ac0cf | |||
| 0eda576189 | |||
| 6ee9fb4027 | |||
| 64134cee92 | |||
| fead0eb33b | |||
| ff71b324a1 | |||
| b10ab478bd | |||
| 710b6adb8c | |||
| 6a01bdbabd | |||
| 76e19c6dcf | |||
| 8af289c33e | |||
| 35fa7db5c7 | |||
| 67739ee3d1 | |||
| d8ba7284a8 | |||
| fdc0309592 | |||
| 55d77f0dbb | |||
| 14fafebbc7 | |||
| 7ca472deb8 | |||
| fdb3612565 | |||
| bf59a6305a | |||
| 17db770d92 | |||
| b3004c9d96 | |||
| c54ebdecd2 | |||
| 6fc15ed8df | |||
| e7779d9b91 | |||
| 06a91637a7 | |||
| 08e9ce2828 | |||
| 24f82ab87d | |||
| bcf069699d | |||
| f8d694e4d0 | |||
| b80334baa1 | |||
| 6c359e2f06 | |||
| a3eff548b7 | |||
| e33a732371 | |||
| 95d3200a3a | |||
| 5ee7ae4a45 | |||
| b13a9e231b | |||
| 1011f361fd | |||
| 288a08b9c2 | |||
| cac1979f61 | |||
| 38a9477423 | |||
| 072446e79d | |||
| 4fc528819d | |||
| d5f52000ce | |||
| 8e4d7da4ea | |||
| ea3f0bada4 | |||
| 3b33ce8bcc | |||
| 74b42f1bb2 | |||
| b455a4cd54 | |||
| 5021f6ee26 | |||
| 0be2b88f5a | |||
| f3a57cf763 | |||
| ddd69019bc | |||
| 94e34cb1eb | |||
| 6470212edd | |||
| 8c3bcade1c | |||
| 70e99acce6 | |||
| 25be138ac1 | |||
| 9f196d2e64 | |||
| b51fed4118 | |||
| a914f361d3 | |||
| 846b634e0e | |||
| 08b54e205d | |||
| 7cba1e1a55 | |||
| 6ae334a751 | |||
| 61687e8499 | |||
| e014f2274f | |||
| 7e0f05f991 | |||
| 1e21b41be5 | |||
| 4a7dcfdd1f | |||
| d1684b8a72 | |||
| 8da026baff | |||
| 89a3ead51e | |||
| 5064834716 | |||
| 51a3859d7e | |||
| bf37bd8ed5 | |||
| 283fed83c3 | |||
| 48983dd31d | |||
| ccd4b0cf05 | |||
| 154c755a1b | |||
| 4157d3350e | |||
| 08ba185003 | |||
| 7b0e5cd080 | |||
| 66f50d0c0b | |||
| 973d2d6c03 | |||
| fa854b80da | |||
| 05f8bc05ec | |||
| d9af68b910 | |||
| 0c8172880f | |||
| 45559cb809 | |||
| d3e1d94046 | |||
| 2c75396b80 | |||
| 7aae0a9f65 | |||
| bfd6d96ffc | |||
| f4efa47fe7 | |||
| d1fd8b18ad | |||
| 5ee1c0ab42 | |||
| 8d53326021 | |||
| 246afee56e | |||
| 352faf526f | |||
| c183a63c50 | |||
| 9c34432b99 | |||
| 76bc0e27fc | |||
| b2f6d341dd | |||
| 7b5afe805e | |||
| b77a591c45 | |||
| 3adec39b0c | |||
| a0ad6add34 | |||
| 80079c16e8 | |||
| 632ae136d8 | |||
| 88b11ef065 | |||
| 63b89688df | |||
| ab9a4295a0 | |||
| e6ce4eb73e | |||
| 86f122416b | |||
| be91576758 | |||
| 784c2cda5a | |||
| 836de8d233 | |||
| ac01d1986f | |||
| 8a0693d328 | |||
| 2a62ffe32d | |||
| cb895c9710 | |||
| 52a73986bc | |||
| 15582773bd | |||
| fc3435113d | |||
| 801492b708 | |||
| 8c25e5b68e | |||
| 1525da154f | |||
| f2199eebf5 | |||
| 1a761bf6ce | |||
| 21f8b23ade | |||
| 4fc82b97cf | |||
| 721e7359b3 | |||
| 7e0c822451 | |||
| 6d9160ea31 | |||
| 31cc51fe42 | |||
| c85ef81e6b | |||
| ddb29d6ab8 | |||
| d666021572 | |||
| 360d6d87a4 | |||
| 97d3b369d5 | |||
| 7936df3e1e | |||
| eca370792a | |||
| af68514acd | |||
| a0e0f05977 | |||
| 78c09b1e2f | |||
| a2051132b5 | |||
| a67bf40def | |||
| 9b47650b4a | |||
| 748dd4f02c | |||
| 530167cf69 | |||
| 7d6e8853db | |||
| 9f3631f0e9 | |||
| c8253a5018 | |||
| 3aaae7405d | |||
| f2e012119a | |||
| 48b9027842 | |||
| 0511926a4c | |||
| 1ac1a5bb3b | |||
| 6cfe4482f7 | |||
| 61680eacd4 | |||
| 3aef3818cd | |||
| 355805756e | |||
| 96acf00e81 | |||
| 1ad4fb2eea | |||
| 1dcd65ec71 | |||
| 1109878da0 | |||
| 7a0803f384 | |||
| 8f56d0b38e | |||
| 9309f612ef | |||
| d2b13060fe | |||
| 393a72216e | |||
| 76e50881fb | |||
| 9779ee0fd3 | |||
| 9fdd825681 | |||
| f4f9513f80 | |||
| d35431c888 | |||
| bcb7acf5c2 | |||
| 1e82ed302d | |||
| 1fde8ea6f5 | |||
| dab3a38815 | |||
| c9db8f6bfc | |||
| 3c655836df | |||
| 544b235910 | |||
| bf34bf24ab | |||
| 6b199c52a1 | |||
| 94f667d87f | |||
| 464c3815b9 | |||
| 53732e2276 | |||
| bd554a5808 | |||
| b48051d52f | |||
| 03079a4f4f | |||
| 6daa857c2d | |||
| 5a1f60a7c6 |
@@ -381,7 +381,13 @@ bool S3D_CACHE::getSHA1( const wxString& aFileName, unsigned char* aSHA1Sum )
|
||||
|
||||
fclose( fp );
|
||||
unsigned int digest[5];
|
||||
dblock.get_digest( digest );
|
||||
// V8 only
|
||||
// Boost 1.86 and later changed digest_type from uchar[20] from int[5]
|
||||
// But KiCad 8.99 and later use MurmurHash3 here, so just do a fairly ugly cast to keep
|
||||
// this going for another few months.
|
||||
static_assert( sizeof( digest ) == sizeof( boost::uuids::detail::sha1::digest_type& ),
|
||||
"SHA1 digest size mismatch" );
|
||||
dblock.get_digest( reinterpret_cast<boost::uuids::detail::sha1::digest_type&>( digest ) );
|
||||
|
||||
// ensure MSB order
|
||||
for( int i = 0; i < 5; ++i )
|
||||
|
||||
@@ -185,8 +185,12 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
|
||||
for( PCB_TRACK* track : m_board->Tracks() )
|
||||
{
|
||||
if( !Is3dLayerEnabled( track->GetLayer(), visibilityFlags ) ) // Skip non enabled layers
|
||||
// Skip tracks (not vias that are on more than one layer ) on disabled layers
|
||||
if( track->Type() != PCB_VIA_T
|
||||
&& !Is3dLayerEnabled( track->GetLayer(), visibilityFlags ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Note: a PCB_TRACK holds normal segment tracks and also vias circles (that have also
|
||||
// drill values)
|
||||
|
||||
@@ -752,6 +752,11 @@ void EDA_3D_CANVAS::OnLeftDown( wxMouseEvent& event )
|
||||
SetFocus();
|
||||
stop_editingTimeOut_Timer();
|
||||
|
||||
// Ensure m_camera.m_lastPosition (current mouse position) is up to date for
|
||||
// future drag events (can be not the case when left clicking after
|
||||
// opening a context menu)
|
||||
OnMouseMoveCamera( event );
|
||||
|
||||
if( !event.Dragging() && ( m_3d_render_raytracing != nullptr ) )
|
||||
{
|
||||
RAY mouseRay = getRayAtCurrentMousePosition();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
add_library(3d-viewer_navlib STATIC
|
||||
"nl_3d_viewer_plugin.cpp"
|
||||
"nl_3d_viewer_plugin_impl.cpp"
|
||||
"nl_footprint_properties_plugin.cpp"
|
||||
"nl_footprint_properties_plugin_impl.cpp"
|
||||
)
|
||||
|
||||
# 3d-viewer_navlib depends on make_lexer outputs in common
|
||||
|
||||
@@ -25,20 +25,17 @@
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport )
|
||||
: m_impl( nullptr )
|
||||
{
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver
|
||||
&& KIPLATFORM::DRIVERS::Valid3DConnexionDriverVersion() )
|
||||
{
|
||||
m_impl = new NL_3D_VIEWER_PLUGIN_IMPL( aViewport );
|
||||
m_impl = std::make_unique<NL_3D_VIEWER_PLUGIN_IMPL>( aViewport, "KiCAD 3D" );
|
||||
m_impl->Connect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::~NL_3D_VIEWER_PLUGIN()
|
||||
{
|
||||
delete m_impl;
|
||||
}
|
||||
NL_3D_VIEWER_PLUGIN::~NL_3D_VIEWER_PLUGIN() = default;
|
||||
|
||||
|
||||
void NL_3D_VIEWER_PLUGIN::SetFocus( bool focus )
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#ifndef NL_3D_VIEWER_PLUGIN_H_
|
||||
#define NL_3D_VIEWER_PLUGIN_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
// Forward declarations.
|
||||
class EDA_3D_CANVAS;
|
||||
class NL_3D_VIEWER_PLUGIN_IMPL;
|
||||
@@ -54,7 +56,7 @@ public:
|
||||
void SetFocus( bool aFocus = true );
|
||||
|
||||
private:
|
||||
NL_3D_VIEWER_PLUGIN_IMPL* m_impl;
|
||||
std::unique_ptr<NL_3D_VIEWER_PLUGIN_IMPL> m_impl;
|
||||
};
|
||||
|
||||
#endif // NL_3D_VIEWER_PLUGIN_H_
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 3Dconnexion
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2024 3Dconnexion
|
||||
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -27,6 +27,7 @@
|
||||
// KiCAD includes
|
||||
#include <tool/action_manager.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/tools_holder.h>
|
||||
|
||||
// stdlib
|
||||
#include <map>
|
||||
@@ -72,7 +73,7 @@ bool equals( glm::mat<L, C, T, Q> const& aFirst, glm::mat<L, C, T, Q> const& aSe
|
||||
}
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN_IMPL::NL_3D_VIEWER_PLUGIN_IMPL( EDA_3D_CANVAS* aCanvas ) :
|
||||
NL_3D_VIEWER_PLUGIN_IMPL::NL_3D_VIEWER_PLUGIN_IMPL( EDA_3D_CANVAS* aCanvas, const std::string& aProfileHint ) :
|
||||
NAV_3D( false, false ),
|
||||
m_canvas( aCanvas ),
|
||||
m_capIsMoving( false ),
|
||||
@@ -80,12 +81,7 @@ NL_3D_VIEWER_PLUGIN_IMPL::NL_3D_VIEWER_PLUGIN_IMPL( EDA_3D_CANVAS* aCanvas ) :
|
||||
{
|
||||
m_camera = dynamic_cast<TRACK_BALL*>( m_canvas->GetCamera() );
|
||||
|
||||
PutProfileHint( "KiCAD 3D" );
|
||||
|
||||
EnableNavigation( true );
|
||||
PutFrameTimingSource( TimingSource::SpaceMouse );
|
||||
|
||||
exportCommandsAndImages();
|
||||
PutProfileHint( aProfileHint );
|
||||
}
|
||||
|
||||
|
||||
@@ -101,8 +97,19 @@ void NL_3D_VIEWER_PLUGIN_IMPL::SetFocus( bool aFocus )
|
||||
NAV_3D::Write( navlib::focus_k, aFocus );
|
||||
}
|
||||
|
||||
// temporary store for the categories
|
||||
typedef std::map<std::string, TDx::CCommandTreeNode*> CATEGORY_STORE;
|
||||
|
||||
EDA_3D_CANVAS* NL_3D_VIEWER_PLUGIN_IMPL::GetCanvas() const
|
||||
{
|
||||
return m_canvas;
|
||||
}
|
||||
|
||||
|
||||
void NL_3D_VIEWER_PLUGIN_IMPL::Connect()
|
||||
{
|
||||
EnableNavigation(true);
|
||||
PutFrameTimingSource(TimingSource::SpaceMouse);
|
||||
exportCommandsAndImages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a category to the store.
|
||||
@@ -571,7 +578,7 @@ long NL_3D_VIEWER_PLUGIN_IMPL::SetActiveCommand( std::string commandId )
|
||||
|
||||
if( parent->IsEnabled() )
|
||||
{
|
||||
TOOL_MANAGER* tool_manager = static_cast<PCB_BASE_FRAME*>( parent )->GetToolManager();
|
||||
TOOL_MANAGER* tool_manager = dynamic_cast<TOOLS_HOLDER*>( parent )->GetToolManager();
|
||||
|
||||
if( tool_manager == nullptr )
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 3Dconnexion
|
||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2024 3Dconnexion
|
||||
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -42,6 +42,11 @@
|
||||
class EDA_3D_CANVAS;
|
||||
class TRACK_BALL;
|
||||
|
||||
// temporary store for the categories
|
||||
typedef std::map<std::string, TDx::CCommandTreeNode*> CATEGORY_STORE;
|
||||
|
||||
CATEGORY_STORE::iterator add_category( std::string aCategoryPath, CATEGORY_STORE& aCategoryStore );
|
||||
|
||||
// Convenience typedef.
|
||||
typedef TDx::SpaceMouse::Navigation3D::CNavigation3D NAV_3D;
|
||||
|
||||
@@ -56,8 +61,9 @@ public:
|
||||
* Initializes a new instance of the NL_3DVIEWER_PLUGIN.
|
||||
*
|
||||
* @param aCanvas is the viewport to be navigated.
|
||||
* @param aProfileHint tells the 3DConnexion UI which profile to use.
|
||||
*/
|
||||
NL_3D_VIEWER_PLUGIN_IMPL( EDA_3D_CANVAS* aCanvas );
|
||||
NL_3D_VIEWER_PLUGIN_IMPL( EDA_3D_CANVAS* aCanvas, const std::string& aProfileHint );
|
||||
|
||||
virtual ~NL_3D_VIEWER_PLUGIN_IMPL();
|
||||
|
||||
@@ -69,11 +75,21 @@ public:
|
||||
*/
|
||||
void SetFocus( bool aFocus = true );
|
||||
|
||||
/**
|
||||
* Get the m_canvas pointer.
|
||||
*/
|
||||
EDA_3D_CANVAS* GetCanvas() const;
|
||||
|
||||
/**
|
||||
* Connect plugin implementation to the driver.
|
||||
*/
|
||||
void Connect();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Export the invocable actions and images to the 3Dconnexion UI.
|
||||
*/
|
||||
void exportCommandsAndImages();
|
||||
virtual void exportCommandsAndImages();
|
||||
|
||||
long GetCameraMatrix( navlib::matrix_t& aMatrix ) const override;
|
||||
long GetPointerPosition( navlib::point_t& aPosition ) const override;
|
||||
@@ -111,6 +127,7 @@ private:
|
||||
long GetCoordinateSystem( navlib::matrix_t& aMatrix ) const override;
|
||||
long GetIsViewRotatable( navlib::bool_t& isRotatable ) const override;
|
||||
|
||||
|
||||
private:
|
||||
EDA_3D_CANVAS* m_canvas;
|
||||
TRACK_BALL* m_camera;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 3Dconnexion
|
||||
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "nl_footprint_properties_plugin.h"
|
||||
#include "nl_footprint_properties_plugin_impl.h"
|
||||
#include <advanced_config.h>
|
||||
#include <kiplatform/drivers.h>
|
||||
|
||||
|
||||
NL_FOOTPRINT_PROPERTIES_PLUGIN::NL_FOOTPRINT_PROPERTIES_PLUGIN( EDA_3D_CANVAS* aViewport )
|
||||
{
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver
|
||||
&& KIPLATFORM::DRIVERS::Valid3DConnexionDriverVersion() )
|
||||
{
|
||||
m_impl = std::make_unique<NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL>( aViewport );
|
||||
m_impl->Connect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NL_FOOTPRINT_PROPERTIES_PLUGIN::~NL_FOOTPRINT_PROPERTIES_PLUGIN() = default;
|
||||
|
||||
|
||||
void NL_FOOTPRINT_PROPERTIES_PLUGIN::SetFocus( bool focus )
|
||||
{
|
||||
if( m_impl )
|
||||
m_impl->SetFocus( focus );
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 3Dconnexion
|
||||
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file nl_footprint_properties_plugin.h
|
||||
* @brief declaration of the nl_footprint_properties_plugin class
|
||||
*/
|
||||
|
||||
#ifndef NL_FOOTPRINT_PROPERTIES_PLUGIN_H_
|
||||
#define NL_FOOTPRINT_PROPERTIES_PLUGIN_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
// Forward declarations.
|
||||
class EDA_3D_CANVAS;
|
||||
class NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL;
|
||||
|
||||
/**
|
||||
* The class that implements the public interface to the SpaceMouse plug-in.
|
||||
*/
|
||||
class NL_FOOTPRINT_PROPERTIES_PLUGIN
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initializes a new instance of the NL_FOOTPRINT_PROPERTIES_PLUGIN.
|
||||
*
|
||||
* @param aViewport is the viewport to be navigated.
|
||||
*/
|
||||
NL_FOOTPRINT_PROPERTIES_PLUGIN( EDA_3D_CANVAS* aViewport );
|
||||
|
||||
virtual ~NL_FOOTPRINT_PROPERTIES_PLUGIN();
|
||||
|
||||
/**
|
||||
* Set the connection to the 3Dconnexion driver to the focus state so that
|
||||
* 3DMouse data is routed here.
|
||||
*
|
||||
* @param aFocus is true to set the connection active.
|
||||
*/
|
||||
void SetFocus( bool aFocus = true );
|
||||
|
||||
private:
|
||||
std::unique_ptr<NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL> m_impl;
|
||||
};
|
||||
|
||||
#endif // NL_FOOTPRINT_PROPERTIES_PLUGIN_H_
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 3Dconnexion
|
||||
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "nl_footprint_properties_plugin_impl.h"
|
||||
#include <3d-viewer/3d_canvas/eda_3d_canvas.h>
|
||||
|
||||
// KiCAD includes
|
||||
#include <tool/action_manager.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/tools_holder.h>
|
||||
|
||||
#include <wx/mstream.h>
|
||||
|
||||
#define BOUNDING_BOX_SCALE_FACTOR 1.3f
|
||||
|
||||
/**
|
||||
* Flag to enable the NL_FOOTPRINT_PROPERTIES_PLUGIN debug tracing.
|
||||
*
|
||||
* Use "KI_TRACE_NL_FOOTPRINT_PROPERTIES_PLUGIN" to enable.
|
||||
*
|
||||
* @ingroup trace_env_vars
|
||||
*/
|
||||
const wxChar* NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL::m_logTrace =
|
||||
wxT( "KI_TRACE_NL_FOOTPRINT_PROPERTIES_PLUGIN" );
|
||||
|
||||
|
||||
NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL::NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL(EDA_3D_CANVAS* aCanvas) :
|
||||
NL_3D_VIEWER_PLUGIN_IMPL(aCanvas, "KiCAD Footprint Properties")
|
||||
{}
|
||||
|
||||
|
||||
long NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL::GetModelExtents( navlib::box_t& extents ) const
|
||||
{
|
||||
SFVEC3F min = NL_3D_VIEWER_PLUGIN_IMPL::GetCanvas()->GetBoardAdapter().GetBBox().Min();
|
||||
SFVEC3F max = NL_3D_VIEWER_PLUGIN_IMPL::GetCanvas()->GetBoardAdapter().GetBBox().Max();
|
||||
|
||||
SFVEC3F diff = ( BOUNDING_BOX_SCALE_FACTOR - 1.f ) / 2.f * ( max - min );
|
||||
|
||||
min -= diff;
|
||||
max += diff;
|
||||
|
||||
extents = { min.x, min.y, min.z, max.x, max.y, max.z };
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL::exportCommandsAndImages()
|
||||
{
|
||||
std::list<TOOL_ACTION*> actions = ACTION_MANAGER::GetActionList();
|
||||
|
||||
if( actions.size() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using TDx::SpaceMouse::CCommand;
|
||||
using TDx::SpaceMouse::CCommandSet;
|
||||
|
||||
// The root action set node
|
||||
CCommandSet commandSet( "EDA_3D_CANVAS", "3D Viewer" );
|
||||
|
||||
// Activate the command set
|
||||
NAV_3D::PutActiveCommands( commandSet.GetId() );
|
||||
|
||||
// temporary store for the categories
|
||||
CATEGORY_STORE categoryStore;
|
||||
|
||||
std::vector<TDx::CImage> vImages;
|
||||
|
||||
// add the action set to the category_store
|
||||
categoryStore.insert( categoryStore.end(), CATEGORY_STORE::value_type( ".", &commandSet ) );
|
||||
|
||||
std::list<TOOL_ACTION*>::const_iterator it;
|
||||
|
||||
for( it = actions.begin(); it != actions.end(); ++it )
|
||||
{
|
||||
const TOOL_ACTION* action = *it;
|
||||
std::string label = action->GetMenuLabel().ToStdString();
|
||||
|
||||
if( label.empty() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string name = action->GetName();
|
||||
|
||||
// Do no export commands for the pcbnew app.
|
||||
if( name.rfind( "pcbnew.", 0 ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Exclude commands which can't be used in the footprint properties.
|
||||
if( name.rfind( "3DViewer.Control.pivotCenter", 0 ) == 0
|
||||
|| name.rfind( "3DViewer.Control.material", 0 ) == 0
|
||||
|| name.rfind( "3DViewer.Control.attribute", 0 ) == 0
|
||||
|| name.rfind( "3DViewer.Control.show", 0 ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string strCategory = action->GetToolName();
|
||||
CATEGORY_STORE::iterator iter = categoryStore.find( strCategory );
|
||||
|
||||
if( iter == categoryStore.end() )
|
||||
{
|
||||
iter = add_category( std::move( strCategory ), categoryStore );
|
||||
}
|
||||
|
||||
std::string description = action->GetDescription().ToStdString();
|
||||
|
||||
// Arbitrary 8-bit data stream
|
||||
wxMemoryOutputStream imageStream;
|
||||
|
||||
if( action->GetIcon() != BITMAPS::INVALID_BITMAP )
|
||||
{
|
||||
wxImage image = KiBitmap( action->GetIcon() ).ConvertToImage();
|
||||
image.SaveFile( imageStream, wxBitmapType::wxBITMAP_TYPE_PNG );
|
||||
image.Destroy();
|
||||
|
||||
if( imageStream.GetSize() )
|
||||
{
|
||||
wxStreamBuffer* streamBuffer = imageStream.GetOutputStreamBuffer();
|
||||
TDx::CImage tdxImage = TDx::CImage::FromData( "", 0, name.c_str() );
|
||||
tdxImage.AssignImage( std::string( reinterpret_cast<const char*>(
|
||||
streamBuffer->GetBufferStart() ),
|
||||
streamBuffer->GetBufferSize() ),
|
||||
0 );
|
||||
|
||||
wxLogTrace( m_logTrace, wxT( "Adding image for : %s" ), name );
|
||||
vImages.push_back( std::move( tdxImage ) );
|
||||
}
|
||||
}
|
||||
|
||||
wxLogTrace( m_logTrace, wxT( "Inserting command: %s, description: %s, in category: %s" ),
|
||||
name, description, iter->first );
|
||||
|
||||
iter->second->push_back(
|
||||
CCommand( std::move( name ), std::move( label ), std::move( description ) ) );
|
||||
}
|
||||
|
||||
NAV_3D::AddCommandSet( commandSet );
|
||||
NAV_3D::AddImages( vImages );
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 3Dconnexion
|
||||
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file nl_footprint_properties_plugin_impl.h
|
||||
* @brief declaration of the nl_footprint_properties_plugin_impl class
|
||||
*/
|
||||
|
||||
#ifndef NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL_H_
|
||||
#define NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL_H_
|
||||
|
||||
#include "nl_3d_viewer_plugin_impl.h"
|
||||
// TDxWare SDK.
|
||||
#include <SpaceMouse/CNavigation3D.hpp>
|
||||
|
||||
/**
|
||||
* The class that adjusts NL_3D_VIEWER_PLUGIN_IMPL implementation for 3D Model preview in footprint properties dialog.
|
||||
*/
|
||||
class NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL : public NL_3D_VIEWER_PLUGIN_IMPL
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initializes a new instance of the NL_FOOTPRINT_PROPERTIES_PLUGIN.
|
||||
*
|
||||
* @param aCanvas is the viewport to be navigated.
|
||||
*/
|
||||
NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL( EDA_3D_CANVAS* aCanvas );
|
||||
|
||||
private:
|
||||
/**
|
||||
* Get Footprint 3D Model extents.
|
||||
*
|
||||
* @param extents is the box around the 3D model.
|
||||
*/
|
||||
long GetModelExtents( navlib::box_t& extents ) const override;
|
||||
|
||||
/**
|
||||
* Export the invocable actions and images to the 3Dconnexion UI.
|
||||
*/
|
||||
void exportCommandsAndImages() override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Trace mask used to enable or disable the trace output of this class.
|
||||
* The debug output can be turned on by setting the WXTRACE environment variable to
|
||||
* "KI_TRACE_NL_FOOTPRINT_PROPERTIES_PLUGIN". See the wxWidgets documentation on wxLogTrace for
|
||||
* more information.
|
||||
*/
|
||||
static const wxChar* m_logTrace;
|
||||
};
|
||||
#endif // NL_FOOTPRINT_PROPERTIES_PLUGIN_IMPL_H_
|
||||
@@ -570,6 +570,9 @@ void EDA_3D_VIEWER_FRAME::LoadSettings( APP_SETTINGS_BASE *aCfg )
|
||||
{
|
||||
applySettings( cfg );
|
||||
|
||||
if( !GetBoard()->GetProject() )
|
||||
GetBoard()->SetProject( &Prj() );
|
||||
|
||||
m_boardAdapter.SetBoard( GetBoard() );
|
||||
|
||||
// When opening the 3D viewer, we use the OpenGL mode, never the ray tracing engine
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include <eda_3d_viewer_settings.h>
|
||||
#include <board_design_settings.h>
|
||||
|
||||
#include <3d_navlib/nl_footprint_properties_plugin.h>
|
||||
|
||||
PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAME* aFrame,
|
||||
FOOTPRINT* aFootprint,
|
||||
std::vector<FP_3DMODEL>* aParentModelList ) :
|
||||
@@ -125,6 +127,9 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
OGL_ATT_LIST::GetAttributesList( ANTIALIASING_MODE::AA_8X ),
|
||||
m_boardAdapter, m_currentCamera, PROJECT_PCB::Get3DCacheManager( &aFrame->Prj() ) );
|
||||
|
||||
m_spaceMouse = new NL_FOOTPRINT_PROPERTIES_PLUGIN( m_previewPane );
|
||||
m_spaceMouse->SetFocus( true );
|
||||
|
||||
m_boardAdapter.SetBoard( m_dummyBoard );
|
||||
m_boardAdapter.m_IsBoardView = false;
|
||||
m_boardAdapter.m_IsPreviewer = true; // Force display 3D models, regardless the 3D viewer options
|
||||
@@ -162,6 +167,8 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL::onUnitsChanged ),
|
||||
nullptr, this );
|
||||
|
||||
Bind( wxCUSTOM_PANEL_SHOWN_EVENT, &PANEL_PREVIEW_3D_MODEL::onPanelShownEvent, this );
|
||||
|
||||
#ifdef __WXOSX__
|
||||
// Call layout once to get the proper button sizes after the bitmaps have been set
|
||||
Layout();
|
||||
@@ -190,6 +197,7 @@ PANEL_PREVIEW_3D_MODEL::~PANEL_PREVIEW_3D_MODEL()
|
||||
if( m_boardAdapter.m_Cfg )
|
||||
m_boardAdapter.m_Cfg->m_Render = m_initialRender;
|
||||
|
||||
delete m_spaceMouse;
|
||||
delete m_dummyBoard;
|
||||
delete m_previewPane;
|
||||
}
|
||||
@@ -620,6 +628,17 @@ void PANEL_PREVIEW_3D_MODEL::onUnitsChanged( wxCommandEvent& aEvent )
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::onPanelShownEvent( wxCommandEvent& aEvent )
|
||||
{
|
||||
if( m_spaceMouse != nullptr )
|
||||
{
|
||||
m_spaceMouse->SetFocus( static_cast<bool>( aEvent.GetInt() ) );
|
||||
}
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::UpdateDummyFootprint( bool aReloadRequired )
|
||||
{
|
||||
m_dummyFootprint->Models().clear();
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <3d_canvas/eda_3d_canvas.h>
|
||||
#include <3d_viewer_id.h>
|
||||
#include <3d_rendering/track_ball.h>
|
||||
#include <wx/event.h>
|
||||
|
||||
// Define min and max parameter values
|
||||
#define MAX_SCALE 10000.0
|
||||
@@ -52,6 +53,7 @@
|
||||
#define OFFSET_INCREMENT_MIL 25.0
|
||||
#define OFFSET_INCREMENT_MIL_FINE 5.0
|
||||
|
||||
wxDECLARE_EVENT( wxCUSTOM_PANEL_SHOWN_EVENT, wxCommandEvent );
|
||||
|
||||
// Declared classes to create pointers
|
||||
class WX_INFOBAR;
|
||||
@@ -60,6 +62,7 @@ class FILENAME_RESOLVER;
|
||||
class BOARD;
|
||||
class BOARD_ADAPTER;
|
||||
class FOOTPRINT;
|
||||
class NL_FOOTPRINT_PROPERTIES_PLUGIN;
|
||||
|
||||
class PANEL_PREVIEW_3D_MODEL: public EDA_3D_BOARD_HOLDER, public TOOLS_HOLDER, public PANEL_PREVIEW_3D_MODEL_BASE
|
||||
{
|
||||
@@ -139,6 +142,7 @@ private:
|
||||
void doIncrementOffset( wxSpinEvent& aEvent, double aSign );
|
||||
|
||||
void onUnitsChanged( wxCommandEvent& aEvent );
|
||||
void onPanelShownEvent( wxCommandEvent& aEvent );
|
||||
|
||||
wxString formatScaleValue( double aValue );
|
||||
wxString formatRotationValue( double aValue );
|
||||
@@ -211,6 +215,8 @@ private:
|
||||
bool m_bodyStyleShowAll; /// true if the board body is show
|
||||
/// The 3d viewer Render initial settings (must be saved and restored)
|
||||
EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS m_initialRender;
|
||||
|
||||
NL_FOOTPRINT_PROPERTIES_PLUGIN* m_spaceMouse;
|
||||
};
|
||||
|
||||
#endif // PANEL_PREVIEW_3D_MODEL_H
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "8.0.5" )
|
||||
set( KICAD_SEMANTIC_VERSION "8.0.7" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -109,6 +109,7 @@ static const wxChar OcePluginAngularDeflection[] = wxT( "OcePluginAngularDeflect
|
||||
static const wxChar TriangulateSimplificationLevel[] = wxT( "TriangulateSimplificationLevel" );
|
||||
static const wxChar TriangulateMinimumArea[] = wxT( "TriangulateMinimumArea" );
|
||||
static const wxChar EnableCacheFriendlyFracture[] = wxT( "EnableCacheFriendlyFracture" );
|
||||
static const wxChar MinParallelAngle[] = wxT( "MinParallelAngle" );
|
||||
} // namespace KEYS
|
||||
|
||||
|
||||
@@ -261,6 +262,8 @@ ADVANCED_CFG::ADVANCED_CFG()
|
||||
|
||||
m_EnableCacheFriendlyFracture = true;
|
||||
|
||||
m_MinParallelAngle = 0.001;
|
||||
|
||||
loadFromConfigFile();
|
||||
}
|
||||
|
||||
@@ -477,6 +480,10 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
|
||||
&m_EnableCacheFriendlyFracture,
|
||||
m_EnableCacheFriendlyFracture ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::MinParallelAngle,
|
||||
&m_MinParallelAngle, m_MinParallelAngle,
|
||||
0.0, 45.0 ) );
|
||||
|
||||
// Special case for trace mask setting...we just grab them and set them immediately
|
||||
// Because we even use wxLogTrace inside of advanced config
|
||||
wxString traceMasks;
|
||||
|
||||
@@ -162,6 +162,9 @@ void COMMIT::makeEntry( EDA_ITEM* aItem, CHANGE_TYPE aType, EDA_ITEM* aCopy, BAS
|
||||
ent.m_copy = aCopy;
|
||||
ent.m_screen = aScreen;
|
||||
|
||||
// N.B. Do not throw an assertion for multiple changed items. An item can be changed multiple times
|
||||
// in a single commit such as when importing graphics and grouping them.
|
||||
|
||||
m_changedItems.insert( aItem );
|
||||
m_changes.push_back( ent );
|
||||
}
|
||||
|
||||
+3
-10
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2014-2020 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -347,18 +347,11 @@ const wxString ExpandEnvVarSubstitutions( const wxString& aString, const PROJECT
|
||||
}
|
||||
|
||||
|
||||
const wxString ResolveUriByEnvVars( const wxString& aUri, PROJECT* aProject )
|
||||
const wxString ResolveUriByEnvVars( const wxString& aUri, const PROJECT* aProject )
|
||||
{
|
||||
wxString uri = ExpandTextVars( aUri, aProject );
|
||||
|
||||
// URL-like URI: return as is.
|
||||
wxURL url( uri );
|
||||
|
||||
if( url.GetError() == wxURL_NOERR )
|
||||
return uri;
|
||||
|
||||
// Otherwise, the path points to a local file. Resolve environment variables if any.
|
||||
return ExpandEnvVarSubstitutions( aUri, aProject );
|
||||
return ExpandEnvVarSubstitutions( uri, aProject );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -106,6 +106,9 @@ DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
|
||||
|
||||
table.properties.exclude_from_board =
|
||||
fetchOrDefault<std::string>( pj, "exclude_from_board" );
|
||||
|
||||
table.properties.exclude_from_sim =
|
||||
fetchOrDefault<std::string>( pj, "exclude_from_sim" );
|
||||
}
|
||||
|
||||
if( entry.contains( "fields" ) && entry["fields"].is_array() )
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2018-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <wx/dcmemory.h>
|
||||
|
||||
#define ALPHA_MAX 100 // the max value returned by the alpha (opacity) slider
|
||||
#define SLOPE_AXIS ( bmsize.y / 5.28 ) // was 50 at 264 size
|
||||
|
||||
using KIGFX::COLOR4D;
|
||||
|
||||
@@ -52,13 +53,17 @@ DIALOG_COLOR_PICKER::DIALOG_COLOR_PICKER( wxWindow* aParent, const COLOR4D& aCur
|
||||
m_allowOpacityCtrl = aAllowOpacityControl;
|
||||
m_previousColor4D = aCurrentColor;
|
||||
m_newColor4D = aCurrentColor;
|
||||
m_cursorsSize = 8; // Size of square cursors drawn on color bitmaps
|
||||
m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
|
||||
m_bitmapRGB = nullptr;
|
||||
m_bitmapHSV = nullptr;
|
||||
m_selectedCursor = nullptr;
|
||||
m_defaultColor = aDefaultColor;
|
||||
|
||||
updateHandleSize();
|
||||
|
||||
m_OldColorRect->SetMinSize( FromDIP( wxSize( 24, 24 ) ) );
|
||||
m_NewColorRect->SetMinSize( FromDIP( wxSize( 24, 24 ) ) );
|
||||
|
||||
if( !m_allowOpacityCtrl )
|
||||
{
|
||||
m_SizerTransparency->Show( false );
|
||||
@@ -121,16 +126,15 @@ void DIALOG_COLOR_PICKER::updatePreview( wxStaticBitmap* aStaticBitmap, COLOR4D&
|
||||
wxBitmap newBm = COLOR_SWATCH::MakeBitmap( aColor4D, COLOR4D::WHITE, aStaticBitmap->GetSize(),
|
||||
ConvertDialogToPixels( CHECKERBOARD_SIZE_DU ),
|
||||
aStaticBitmap->GetParent()->GetBackgroundColour() );
|
||||
|
||||
newBm.SetScaleFactor( GetDPIScaleFactor() );
|
||||
aStaticBitmap->SetBitmap( newBm );
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_COLOR_PICKER::TransferDataToWindow()
|
||||
{
|
||||
// Draw all bitmaps, with colors according to the color 4D
|
||||
updatePreview( m_OldColorRect, m_previousColor4D );
|
||||
SetEditVals( ALL_CHANGED, false );
|
||||
drawAll();
|
||||
|
||||
// Configure the spin control sizes
|
||||
configureSpinCtrl( m_spinCtrlGreen );
|
||||
@@ -144,6 +148,10 @@ bool DIALOG_COLOR_PICKER::TransferDataToWindow()
|
||||
|
||||
finishDialogSettings();
|
||||
|
||||
// Draw all bitmaps, with colors according to the color 4D
|
||||
updatePreview( m_OldColorRect, m_previousColor4D );
|
||||
drawAll();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -171,6 +179,8 @@ void DIALOG_COLOR_PICKER::initDefinedColors( CUSTOM_COLORS_LIST* aPredefinedColo
|
||||
{
|
||||
wxBitmap bm = COLOR_SWATCH::MakeBitmap( aColor, COLOR4D::WHITE, swatchSize,
|
||||
checkerboardSize, checkboardBackground );
|
||||
|
||||
bm.SetScaleFactor( GetDPIScaleFactor() );
|
||||
wxStaticBitmap* swatch = new wxStaticBitmap( m_panelDefinedColors, aId, bm );
|
||||
|
||||
m_fgridColor->Add( swatch, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
@@ -245,7 +255,6 @@ void DIALOG_COLOR_PICKER::createRGBBitmap()
|
||||
|
||||
// Red blue area in X Z 3d axis
|
||||
double inc = 255.0 / half_size;
|
||||
#define SLOPE_AXIS 50.0
|
||||
double slope = SLOPE_AXIS/half_size;
|
||||
color.g = 0.0;
|
||||
|
||||
@@ -315,6 +324,7 @@ void DIALOG_COLOR_PICKER::createRGBBitmap()
|
||||
|
||||
delete m_bitmapRGB;
|
||||
m_bitmapRGB = new wxBitmap( img, 24 );
|
||||
m_bitmapRGB->SetScaleFactor( m_RgbBitmap->GetDPIScaleFactor() );
|
||||
m_RgbBitmap->SetBitmap( *m_bitmapRGB );
|
||||
}
|
||||
|
||||
@@ -379,6 +389,7 @@ void DIALOG_COLOR_PICKER::createHSVBitmap()
|
||||
|
||||
delete m_bitmapHSV;
|
||||
m_bitmapHSV = new wxBitmap( img, 24 );
|
||||
m_bitmapHSV->SetScaleFactor( m_HsvBitmap->GetDPIScaleFactor() );
|
||||
m_HsvBitmap->SetBitmap( *m_bitmapHSV );
|
||||
}
|
||||
|
||||
@@ -413,8 +424,7 @@ void DIALOG_COLOR_PICKER::drawRGBPalette()
|
||||
bitmapDC.SetBrush( brush );
|
||||
int half_csize = m_cursorsSize / 2;
|
||||
|
||||
#define SLOPE_AXIS 50.0
|
||||
double slope = SLOPE_AXIS / half_size;
|
||||
double slope = SLOPE_AXIS / ( half_size );
|
||||
|
||||
// Red axis cursor (Z 3Daxis):
|
||||
m_cursorBitmapRed.x = 0;
|
||||
@@ -539,8 +549,15 @@ void DIALOG_COLOR_PICKER::SetEditVals( CHANGED_COLOR aChanged, bool aCheckTransp
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_COLOR_PICKER::updateHandleSize()
|
||||
{
|
||||
m_cursorsSize = FromDIP( 8 ); // Size of square cursors drawn on color bitmaps
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_COLOR_PICKER::drawAll()
|
||||
{
|
||||
updateHandleSize();
|
||||
m_NewColorRect->Freeze(); // Avoid flicker
|
||||
m_HsvBitmap->Freeze();
|
||||
m_RgbBitmap->Freeze();
|
||||
@@ -699,6 +716,14 @@ void DIALOG_COLOR_PICKER::onHSVMouseDrag( wxMouseEvent& event )
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_COLOR_PICKER::onSize( wxSizeEvent& event )
|
||||
{
|
||||
drawAll();
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_COLOR_PICKER::OnColorValueText( wxCommandEvent& event )
|
||||
{
|
||||
if( m_newColor4D.SetFromHexString( m_colorValue->GetValue() ) )
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version 4.1.0-0-g733bf3d)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -33,7 +33,10 @@ DIALOG_COLOR_PICKER_BASE::DIALOG_COLOR_PICKER_BASE( wxWindow* parent, wxWindowID
|
||||
m_RgbBitmap = new wxStaticBitmap( sbSizerViewRGB->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 264,264 ), 0 );
|
||||
m_RgbBitmap->SetMinSize( wxSize( 264,264 ) );
|
||||
|
||||
sbSizerViewRGB->Add( m_RgbBitmap, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
|
||||
sbSizerViewRGB->Add( m_RgbBitmap, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND|wxSHAPED, 5 );
|
||||
|
||||
|
||||
sbSizerViewRGB->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
wxFlexGridSizer* fgSizerRGB;
|
||||
fgSizerRGB = new wxFlexGridSizer( 0, 3, 0, 0 );
|
||||
@@ -68,18 +71,18 @@ DIALOG_COLOR_PICKER_BASE::DIALOG_COLOR_PICKER_BASE( wxWindow* parent, wxWindowID
|
||||
sbSizerViewRGB->Add( fgSizerRGB, 0, wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizerPanels->Add( sbSizerViewRGB, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
bSizerPanels->Add( sbSizerViewRGB, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
wxStaticBoxSizer* sbSizerViewHSV;
|
||||
sbSizerViewHSV = new wxStaticBoxSizer( new wxStaticBox( m_panelFreeColors, wxID_ANY, _("HSV") ), wxHORIZONTAL );
|
||||
|
||||
wxBoxSizer* bSizer10;
|
||||
bSizer10 = new wxBoxSizer( wxVERTICAL );
|
||||
sbSizerViewHSV = new wxStaticBoxSizer( new wxStaticBox( m_panelFreeColors, wxID_ANY, _("HSV") ), wxVERTICAL );
|
||||
|
||||
m_HsvBitmap = new wxStaticBitmap( sbSizerViewHSV->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 264,264 ), 0 );
|
||||
m_HsvBitmap->SetMinSize( wxSize( 264,264 ) );
|
||||
|
||||
bSizer10->Add( m_HsvBitmap, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
|
||||
sbSizerViewHSV->Add( m_HsvBitmap, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND|wxSHAPED, 5 );
|
||||
|
||||
|
||||
sbSizerViewHSV->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
wxFlexGridSizer* fgSizerHSV;
|
||||
fgSizerHSV = new wxFlexGridSizer( 0, 2, 0, 0 );
|
||||
@@ -103,26 +106,23 @@ DIALOG_COLOR_PICKER_BASE::DIALOG_COLOR_PICKER_BASE( wxWindow* parent, wxWindowID
|
||||
fgSizerHSV->Add( m_spinCtrlSaturation, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
bSizer10->Add( fgSizerHSV, 0, wxEXPAND, 5 );
|
||||
sbSizerViewHSV->Add( fgSizerHSV, 0, wxEXPAND, 5 );
|
||||
|
||||
|
||||
sbSizerViewHSV->Add( bSizer10, 0, wxEXPAND, 5 );
|
||||
bSizerPanels->Add( sbSizerViewHSV, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
wxBoxSizer* bSizerBright;
|
||||
bSizerBright = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_staticTextBright = new wxStaticText( sbSizerViewHSV->GetStaticBox(), wxID_ANY, _("Value:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextBright = new wxStaticText( m_panelFreeColors, wxID_ANY, _("Value:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextBright->Wrap( -1 );
|
||||
bSizerBright->Add( m_staticTextBright, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
|
||||
|
||||
m_sliderBrightness = new wxSlider( sbSizerViewHSV->GetStaticBox(), wxID_ANY, 255, 0, 255, wxDefaultPosition, wxDefaultSize, wxSL_INVERSE|wxSL_LABELS|wxSL_LEFT|wxSL_VERTICAL );
|
||||
m_sliderBrightness = new wxSlider( m_panelFreeColors, wxID_ANY, 255, 0, 255, wxDefaultPosition, wxDefaultSize, wxSL_INVERSE|wxSL_LABELS|wxSL_LEFT|wxSL_VERTICAL );
|
||||
bSizerBright->Add( m_sliderBrightness, 1, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxTOP, 5 );
|
||||
|
||||
|
||||
sbSizerViewHSV->Add( bSizerBright, 0, wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizerPanels->Add( sbSizerViewHSV, 0, wxEXPAND|wxBOTTOM|wxRIGHT, 5 );
|
||||
bSizerPanels->Add( bSizerBright, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizerUpperFreeColors->Add( bSizerPanels, 1, wxEXPAND, 5 );
|
||||
@@ -153,7 +153,7 @@ DIALOG_COLOR_PICKER_BASE::DIALOG_COLOR_PICKER_BASE( wxWindow* parent, wxWindowID
|
||||
m_SizerDefinedColors->Fit( m_panelDefinedColors );
|
||||
m_notebook->AddPage( m_panelDefinedColors, _("Defined Colors"), false );
|
||||
|
||||
bSizerUpperMain->Add( m_notebook, 0, wxEXPAND | wxALL, 5 );
|
||||
bSizerUpperMain->Add( m_notebook, 1, wxEXPAND | wxALL, 5 );
|
||||
|
||||
m_SizerTransparency = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
@@ -171,35 +171,29 @@ DIALOG_COLOR_PICKER_BASE::DIALOG_COLOR_PICKER_BASE( wxWindow* parent, wxWindowID
|
||||
bSizerUpperMain->Add( m_SizerTransparency, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
bSizerUpperMain->Add( 0, 0, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
bSizerMain->Add( bSizerUpperMain, 0, wxEXPAND, 5 );
|
||||
bSizerMain->Add( bSizerUpperMain, 1, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bButtonsSizer;
|
||||
bButtonsSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_staticTextOldColor = new wxStaticText( this, wxID_ANY, _("Preview (old/new):"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextOldColor->Wrap( -1 );
|
||||
bButtonsSizer->Add( m_staticTextOldColor, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
bButtonsSizer->Add( m_staticTextOldColor, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
m_OldColorRect = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), 0 );
|
||||
m_OldColorRect->SetMinSize( wxSize( 24,24 ) );
|
||||
|
||||
bButtonsSizer->Add( m_OldColorRect, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
bButtonsSizer->Add( m_OldColorRect, 0, wxALIGN_CENTER_VERTICAL|wxSHAPED, 5 );
|
||||
|
||||
m_NewColorRect = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), 0 );
|
||||
m_NewColorRect->SetMinSize( wxSize( 24,24 ) );
|
||||
|
||||
bButtonsSizer->Add( m_NewColorRect, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
|
||||
bButtonsSizer->Add( 10, 0, 0, wxEXPAND, 5 );
|
||||
bButtonsSizer->Add( m_NewColorRect, 0, wxALIGN_CENTER_VERTICAL|wxSHAPED, 5 );
|
||||
|
||||
m_colorValue = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_colorValue->SetMinSize( wxSize( 176,-1 ) );
|
||||
|
||||
bButtonsSizer->Add( m_colorValue, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
bButtonsSizer->Add( m_colorValue, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
|
||||
bButtonsSizer->Add( 20, 0, 0, wxEXPAND, 5 );
|
||||
@@ -217,7 +211,7 @@ DIALOG_COLOR_PICKER_BASE::DIALOG_COLOR_PICKER_BASE( wxWindow* parent, wxWindowID
|
||||
bButtonsSizer->Add( m_sdbSizer, 1, wxALL, 5 );
|
||||
|
||||
|
||||
bSizerMain->Add( bButtonsSizer, 1, wxEXPAND|wxLEFT, 10 );
|
||||
bSizerMain->Add( bButtonsSizer, 0, wxEXPAND|wxLEFT, 10 );
|
||||
|
||||
|
||||
this->SetSizer( bSizerMain );
|
||||
@@ -234,6 +228,7 @@ DIALOG_COLOR_PICKER_BASE::DIALOG_COLOR_PICKER_BASE( wxWindow* parent, wxWindowID
|
||||
m_spinCtrlBlue->Connect( wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler( DIALOG_COLOR_PICKER_BASE::OnChangeEditBlue ), NULL, this );
|
||||
m_HsvBitmap->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_COLOR_PICKER_BASE::onHSVMouseClick ), NULL, this );
|
||||
m_HsvBitmap->Connect( wxEVT_MOTION, wxMouseEventHandler( DIALOG_COLOR_PICKER_BASE::onHSVMouseDrag ), NULL, this );
|
||||
m_HsvBitmap->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_COLOR_PICKER_BASE::onSize ), NULL, this );
|
||||
m_spinCtrlHue->Connect( wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler( DIALOG_COLOR_PICKER_BASE::OnChangeEditHue ), NULL, this );
|
||||
m_spinCtrlSaturation->Connect( wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler( DIALOG_COLOR_PICKER_BASE::OnChangeEditSat ), NULL, this );
|
||||
m_sliderBrightness->Connect( wxEVT_SCROLL_TOP, wxScrollEventHandler( DIALOG_COLOR_PICKER_BASE::OnChangeBrightness ), NULL, this );
|
||||
@@ -268,6 +263,7 @@ DIALOG_COLOR_PICKER_BASE::~DIALOG_COLOR_PICKER_BASE()
|
||||
m_spinCtrlBlue->Disconnect( wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler( DIALOG_COLOR_PICKER_BASE::OnChangeEditBlue ), NULL, this );
|
||||
m_HsvBitmap->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_COLOR_PICKER_BASE::onHSVMouseClick ), NULL, this );
|
||||
m_HsvBitmap->Disconnect( wxEVT_MOTION, wxMouseEventHandler( DIALOG_COLOR_PICKER_BASE::onHSVMouseDrag ), NULL, this );
|
||||
m_HsvBitmap->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_COLOR_PICKER_BASE::onSize ), NULL, this );
|
||||
m_spinCtrlHue->Disconnect( wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler( DIALOG_COLOR_PICKER_BASE::OnChangeEditHue ), NULL, this );
|
||||
m_spinCtrlSaturation->Disconnect( wxEVT_COMMAND_SPINCTRL_UPDATED, wxSpinEventHandler( DIALOG_COLOR_PICKER_BASE::OnChangeEditSat ), NULL, this );
|
||||
m_sliderBrightness->Disconnect( wxEVT_SCROLL_TOP, wxScrollEventHandler( DIALOG_COLOR_PICKER_BASE::OnChangeBrightness ), NULL, this );
|
||||
|
||||
+1767
-1752
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version 4.1.0-0-g733bf3d)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -81,6 +81,7 @@ class DIALOG_COLOR_PICKER_BASE : public DIALOG_SHIM
|
||||
virtual void OnChangeEditBlue( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onHSVMouseClick( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onHSVMouseDrag( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void onSize( wxSizeEvent& event ) { event.Skip(); }
|
||||
virtual void OnChangeEditHue( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void OnChangeEditSat( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void OnChangeBrightness( wxScrollEvent& event ) { event.Skip(); }
|
||||
|
||||
@@ -279,7 +279,7 @@ void KIGFX::DS_PAINTER::draw( const DS_DRAW_ITEM_TEXT* aItem, int aLayer ) const
|
||||
if( !font )
|
||||
{
|
||||
font = KIFONT::FONT::GetFont( m_renderSettings.GetDefaultFont(), aItem->IsBold(),
|
||||
aItem->IsItalic() );
|
||||
aItem->IsItalic(), true );
|
||||
}
|
||||
|
||||
const COLOR4D& color = m_renderSettings.GetColor( aItem, aLayer );
|
||||
|
||||
+11
-3
@@ -2070,9 +2070,17 @@ static struct EDA_SHAPE_DESC
|
||||
shapeProps )
|
||||
.SetAvailableFunc( fillAvailable );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, COLOR4D>( _HKI( "Fill Color" ),
|
||||
&EDA_SHAPE::SetFillColor, &EDA_SHAPE::GetFillColor ),
|
||||
shapeProps )
|
||||
auto fillColor = new PROPERTY<EDA_SHAPE, COLOR4D>( _HKI( "Fill Color" ),
|
||||
&EDA_SHAPE::SetFillColor, &EDA_SHAPE::GetFillColor );
|
||||
fillColor->SetWriteableFunc(
|
||||
[=]( INSPECTABLE* aItem ) -> bool
|
||||
{
|
||||
if( EDA_SHAPE* edaShape = dynamic_cast<EDA_SHAPE*>( aItem ) )
|
||||
return edaShape->GetFillMode() == FILL_T::FILLED_WITH_COLOR;
|
||||
|
||||
return true;
|
||||
} );
|
||||
propMgr.AddProperty( fillColor, shapeProps )
|
||||
.SetAvailableFunc( fillAvailable )
|
||||
.SetIsHiddenFromRulesEditor();
|
||||
}
|
||||
|
||||
+50
-4
@@ -212,6 +212,26 @@ void EDA_TEXT::SetTextAngle( const EDA_ANGLE& aAngle )
|
||||
|
||||
|
||||
void EDA_TEXT::SetItalic( bool aItalic )
|
||||
{
|
||||
if( m_attributes.m_Italic != aItalic )
|
||||
{
|
||||
const KIFONT::FONT* font = GetFont();
|
||||
|
||||
if( !font || font->IsStroke() )
|
||||
{
|
||||
// For stroke fonts, just need to set the attribute.
|
||||
}
|
||||
else
|
||||
{
|
||||
// For outline fonts, italic-ness is determined by the font itself.
|
||||
SetFont( KIFONT::FONT::GetFont( font->GetName(), IsBold(), aItalic ) );
|
||||
}
|
||||
}
|
||||
|
||||
SetItalicFlag( aItalic );
|
||||
}
|
||||
|
||||
void EDA_TEXT::SetItalicFlag( bool aItalic )
|
||||
{
|
||||
m_attributes.m_Italic = aItalic;
|
||||
ClearRenderCache();
|
||||
@@ -223,12 +243,38 @@ void EDA_TEXT::SetBold( bool aBold )
|
||||
{
|
||||
if( m_attributes.m_Bold != aBold )
|
||||
{
|
||||
int size = std::min( m_attributes.m_Size.x, m_attributes.m_Size.y );
|
||||
const KIFONT::FONT* font = GetFont();
|
||||
|
||||
if( aBold )
|
||||
m_attributes.m_StrokeWidth = GetPenSizeForBold( size );
|
||||
if( !font || font->IsStroke() )
|
||||
{
|
||||
// For stroke fonts, boldness is determined by the pen size.
|
||||
const int size = std::min( m_attributes.m_Size.x, m_attributes.m_Size.y );
|
||||
|
||||
if( aBold )
|
||||
{
|
||||
m_attributes.m_StoredStrokeWidth = m_attributes.m_StrokeWidth;
|
||||
m_attributes.m_StrokeWidth = GetPenSizeForBold( size );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restore the original stroke width from `m_StoredStrokeWidth` if it was previously stored,
|
||||
// resetting the width after unbolding.
|
||||
if( m_attributes.m_StoredStrokeWidth )
|
||||
m_attributes.m_StrokeWidth = m_attributes.m_StoredStrokeWidth;
|
||||
else
|
||||
{
|
||||
m_attributes.m_StrokeWidth = GetPenSizeForNormal( size );
|
||||
// Sets `m_StrokeWidth` to the normal pen size and stores it in `m_StoredStrokeWidth`
|
||||
// as the default, but only if the bold option was applied before this feature was implemented.
|
||||
m_attributes.m_StoredStrokeWidth = m_attributes.m_StrokeWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_attributes.m_StrokeWidth = GetPenSizeForNormal( size );
|
||||
{
|
||||
// For outline fonts, boldness is determined by the font itself.
|
||||
SetFont( KIFONT::FONT::GetFont( font->GetName(), aBold, IsItalic() ) );
|
||||
}
|
||||
}
|
||||
|
||||
SetBoldFlag( aBold );
|
||||
|
||||
@@ -57,7 +57,7 @@ const METRICS& METRICS::Default()
|
||||
|
||||
FONT* FONT::s_defaultFont = nullptr;
|
||||
|
||||
std::map< std::tuple<wxString, bool, bool>, FONT*> FONT::s_fontMap;
|
||||
std::map< std::tuple<wxString, bool, bool, bool>, FONT*> FONT::s_fontMap;
|
||||
|
||||
class MARKUP_CACHE
|
||||
{
|
||||
@@ -143,12 +143,13 @@ FONT* FONT::getDefaultFont()
|
||||
}
|
||||
|
||||
|
||||
FONT* FONT::GetFont( const wxString& aFontName, bool aBold, bool aItalic )
|
||||
FONT* FONT::GetFont( const wxString& aFontName, bool aBold, bool aItalic,
|
||||
bool aForDrawingSheet )
|
||||
{
|
||||
if( aFontName.empty() || aFontName.StartsWith( KICAD_FONT_NAME ) )
|
||||
return getDefaultFont();
|
||||
|
||||
std::tuple<wxString, bool, bool> key = { aFontName, aBold, aItalic };
|
||||
std::tuple<wxString, bool, bool, bool> key = { aFontName, aBold, aItalic, aForDrawingSheet };
|
||||
|
||||
FONT* font = nullptr;
|
||||
|
||||
@@ -156,7 +157,7 @@ FONT* FONT::GetFont( const wxString& aFontName, bool aBold, bool aItalic )
|
||||
font = s_fontMap[key];
|
||||
|
||||
if( !font )
|
||||
font = OUTLINE_FONT::LoadFont( aFontName, aBold, aItalic );
|
||||
font = OUTLINE_FONT::LoadFont( aFontName, aBold, aItalic, aForDrawingSheet );
|
||||
|
||||
if( !font )
|
||||
font = getDefaultFont();
|
||||
|
||||
@@ -44,7 +44,8 @@ OUTLINE_FONT::OUTLINE_FONT() :
|
||||
m_face(NULL),
|
||||
m_faceSize( 16 ),
|
||||
m_fakeBold( false ),
|
||||
m_fakeItal( false )
|
||||
m_fakeItal( false ),
|
||||
m_forDrawingSheet( false )
|
||||
{
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
@@ -53,7 +54,8 @@ OUTLINE_FONT::OUTLINE_FONT() :
|
||||
}
|
||||
|
||||
|
||||
OUTLINE_FONT* OUTLINE_FONT::LoadFont( const wxString& aFontName, bool aBold, bool aItalic )
|
||||
OUTLINE_FONT* OUTLINE_FONT::LoadFont( const wxString& aFontName, bool aBold, bool aItalic,
|
||||
bool aForDrawingSheet )
|
||||
{
|
||||
std::unique_ptr<OUTLINE_FONT> font = std::make_unique<OUTLINE_FONT>();
|
||||
|
||||
@@ -77,6 +79,7 @@ OUTLINE_FONT* OUTLINE_FONT::LoadFont( const wxString& aFontName, bool aBold, boo
|
||||
|
||||
font->m_fontName = aFontName; // Keep asked-for name, even if we substituted.
|
||||
font->m_fontFileName = fontFile;
|
||||
font->m_forDrawingSheet = aForDrawingSheet;
|
||||
|
||||
return font.release();
|
||||
}
|
||||
@@ -260,6 +263,7 @@ struct GLYPH_CACHE_KEY {
|
||||
FT_Face face;
|
||||
hb_codepoint_t codepoint;
|
||||
double scaler;
|
||||
bool forDrawingSheet;
|
||||
bool fakeItalic;
|
||||
bool fakeBold;
|
||||
bool mirror;
|
||||
@@ -267,9 +271,14 @@ struct GLYPH_CACHE_KEY {
|
||||
|
||||
bool operator==(const GLYPH_CACHE_KEY& rhs ) const
|
||||
{
|
||||
return face == rhs.face && codepoint == rhs.codepoint && scaler == rhs.scaler
|
||||
&& fakeItalic == rhs.fakeItalic && fakeBold == rhs.fakeBold
|
||||
&& mirror == rhs.mirror && angle == rhs.angle;
|
||||
return face == rhs.face
|
||||
&& codepoint == rhs.codepoint
|
||||
&& scaler == rhs.scaler
|
||||
&& forDrawingSheet == rhs.forDrawingSheet
|
||||
&& fakeItalic == rhs.fakeItalic
|
||||
&& fakeBold == rhs.fakeBold
|
||||
&& mirror == rhs.mirror
|
||||
&& angle == rhs.angle;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -280,10 +289,14 @@ namespace std
|
||||
{
|
||||
std::size_t operator()( const GLYPH_CACHE_KEY& k ) const
|
||||
{
|
||||
return hash<const void*>()( k.face ) ^ hash<unsigned>()( k.codepoint )
|
||||
return hash<const void*>()( k.face )
|
||||
^ hash<unsigned>()( k.codepoint )
|
||||
^ hash<double>()( k.scaler )
|
||||
^ hash<int>()( k.fakeItalic ) ^ hash<int>()( k.fakeBold )
|
||||
^ hash<int>()( k.mirror ) ^ hash<int>()( k.angle.AsTenthsOfADegree() );
|
||||
^ hash<double>()( k.forDrawingSheet )
|
||||
^ hash<int>()( k.fakeItalic )
|
||||
^ hash<int>()( k.fakeBold )
|
||||
^ hash<int>()( k.mirror )
|
||||
^ hash<int>()( k.angle.AsTenthsOfADegree() );
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -341,8 +354,8 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
GLYPH_CACHE_KEY key = { face, glyphInfo[i].codepoint, scaler, m_fakeItal, m_fakeBold,
|
||||
aMirror, aAngle };
|
||||
GLYPH_CACHE_KEY key = { face, glyphInfo[i].codepoint, scaler, m_forDrawingSheet,
|
||||
m_fakeItal, m_fakeBold, aMirror, aAngle };
|
||||
GLYPH_DATA& glyphData = s_glyphCache[ key ];
|
||||
|
||||
if( glyphData.m_Contours.empty() )
|
||||
@@ -439,6 +452,8 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
|
||||
for( SHAPE_LINE_CHAIN& hole : holes )
|
||||
{
|
||||
bool added_hole = false;
|
||||
|
||||
if( hole.PointCount() )
|
||||
{
|
||||
for( int ii = 0; ii < glyph->OutlineCount(); ++ii )
|
||||
@@ -446,9 +461,15 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
if( glyph->Outline( ii ).PointInside( hole.GetPoint( 0 ) ) )
|
||||
{
|
||||
glyph->AddHole( std::move( hole ), ii );
|
||||
added_hole = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Some lovely TTF fonts decided that winding didn't matter for outlines that
|
||||
// don't have holes, so holes that don't fit in any outline are added as outlines
|
||||
if( !added_hole )
|
||||
glyph->AddOutline( std::move( hole ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ TEXT_ATTRIBUTES::TEXT_ATTRIBUTES( KIFONT::FONT* aFont ) :
|
||||
m_Visible( true ),
|
||||
m_Mirrored( false ),
|
||||
m_Multiline( true ),
|
||||
m_KeepUpright( false )
|
||||
m_KeepUpright( false ),
|
||||
m_StoredStrokeWidth( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1828,7 +1828,7 @@ void CAIRO_GAL_BASE::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTota
|
||||
for( const std::vector<VECTOR2D>& pointList : glyph )
|
||||
drawPoly( pointList );
|
||||
}
|
||||
else if( aGlyph.IsOutline() )
|
||||
else if( aGlyph.IsOutline() )
|
||||
{
|
||||
const KIFONT::OUTLINE_GLYPH& glyph = static_cast<const KIFONT::OUTLINE_GLYPH&>( aGlyph );
|
||||
|
||||
@@ -1866,15 +1866,9 @@ void CAIRO_GAL_BASE::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTota
|
||||
|
||||
if( aNth == aTotal - 1 )
|
||||
{
|
||||
/*
|
||||
cairo_close_path( currentContext );
|
||||
setSourceRgba( currentContext, fillColor );
|
||||
cairo_set_fill_rule( currentContext, CAIRO_FILL_RULE_EVEN_ODD );
|
||||
cairo_fill_preserve( currentContext );
|
||||
setSourceRgba( currentContext, strokeColor );
|
||||
cairo_stroke( currentContext );
|
||||
*/
|
||||
flushPath();
|
||||
SetIsFill( false );
|
||||
SetIsStroke( true );
|
||||
m_isElementAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
+16
-1
@@ -693,7 +693,14 @@ void GRID_TRICKS::paste_clipboard()
|
||||
|
||||
wxTheClipboard->GetData( data );
|
||||
|
||||
paste_text( data.GetText() );
|
||||
wxString text = data.GetText();
|
||||
|
||||
#ifdef __WXMAC__
|
||||
// Some editors use windows linefeeds (\r\n), which wx re-writes to \n\n
|
||||
text.Replace( "\n\n", "\n" );
|
||||
#endif
|
||||
|
||||
paste_text( text );
|
||||
}
|
||||
|
||||
wxTheClipboard->Close();
|
||||
@@ -802,6 +809,14 @@ void GRID_TRICKS::paste_text( const wxString& cb_text )
|
||||
{
|
||||
tbl->SetValue( row, col, cellTxt );
|
||||
|
||||
wxGridEvent evt( m_grid->GetId(), wxEVT_GRID_CELL_CHANGED, m_grid, row, col );
|
||||
m_grid->GetEventHandler()->ProcessEvent( evt );
|
||||
}
|
||||
// Allow paste to any cell that can accept a boolean value
|
||||
else if( tbl->CanSetValueAs( row, col, wxGRID_VALUE_BOOL ) )
|
||||
{
|
||||
tbl->SetValueAsBool( row, col, cellTxt == wxT( "1" ) );
|
||||
|
||||
wxGridEvent evt( m_grid->GetId(), wxEVT_GRID_CELL_CHANGED, m_grid, row, col );
|
||||
m_grid->GetEventHandler()->ProcessEvent( evt );
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ DXF_IMPORT_PLUGIN::DXF_IMPORT_PLUGIN() : DL_CreationAdapter()
|
||||
m_brdLayer = Dwgs_User; // The default import layer
|
||||
m_importAsFPShapes = true;
|
||||
m_minX = m_minY = std::numeric_limits<double>::max();
|
||||
m_maxX = m_maxY = std::numeric_limits<double>::min();
|
||||
m_maxX = m_maxY = std::numeric_limits<double>::lowest();
|
||||
m_currentUnit = DXF_IMPORT_UNITS::DEFAULT;
|
||||
|
||||
m_importCoordinatePrecision = 4; // initial value per dxf spec
|
||||
@@ -131,7 +131,7 @@ bool DXF_IMPORT_PLUGIN::Load( const wxString& aFileName )
|
||||
|
||||
m_internalImporter.ClearShapes();
|
||||
|
||||
reportMsg( _( "Memory was exhausted trying to load the DXF, it may be too large." ) );
|
||||
ReportMsg( _( "Memory was exhausted trying to load the DXF, it may be too large." ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -151,7 +151,7 @@ bool DXF_IMPORT_PLUGIN::LoadFromMemory( const wxMemoryBuffer& aMemBuffer )
|
||||
|
||||
m_internalImporter.ClearShapes();
|
||||
|
||||
reportMsg( _( "Memory was exhausted trying to load the DXF, it may be too large." ) );
|
||||
ReportMsg( _( "Memory was exhausted trying to load the DXF, it may be too large." ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -247,7 +247,7 @@ bool DXF_IMPORT_PLUGIN::ImportDxfFile( const wxMemoryBuffer& aMemBuffer )
|
||||
}
|
||||
|
||||
|
||||
void DXF_IMPORT_PLUGIN::reportMsg( const wxString& aMessage )
|
||||
void DXF_IMPORT_PLUGIN::ReportMsg( const wxString& aMessage )
|
||||
{
|
||||
// Add message to keep trace of not handled dxf entities
|
||||
m_messages += aMessage;
|
||||
@@ -1411,8 +1411,8 @@ void DXF_IMPORT_PLUGIN::insertSpline( double aWidth )
|
||||
ctrlp.push_back( m_curr_entity.m_SplineControlPointList[ii].m_y );
|
||||
}
|
||||
|
||||
std::vector<double> coords;
|
||||
tinyspline::BSpline beziers;
|
||||
std::vector<double> coords;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1421,15 +1421,18 @@ void DXF_IMPORT_PLUGIN::insertSpline( double aWidth )
|
||||
|
||||
dxfspline.setControlPoints( ctrlp );
|
||||
dxfspline.setKnots( m_curr_entity.m_SplineKnotsList );
|
||||
beziers = tinyspline::BSpline( dxfspline.toBeziers() );
|
||||
|
||||
if( dxfspline.degree() < 3 )
|
||||
dxfspline = dxfspline.elevateDegree( 3 - dxfspline.degree() );
|
||||
|
||||
beziers = dxfspline.toBeziers();
|
||||
coords = beziers.controlPoints();
|
||||
}
|
||||
catch( const std::runtime_error& ) // tinyspline throws everything including data validation
|
||||
// as runtime errors
|
||||
{
|
||||
// invalid spline definition, drop this block
|
||||
reportMsg( _( "Invalid spline definition encountered" ) );
|
||||
ReportMsg( _( "Invalid spline definition encountered" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1446,14 +1449,14 @@ void DXF_IMPORT_PLUGIN::insertSpline( double aWidth )
|
||||
// not sure why this happens, but it seems to sometimes slip degree on the final bezier
|
||||
VECTOR2D bezierControl2;
|
||||
|
||||
if( ii + 4 >= coords.size() )
|
||||
if( ii + 5 >= coords.size() )
|
||||
bezierControl2 = bezierControl1;
|
||||
else
|
||||
bezierControl2 = VECTOR2D( mapX( coords[ii + 4] ), mapY( coords[ii + 5] ) );
|
||||
|
||||
VECTOR2D end;
|
||||
|
||||
if( ii + 6 >= coords.size() )
|
||||
if( ii + 7 >= coords.size() )
|
||||
end = bezierControl2;
|
||||
else
|
||||
end = VECTOR2D( mapX( coords[ii + 6] ), mapY( coords[ii + 7] ) );
|
||||
|
||||
@@ -320,10 +320,10 @@ public:
|
||||
{
|
||||
return m_messages;
|
||||
}
|
||||
// report message to keep trace of not supported dxf entities:
|
||||
void ReportMsg( const wxString& aMessage ) override;
|
||||
|
||||
private:
|
||||
// report message to keep trace of not supported dxf entities:
|
||||
void reportMsg( const wxString& aMessage );
|
||||
|
||||
// coordinate conversions from dxf file to mm
|
||||
double mapX( double aDxfCoordX );
|
||||
@@ -455,77 +455,77 @@ private:
|
||||
// Not yet handled DXF entities:
|
||||
virtual void addXLine( const DL_XLineData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF construction lines not currently supported." ) );
|
||||
ReportMsg( _( "DXF construction lines not currently supported." ) );
|
||||
}
|
||||
virtual void addRay( const DL_RayData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF construction lines not currently supported." ) );
|
||||
ReportMsg( _( "DXF construction lines not currently supported." ) );
|
||||
}
|
||||
|
||||
virtual void addArcAlignedText( const DL_ArcAlignedTextData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF arc-aligned text not currently supported." ) );
|
||||
ReportMsg( _( "DXF arc-aligned text not currently supported." ) );
|
||||
}
|
||||
|
||||
virtual void addDimAlign( const DL_DimensionData&, const DL_DimAlignedData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
ReportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
}
|
||||
virtual void addDimLinear( const DL_DimensionData&, const DL_DimLinearData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
ReportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
}
|
||||
virtual void addDimRadial( const DL_DimensionData&, const DL_DimRadialData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
ReportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
}
|
||||
virtual void addDimDiametric( const DL_DimensionData&, const DL_DimDiametricData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
ReportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
}
|
||||
virtual void addDimAngular( const DL_DimensionData&, const DL_DimAngular2LData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
ReportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
}
|
||||
virtual void addDimAngular3P( const DL_DimensionData&, const DL_DimAngular3PData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
ReportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
}
|
||||
virtual void addDimOrdinate( const DL_DimensionData&, const DL_DimOrdinateData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
ReportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
}
|
||||
virtual void addLeader( const DL_LeaderData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
ReportMsg( _( "DXF dimensions not currently supported." ) );
|
||||
}
|
||||
virtual void addLeaderVertex( const DL_LeaderVertexData& ) override { }
|
||||
|
||||
virtual void addHatch( const DL_HatchData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF hatches not currently supported." ) );
|
||||
ReportMsg( _( "DXF hatches not currently supported." ) );
|
||||
}
|
||||
virtual void addHatchLoop( const DL_HatchLoopData& ) override { }
|
||||
virtual void addHatchEdge( const DL_HatchEdgeData& ) override { }
|
||||
|
||||
virtual void addTrace( const DL_TraceData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF traces not currently supported." ) );
|
||||
ReportMsg( _( "DXF traces not currently supported." ) );
|
||||
}
|
||||
|
||||
virtual void add3dFace( const DL_3dFaceData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF 3dfaces not currently supported." ) );
|
||||
ReportMsg( _( "DXF 3dfaces not currently supported." ) );
|
||||
}
|
||||
|
||||
virtual void addSolid( const DL_SolidData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF solids not currently supported." ) );
|
||||
ReportMsg( _( "DXF solids not currently supported." ) );
|
||||
}
|
||||
|
||||
virtual void addImage( const DL_ImageData& ) override
|
||||
{
|
||||
reportMsg( _( "DXF images not currently supported." ) );
|
||||
ReportMsg( _( "DXF images not currently supported." ) );
|
||||
}
|
||||
virtual void linkImage( const DL_ImageDefData& ) override {}
|
||||
|
||||
|
||||
@@ -131,6 +131,8 @@ public:
|
||||
*/
|
||||
const virtual wxString& GetMessages() const = 0;
|
||||
|
||||
virtual void ReportMsg( const wxString& aMessage ) = 0;
|
||||
|
||||
protected:
|
||||
///< Importer used to create objects representing the imported shapes.
|
||||
GRAPHICS_IMPORTER* m_importer;
|
||||
|
||||
@@ -125,6 +125,11 @@ public:
|
||||
return m_plugin->GetMessages();
|
||||
}
|
||||
|
||||
void ReportMsg( const wxString& aMessage )
|
||||
{
|
||||
m_plugin->ReportMsg( aMessage );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get original image Width.
|
||||
*
|
||||
|
||||
@@ -98,6 +98,89 @@ void GRAPHICS_IMPORTER_BUFFER::AddShape( std::unique_ptr<IMPORTED_SHAPE>& aShape
|
||||
|
||||
void GRAPHICS_IMPORTER_BUFFER::ImportTo( GRAPHICS_IMPORTER& aImporter )
|
||||
{
|
||||
BOX2D boundingBox;
|
||||
|
||||
for( std::unique_ptr<IMPORTED_SHAPE>& shape : m_shapes )
|
||||
{
|
||||
BOX2D box = shape->GetBoundingBox();
|
||||
|
||||
if( box.IsValid() )
|
||||
boundingBox.Merge( box );
|
||||
}
|
||||
|
||||
boundingBox.SetOrigin( boundingBox.GetPosition().x * aImporter.GetScale().x,
|
||||
boundingBox.GetPosition().y * aImporter.GetScale().y );
|
||||
boundingBox.SetSize( boundingBox.GetSize().x * aImporter.GetScale().x,
|
||||
boundingBox.GetSize().y * aImporter.GetScale().y );
|
||||
|
||||
// Check that the scaled graphics fit in the KiCad numeric limits
|
||||
if( boundingBox.GetSize().x * aImporter.GetMillimeterToIuFactor() > std::numeric_limits<int>::max() ||
|
||||
boundingBox.GetSize().y * aImporter.GetMillimeterToIuFactor() > std::numeric_limits<int>::max() )
|
||||
{
|
||||
double scale_factor = std::numeric_limits<int>::max() / ( aImporter.GetMillimeterToIuFactor() + 100 );
|
||||
double max_scale = std::max( scale_factor / boundingBox.GetSize().x,
|
||||
scale_factor / boundingBox.GetSize().y );
|
||||
aImporter.ReportMsg( wxString::Format( _( "Imported graphic is too large. Maximum scale is %f" ),
|
||||
max_scale ) );
|
||||
return;
|
||||
}
|
||||
// They haven't set the import offset, so we set it to the bounding box origin to keep the graphics
|
||||
// in the KiCad drawing area
|
||||
else if( aImporter.GetImportOffsetMM() == VECTOR2D( 0, 0 ) )
|
||||
{
|
||||
VECTOR2D offset = boundingBox.GetOrigin();
|
||||
aImporter.SetImportOffsetMM( -offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
VECTOR2D bbox_origin = boundingBox.GetOrigin();
|
||||
aImporter.SetImportOffsetMM( -bbox_origin + aImporter.GetImportOffsetMM() );
|
||||
|
||||
double total_scale_x = aImporter.GetScale().x * aImporter.GetMillimeterToIuFactor();
|
||||
double total_scale_y = aImporter.GetScale().y * aImporter.GetMillimeterToIuFactor();
|
||||
|
||||
double max_offset_x =
|
||||
( aImporter.GetImportOffsetMM().x + boundingBox.GetRight() ) * total_scale_x;
|
||||
double max_offset_y =
|
||||
( aImporter.GetImportOffsetMM().y + boundingBox.GetBottom() ) * total_scale_y;
|
||||
double min_offset_x =
|
||||
( aImporter.GetImportOffsetMM().x + boundingBox.GetLeft() ) * total_scale_x;
|
||||
double min_offset_y =
|
||||
( aImporter.GetImportOffsetMM().y + boundingBox.GetTop() ) * total_scale_y;
|
||||
|
||||
VECTOR2D newOffset = aImporter.GetImportOffsetMM();
|
||||
bool needsAdjustment = false;
|
||||
|
||||
if( max_offset_x >= std::numeric_limits<int>::max() )
|
||||
{
|
||||
newOffset.x -= ( max_offset_x - std::numeric_limits<int>::max() + 100.0 ) / total_scale_x;
|
||||
needsAdjustment = true;
|
||||
}
|
||||
else if( min_offset_x <= std::numeric_limits<int>::min() )
|
||||
{
|
||||
newOffset.x -= ( min_offset_x - std::numeric_limits<int>::min() - 100 ) / total_scale_x;
|
||||
needsAdjustment = true;
|
||||
}
|
||||
|
||||
if( max_offset_y >= std::numeric_limits<int>::max() )
|
||||
{
|
||||
newOffset.y -= ( max_offset_y - std::numeric_limits<int>::max() + 100 ) / total_scale_y;
|
||||
needsAdjustment = true;
|
||||
}
|
||||
else if( min_offset_y <= std::numeric_limits<int>::min() )
|
||||
{
|
||||
newOffset.y -= ( min_offset_y - std::numeric_limits<int>::min() - 100 ) / total_scale_y;
|
||||
needsAdjustment = true;
|
||||
}
|
||||
|
||||
if( needsAdjustment )
|
||||
{
|
||||
aImporter.ReportMsg( wxString::Format( _( "Import offset adjusted to (%f, %f) to fit within numeric limits" ),
|
||||
newOffset.x, newOffset.y ) );
|
||||
aImporter.SetImportOffsetMM( newOffset );
|
||||
}
|
||||
}
|
||||
|
||||
for( std::unique_ptr<IMPORTED_SHAPE>& shape : m_shapes )
|
||||
shape->ImportTo( aImporter );
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "graphics_importer.h"
|
||||
|
||||
#include <math/matrix3x3.h>
|
||||
#include <math/box2.h>
|
||||
#include <list>
|
||||
|
||||
|
||||
@@ -46,6 +47,8 @@ public:
|
||||
void SetParentShapeIndex( int aIndex ) { m_parentShapeIndex = aIndex; }
|
||||
int GetParentShapeIndex() const { return m_parentShapeIndex; }
|
||||
|
||||
virtual BOX2D GetBoundingBox() const = 0;
|
||||
|
||||
protected:
|
||||
int m_parentShapeIndex = -1;
|
||||
};
|
||||
@@ -75,6 +78,14 @@ public:
|
||||
m_end = aTransform * m_end + aTranslation;
|
||||
}
|
||||
|
||||
BOX2D GetBoundingBox() const override
|
||||
{
|
||||
BOX2D box;
|
||||
box.Merge( m_start );
|
||||
box.Merge( m_end );
|
||||
return box;
|
||||
}
|
||||
|
||||
private:
|
||||
VECTOR2D m_start;
|
||||
VECTOR2D m_end;
|
||||
@@ -113,6 +124,14 @@ public:
|
||||
m_radius = newRadius.EuclideanNorm();
|
||||
}
|
||||
|
||||
BOX2D GetBoundingBox() const override
|
||||
{
|
||||
BOX2D box;
|
||||
box.Merge( m_center - VECTOR2D( m_radius, m_radius ) );
|
||||
box.Merge( m_center + VECTOR2D( m_radius, m_radius ) );
|
||||
return box;
|
||||
}
|
||||
|
||||
private:
|
||||
VECTOR2D m_center;
|
||||
double m_radius;
|
||||
@@ -148,6 +167,26 @@ public:
|
||||
m_center = aTransform * m_center + aTranslation;
|
||||
}
|
||||
|
||||
BOX2D GetBoundingBox() const override
|
||||
{
|
||||
BOX2D box;
|
||||
|
||||
box.Merge( m_start + m_stroke.GetWidth() );
|
||||
box.Merge( m_start - m_stroke.GetWidth() );
|
||||
|
||||
for( double angle = 0; angle < m_angle.AsDegrees(); angle += 5 )
|
||||
{
|
||||
EDA_ANGLE ang = EDA_ANGLE( angle );
|
||||
VECTOR2D start = m_center + m_start;
|
||||
VECTOR2D pt = {start.x * ang.Cos() + start.y * ang.Sin(),
|
||||
start.x * ang.Sin() - start.y * ang.Cos()};
|
||||
|
||||
box.Merge( pt );
|
||||
}
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
private:
|
||||
VECTOR2D m_center;
|
||||
VECTOR2D m_start;
|
||||
@@ -192,6 +231,16 @@ public:
|
||||
|
||||
const IMPORTED_STROKE& GetStroke() const { return m_stroke; }
|
||||
|
||||
BOX2D GetBoundingBox() const override
|
||||
{
|
||||
BOX2D box;
|
||||
|
||||
for( const VECTOR2D& vert : m_vertices )
|
||||
box.Merge( vert );
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<VECTOR2D> m_vertices;
|
||||
IMPORTED_STROKE m_stroke;
|
||||
@@ -227,6 +276,19 @@ public:
|
||||
void Transform( const MATRIX3x3D& aTransform, const VECTOR2D& aTranslation ) override
|
||||
{
|
||||
m_origin = aTransform * m_origin + aTranslation;
|
||||
|
||||
VECTOR2D textSize = aTransform * VECTOR2D( m_width, m_height );
|
||||
m_width = textSize.x;
|
||||
m_height = textSize.y;
|
||||
}
|
||||
|
||||
BOX2D GetBoundingBox() const override
|
||||
{
|
||||
BOX2D box;
|
||||
box.Merge( m_origin );
|
||||
box.Merge( m_origin + VECTOR2D( m_width * m_text.length(), m_height ) );
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -272,6 +334,14 @@ public:
|
||||
m_end = aTransform * m_end + aTranslation;
|
||||
}
|
||||
|
||||
BOX2D GetBoundingBox() const override
|
||||
{
|
||||
BOX2D box;
|
||||
box.Merge( m_start );
|
||||
box.Merge( m_end );
|
||||
return box;
|
||||
}
|
||||
|
||||
private:
|
||||
VECTOR2D m_start;
|
||||
VECTOR2D m_bezierControl1;
|
||||
|
||||
@@ -426,3 +426,11 @@ static float distanceFromPointToLine( const VECTOR2D& aPoint, const VECTOR2D& aL
|
||||
|
||||
return fabs( distance );
|
||||
}
|
||||
|
||||
|
||||
void SVG_IMPORT_PLUGIN::ReportMsg( const wxString& aMessage )
|
||||
{
|
||||
// Add message to keep trace of not handled svg entities
|
||||
m_messages += aMessage;
|
||||
m_messages += '\n';
|
||||
}
|
||||
@@ -62,6 +62,8 @@ public:
|
||||
return m_messages;
|
||||
}
|
||||
|
||||
void ReportMsg( const wxString& aMessage ) override;
|
||||
|
||||
bool Import() override;
|
||||
bool Load( const wxString& aFileName ) override;
|
||||
bool LoadFromMemory( const wxMemoryBuffer& aMemBuffer ) override;
|
||||
|
||||
@@ -307,3 +307,20 @@ EASYEDAPRO::ParseJsonLinesWithSeparation( wxInputStream& aInput, const wxString&
|
||||
|
||||
return lineBlocks;
|
||||
}
|
||||
|
||||
|
||||
std::map<wxString, wxString>
|
||||
EASYEDAPRO::AnyMapToStringMap( const std::map<wxString, nlohmann::json>& aInput )
|
||||
{
|
||||
std::map<wxString, wxString> stringMap;
|
||||
|
||||
for( auto& [key, value] : aInput )
|
||||
{
|
||||
if( value.is_string() )
|
||||
stringMap[key] = value.get<wxString>();
|
||||
else if( value.is_number() )
|
||||
stringMap[key] = wxString::FromCDouble( value.get<double>() );
|
||||
}
|
||||
|
||||
return stringMap;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,8 @@ std::vector<nlohmann::json> ParseJsonLines( wxInputStream& aInput, const wxStrin
|
||||
std::vector<std::vector<nlohmann::json>> ParseJsonLinesWithSeparation( wxInputStream& aInput,
|
||||
const wxString& aSource );
|
||||
|
||||
std::map<wxString, wxString> AnyMapToStringMap( const std::map<wxString, nlohmann::json>& aInput );
|
||||
|
||||
} // namespace EASYEDAPRO
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <core/json_serializers.h>
|
||||
#include <string_utils.h>
|
||||
#include <io/easyedapro/easyedapro_import_utils.h>
|
||||
|
||||
|
||||
void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::SCH_ATTR& d )
|
||||
@@ -273,7 +274,7 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_DEVICE& d )
|
||||
d.custom_tags = j.at( "custom_tags" );
|
||||
|
||||
if( j.at( "attributes" ).is_object() )
|
||||
d.attributes = j.at( "attributes" );
|
||||
d.attributes = AnyMapToStringMap( j.at( "attributes" ) );
|
||||
}
|
||||
|
||||
void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::BLOB& d )
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
namespace EASYEDAPRO
|
||||
{
|
||||
|
||||
static const bool IMPORT_POURED = false;
|
||||
static const bool IMPORT_POURED = true;
|
||||
static const bool IMPORT_POURED_ECOP = false;
|
||||
|
||||
enum class SYMBOL_TYPE
|
||||
{
|
||||
|
||||
+2
-10
@@ -25,9 +25,9 @@
|
||||
|
||||
#include <kiid.h>
|
||||
|
||||
#include <boost/random/mersenne_twister.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 106700
|
||||
#include <boost/uuid/entropy_error.hpp>
|
||||
@@ -235,15 +235,7 @@ timestamp_t KIID::AsLegacyTimestamp() const
|
||||
|
||||
size_t KIID::Hash() const
|
||||
{
|
||||
size_t hash = 0;
|
||||
|
||||
// Note: this is NOT little-endian/big-endian safe, but as long as it's just used
|
||||
// at runtime it won't matter.
|
||||
|
||||
for( int i = 0; i < 4; ++i )
|
||||
boost::hash_combine( hash, reinterpret_cast<const uint32_t*>( m_uuid.data )[i] );
|
||||
|
||||
return hash;
|
||||
return boost::uuids::hash_value( m_uuid );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -273,7 +273,7 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
|
||||
}
|
||||
|
||||
ch = m_token.input[ ++m_token.pos ];
|
||||
} while( isdigit( ch ) || isDecimalSeparator( ch ) );
|
||||
} while( isdigit( (unsigned char) ch ) || isDecimalSeparator( ch ) );
|
||||
|
||||
m_token.token[ idx ] = 0;
|
||||
};
|
||||
@@ -373,7 +373,7 @@ NUMERIC_EVALUATOR::Token NUMERIC_EVALUATOR::getToken()
|
||||
{
|
||||
/* End of input */
|
||||
}
|
||||
else if( isdigit( ch ) || isDecimalSeparator( ch ) )
|
||||
else if( isdigit( (unsigned char) ch ) || isDecimalSeparator( ch ) )
|
||||
{
|
||||
// VALUE
|
||||
extractNumber( &siScaler );
|
||||
|
||||
@@ -491,8 +491,15 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest )
|
||||
}
|
||||
#endif
|
||||
|
||||
// Ensure the instance checker directory exists
|
||||
// It should be globally writable because it is shared between all users on Linux, and so on a
|
||||
// multi-user machine, other need to be able to access it to check for the lock files or make
|
||||
// their own lock files.
|
||||
wxString instanceCheckerDir = PATHS::GetInstanceCheckerPath();
|
||||
PATHS::EnsurePathExists( instanceCheckerDir );
|
||||
wxChmod( instanceCheckerDir, wxPOSIX_USER_READ | wxPOSIX_USER_WRITE | wxPOSIX_USER_EXECUTE |
|
||||
wxPOSIX_GROUP_READ | wxPOSIX_GROUP_WRITE | wxPOSIX_GROUP_EXECUTE |
|
||||
wxPOSIX_OTHERS_READ | wxPOSIX_OTHERS_WRITE | wxPOSIX_OTHERS_EXECUTE );
|
||||
|
||||
wxString instanceCheckerName = wxString::Format( wxS( "%s-%s" ), pgm_name,
|
||||
GetMajorMinorVersion() );
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2012 Lorenzo Marcantonio, l.marcantonio@logossrl.com
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -37,7 +37,8 @@
|
||||
#include <wx/datstrm.h>
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <eda_text.h> // for IsGotoPageHref
|
||||
#include <common.h> // ResolveUriByEnvVars
|
||||
#include <eda_text.h> // for IsGotoPageHref
|
||||
#include <font/font.h>
|
||||
#include <core/ignore.h>
|
||||
#include <macros.h>
|
||||
@@ -400,12 +401,12 @@ void PDF_PLOTTER::PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFi
|
||||
SetCurrentLineWidth( aWidth );
|
||||
|
||||
VECTOR2D pos = userToDeviceCoordinates( aCornerList[0] );
|
||||
fprintf( m_workFile, "%g %g m\n", pos.x, pos.y );
|
||||
fprintf( m_workFile, "%f %f m\n", pos.x, pos.y );
|
||||
|
||||
for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
|
||||
{
|
||||
pos = userToDeviceCoordinates( aCornerList[ii] );
|
||||
fprintf( m_workFile, "%g %g l\n", pos.x, pos.y );
|
||||
fprintf( m_workFile, "%f %f l\n", pos.x, pos.y );
|
||||
}
|
||||
|
||||
// Close path and stroke and/or fill
|
||||
@@ -438,7 +439,7 @@ void PDF_PLOTTER::PenTo( const VECTOR2I& pos, char plume )
|
||||
if( m_penState != plume || pos != m_penLastpos )
|
||||
{
|
||||
VECTOR2D pos_dev = userToDeviceCoordinates( pos );
|
||||
fprintf( m_workFile, "%g %g %c\n",
|
||||
fprintf( m_workFile, "%f %f %c\n",
|
||||
pos_dev.x, pos_dev.y,
|
||||
( plume=='D' ) ? 'l' : 'm' );
|
||||
}
|
||||
@@ -1332,16 +1333,35 @@ bool PDF_PLOTTER::EndPlot()
|
||||
{
|
||||
wxString href = property.substr( property.Find( "http:" ) );
|
||||
|
||||
if( m_project )
|
||||
href = ResolveUriByEnvVars( href, m_project );
|
||||
|
||||
js += wxString::Format( wxT( "[\"%s\", \"%s\"],\n" ),
|
||||
EscapeString( property, CTX_JS_STR ),
|
||||
EscapeString( href, CTX_JS_STR ),
|
||||
EscapeString( href, CTX_JS_STR ) );
|
||||
}
|
||||
else if( property.Find( "https:" ) >= 0 )
|
||||
{
|
||||
wxString href = property.substr( property.Find( "https:" ) );
|
||||
|
||||
if( m_project )
|
||||
href = ResolveUriByEnvVars( href, m_project );
|
||||
|
||||
js += wxString::Format( wxT( "[\"%s\", \"%s\"],\n" ),
|
||||
EscapeString( property, CTX_JS_STR ),
|
||||
EscapeString( href, CTX_JS_STR ),
|
||||
EscapeString( href, CTX_JS_STR ) );
|
||||
}
|
||||
else if( property.Find( "file:" ) >= 0 )
|
||||
{
|
||||
wxString href = property.substr( property.Find( "file:" ) );
|
||||
|
||||
if( m_project )
|
||||
href = ResolveUriByEnvVars( href, m_project );
|
||||
|
||||
href = NormalizeFileUri( href );
|
||||
|
||||
js += wxString::Format( wxT( "[\"%s\", \"%s\"],\n" ),
|
||||
EscapeString( href, CTX_JS_STR ),
|
||||
EscapeString( href, CTX_JS_STR ) );
|
||||
}
|
||||
else
|
||||
@@ -1367,13 +1387,22 @@ bool PDF_PLOTTER::EndPlot()
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( url.StartsWith( "http:" ) || url.StartsWith( "https:" ) )
|
||||
else if( url.StartsWith( "http:" ) || url.StartsWith( "https:" )
|
||||
|| url.StartsWith( "file:" ) )
|
||||
{
|
||||
wxString menuText = wxString::Format( _( "Open %s" ), url );
|
||||
wxString href = url;
|
||||
|
||||
if( m_project )
|
||||
href = ResolveUriByEnvVars( url, m_project );
|
||||
|
||||
if( url.StartsWith( "file:" ) )
|
||||
href = NormalizeFileUri( href );
|
||||
|
||||
wxString menuText = wxString::Format( _( "Open %s" ), href );
|
||||
|
||||
js += wxString::Format( wxT( "[\"%s\", \"%s\"],\n" ),
|
||||
EscapeString( menuText, CTX_JS_STR ),
|
||||
EscapeString( url, CTX_JS_STR ) );
|
||||
EscapeString( href, CTX_JS_STR ),
|
||||
EscapeString( href, CTX_JS_STR ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1413,6 +1442,7 @@ function ShM(aEntries) {
|
||||
var cChoice = app.popUpMenuEx.apply(app, aParams);
|
||||
if (cChoice != null && cChoice.substring(0, 1) == '#') this.pageNum = parseInt(cChoice.slice(1));
|
||||
else if (cChoice != null && cChoice.substring(0, 4) == 'http') app.launchURL(cChoice);
|
||||
else if (cChoice != null && cChoice.substring(0, 4) == 'file') app.openDoc(cChoice.substring(7));
|
||||
}
|
||||
)JS";
|
||||
|
||||
@@ -1634,7 +1664,7 @@ void PDF_PLOTTER::Text( const VECTOR2I& aPos,
|
||||
coordinate system will be used for the overlining. Also the %f
|
||||
for the trig part of the matrix to avoid %g going in exponential
|
||||
format (which is not supported) */
|
||||
fprintf( m_workFile, "q %f %f %f %f %g %g cm BT %s %g Tf %d Tr %g Tz ",
|
||||
fprintf( m_workFile, "q %f %f %f %f %f %f cm BT %s %g Tf %d Tr %g Tz ",
|
||||
ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f,
|
||||
fontname, heightFactor, render_mode, wideningFactor * 100 );
|
||||
|
||||
|
||||
@@ -162,7 +162,8 @@ static wxString XmlEsc( const wxString& aStr, bool isAttribute = false )
|
||||
}
|
||||
|
||||
|
||||
SVG_PLOTTER::SVG_PLOTTER()
|
||||
SVG_PLOTTER::SVG_PLOTTER( const PROJECT* aProject ) :
|
||||
PSLIKE_PLOTTER( aProject )
|
||||
{
|
||||
m_graphics_changed = true;
|
||||
SetTextMode( PLOT_TEXT_MODE::STROKE );
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -44,7 +44,8 @@
|
||||
#include <callback_gal.h>
|
||||
#include <math/util.h> // for KiROUND
|
||||
|
||||
PLOTTER::PLOTTER( )
|
||||
PLOTTER::PLOTTER( const PROJECT* aProject ) :
|
||||
m_project( aProject )
|
||||
{
|
||||
m_plotScale = 1;
|
||||
m_currentPenWidth = -1; // To-be-set marker
|
||||
|
||||
+37
-6
@@ -42,6 +42,13 @@ REPORTER& REPORTER::Report( const char* aText, SEVERITY aSeverity )
|
||||
}
|
||||
|
||||
|
||||
bool REPORTER::HasMessageOfSeverity( int aSeverityMask ) const
|
||||
{
|
||||
wxFAIL_MSG( "HasMessageOfSeverity is not implemented in this reporter" );
|
||||
return HasMessage();
|
||||
}
|
||||
|
||||
|
||||
REPORTER& WX_TEXT_CTRL_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
wxCHECK_MSG( m_textCtrl != nullptr, *this,
|
||||
@@ -60,17 +67,34 @@ bool WX_TEXT_CTRL_REPORTER::HasMessage() const
|
||||
|
||||
REPORTER& WX_STRING_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
wxCHECK_MSG( m_string != nullptr, *this,
|
||||
wxT( "No wxString object defined in WX_STRING_REPORTER." ) );
|
||||
|
||||
*m_string << aText << wxS( "\n" );
|
||||
m_severityMask |= aSeverity;
|
||||
m_string << aText << wxS( "\n" );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
const wxString& WX_STRING_REPORTER::GetMessages() const
|
||||
{
|
||||
return m_string;
|
||||
}
|
||||
|
||||
|
||||
void WX_STRING_REPORTER::Clear()
|
||||
{
|
||||
m_severityMask = 0;
|
||||
m_string.clear();
|
||||
}
|
||||
|
||||
|
||||
bool WX_STRING_REPORTER::HasMessage() const
|
||||
{
|
||||
return !m_string->IsEmpty();
|
||||
return !m_string.IsEmpty();
|
||||
}
|
||||
|
||||
|
||||
bool WX_STRING_REPORTER::HasMessageOfSeverity( int aSeverityMask ) const
|
||||
{
|
||||
return ( m_severityMask & aSeverityMask ) != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +130,14 @@ REPORTER& WX_HTML_PANEL_REPORTER::ReportHead( const wxString& aText, SEVERITY aS
|
||||
|
||||
bool WX_HTML_PANEL_REPORTER::HasMessage() const
|
||||
{
|
||||
return m_panel->Count( RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING ) > 0;
|
||||
// Check just for errors and warnings for compatibility
|
||||
return HasMessageOfSeverity( RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING );
|
||||
}
|
||||
|
||||
|
||||
bool WX_HTML_PANEL_REPORTER::HasMessageOfSeverity( int aSeverityMask ) const
|
||||
{
|
||||
return m_panel->Count( aSeverityMask ) > 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ COMMON_SETTINGS::COMMON_SETTINGS() :
|
||||
m_params.emplace_back( new PARAM<int>( "auto_backup.min_interval",
|
||||
&m_Backup.min_interval, 300 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "environment.vars",
|
||||
auto envVarsParam = m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "environment.vars",
|
||||
[&]() -> nlohmann::json
|
||||
{
|
||||
nlohmann::json ret = {};
|
||||
@@ -212,6 +212,7 @@ COMMON_SETTINGS::COMMON_SETTINGS() :
|
||||
}
|
||||
},
|
||||
{} ) );
|
||||
envVarsParam->SetClearUnknownKeys();
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "input.focus_follow_sch_pcb",
|
||||
&m_Input.focus_follow_sch_pcb, false ) );
|
||||
|
||||
@@ -75,6 +75,7 @@ JSON_SETTINGS::JSON_SETTINGS( const wxString& aFilename, SETTINGS_LOC aLocation,
|
||||
m_createIfMissing( aCreateIfMissing ),
|
||||
m_createIfDefault( aCreateIfDefault ),
|
||||
m_writeFile( aWriteFile ),
|
||||
m_modified( false ),
|
||||
m_deleteLegacyAfterMigration( true ),
|
||||
m_resetParamsIfMissing( true ),
|
||||
m_schemaVersion( aSchemaVersion ),
|
||||
@@ -353,6 +354,8 @@ bool JSON_SETTINGS::LoadFromFile( const wxString& aDirectory )
|
||||
wxLogTrace( traceSettings, wxT( "Loaded <%s> with schema %d" ), GetFullFilename(),
|
||||
m_schemaVersion );
|
||||
|
||||
m_modified = false;
|
||||
|
||||
// If we migrated, clean up the legacy file (with no extension)
|
||||
if( m_writeFile && ( legacy_migrated || migrated ) )
|
||||
{
|
||||
@@ -373,15 +376,13 @@ bool JSON_SETTINGS::LoadFromFile( const wxString& aDirectory )
|
||||
|
||||
bool JSON_SETTINGS::Store()
|
||||
{
|
||||
bool modified = false;
|
||||
|
||||
for( PARAM_BASE* param : m_params )
|
||||
{
|
||||
modified |= !param->MatchesFile( this );
|
||||
m_modified |= !param->MatchesFile( this );
|
||||
param->Store( this );
|
||||
}
|
||||
|
||||
return modified;
|
||||
return m_modified;
|
||||
}
|
||||
|
||||
|
||||
@@ -469,10 +470,12 @@ bool JSON_SETTINGS::SaveToFile( const wxString& aDirectory, bool aForce )
|
||||
|
||||
for( PARAM_BASE* param : m_params )
|
||||
{
|
||||
if( PARAM_WXSTRING_MAP* stringMap = dynamic_cast<PARAM_WXSTRING_MAP*>( param ) )
|
||||
if( param->ClearUnknownKeys() )
|
||||
{
|
||||
if( stringMap->ClearUnknownKeys() )
|
||||
toSave[ stringMap->GetJsonPath() ] = nlohmann::json( {} );
|
||||
nlohmann::json_pointer p
|
||||
= JSON_SETTINGS_INTERNALS::PointerFromString( param->GetJsonPath() );
|
||||
|
||||
toSave[p] = nlohmann::json( {} );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,6 +507,9 @@ bool JSON_SETTINGS::SaveToFile( const wxString& aDirectory, bool aForce )
|
||||
success = false;
|
||||
}
|
||||
|
||||
if( success )
|
||||
m_modified = false;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -858,7 +864,7 @@ void JSON_SETTINGS::ReleaseNestedSettings( NESTED_SETTINGS* aSettings )
|
||||
if( it != m_nested_settings.end() )
|
||||
{
|
||||
wxLogTrace( traceSettings, wxT( "Flush and release %s" ), ( *it )->GetFilename() );
|
||||
( *it )->SaveToFile();
|
||||
m_modified |= ( *it )->SaveToFile();
|
||||
m_nested_settings.erase( it );
|
||||
}
|
||||
|
||||
|
||||
+91
-14
@@ -28,11 +28,15 @@
|
||||
|
||||
#include <clocale>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <core/map_helpers.h>
|
||||
#include <fmt/core.h>
|
||||
#include <macros.h>
|
||||
#include <richio.h> // StrPrintf
|
||||
#include <string_utils.h>
|
||||
#include <wx_filename.h>
|
||||
#include <fmt/chrono.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/regex.h>
|
||||
#include "locale_io.h"
|
||||
|
||||
@@ -45,6 +49,34 @@
|
||||
static const char illegalFileNameChars[] = "\\/:\"<>|*?";
|
||||
|
||||
|
||||
// Checks if a full filename is valid, i.e. does not contains illegal chars
|
||||
bool IsFullFileNameValid( const wxString& aFullFilename )
|
||||
{
|
||||
|
||||
// Test for forbidden chars in aFullFilename.
|
||||
// '\'and '/' are allowed here because aFullFilename can be a full path, and
|
||||
// ':' is allowed on Windows as second char in string.
|
||||
// So remove allowed separators from string to test
|
||||
wxString filtered_fullpath = aFullFilename;
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
// On MSW, the list returned by wxFileName::GetForbiddenChars() contains separators
|
||||
// '\'and '/'
|
||||
filtered_fullpath.Replace( "/", "_" );
|
||||
filtered_fullpath.Replace( "\\", "_" );
|
||||
|
||||
// A disk identifier is allowed, and therefore remove its separator
|
||||
if( filtered_fullpath.Length() > 1 && filtered_fullpath[1] == ':' )
|
||||
filtered_fullpath[1] = ' ';
|
||||
#endif
|
||||
|
||||
if( wxString::npos != filtered_fullpath.find_first_of( wxFileName::GetForbiddenChars() ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
wxString ConvertToNewOverbarNotation( const wxString& aOldStr )
|
||||
{
|
||||
wxString newStr;
|
||||
@@ -540,22 +572,32 @@ wxString UnescapeHTML( const wxString& aString )
|
||||
{
|
||||
wxString converted = aString;
|
||||
|
||||
converted.Replace( wxS( """ ), wxS( "\"" ) );
|
||||
converted.Replace( wxS( "'" ), wxS( "'" ) );
|
||||
converted.Replace( wxS( "&" ), wxS( "&" ) );
|
||||
converted.Replace( wxS( "<" ), wxS( "<" ) );
|
||||
converted.Replace( wxS( ">" ), wxS( ">" ) );
|
||||
// clang-format off
|
||||
static const std::map<wxString, wxString> c_replacements = {
|
||||
{ wxS( "quot" ), wxS( "\"" ) },
|
||||
{ wxS( "apos" ), wxS( "'" ) },
|
||||
{ wxS( "amp" ), wxS( "&" ) },
|
||||
{ wxS( "lt" ), wxS( "<" ) },
|
||||
{ wxS( "gt" ), wxS( ">" ) }
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// Yes, &#123; is going to give unexpected results.
|
||||
// Construct regex
|
||||
wxString regexStr = "&(#(\\d*)|#x([a-zA-Z0-9]{4})";
|
||||
|
||||
wxString result;
|
||||
for( auto& [key, value] : c_replacements )
|
||||
regexStr << '|' << key;
|
||||
|
||||
wxRegEx regex( "&#(\\d*);" );
|
||||
regexStr << ");";
|
||||
|
||||
wxRegEx regex( regexStr );
|
||||
|
||||
// Process matches
|
||||
size_t start = 0;
|
||||
size_t len = 0;
|
||||
|
||||
wxString str = aString;
|
||||
wxString result;
|
||||
wxString str = converted;
|
||||
|
||||
while( regex.Matches( str ) )
|
||||
{
|
||||
@@ -564,12 +606,26 @@ wxString UnescapeHTML( const wxString& aString )
|
||||
|
||||
result << str.Left( start );
|
||||
|
||||
unsigned long codeVal = 0;
|
||||
wxString code = regex.GetMatch( str, 1 );
|
||||
code.ToCULong( &codeVal );
|
||||
wxString code = regex.GetMatch( str, 1 );
|
||||
wxString codeDec = regex.GetMatch( str, 2 );
|
||||
wxString codeHex = regex.GetMatch( str, 3 );
|
||||
|
||||
if( codeVal != 0 )
|
||||
result << wxUniChar( codeVal );
|
||||
if( !codeDec.IsEmpty() || !codeHex.IsEmpty() )
|
||||
{
|
||||
unsigned long codeVal = 0;
|
||||
|
||||
if( !codeDec.IsEmpty() )
|
||||
codeDec.ToCULong( &codeVal );
|
||||
else if( !codeHex.IsEmpty() )
|
||||
codeHex.ToCULong( &codeVal, 16 );
|
||||
|
||||
if( codeVal != 0 )
|
||||
result << wxUniChar( codeVal );
|
||||
}
|
||||
else if( auto val = get_opt( c_replacements, code ) )
|
||||
{
|
||||
result << *val;
|
||||
}
|
||||
|
||||
str = str.Mid( start + len );
|
||||
}
|
||||
@@ -1400,3 +1456,24 @@ wxString From_UTF8( const std::string& aString )
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
wxString NormalizeFileUri( const wxString& aFileUri )
|
||||
{
|
||||
wxString uriPathAndFileName;
|
||||
|
||||
wxCHECK( aFileUri.StartsWith( wxS( "file://" ), &uriPathAndFileName ), aFileUri );
|
||||
|
||||
wxString tmp = uriPathAndFileName;
|
||||
wxString retv = wxS( "file://" );
|
||||
|
||||
tmp.Replace( wxS( "\\" ), wxS( "/" ) );
|
||||
tmp.Replace( wxS( ":" ), wxS( "" ) );
|
||||
|
||||
if( !tmp.IsEmpty() && tmp[0] != '/' )
|
||||
tmp = wxS( "/" ) + tmp;
|
||||
|
||||
retv += tmp;
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ ACTION_MANAGER::ACTION_MANAGER( TOOL_MANAGER* aToolManager ) :
|
||||
std::string groupName = "none";
|
||||
|
||||
std::optional<TOOL_ACTION_GROUP> group = action->GetActionGroup();
|
||||
|
||||
|
||||
if( group.has_value() )
|
||||
{
|
||||
groupID = group.value().GetGroupID();
|
||||
@@ -152,19 +152,21 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
|
||||
// If no luck, try without Shift, to handle keys that require it
|
||||
// e.g. to get ? you need to press Shift+/ without US keyboard layout
|
||||
// Hardcoding ? as Shift+/ is a bad idea, as on another layout you may need to press a
|
||||
// different combination
|
||||
if( it == m_actionHotKeys.end() )
|
||||
// different combination.
|
||||
// This doesn't apply for letters, as we already handled case normalisation.
|
||||
if( it == m_actionHotKeys.end() && !std::isalpha( key ) )
|
||||
{
|
||||
wxLogTrace( kicadTraceToolStack,
|
||||
wxS( "ACTION_MANAGER::RunHotKey No actions found, searching with key: %s" ),
|
||||
KeyNameFromKeyCode( key | ( mod & ~MD_SHIFT ) ) );
|
||||
|
||||
it = m_actionHotKeys.find( key | ( mod & ~MD_SHIFT ) );
|
||||
|
||||
if( it == m_actionHotKeys.end() )
|
||||
return false; // no appropriate action found for the hotkey
|
||||
}
|
||||
|
||||
// Still no luck, we're done without a match
|
||||
if( it == m_actionHotKeys.end() )
|
||||
return false; // no appropriate action found for the hotkey
|
||||
|
||||
const std::list<TOOL_ACTION*>& actions = it->second;
|
||||
|
||||
// Choose the action that has the highest priority on the active tools stack
|
||||
|
||||
+18
-5
@@ -38,6 +38,8 @@
|
||||
#include <wx/textentry.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/combo.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <refdes_utils.h>
|
||||
|
||||
|
||||
FOOTPRINT_NAME_VALIDATOR::FOOTPRINT_NAME_VALIDATOR( wxString* aValue ) :
|
||||
@@ -355,18 +357,24 @@ bool FIELD_VALIDATOR::Validate( wxWindow* aParent )
|
||||
return false;
|
||||
|
||||
wxString val( text->GetValue() );
|
||||
|
||||
return DoValidate( val, aParent );
|
||||
}
|
||||
|
||||
bool FIELD_VALIDATOR::DoValidate( const wxString& aValue, wxWindow* aParent )
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
if( HasFlag( wxFILTER_EMPTY ) && val.empty() )
|
||||
if( HasFlag( wxFILTER_EMPTY ) && aValue.empty() )
|
||||
msg.Printf( _( "The value of the field cannot be empty." ) );
|
||||
|
||||
if( HasFlag( wxFILTER_EXCLUDE_CHAR_LIST ) && ContainsExcludedCharacters( val ) )
|
||||
if( HasFlag( wxFILTER_EXCLUDE_CHAR_LIST ) && ContainsExcludedCharacters( aValue ) )
|
||||
{
|
||||
wxArrayString badCharsFound;
|
||||
|
||||
for( const wxUniCharRef& excludeChar : GetCharExcludes() )
|
||||
{
|
||||
if( val.Find( excludeChar ) != wxNOT_FOUND )
|
||||
if( aValue.Find( excludeChar ) != wxNOT_FOUND )
|
||||
{
|
||||
if( excludeChar == '\r' )
|
||||
badCharsFound.Add( _( "carriage return" ) );
|
||||
@@ -434,14 +442,19 @@ bool FIELD_VALIDATOR::Validate( wxWindow* aParent )
|
||||
break;
|
||||
};
|
||||
}
|
||||
else if( m_fieldId == REFERENCE_FIELD && val.Contains( wxT( "${" ) ) )
|
||||
else if( m_fieldId == REFERENCE_FIELD && aValue.Contains( wxT( "${" ) ) )
|
||||
{
|
||||
msg.Printf( _( "The reference designator cannot contain text variable references" ) );
|
||||
}
|
||||
else if( m_fieldId == REFERENCE_FIELD && UTIL::GetRefDesPrefix( aValue ).IsEmpty() )
|
||||
{
|
||||
msg.Printf( _( "References must start with a letter." ) );
|
||||
}
|
||||
|
||||
if( !msg.empty() )
|
||||
{
|
||||
m_validatorWindow->SetFocus();
|
||||
if( m_validatorWindow )
|
||||
m_validatorWindow->SetFocus();
|
||||
|
||||
wxMessageBox( msg, _( "Field Validation Error" ), wxOK | wxICON_EXCLAMATION, aParent );
|
||||
|
||||
|
||||
@@ -105,13 +105,19 @@ bool FONT_CHOICE::HaveFontSelection() const
|
||||
}
|
||||
|
||||
|
||||
KIFONT::FONT* FONT_CHOICE::GetFontSelection( bool aBold, bool aItalic ) const
|
||||
KIFONT::FONT* FONT_CHOICE::GetFontSelection( bool aBold, bool aItalic, bool aForDrawingSheet ) const
|
||||
{
|
||||
if( GetSelection() <= 0 )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else if( GetSelection() == 1 && m_systemFontCount == 2 )
|
||||
{
|
||||
return KIFONT::FONT::GetFont( KICAD_FONT_NAME, aBold, aItalic );
|
||||
}
|
||||
else
|
||||
return KIFONT::FONT::GetFont( GetStringSelection(), aBold, aItalic );
|
||||
{
|
||||
return KIFONT::FONT::GetFont( GetStringSelection(), aBold, aItalic, aForDrawingSheet );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event )
|
||||
m_sdbSizer1Cancel->SetDefault();
|
||||
|
||||
// Don't close dialog if there are things the user needs to address
|
||||
if( reporter.HasMessage() )
|
||||
if( reporter.HasMessageOfSeverity( RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING ) )
|
||||
return;
|
||||
|
||||
if( m_infoBar->IsShown() )
|
||||
|
||||
@@ -333,8 +333,7 @@ void DIALOG_BOM::OnRunGenerator( wxCommandEvent& event )
|
||||
wxString fullfilename = fn.GetFullPath();
|
||||
m_parent->ClearMsgPanel();
|
||||
|
||||
wxString reportmsg;
|
||||
WX_STRING_REPORTER reporter( &reportmsg );
|
||||
WX_STRING_REPORTER reporter;
|
||||
m_parent->SetNetListerCommand( m_textCtrlCommand->GetValue() );
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
@@ -350,7 +349,7 @@ void DIALOG_BOM::OnRunGenerator( wxCommandEvent& event )
|
||||
if( !status )
|
||||
DisplayError( this, _( "Failed to create file." ) );
|
||||
|
||||
m_Messages->SetValue( reportmsg );
|
||||
m_Messages->SetValue( reporter.GetMessages() );
|
||||
|
||||
// Force focus back on the dialog
|
||||
SetFocus();
|
||||
|
||||
@@ -353,19 +353,8 @@ bool DIALOG_FIELD_PROPERTIES::TransferDataFromWindow()
|
||||
else if( m_StyledTextCtrl->IsShown() )
|
||||
m_text = UnescapeString( m_StyledTextCtrl->GetValue() );
|
||||
|
||||
if( m_fieldId == REFERENCE_FIELD )
|
||||
{
|
||||
// Test if the reference string is valid:
|
||||
if( !SCH_SYMBOL::IsReferenceStringValid( m_text ) )
|
||||
{
|
||||
DisplayError( this, _( "Illegal reference designator value!" ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if( m_fieldId == SHEETFILENAME_V )
|
||||
{
|
||||
if( m_fieldId == SHEETFILENAME_V )
|
||||
m_text = EnsureFileExtension( m_text, FILEEXT::KiCadSchematicFileExtension );
|
||||
}
|
||||
|
||||
m_position = VECTOR2I( m_posX.GetValue(), m_posY.GetValue() );
|
||||
m_size = m_textSize.GetValue();
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <widgets/std_bitmap_button.h>
|
||||
#include <string_utils.h>
|
||||
#include <project_sch.h>
|
||||
|
||||
#include <refdes_utils.h>
|
||||
#include <dialog_sim_model.h>
|
||||
|
||||
#include <dialog_lib_symbol_properties.h>
|
||||
@@ -238,8 +238,8 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::Validate()
|
||||
return false;
|
||||
|
||||
// Alias symbol reference can be empty because it inherits from the parent symbol.
|
||||
if( m_libEntry->IsRoot() &&
|
||||
!SCH_SYMBOL::IsReferenceStringValid( m_fields->at( REFERENCE_FIELD ).GetText() ) )
|
||||
if( m_libEntry->IsRoot()
|
||||
&& UTIL::GetRefDesPrefix( m_fields->at( REFERENCE_FIELD ).GetText() ).IsEmpty() )
|
||||
{
|
||||
if( m_NoteBook->GetSelection() != 0 )
|
||||
m_NoteBook->SetSelection( 0 );
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <trace_helpers.h>
|
||||
#include "panel_eeschema_color_settings.h"
|
||||
#include "wx/dcclient.h"
|
||||
#include "string_utils.h"
|
||||
|
||||
DIALOG_SHEET_PROPERTIES::DIALOG_SHEET_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_SHEET* aSheet,
|
||||
bool* aClearAnnotationNewItems,
|
||||
@@ -286,7 +287,15 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow()
|
||||
// but unedited data from existing files can be bad.)
|
||||
sheetFileName = EnsureFileExtension( sheetFileName, FILEEXT::KiCadSchematicFileExtension );
|
||||
|
||||
// Ensure sheetFileName is legal
|
||||
if( !IsFullFileNameValid( sheetFileName ) )
|
||||
{
|
||||
DisplayError( this, _( "A sheet must have a valid file name." ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
wxFileName fn( sheetFileName );
|
||||
|
||||
wxString newRelativeFilename = fn.GetFullPath();
|
||||
|
||||
// Inside Eeschema, filenames are stored using unix notation
|
||||
@@ -431,6 +440,9 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow()
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_updateHierarchyNavigator )
|
||||
*m_updateHierarchyNavigator = true;
|
||||
|
||||
// If we are renaming files, the undo/redo list becomes invalid and must be cleared.
|
||||
m_frame->ClearUndoRedoList();
|
||||
m_frame->OnModify();
|
||||
|
||||
@@ -173,8 +173,7 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
||||
wxString pinMap;
|
||||
bool storeInValue = false;
|
||||
|
||||
wxString msg;
|
||||
WX_STRING_REPORTER reporter( &msg );
|
||||
WX_STRING_REPORTER reporter;
|
||||
|
||||
auto setFieldValue =
|
||||
[&]( const wxString& aFieldName, const wxString& aValue )
|
||||
@@ -222,7 +221,7 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
||||
if( !loadLibrary( libraryFilename, reporter ) )
|
||||
{
|
||||
if( reporter.HasMessage() )
|
||||
m_infoBar->ShowMessage( msg );
|
||||
m_infoBar->ShowMessage( reporter.GetMessages() );
|
||||
|
||||
m_libraryPathText->ChangeValue( libraryFilename );
|
||||
m_curModelType = SIM_MODEL::ReadTypeFromFields( m_fields, reporter );
|
||||
@@ -305,24 +304,24 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
||||
// The model is sourced from the instance.
|
||||
m_rbBuiltinModel->SetValue( true );
|
||||
|
||||
msg.clear();
|
||||
reporter.Clear();
|
||||
m_curModelType = SIM_MODEL::ReadTypeFromFields( m_fields, reporter );
|
||||
|
||||
if( reporter.HasMessage() )
|
||||
DisplayErrorMessage( this, msg );
|
||||
DisplayErrorMessage( this, reporter.GetMessages() );
|
||||
}
|
||||
|
||||
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
|
||||
{
|
||||
if( m_rbBuiltinModel->GetValue() && type == m_curModelType )
|
||||
{
|
||||
msg.clear();
|
||||
reporter.Clear();
|
||||
m_builtinModelsMgr.CreateModel( m_fields, m_sortedPartPins, false, reporter );
|
||||
|
||||
if( reporter.HasMessage() )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "Failed to read simulation model from fields." )
|
||||
+ wxT( "\n\n" ) + msg );
|
||||
+ wxT( "\n\n" ) + reporter.GetMessages() );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -819,7 +818,7 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::loadLibrary( const wxString& aLibraryP
|
||||
m_libraryModelsMgr.SetForceFullParse();
|
||||
m_libraryModelsMgr.SetLibrary( aLibraryPath, aReporter );
|
||||
|
||||
if( aReporter.HasMessage() )
|
||||
if( aReporter.HasMessageOfSeverity( RPT_SEVERITY_UNDEFINED | RPT_SEVERITY_ERROR ) )
|
||||
return false;
|
||||
|
||||
std::string modelName = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::NAME_FIELD );
|
||||
@@ -1181,14 +1180,13 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::onLibraryPathTextEnter( wxCommandEvent
|
||||
{
|
||||
m_rbLibraryModel->SetValue( true );
|
||||
|
||||
wxString msg;
|
||||
WX_STRING_REPORTER reporter( &msg );
|
||||
WX_STRING_REPORTER reporter;
|
||||
wxString path = m_libraryPathText->GetValue();
|
||||
|
||||
if( loadLibrary( path, reporter, true ) )
|
||||
m_infoBar->Hide();
|
||||
else if( reporter.HasMessage() )
|
||||
m_infoBar->ShowMessage( msg );
|
||||
m_infoBar->ShowMessage( reporter.GetMessages() );
|
||||
|
||||
updateWidgets();
|
||||
}
|
||||
@@ -1233,13 +1231,12 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::onBrowseButtonClick( wxCommandEvent& a
|
||||
if( fn.MakeRelativeTo( Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith( wxS( ".." ) ) )
|
||||
path = fn.GetFullPath();
|
||||
|
||||
wxString msg;
|
||||
WX_STRING_REPORTER reporter( &msg );
|
||||
WX_STRING_REPORTER reporter;
|
||||
|
||||
if( loadLibrary( path, reporter, true ) )
|
||||
m_infoBar->Hide();
|
||||
else
|
||||
m_infoBar->ShowMessage( msg );
|
||||
m_infoBar->ShowMessage( reporter.GetMessages() );
|
||||
|
||||
updateWidgets();
|
||||
}
|
||||
|
||||
@@ -634,17 +634,6 @@ bool DIALOG_SYMBOL_PROPERTIES::Validate()
|
||||
if( !m_fieldsGrid->CommitPendingChanges() || !m_fieldsGrid->Validate() )
|
||||
return false;
|
||||
|
||||
if( !SCH_SYMBOL::IsReferenceStringValid( m_fields->at( REFERENCE_FIELD ).GetText() ) )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "References must start with a letter." ) );
|
||||
|
||||
wxCommandEvent *evt = new wxCommandEvent( SYMBOL_DELAY_FOCUS );
|
||||
evt->SetClientData( new VECTOR2I( REFERENCE_FIELD, FDC_VALUE ) );
|
||||
QueueEvent( evt );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for missing field names.
|
||||
for( size_t i = MANDATORY_FIELDS; i < m_fields->size(); ++i )
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <schematic.h>
|
||||
#include <dialogs/panel_setup_buses.h>
|
||||
#include "grid_tricks.h"
|
||||
#include <wx/clipbrd.h>
|
||||
|
||||
PANEL_SETUP_BUSES::PANEL_SETUP_BUSES( wxWindow* aWindow, SCH_EDIT_FRAME* aFrame ) :
|
||||
PANEL_SETUP_BUSES_BASE( aWindow ),
|
||||
@@ -147,6 +148,9 @@ bool PANEL_SETUP_BUSES::TransferDataFromWindow()
|
||||
for( int ii = 0; ii < m_aliasesGrid->GetNumberRows(); ++ii )
|
||||
m_aliases[ii]->SetName( m_aliasesGrid->GetCellValue( ii, 0 ) );
|
||||
|
||||
// Associate the respective members with the last alias that is active.
|
||||
updateAliasMembers( m_lastAlias );
|
||||
|
||||
SCH_SCREENS screens( m_frame->Schematic().Root() );
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
|
||||
@@ -168,6 +172,12 @@ void PANEL_SETUP_BUSES::OnAddAlias( wxCommandEvent& aEvent )
|
||||
m_aliases.push_back( std::make_shared<BUS_ALIAS>( m_frame->GetScreen() ) );
|
||||
|
||||
int row = m_aliasesGrid->GetNumberRows();
|
||||
|
||||
// Associate the respective members with the previous alias. This ensures that the association starts
|
||||
// correctly when adding more than one row
|
||||
if( row > 0 )
|
||||
updateAliasMembers( row - 1 );
|
||||
|
||||
m_aliasesGrid->AppendRows();
|
||||
|
||||
m_aliasesGrid->MakeCellVisible( row, 0 );
|
||||
@@ -216,8 +226,35 @@ void PANEL_SETUP_BUSES::OnAddMember( wxCommandEvent& aEvent )
|
||||
m_membersGrid->MakeCellVisible( row, 0 );
|
||||
m_membersGrid->SetGridCursor( row, 0 );
|
||||
|
||||
m_membersGrid->EnableCellEditControl( true );
|
||||
m_membersGrid->ShowCellEditControl();
|
||||
/*
|
||||
* Check if the clipboard contains text data.
|
||||
*
|
||||
* - If `clipboardHasText` is true, select the specified row in the members grid to allow our custom
|
||||
* conext menu to paste the clipbaord .
|
||||
* - Otherwise, enable and display the cell edit control, allowing the user to manually edit the cell.
|
||||
*/
|
||||
bool clipboardHasText = false;
|
||||
|
||||
if( wxTheClipboard->Open() )
|
||||
{
|
||||
if( wxTheClipboard->IsSupported( wxDF_TEXT )
|
||||
|| wxTheClipboard->IsSupported( wxDF_UNICODETEXT ) )
|
||||
{
|
||||
clipboardHasText = true;
|
||||
}
|
||||
|
||||
wxTheClipboard->Close();
|
||||
}
|
||||
|
||||
if( clipboardHasText )
|
||||
{
|
||||
m_membersGrid->SelectRow( row );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_membersGrid->EnableCellEditControl( true );
|
||||
m_membersGrid->ShowCellEditControl();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -459,3 +496,23 @@ void PANEL_SETUP_BUSES::OnUpdateUI( wxUpdateUIEvent& event )
|
||||
}
|
||||
|
||||
|
||||
void PANEL_SETUP_BUSES::updateAliasMembers( int aAliasIndex )
|
||||
{
|
||||
if( !m_aliases.empty() && m_membersGrid->GetNumberRows() > 0 && aAliasIndex >= 0
|
||||
&& aAliasIndex < m_aliases.size() )
|
||||
{
|
||||
const std::shared_ptr<BUS_ALIAS>& alias = m_aliases[aAliasIndex];
|
||||
|
||||
alias->Members().clear();
|
||||
|
||||
for( int ii = 0; ii < m_membersGrid->GetNumberRows(); ++ii )
|
||||
{
|
||||
wxString memberValue = m_membersGrid->GetCellValue( ii, 0 );
|
||||
|
||||
if( !memberValue.empty() )
|
||||
{
|
||||
alias->Members().push_back( memberValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,16 @@ protected:
|
||||
|
||||
void doReloadMembersGrid();
|
||||
|
||||
/*
|
||||
* When rows are created programmatically by pasting values from the clipboard,
|
||||
* the cell change event may not be triggered. This can prevent members from
|
||||
* being automatically added to the corresponding alias.
|
||||
*
|
||||
* To ensure that members are correctly associated with the alias,
|
||||
* we manually update the members for the needed alias.
|
||||
*/
|
||||
void updateAliasMembers( int aAliasIndex );
|
||||
|
||||
private:
|
||||
SCH_EDIT_FRAME* m_frame;
|
||||
wxString m_membersLabelTemplate;
|
||||
|
||||
@@ -346,12 +346,14 @@ PANEL_SYM_LIB_TABLE::PANEL_SYM_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, P
|
||||
aGrid->SelectRow( 0 );
|
||||
};
|
||||
|
||||
setupGrid( m_global_grid );
|
||||
setupGrid( m_global_grid );
|
||||
m_global_grid->Bind( wxEVT_GRID_CELL_LEFT_CLICK, &PANEL_SYM_LIB_TABLE::onGridCellLeftClickHandler, this );
|
||||
|
||||
if( m_projectTable )
|
||||
{
|
||||
m_project_grid->SetTable( new SYMBOL_LIB_TABLE_GRID( *m_projectTable ), true );
|
||||
setupGrid( m_project_grid );
|
||||
m_project_grid->Bind( wxEVT_GRID_CELL_LEFT_CLICK, &PANEL_SYM_LIB_TABLE::onGridCellLeftClickHandler, this );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -389,9 +391,13 @@ PANEL_SYM_LIB_TABLE::~PANEL_SYM_LIB_TABLE()
|
||||
// Delete the GRID_TRICKS.
|
||||
// Any additional event handlers should be popped before the window is deleted.
|
||||
m_global_grid->PopEventHandler( true );
|
||||
m_global_grid->Unbind( wxEVT_GRID_CELL_LEFT_CLICK, &PANEL_SYM_LIB_TABLE::onGridCellLeftClickHandler, this );
|
||||
|
||||
if( m_project_grid )
|
||||
{
|
||||
m_project_grid->PopEventHandler( true );
|
||||
m_project_grid->Unbind( wxEVT_GRID_CELL_LEFT_CLICK, &PANEL_SYM_LIB_TABLE::onGridCellLeftClickHandler, this );
|
||||
}
|
||||
|
||||
m_path_subs_grid->PopEventHandler( true );
|
||||
}
|
||||
@@ -1072,6 +1078,33 @@ SYMBOL_LIB_TABLE_GRID* PANEL_SYM_LIB_TABLE::cur_model() const
|
||||
}
|
||||
|
||||
|
||||
void PANEL_SYM_LIB_TABLE::onGridCellLeftClickHandler( wxGridEvent& event )
|
||||
{
|
||||
// Get the grid object that triggered the event
|
||||
wxGrid* grid = dynamic_cast<wxGrid*>( event.GetEventObject() );
|
||||
|
||||
// If the event object is a wxGrid, proceed with the handling
|
||||
if( grid )
|
||||
{
|
||||
int row = event.GetRow();
|
||||
int col = event.GetCol();
|
||||
|
||||
// Get the cell renderer for the clicked cell
|
||||
wxGridCellRenderer* renderer = grid->GetCellRenderer( row, col );
|
||||
|
||||
// Check if the renderer is a wxGridCellBoolRenderer using dynamic_cast
|
||||
if( dynamic_cast<wxGridCellBoolRenderer*>( renderer ) )
|
||||
{
|
||||
// Set the grid cursor to the clicked boolean cell
|
||||
grid->SetGridCursor( row, col );
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the default behavior to continue (toggle the bool)
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
size_t PANEL_SYM_LIB_TABLE::m_pageNdx = 0;
|
||||
|
||||
|
||||
@@ -1163,4 +1196,4 @@ void InvokeSchEditSymbolLibTable( KIWAY* aKiway, wxWindow *aParent )
|
||||
aKiway->ExpressMail( FRAME_SCH, MAIL_RELOAD_LIB, payload );
|
||||
aKiway->ExpressMail( FRAME_SCH_SYMBOL_EDITOR, MAIL_RELOAD_LIB, payload );
|
||||
aKiway->ExpressMail( FRAME_SCH_VIEWER, MAIL_RELOAD_LIB, payload );
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,7 @@ private:
|
||||
void onSizeGrid( wxSizeEvent& event ) override;
|
||||
void adjustPathSubsGridColumns( int aWidth );
|
||||
void onConvertLegacyLibraries( wxCommandEvent& event ) override;
|
||||
void onGridCellLeftClickHandler( wxGridEvent& event );
|
||||
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
#include <pgm_base.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <eeschema_settings.h>
|
||||
@@ -186,10 +188,41 @@ bool PANEL_TEMPLATE_FIELDNAMES::TransferDataFromWindow()
|
||||
|
||||
m_templateMgr->DeleteAllFieldNameTemplates( m_global );
|
||||
|
||||
for( const TEMPLATE_FIELDNAME& field : m_fields )
|
||||
for( TEMPLATE_FIELDNAME& field : m_fields )
|
||||
{
|
||||
if( !field.m_Name.IsEmpty() )
|
||||
{
|
||||
wxString trimmedName = field.m_Name;
|
||||
|
||||
trimmedName.Trim();
|
||||
trimmedName.Trim( false );
|
||||
|
||||
// Check if the field name contains leading and/or trailing white space.
|
||||
if( field.m_Name != trimmedName )
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( _( "The field name \"%s\" contains trailing and/or leading white"
|
||||
"space." ), field.m_Name );
|
||||
|
||||
wxMessageDialog dlg( this, msg, _( "Warning" ),
|
||||
wxOK | wxCANCEL | wxCENTER | wxICON_WARNING );
|
||||
|
||||
dlg.SetExtendedMessage( _( "This may result in what appears to be duplicate field "
|
||||
"names but are actually unique names differing only by "
|
||||
"white space characters. Removing the white space "
|
||||
"characters will have no effect on existing symbol "
|
||||
"field names." ) );
|
||||
|
||||
dlg.SetOKCancelLabels( wxMessageDialog::ButtonLabel( _( "Remove White Space" ) ),
|
||||
wxMessageDialog::ButtonLabel( _( "Keep White Space" ) ) );
|
||||
|
||||
if( dlg.ShowModal() == wxID_OK )
|
||||
field.m_Name = trimmedName;
|
||||
}
|
||||
|
||||
m_templateMgr->AddTemplateFieldName( field, m_global );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_global )
|
||||
|
||||
+4
-4
@@ -1083,8 +1083,7 @@ int ERC_TESTER::TestOffGridEndpoints()
|
||||
|
||||
int ERC_TESTER::TestSimModelIssues()
|
||||
{
|
||||
wxString msg;
|
||||
WX_STRING_REPORTER reporter( &msg );
|
||||
WX_STRING_REPORTER reporter;
|
||||
int err_count = 0;
|
||||
SIM_LIB_MGR libMgr( &m_schematic->Prj() );
|
||||
|
||||
@@ -1102,12 +1101,13 @@ int ERC_TESTER::TestSimModelIssues()
|
||||
continue;
|
||||
|
||||
// Reset for each symbol
|
||||
msg.Clear();
|
||||
reporter.Clear();
|
||||
|
||||
SIM_LIBRARY::MODEL model = libMgr.CreateModel( &sheet, *symbol, reporter );
|
||||
|
||||
if( !msg.IsEmpty() )
|
||||
if( reporter.HasMessage() )
|
||||
{
|
||||
wxString msg = reporter.GetMessages();
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_SIMULATION_MODEL );
|
||||
|
||||
//Remove \n and \r at e.o.l if any:
|
||||
|
||||
+11
-4
@@ -533,6 +533,13 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||
SCH_COMMIT dummy( this );
|
||||
|
||||
RecalculateConnections( &dummy, GLOBAL_CLEANUP );
|
||||
|
||||
if( schematic.HasSymbolFieldNamesWithWhiteSpace() )
|
||||
{
|
||||
m_infoBar->QueueShowMessage( _( "This schematic contains symbols that have leading "
|
||||
"and/or trailing white space field names." ),
|
||||
wxICON_WARNING );
|
||||
}
|
||||
}
|
||||
|
||||
// Load any exclusions from the project file
|
||||
@@ -1276,10 +1283,10 @@ bool SCH_EDIT_FRAME::SaveProject( bool aSaveAs )
|
||||
|
||||
if( !Kiface().IsSingle() )
|
||||
{
|
||||
WX_STRING_REPORTER backupReporter( &msg );
|
||||
WX_STRING_REPORTER backupReporter;
|
||||
|
||||
if( !GetSettingsManager()->TriggerBackupIfNeeded( backupReporter ) )
|
||||
SetStatusText( msg, 0 );
|
||||
SetStatusText( backupReporter.GetMessages(), 0 );
|
||||
}
|
||||
|
||||
updateTitle();
|
||||
@@ -1404,8 +1411,8 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
|
||||
|
||||
pi->SetProgressReporter( &progressReporter );
|
||||
|
||||
SCH_SHEET* loadedSheet =
|
||||
pi->LoadSchematicFile( aFileName, &Schematic(), nullptr, aProperties );
|
||||
SCH_SHEET* loadedSheet = pi->LoadSchematicFile( aFileName, &Schematic(), nullptr,
|
||||
aProperties );
|
||||
|
||||
if( loadedSheet )
|
||||
{
|
||||
|
||||
@@ -136,9 +136,11 @@ void ConvertImageToLibShapes( LIB_SYMBOL* aSymbol, int unit, wxImage img, VECTOR
|
||||
|
||||
shape->Offset( offset );
|
||||
|
||||
aSymbol->AddDrawItem( shape.release() );
|
||||
aSymbol->AddDrawItem( shape.release(), false );
|
||||
}
|
||||
}
|
||||
|
||||
aSymbol->GetDrawItems().sort();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -372,8 +372,8 @@ void SCH_EDIT_FRAME::onNetNavigatorSelection( wxTreeEvent& aEvent )
|
||||
|
||||
if( GetCurrentSheet() != itemData->GetSheetPath() )
|
||||
{
|
||||
Schematic().SetCurrentSheet( itemData->GetSheetPath() );
|
||||
DisplayCurrentSheet();
|
||||
GetToolManager()->RunAction<SCH_SHEET_PATH*>( EE_ACTIONS::changeSheet,
|
||||
&itemData->GetSheetPath() );
|
||||
}
|
||||
|
||||
// Do not focus on item when a sheet tree node is selected.
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <sch_text.h>
|
||||
#include <sch_textbox.h>
|
||||
#include <string_utils.h>
|
||||
#include <ki_exception.h>
|
||||
|
||||
#include <dialogs/html_message_box.h>
|
||||
#include <fmt/core.h>
|
||||
@@ -210,31 +211,38 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
||||
if( !symbol || symbol->GetExcludedFromSim() )
|
||||
continue;
|
||||
|
||||
SPICE_ITEM spiceItem;
|
||||
std::vector<PIN_INFO> pins = CreatePinList( symbol, &sheet, true );
|
||||
|
||||
for( const SCH_FIELD& field : symbol->GetFields() )
|
||||
try
|
||||
{
|
||||
spiceItem.fields.emplace_back( VECTOR2I(), -1, symbol, field.GetName() );
|
||||
SPICE_ITEM spiceItem;
|
||||
std::vector<PIN_INFO> pins = CreatePinList( symbol, &sheet, true );
|
||||
|
||||
if( field.GetId() == REFERENCE_FIELD )
|
||||
spiceItem.fields.back().SetText( symbol->GetRef( &sheet ) );
|
||||
else
|
||||
spiceItem.fields.back().SetText( field.GetShownText( &sheet, false ) );
|
||||
for( const SCH_FIELD& field : symbol->GetFields() )
|
||||
{
|
||||
spiceItem.fields.emplace_back( VECTOR2I(), -1, symbol, field.GetName() );
|
||||
|
||||
if( field.GetId() == REFERENCE_FIELD )
|
||||
spiceItem.fields.back().SetText( symbol->GetRef( &sheet ) );
|
||||
else
|
||||
spiceItem.fields.back().SetText( field.GetShownText( &sheet, false ) );
|
||||
}
|
||||
|
||||
readRefName( sheet, *symbol, spiceItem, refNames );
|
||||
readModel( sheet, *symbol, spiceItem, aReporter );
|
||||
readPinNumbers( *symbol, spiceItem, pins );
|
||||
readPinNetNames( *symbol, spiceItem, pins, ncCounter );
|
||||
|
||||
// TODO: transmission line handling?
|
||||
|
||||
m_items.push_back( std::move( spiceItem ) );
|
||||
}
|
||||
catch( IO_ERROR& e )
|
||||
{
|
||||
aReporter.Report( e.What(), RPT_SEVERITY_ERROR );
|
||||
}
|
||||
|
||||
readRefName( sheet, *symbol, spiceItem, refNames );
|
||||
readModel( sheet, *symbol, spiceItem, aReporter );
|
||||
readPinNumbers( *symbol, spiceItem, pins );
|
||||
readPinNetNames( *symbol, spiceItem, pins, ncCounter );
|
||||
|
||||
// TODO: transmission line handling?
|
||||
|
||||
m_items.push_back( std::move( spiceItem ) );
|
||||
}
|
||||
}
|
||||
|
||||
return !aReporter.HasMessage();
|
||||
return !aReporter.HasMessageOfSeverity( RPT_SEVERITY_UNDEFINED | RPT_SEVERITY_ERROR );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -184,6 +184,7 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
|
||||
bool itemsDeselected = false;
|
||||
bool selectedModified = false;
|
||||
bool dirtyConnectivity = false;
|
||||
bool refreshHierarchy = false;
|
||||
SCH_CLEANUP_FLAGS connectivityCleanUp = NO_CLEANUP;
|
||||
|
||||
if( Empty() )
|
||||
@@ -261,6 +262,9 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
|
||||
|
||||
bulkAddedItems.push_back( schItem );
|
||||
|
||||
if( schItem->Type() == SCH_SHEET_T )
|
||||
refreshHierarchy = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -298,6 +302,9 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
|
||||
|
||||
bulkRemovedItems.push_back( schItem );
|
||||
|
||||
if( schItem->Type() == SCH_SHEET_T )
|
||||
refreshHierarchy = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -321,6 +328,17 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
|
||||
if( itemCopy->HasConnectivityChanges( schItem, ¤tSheet ) )
|
||||
updateConnectivityFlag();
|
||||
|
||||
|
||||
if( schItem->Type() == SCH_SHEET_T )
|
||||
{
|
||||
const SCH_SHEET* modifiedSheet = static_cast<const SCH_SHEET*>( schItem );
|
||||
const SCH_SHEET* originalSheet = static_cast<const SCH_SHEET*>( itemCopy );
|
||||
wxCHECK2( modifiedSheet && originalSheet, continue );
|
||||
|
||||
if( originalSheet->HasPageNumberChanges( *modifiedSheet ) )
|
||||
refreshHierarchy = true;
|
||||
}
|
||||
|
||||
undoList.PushItem( itemWrapper );
|
||||
ent.m_copy = nullptr; // We've transferred ownership to the undo list
|
||||
}
|
||||
@@ -361,6 +379,9 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
|
||||
|
||||
if( itemsChanged.size() > 0 )
|
||||
schematic->OnItemsChanged( itemsChanged );
|
||||
|
||||
if( frame && refreshHierarchy )
|
||||
frame->UpdateHierarchyNavigator();
|
||||
}
|
||||
|
||||
if( !( aCommitFlags & SKIP_UNDO ) )
|
||||
|
||||
@@ -769,8 +769,9 @@ void SCH_EDIT_FRAME::AddCopyForRepeatItem( const SCH_ITEM* aItem )
|
||||
{
|
||||
std::unique_ptr<SCH_ITEM> repeatItem( static_cast<SCH_ITEM*>( aItem->Duplicate() ) );
|
||||
|
||||
// Clone() preserves the flags, we want 'em cleared.
|
||||
// Clone() preserves the flags & parent, we want 'em cleared.
|
||||
repeatItem->ClearFlags();
|
||||
repeatItem->SetParent( nullptr );
|
||||
|
||||
m_items_to_repeat.emplace_back( std::move( repeatItem ) );
|
||||
}
|
||||
|
||||
@@ -58,6 +58,26 @@ const wxString PartVersionFieldName = "Part Version";
|
||||
const wxString PartAcceptanceFieldName = "Part Acceptance";
|
||||
|
||||
|
||||
wxString CADSTAR_SCH_ARCHIVE_LOADER::CreateLibName( const wxFileName& aFileName,
|
||||
const SCH_SHEET* aRootSheet )
|
||||
{
|
||||
wxString libName = aFileName.GetName();
|
||||
|
||||
if( libName.IsEmpty() && aRootSheet )
|
||||
{
|
||||
wxFileName fn( aRootSheet->GetFileName() );
|
||||
libName = fn.GetName();
|
||||
}
|
||||
|
||||
if( libName.IsEmpty() )
|
||||
libName = "noname";
|
||||
|
||||
libName = LIB_ID::FixIllegalChars( libName, true ).wx_str();
|
||||
|
||||
return libName;
|
||||
}
|
||||
|
||||
|
||||
std::vector<LIB_SYMBOL*> CADSTAR_SCH_ARCHIVE_LOADER::LoadPartsLib( const wxString& aFilename )
|
||||
{
|
||||
if( m_progressReporter )
|
||||
@@ -2078,8 +2098,11 @@ SCH_SYMBOL* CADSTAR_SCH_ARCHIVE_LOADER::loadSchematicSymbol( const SYMBOL& aCads
|
||||
const LIB_SYMBOL& aKiCadPart,
|
||||
EDA_ANGLE& aComponentOrientation )
|
||||
{
|
||||
wxString libName = CreateLibName( m_footprintLibName, m_rootSheet );
|
||||
|
||||
LIB_ID libId;
|
||||
libId.SetLibItemName( aKiCadPart.GetName() );
|
||||
libId.SetLibNickname( libName );
|
||||
|
||||
int unit = getKiCadUnitNumberFromGate( aCadstarSymbol.GateID );
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ public:
|
||||
m_designCenter.y = 0;
|
||||
m_reporter = aReporter;
|
||||
m_progressReporter = aProgressReporter;
|
||||
m_fileName = aFilename;
|
||||
|
||||
// Assume that the PCB footprint library name will be the same as the schematic filename
|
||||
wxFileName schFilename( Filename );
|
||||
@@ -97,6 +98,7 @@ public:
|
||||
*/
|
||||
void Load( SCHEMATIC* aSchematic, SCH_SHEET* aRootSheet );
|
||||
|
||||
static wxString CreateLibName( const wxFileName& aFileName, const SCH_SHEET* aRootSheet );
|
||||
|
||||
private:
|
||||
typedef std::pair<BLOCK_ID, TERMINAL_ID> BLOCK_PIN_ID;
|
||||
@@ -113,6 +115,7 @@ private:
|
||||
REPORTER* m_reporter;
|
||||
SCHEMATIC* m_schematic;
|
||||
SCH_SHEET* m_rootSheet;
|
||||
wxFileName m_fileName;
|
||||
wxString m_footprintLibName; ///< Name of the footprint library to prepend all footprints with
|
||||
|
||||
/**
|
||||
|
||||
@@ -102,19 +102,8 @@ SCH_SHEET* SCH_IO_CADSTAR_ARCHIVE::LoadSchematicFile( const wxString& aFi
|
||||
|
||||
wxCHECK_MSG( libTable, nullptr, "Could not load symbol lib table." );
|
||||
|
||||
// Lets come up with a nice library name
|
||||
wxString libName = aSchematic->Prj().GetProjectName();
|
||||
|
||||
if( libName.IsEmpty() )
|
||||
{
|
||||
wxFileName fn( rootSheet->GetFileName() );
|
||||
libName = fn.GetName();
|
||||
}
|
||||
|
||||
if( libName.IsEmpty() )
|
||||
libName = "noname";
|
||||
|
||||
libName = LIB_ID::FixIllegalChars( libName, true ).wx_str();
|
||||
wxFileName fn = aSchematic->Prj().GetProjectFullName();
|
||||
wxString libName = CADSTAR_SCH_ARCHIVE_LOADER::CreateLibName( fn, nullptr );
|
||||
|
||||
wxFileName libFileName( aSchematic->Prj().GetProjectPath(), libName,
|
||||
FILEEXT::KiCadSymbolLibFileExtension );
|
||||
|
||||
@@ -505,6 +505,32 @@ SCH_EASYEDAPRO_PARSER::ParseSymbol( const std::vector<nlohmann::json>& aLines,
|
||||
|
||||
ksymbol->AddDrawItem( shape.release() );
|
||||
}
|
||||
else if( type == wxS( "BEZIER" ) )
|
||||
{
|
||||
std::vector<double> points = line.at( 2 );
|
||||
wxString styleStr = line.at( 3 );
|
||||
|
||||
std::unique_ptr<LIB_SHAPE> shape =
|
||||
std::make_unique<LIB_SHAPE>( ksymbol, SHAPE_T::BEZIER );
|
||||
|
||||
for( size_t i = 1; i < points.size(); i += 2 )
|
||||
{
|
||||
VECTOR2I pt = ScalePosSym( VECTOR2D( points[i - 1], points[i] ) );
|
||||
|
||||
switch( i )
|
||||
{
|
||||
case 1: shape->SetStart( pt ); break;
|
||||
case 3: shape->SetBezierC1( pt ); break;
|
||||
case 5: shape->SetBezierC2( pt ); break;
|
||||
case 7: shape->SetEnd( pt ); break;
|
||||
}
|
||||
}
|
||||
|
||||
shape->SetUnit( currentUnit );
|
||||
ApplyLineStyle( lineStyles, shape, styleStr );
|
||||
|
||||
ksymbol->AddDrawItem( shape.release() );
|
||||
}
|
||||
else if( type == wxS( "POLY" ) )
|
||||
{
|
||||
std::vector<double> points = line.at( 2 );
|
||||
@@ -1148,8 +1174,8 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
|
||||
if( !deviceAttr )
|
||||
continue;
|
||||
|
||||
std::map<wxString, wxString> compAttrs =
|
||||
aProject.at( "devices" ).at( deviceAttr->value ).at( "attributes" );
|
||||
std::map<wxString, wxString> compAttrs = EASYEDAPRO::AnyMapToStringMap(
|
||||
aProject.at( "devices" ).at( deviceAttr->value ).at( "attributes" ) );
|
||||
|
||||
wxString symbolId;
|
||||
|
||||
@@ -1210,39 +1236,60 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
|
||||
{
|
||||
auto nameAttr = get_opt( attributes, "Name" );
|
||||
|
||||
wxString netName;
|
||||
|
||||
if( nameAttr && !nameAttr->value.IsEmpty() )
|
||||
netName = nameAttr->value;
|
||||
else
|
||||
netName = compAttrs.at( "Name" );
|
||||
|
||||
std::unique_ptr<SCH_GLOBALLABEL> label = std::make_unique<SCH_GLOBALLABEL>(
|
||||
ScalePos( component->position ), netName );
|
||||
|
||||
std::vector<SCH_PIN*> pins = schSym->GetPins( &aSchematic->CurrentSheet() );
|
||||
|
||||
if( pins.size() > 0 )
|
||||
{
|
||||
switch( pins[0]->GetType() )
|
||||
{
|
||||
case ELECTRICAL_PINTYPE::PT_INPUT:
|
||||
label->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
|
||||
break;
|
||||
case ELECTRICAL_PINTYPE::PT_OUTPUT:
|
||||
label->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
|
||||
break;
|
||||
case ELECTRICAL_PINTYPE::PT_BIDI:
|
||||
label->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
BOX2I bbox = schSym->GetBodyAndPinsBoundingBox();
|
||||
bbox.Offset( -schSym->GetPosition() );
|
||||
VECTOR2I bboxCenter = bbox.GetCenter();
|
||||
|
||||
SPIN_STYLE spin = SPIN_STYLE::LEFT;
|
||||
|
||||
if( std::abs( bboxCenter.x ) >= std::abs( bboxCenter.y ) )
|
||||
{
|
||||
if( bboxCenter.x >= 0 )
|
||||
spin = SPIN_STYLE::RIGHT;
|
||||
else
|
||||
spin = SPIN_STYLE::LEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( bboxCenter.y >= 0 )
|
||||
spin = SPIN_STYLE::BOTTOM;
|
||||
else
|
||||
spin = SPIN_STYLE::UP;
|
||||
}
|
||||
|
||||
label->SetSpinStyle( spin );
|
||||
|
||||
if( nameAttr )
|
||||
{
|
||||
std::unique_ptr<SCH_GLOBALLABEL> label = std::make_unique<SCH_GLOBALLABEL>(
|
||||
ScalePos( component->position ), nameAttr->value );
|
||||
|
||||
SPIN_STYLE spin = SPIN_STYLE::LEFT;
|
||||
|
||||
if( esymInfo.symbolAttr )
|
||||
{
|
||||
wxString symStr = esymInfo.symbolAttr->value;
|
||||
|
||||
if( symStr == wxS( "Netport-IN" ) )
|
||||
{
|
||||
spin = SPIN_STYLE::LEFT;
|
||||
label->SetShape( LABEL_FLAG_SHAPE::L_INPUT );
|
||||
}
|
||||
if( symStr == wxS( "Netport-OUT" ) )
|
||||
{
|
||||
spin = SPIN_STYLE::RIGHT;
|
||||
label->SetShape( LABEL_FLAG_SHAPE::L_OUTPUT );
|
||||
}
|
||||
if( symStr == wxS( "Netport-BI" ) )
|
||||
{
|
||||
spin = SPIN_STYLE::RIGHT;
|
||||
label->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
|
||||
}
|
||||
}
|
||||
|
||||
for( double i = component->rotation; i > 0; i -= 90 )
|
||||
spin = spin.RotateCCW();
|
||||
|
||||
label->SetSpinStyle( spin );
|
||||
|
||||
nlohmann::json style = fontStyles[nameAttr->fontStyle];
|
||||
|
||||
if( !style.is_null() && style.at( 5 ).is_number() )
|
||||
@@ -1250,10 +1297,10 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
|
||||
double size = style.at( 5 ).get<double>() * 0.5;
|
||||
label->SetTextSize( VECTOR2I( ScaleSize( size ), ScaleSize( size ) ) );
|
||||
}
|
||||
|
||||
createdItems.push_back( std::move( label ) );
|
||||
}
|
||||
|
||||
createdItems.push_back( std::move( label ) );
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@@ -1285,6 +1332,12 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
|
||||
auto nameAttr = get_opt( attributes, "Name" );
|
||||
auto valueAttr = get_opt( attributes, "Value" );
|
||||
|
||||
if( valueAttr && valueAttr->value.empty() )
|
||||
valueAttr->value = get_def( compAttrs, "Value", wxString() );
|
||||
|
||||
if( nameAttr && nameAttr->value.empty() )
|
||||
nameAttr->value = get_def( compAttrs, "Name", wxString() );
|
||||
|
||||
std::optional<EASYEDAPRO::SCH_ATTR> targetValueAttr;
|
||||
|
||||
if( valueAttr && !valueAttr->value.empty() && valueAttr->valVisible )
|
||||
@@ -1412,7 +1465,7 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
|
||||
|
||||
if( netAttr )
|
||||
{
|
||||
if( !netAttr->valVisible )
|
||||
if( !netAttr->valVisible || netAttr->value.IsEmpty() )
|
||||
continue;
|
||||
|
||||
VECTOR2I kpos = ScalePos( *netAttr->position );
|
||||
|
||||
@@ -1075,7 +1075,7 @@ SCH_TEXT* SCH_IO_KICAD_LEGACY::loadText( LINE_READER& aReader )
|
||||
if( m_version > 2 || *line >= ' ' )
|
||||
{
|
||||
if( strCompare( "Italic", line, &line ) )
|
||||
text->SetItalic( true );
|
||||
text->SetItalicFlag( true );
|
||||
else if( !strCompare( "~", line, &line ) )
|
||||
SCH_PARSE_ERROR( _( "expected 'Italics' or '~'" ), aReader, line );
|
||||
}
|
||||
@@ -1359,7 +1359,7 @@ SCH_SYMBOL* SCH_IO_KICAD_LEGACY::loadSymbol( LINE_READER& aReader )
|
||||
|
||||
if( textAttrs[1] == 'I' )
|
||||
{
|
||||
field.SetItalic( true );
|
||||
field.SetItalicFlag( true );
|
||||
}
|
||||
else if( textAttrs[1] != 'N' )
|
||||
{
|
||||
|
||||
@@ -647,7 +647,7 @@ void SCH_IO_KICAD_LEGACY_LIB_CACHE::loadField( std::unique_ptr<LIB_SYMBOL>& aSym
|
||||
wxChar attr_2 = attributes[2];
|
||||
|
||||
if( attr_1 == 'I' ) // Italic
|
||||
field->SetItalic( true );
|
||||
field->SetItalicFlag( true );
|
||||
else if( attr_1 != 'N' ) // No italics is default, check for error.
|
||||
SCH_PARSE_ERROR( "invalid field text italic parameter", aReader, line );
|
||||
|
||||
@@ -1015,7 +1015,7 @@ LIB_TEXT* SCH_IO_KICAD_LEGACY_LIB_CACHE::loadText( std::unique_ptr<LIB_SYMBOL>&
|
||||
&& !is_eol( *line ) )
|
||||
{
|
||||
if( strCompare( "Italic", line, &line ) )
|
||||
text->SetItalic( true );
|
||||
text->SetItalicFlag( true );
|
||||
else if( !strCompare( "Normal", line, &line ) )
|
||||
SCH_PARSE_ERROR( "invalid text stype, expected 'Normal' or 'Italic'", aReader, line );
|
||||
|
||||
|
||||
@@ -744,7 +744,7 @@ void SCH_IO_KICAD_SEXPR_PARSER::parseEDA_TEXT( EDA_TEXT* aText, bool aConvertOve
|
||||
case T_italic:
|
||||
{
|
||||
bool italic = parseMaybeAbsentBool( true );
|
||||
aText->SetItalic( italic );
|
||||
aText->SetItalicFlag( italic );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,8 +89,8 @@ public:
|
||||
|
||||
bool CanConnect( const SCH_ITEM* aItem ) const override
|
||||
{
|
||||
return ( aItem->Type() == SCH_LINE_T && aItem->GetLayer() == LAYER_WIRE ) ||
|
||||
aItem->Type() == SCH_SYMBOL_T;
|
||||
return ( aItem->Type() == SCH_LINE_T && aItem->GetLayer() == LAYER_WIRE )
|
||||
|| aItem->Type() == SCH_SYMBOL_T || aItem->Type() == SCH_SHEET_T;
|
||||
}
|
||||
|
||||
std::vector<VECTOR2I> GetConnectionPoints() const override;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 1992-2018 Jean-Pierre Charras jp.charras at wanadoo.fr
|
||||
* Copyright (C) 1992-2010 Lorenzo Marcantonio
|
||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -132,8 +132,10 @@ void SCH_PLOTTER::createPDFFile( const SCH_PLOT_SETTINGS& aPlotSettings,
|
||||
sheetList.push_back( m_schematic->CurrentSheet() );
|
||||
}
|
||||
|
||||
wxCHECK( m_schematic, /* void */ );
|
||||
|
||||
// Allocate the plotter and set the job level parameter
|
||||
PDF_PLOTTER* plotter = new PDF_PLOTTER();
|
||||
PDF_PLOTTER* plotter = new PDF_PLOTTER( &m_schematic->Prj() );
|
||||
plotter->SetRenderSettings( aRenderSettings );
|
||||
plotter->SetColorMode( !aPlotSettings.m_blackAndWhite );
|
||||
plotter->SetCreator( wxT( "Eeschema-PDF" ) );
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 1992-2018 Jean-Pierre Charras jp.charras at wanadoo.fr
|
||||
* Copyright (C) 1992-2010 Lorenzo Marcantonio
|
||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1743,6 +1743,31 @@ void SCH_SCREEN::PruneOrphanedSheetInstances( const wxString& aProjectName,
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SCREEN::HasSymbolFieldNamesWithWhiteSpace() const
|
||||
{
|
||||
wxString trimmedFieldName;
|
||||
|
||||
for( const SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
|
||||
{
|
||||
const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( item );
|
||||
|
||||
wxCHECK2( symbol, continue );
|
||||
|
||||
for( const SCH_FIELD& field : symbol->GetFields() )
|
||||
{
|
||||
trimmedFieldName = field.GetName();
|
||||
trimmedFieldName.Trim();
|
||||
trimmedFieldName.Trim( false );
|
||||
|
||||
if( field.GetName() != trimmedFieldName )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
|
||||
{
|
||||
@@ -2161,3 +2186,15 @@ void SCH_SCREENS::PruneOrphanedSheetInstances( const wxString& aProjectName,
|
||||
for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
|
||||
screen->PruneOrphanedSheetInstances( aProjectName, aValidSheetPaths );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SCREENS::HasSymbolFieldNamesWithWhiteSpace() const
|
||||
{
|
||||
for( const SCH_SCREEN* screen : m_screens )
|
||||
{
|
||||
if( screen->HasSymbolFieldNamesWithWhiteSpace() )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -542,6 +542,8 @@ public:
|
||||
*/
|
||||
bool AllSymbolDefaultInstancesNotSet();
|
||||
|
||||
bool HasSymbolFieldNamesWithWhiteSpace() const;
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const override;
|
||||
#endif
|
||||
@@ -829,6 +831,8 @@ public:
|
||||
void PruneOrphanedSheetInstances( const wxString& aProjectName,
|
||||
const SCH_SHEET_LIST& aValidSheetPaths );
|
||||
|
||||
bool HasSymbolFieldNamesWithWhiteSpace() const;
|
||||
|
||||
private:
|
||||
void addScreenToList( SCH_SCREEN* aScreen, SCH_SHEET* aSheet );
|
||||
void buildScreenList( SCH_SHEET* aSheet);
|
||||
|
||||
@@ -1411,6 +1411,59 @@ void SCH_SHEET::setPageNumber( const KIID_PATH& aPath, const wxString& aPageNumb
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SHEET::HasPageNumberChanges( const SCH_SHEET& aOther ) const
|
||||
{
|
||||
// Avoid self comparison.
|
||||
if( &aOther == this )
|
||||
return false;
|
||||
|
||||
// A difference in the instance data count implies a page numbering change.
|
||||
if( GetInstances().size() != aOther.GetInstances().size() )
|
||||
return true;
|
||||
|
||||
std::vector<SCH_SHEET_INSTANCE> instances = GetInstances();
|
||||
std::vector<SCH_SHEET_INSTANCE> otherInstances = aOther.GetInstances();
|
||||
|
||||
// Sorting may not be necessary but there is no guaratee that sheet
|
||||
// instance data will be in the correct KIID_PATH order. We should
|
||||
// probably use a std::map instead of a std::vector to store the sheet
|
||||
// instance data.
|
||||
std::sort( instances.begin(), instances.end(),
|
||||
[]( const SCH_SHEET_INSTANCE& aLhs, const SCH_SHEET_INSTANCE& aRhs )
|
||||
{
|
||||
if( aLhs.m_Path > aRhs.m_Path )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
} );
|
||||
std::sort( otherInstances.begin(), otherInstances.end(),
|
||||
[]( const SCH_SHEET_INSTANCE& aLhs, const SCH_SHEET_INSTANCE& aRhs )
|
||||
{
|
||||
if( aLhs.m_Path > aRhs.m_Path )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
} );
|
||||
|
||||
auto itThis = instances.begin();
|
||||
auto itOther = otherInstances.begin();
|
||||
|
||||
while( itThis != instances.end() )
|
||||
{
|
||||
if( ( itThis->m_Path == itOther->m_Path )
|
||||
&& ( itThis->m_PageNumber != itOther->m_PageNumber ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
itThis++;
|
||||
itOther++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int SCH_SHEET::ComparePageNum( const wxString& aPageNumberA, const wxString& aPageNumberB )
|
||||
{
|
||||
if( aPageNumberA == aPageNumberB )
|
||||
|
||||
@@ -416,6 +416,14 @@ public:
|
||||
|
||||
void AddInstance( const SCH_SHEET_INSTANCE& aInstance );
|
||||
|
||||
/**
|
||||
* Check if the instance data of this sheet has any changes compared to \a aOther.
|
||||
*
|
||||
* @param aOther is the sheet to compare against.
|
||||
* @return true if there are page number changes with \a aOther otherwise false.
|
||||
*/
|
||||
bool HasPageNumberChanges( const SCH_SHEET& aOther ) const;
|
||||
|
||||
/**
|
||||
* Compares page numbers of schematic sheets.
|
||||
*
|
||||
|
||||
@@ -649,7 +649,19 @@ void SCH_SHEET_PATH::CheckForMissingSymbolInstances( const wxString& aProjectNam
|
||||
"sheet path '%s'.",
|
||||
symbol->m_Uuid.AsString(), PathHumanReadable( false ) );
|
||||
|
||||
symbolInstance.m_Reference = UTIL::GetRefDesUnannotated( symbol->GetPrefix() );
|
||||
// Legacy schematics that are not shared do not contain separate instance data.
|
||||
// The symbol refrence and unit are saved in the reference field and unit entries.
|
||||
if( ( LastScreen()->GetRefCount() <= 1 ) &&
|
||||
( LastScreen()->GetFileFormatVersionAtLoad() <= 20200310 ) )
|
||||
{
|
||||
symbolInstance.m_Reference =
|
||||
symbol->GetField( REFERENCE_FIELD )->GetShownText( this, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
symbolInstance.m_Reference = UTIL::GetRefDesUnannotated( symbol->GetPrefix() );
|
||||
}
|
||||
|
||||
symbolInstance.m_ProjectName = aProjectName;
|
||||
symbolInstance.m_Path = Path();
|
||||
symbol->AddHierarchicalReference( symbolInstance );
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <string_utils.h>
|
||||
|
||||
#include <utility>
|
||||
#include <validators.h>
|
||||
|
||||
|
||||
std::unordered_map<TRANSFORM, int> SCH_SYMBOL::s_transformToOrientationCache;
|
||||
@@ -783,9 +784,12 @@ const wxString SCH_SYMBOL::GetRef( const SCH_SHEET_PATH* sheet, bool aIncludeUni
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SYMBOL::IsReferenceStringValid( const wxString& aReferenceString )
|
||||
void SCH_SYMBOL::SetRefProp( const wxString& aRef )
|
||||
{
|
||||
return !UTIL::GetRefDesPrefix( aReferenceString ).IsEmpty();
|
||||
FIELD_VALIDATOR validator( REFERENCE_FIELD );
|
||||
|
||||
if( validator.DoValidate( aRef, nullptr ) )
|
||||
SetRef( &Schematic()->CurrentSheet(), aRef );
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-14
@@ -556,10 +556,7 @@ public:
|
||||
{
|
||||
return GetRef( &Schematic()->CurrentSheet() );
|
||||
}
|
||||
void SetRefProp( const wxString aRef )
|
||||
{
|
||||
SetRef( &Schematic()->CurrentSheet(), aRef );
|
||||
}
|
||||
void SetRefProp( const wxString& aRef );
|
||||
wxString GetValueProp() const
|
||||
{
|
||||
return GetValueFieldText( false, &Schematic()->CurrentSheet(), false );
|
||||
@@ -677,16 +674,6 @@ public:
|
||||
|
||||
void SwapData( SCH_ITEM* aItem ) override;
|
||||
|
||||
/**
|
||||
* Test for an acceptable reference string.
|
||||
*
|
||||
* An acceptable reference string must support unannotation i.e starts by letter
|
||||
*
|
||||
* @param aReferenceString is the reference string to validate
|
||||
* @return true if reference string is valid.
|
||||
*/
|
||||
static bool IsReferenceStringValid( const wxString& aReferenceString );
|
||||
|
||||
/**
|
||||
* Return the reference for the given sheet path.
|
||||
*
|
||||
|
||||
@@ -453,7 +453,7 @@ std::map<int, wxString> SCHEMATIC::GetVirtualPageToSheetNamesMap() const
|
||||
{
|
||||
std::map<int, wxString> namesMap;
|
||||
|
||||
for( const SCH_SHEET_PATH& sheet : GetUnorderedSheets() )
|
||||
for( const SCH_SHEET_PATH& sheet : GetSheets() )
|
||||
{
|
||||
if( sheet.size() == 1 )
|
||||
namesMap[sheet.GetVirtualPageNumber()] = _( "<root sheet>" );
|
||||
@@ -469,7 +469,7 @@ std::map<int, wxString> SCHEMATIC::GetVirtualPageToSheetPagesMap() const
|
||||
{
|
||||
std::map<int, wxString> pagesMap;
|
||||
|
||||
for( const SCH_SHEET_PATH& sheet : GetUnorderedSheets() )
|
||||
for( const SCH_SHEET_PATH& sheet : GetSheets() )
|
||||
pagesMap[sheet.GetVirtualPageNumber()] = sheet.GetPageNumber();
|
||||
|
||||
return pagesMap;
|
||||
|
||||
@@ -400,7 +400,8 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
|
||||
wxCHECK2( origSheet && copySheet, continue );
|
||||
|
||||
if( ( origSheet->GetName() != copySheet->GetName() )
|
||||
|| ( origSheet->GetFileName() != copySheet->GetFileName() ) )
|
||||
|| ( origSheet->GetFileName() != copySheet->GetFileName() )
|
||||
|| origSheet->HasPageNumberChanges( *copySheet ) )
|
||||
{
|
||||
rebuildHierarchyNavigator = true;
|
||||
}
|
||||
@@ -466,15 +467,13 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
|
||||
|
||||
RecalculateConnections( &localCommit, connectivityCleanUp );
|
||||
|
||||
// Update the hierarchy navigator when there are sheet changes.
|
||||
if( connectivityCleanUp == GLOBAL_CLEANUP )
|
||||
{
|
||||
SetSheetNumberAndCount();
|
||||
|
||||
if( rebuildHierarchyNavigator )
|
||||
UpdateHierarchyNavigator();
|
||||
}
|
||||
}
|
||||
|
||||
// Update the hierarchy navigator when there are sheet changes.
|
||||
if( rebuildHierarchyNavigator )
|
||||
UpdateHierarchyNavigator();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@ void SIMULATOR_FRAME_UI::parseTraceParams( SIM_PLOT_TAB* aPlotTab, TRACE* aTrace
|
||||
CURSOR* cursor = new CURSOR( aTrace, aPlotTab );
|
||||
|
||||
cursor->SetName( aSignalName );
|
||||
cursor->SetPen( wxPen( aTrace->GetTraceColour() ) );
|
||||
cursor->SetCoordX( x );
|
||||
|
||||
aTrace->SetCursor( aCursorId, cursor );
|
||||
|
||||
@@ -129,7 +129,7 @@ void SIM_LIB_MGR::SetLibrary( const wxString& aLibraryPath, REPORTER& aReporter
|
||||
{
|
||||
wxString path = ResolveLibraryPath( aLibraryPath, m_project, aReporter );
|
||||
|
||||
if( aReporter.HasMessage() )
|
||||
if( aReporter.HasMessageOfSeverity( RPT_SEVERITY_UNDEFINED | RPT_SEVERITY_ERROR ) )
|
||||
return;
|
||||
|
||||
if( !wxFileName::Exists( path ) )
|
||||
|
||||
@@ -394,7 +394,7 @@ TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<T>& aFields, REPORTER& aRe
|
||||
std::string deviceTypeFieldValue = GetFieldValue( &aFields, SIM_DEVICE_FIELD );
|
||||
std::string typeFieldValue = GetFieldValue( &aFields, SIM_DEVICE_SUBTYPE_FIELD );
|
||||
|
||||
if( deviceTypeFieldValue != "" )
|
||||
if( !deviceTypeFieldValue.empty() )
|
||||
{
|
||||
for( TYPE type : TYPE_ITERATOR() )
|
||||
{
|
||||
@@ -406,7 +406,7 @@ TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<T>& aFields, REPORTER& aRe
|
||||
}
|
||||
}
|
||||
|
||||
if( typeFieldValue != "" )
|
||||
if( typeFieldValue.empty() )
|
||||
return TYPE::NONE;
|
||||
|
||||
if( aFields.size() > REFERENCE_FIELD )
|
||||
@@ -524,10 +524,15 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL* aBaseModel,
|
||||
{
|
||||
NULL_REPORTER devnull;
|
||||
TYPE type = aBaseModel->GetType();
|
||||
TYPE type_override = ReadTypeFromFields( aFields, devnull );
|
||||
|
||||
// No REPORTER here; we're just checking to see if we have an override
|
||||
if( ReadTypeFromFields( aFields, devnull ) != TYPE::NONE )
|
||||
type = ReadTypeFromFields( aFields, devnull );
|
||||
// Check for an override in the case of IBIS models.
|
||||
// The other models require type to be set from the base model.
|
||||
if( dynamic_cast<const SIM_MODEL_KIBIS*>( aBaseModel ) &&
|
||||
type_override != TYPE::NONE )
|
||||
{
|
||||
type = type_override;
|
||||
}
|
||||
|
||||
if( dynamic_cast<const SIM_MODEL_SPICE_FALLBACK*>( aBaseModel ) )
|
||||
model = std::make_unique<SIM_MODEL_SPICE_FALLBACK>( type );
|
||||
@@ -1804,8 +1809,7 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
||||
|
||||
if( !lib.IsEmpty() )
|
||||
{
|
||||
wxString msg;
|
||||
WX_STRING_REPORTER reporter( &msg );
|
||||
WX_STRING_REPORTER reporter;
|
||||
SIM_LIB_MGR libMgr( aProject );
|
||||
std::vector<T_field> emptyFields;
|
||||
|
||||
|
||||
@@ -68,12 +68,11 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const PR
|
||||
std::string ibisModelName = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY_KIBIS::MODEL_FIELD );
|
||||
bool diffMode = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
|
||||
|
||||
wxString msg;
|
||||
WX_STRING_REPORTER reporter( &msg );
|
||||
WX_STRING_REPORTER reporter;
|
||||
wxString path = SIM_LIB_MGR::ResolveLibraryPath( ibisLibFilename, &aProject, reporter );
|
||||
|
||||
if( reporter.HasMessage() )
|
||||
THROW_IO_ERROR( msg );
|
||||
THROW_IO_ERROR( reporter.GetMessages() );
|
||||
|
||||
KIBIS kibis( std::string( path.c_str() ) );
|
||||
kibis.m_cacheDir = std::string( aCacheDir.c_str() );
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user