You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
5.1 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include "layer_pairs.h"
  24. #include <wx/translation.h>
  25. wxDEFINE_EVENT( PCB_LAYER_PAIR_PRESETS_CHANGED, wxCommandEvent );
  26. wxDEFINE_EVENT( PCB_CURRENT_LAYER_PAIR_CHANGED, wxCommandEvent );
  27. static bool IsAnEnabledPreset( const LAYER_PAIR& aPair, const LAYER_PAIR_SETTINGS& aSettings )
  28. {
  29. const auto presets = aSettings.GetLayerPairs();
  30. const auto matcher = [&aPair]( const LAYER_PAIR_INFO& aPreset )
  31. {
  32. return aPreset.GetLayerPair().HasSameLayers( aPair ) && aPreset.IsEnabled();
  33. };
  34. return std::any_of( presets.begin(), presets.end(), matcher );
  35. }
  36. LAYER_PAIR_SETTINGS::LAYER_PAIR_SETTINGS( const LAYER_PAIR_SETTINGS& aOther )
  37. {
  38. m_pairs = aOther.m_pairs;
  39. m_currentPair = aOther.m_currentPair;
  40. }
  41. bool LAYER_PAIR_SETTINGS::addLayerPairInternal( LAYER_PAIR_INFO aPairInfo )
  42. {
  43. const LAYER_PAIR& newPair = aPairInfo.GetLayerPair();
  44. const auto pairMatcher = [&]( const LAYER_PAIR_INFO& aExistingPair )
  45. {
  46. return newPair.HasSameLayers( aExistingPair.GetLayerPair() );
  47. };
  48. const bool alreadyExists = std::any_of( m_pairs.begin(), m_pairs.end(), pairMatcher );
  49. if( alreadyExists )
  50. {
  51. return false;
  52. }
  53. // If we're adding a pair that matches the last manual pair
  54. // we no longer need the manual one
  55. if( m_lastManualPair && m_lastManualPair->HasSameLayers( newPair ) )
  56. {
  57. m_lastManualPair.reset();
  58. }
  59. m_pairs.push_back( std::move( aPairInfo ) );
  60. return true;
  61. }
  62. bool LAYER_PAIR_SETTINGS::AddLayerPair( LAYER_PAIR_INFO aPair )
  63. {
  64. bool ret = addLayerPairInternal( std::move( aPair ) );
  65. wxCommandEvent* evt = new wxCommandEvent( PCB_LAYER_PAIR_PRESETS_CHANGED, wxID_ANY );
  66. QueueEvent( evt );
  67. return ret;
  68. }
  69. bool LAYER_PAIR_SETTINGS::removeLayerPairInternal( const LAYER_PAIR& aPair )
  70. {
  71. const auto pairMatcher = [&aPair]( const LAYER_PAIR_INFO& aPairInfo )
  72. {
  73. return aPairInfo.GetLayerPair().HasSameLayers( aPair );
  74. };
  75. const auto pairToRemoveIt = std::find_if( m_pairs.begin(), m_pairs.end(), pairMatcher );
  76. if( pairToRemoveIt == m_pairs.end() )
  77. {
  78. return false;
  79. }
  80. m_pairs.erase( pairToRemoveIt );
  81. return true;
  82. }
  83. bool LAYER_PAIR_SETTINGS::RemoveLayerPair( const LAYER_PAIR& aPair )
  84. {
  85. bool ret = removeLayerPairInternal( aPair );
  86. wxCommandEvent* evt = new wxCommandEvent( PCB_LAYER_PAIR_PRESETS_CHANGED, wxID_ANY );
  87. QueueEvent( evt );
  88. return ret;
  89. }
  90. std::span<const LAYER_PAIR_INFO> LAYER_PAIR_SETTINGS::GetLayerPairs() const
  91. {
  92. return m_pairs;
  93. }
  94. std::span<LAYER_PAIR_INFO> LAYER_PAIR_SETTINGS::GetLayerPairs()
  95. {
  96. return m_pairs;
  97. }
  98. std::vector<LAYER_PAIR_INFO> LAYER_PAIR_SETTINGS::GetEnabledLayerPairs( int& aCurrent ) const
  99. {
  100. std::vector<LAYER_PAIR_INFO> enabledPairs;
  101. aCurrent = -1;
  102. if( m_lastManualPair )
  103. {
  104. enabledPairs.emplace_back( LAYER_PAIR_INFO{
  105. *m_lastManualPair,
  106. true,
  107. _( "Manual" ),
  108. } );
  109. if( m_currentPair.HasSameLayers( *m_lastManualPair ) )
  110. {
  111. aCurrent = 0;
  112. }
  113. }
  114. for( const LAYER_PAIR_INFO& pair : m_pairs )
  115. {
  116. if( pair.IsEnabled() )
  117. {
  118. enabledPairs.push_back( pair );
  119. if( m_currentPair.HasSameLayers( pair.GetLayerPair() ) )
  120. {
  121. aCurrent = enabledPairs.size() - 1;
  122. }
  123. }
  124. }
  125. return enabledPairs;
  126. }
  127. void LAYER_PAIR_SETTINGS::SetLayerPairs( std::span<const LAYER_PAIR_INFO> aPairs )
  128. {
  129. // Replace all pairs with the given list
  130. m_pairs.clear();
  131. for( const LAYER_PAIR_INFO& pair : aPairs )
  132. {
  133. // Skip dupes and other
  134. addLayerPairInternal( pair );
  135. }
  136. {
  137. wxCommandEvent* evt = new wxCommandEvent( PCB_LAYER_PAIR_PRESETS_CHANGED, wxID_ANY );
  138. QueueEvent( evt );
  139. }
  140. }
  141. void LAYER_PAIR_SETTINGS::SetCurrentLayerPair( const LAYER_PAIR& aPair )
  142. {
  143. m_currentPair = aPair;
  144. if( !IsAnEnabledPreset( aPair, *this ) )
  145. {
  146. m_lastManualPair = aPair;
  147. }
  148. wxCommandEvent* evt = new wxCommandEvent( PCB_CURRENT_LAYER_PAIR_CHANGED, wxID_ANY );
  149. QueueEvent( evt );
  150. }