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.

491 lines
17 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2019-2021 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 <connection_graph.h>
  24. #include <dialog_global_edit_text_and_graphics_base.h>
  25. #include <string_utils.h>
  26. #include <sch_symbol.h>
  27. #include <sch_connection.h>
  28. #include <sch_edit_frame.h>
  29. #include <sch_line.h>
  30. #include <sch_junction.h>
  31. #include <sch_sheet.h>
  32. #include <schematic.h>
  33. #include <advanced_config.h>
  34. #include <tool/tool_manager.h>
  35. #include <tools/ee_selection_tool.h>
  36. #include <tools/sch_edit_tool.h>
  37. #include <widgets/unit_binder.h>
  38. static bool g_modifyReferences;
  39. static bool g_modifyValues;
  40. static bool g_modifyOtherFields;
  41. static bool g_modifyWires;
  42. static bool g_modifyBuses;
  43. static bool g_modifyGlobalLabels;
  44. static bool g_modifyHierLabels;
  45. static bool g_modifySheetTitles;
  46. static bool g_modifyOtherSheetFields;
  47. static bool g_modifySheetPins;
  48. static bool g_modifySheetBorders;
  49. static bool g_modifySchTextAndGraphics;
  50. static bool g_filterByFieldname;
  51. static wxString g_fieldnameFilter;
  52. static bool g_filterByReference;
  53. static wxString g_referenceFilter;
  54. static bool g_filterBySymbol;
  55. static wxString g_symbolFilter;
  56. static bool g_filterByType;
  57. static bool g_typeFilterIsPower;
  58. static bool g_filterByNet;
  59. static wxString g_netFilter;
  60. static bool g_filterSelected;
  61. #define DEFAULT_STYLE _( "Default" )
  62. class DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS : public DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_BASE
  63. {
  64. SCH_EDIT_FRAME* m_parent;
  65. EE_SELECTION m_selection;
  66. UNIT_BINDER m_textSize;
  67. UNIT_BINDER m_lineWidth;
  68. UNIT_BINDER m_junctionSize;
  69. bool m_appendUndo;
  70. public:
  71. DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS( SCH_EDIT_FRAME* parent );
  72. ~DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS() override;
  73. protected:
  74. void OnUpdateUI( wxUpdateUIEvent& event ) override;
  75. void OnReferenceFilterText( wxCommandEvent& event ) override
  76. {
  77. m_referenceFilterOpt->SetValue( true );
  78. }
  79. void OnSymbolFilterText( wxCommandEvent& event ) override
  80. {
  81. m_symbolFilterOpt->SetValue( true );
  82. }
  83. bool TransferDataToWindow() override;
  84. bool TransferDataFromWindow() override;
  85. void visitItem( const SCH_SHEET_PATH& aSheetPath, SCH_ITEM* aItem );
  86. void processItem( const SCH_SHEET_PATH& aSheetPath, SCH_ITEM* aItem );
  87. };
  88. DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS( SCH_EDIT_FRAME* parent ) :
  89. DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_BASE( parent ),
  90. m_textSize( parent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, true ),
  91. m_lineWidth( parent, m_lineWidthLabel, m_LineWidthCtrl, m_lineWidthUnits, true ),
  92. m_junctionSize( parent, m_dotSizeLabel, m_dotSizeCtrl, m_dotSizeUnits, true )
  93. {
  94. m_parent = parent;
  95. m_appendUndo = false;
  96. // TODO(JE) remove once real-time connectivity is a given
  97. if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
  98. m_parent->RecalculateConnections( NO_CLEANUP );
  99. m_lineStyle->Append( DEFAULT_STYLE );
  100. m_lineStyle->Append( INDETERMINATE_ACTION );
  101. m_colorSwatch->SetSwatchColor( COLOR4D::UNSPECIFIED, false );
  102. m_colorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
  103. m_bgColorSwatch->SetSwatchColor( COLOR4D::UNSPECIFIED, false );
  104. m_bgColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
  105. m_dotColorSwatch->SetSwatchColor( COLOR4D::UNSPECIFIED, false );
  106. m_dotColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
  107. m_sdbSizerButtonsOK->SetDefault();
  108. finishDialogSettings();
  109. }
  110. DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::~DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS()
  111. {
  112. g_modifyReferences = m_references->GetValue();
  113. g_modifyValues = m_values->GetValue();
  114. g_modifyOtherFields = m_otherFields->GetValue();
  115. g_modifyWires = m_wires->GetValue();
  116. g_modifyBuses = m_buses->GetValue();
  117. g_modifyGlobalLabels = m_globalLabels->GetValue();
  118. g_modifyHierLabels = m_hierLabels->GetValue();
  119. g_modifySheetTitles = m_sheetTitles->GetValue();
  120. g_modifyOtherSheetFields = m_sheetFields->GetValue();
  121. g_modifySheetPins = m_sheetPins->GetValue();
  122. g_modifySheetBorders = m_sheetBorders->GetValue();
  123. g_modifySchTextAndGraphics = m_schTextAndGraphics->GetValue();
  124. g_filterByFieldname = m_fieldnameFilterOpt->GetValue();
  125. g_fieldnameFilter = m_fieldnameFilter->GetValue();
  126. g_filterByReference = m_referenceFilterOpt->GetValue();
  127. g_referenceFilter = m_referenceFilter->GetValue();
  128. g_filterBySymbol = m_symbolFilterOpt->GetValue();
  129. g_symbolFilter = m_symbolFilter->GetValue();
  130. g_filterByType = m_typeFilterOpt->GetValue();
  131. g_typeFilterIsPower = m_typeFilter->GetSelection() == 1;
  132. g_filterByNet = m_netFilterOpt->GetValue();
  133. g_netFilter = m_netFilter->GetValue();
  134. g_filterSelected = m_selectedFilterOpt->GetValue();
  135. }
  136. bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataToWindow()
  137. {
  138. EE_SELECTION_TOOL* selectionTool = m_parent->GetToolManager()->GetTool<EE_SELECTION_TOOL>();
  139. m_selection = selectionTool->GetSelection();
  140. m_references->SetValue( g_modifyReferences );
  141. m_values->SetValue( g_modifyValues );
  142. m_otherFields->SetValue( g_modifyOtherFields );
  143. m_wires->SetValue( g_modifyWires );
  144. m_buses->SetValue( g_modifyBuses );
  145. m_globalLabels->SetValue( g_modifyGlobalLabels );
  146. m_hierLabels->SetValue( g_modifyHierLabels );
  147. m_sheetTitles->SetValue( g_modifySheetTitles );
  148. m_sheetFields->SetValue( g_modifyOtherSheetFields );
  149. m_sheetPins->SetValue( g_modifySheetPins );
  150. m_sheetBorders->SetValue( g_modifySheetBorders );
  151. m_schTextAndGraphics->SetValue( g_modifySchTextAndGraphics );
  152. // SetValue() generates events, ChangeValue() does not
  153. m_fieldnameFilter->ChangeValue( g_fieldnameFilter );
  154. m_fieldnameFilterOpt->SetValue( g_filterByFieldname );
  155. m_referenceFilter->ChangeValue( g_referenceFilter );
  156. m_referenceFilterOpt->SetValue( g_filterByReference );
  157. m_symbolFilter->ChangeValue( g_symbolFilter );
  158. m_symbolFilterOpt->SetValue( g_filterBySymbol );
  159. m_typeFilter->SetSelection( g_typeFilterIsPower ? 1 : 0 );
  160. m_typeFilterOpt->SetValue( g_filterByType );
  161. m_selectedFilterOpt->SetValue( g_filterSelected );
  162. if( g_filterByNet && !g_netFilter.IsEmpty() )
  163. {
  164. m_netFilter->SetValue( g_netFilter );
  165. m_netFilterOpt->SetValue( true );
  166. }
  167. else if( m_parent->GetHighlightedConnection() )
  168. {
  169. m_netFilter->SetValue( m_parent->GetHighlightedConnection()->Name() );
  170. }
  171. else if( m_selection.GetSize() )
  172. {
  173. SCH_ITEM* sch_item = (SCH_ITEM*) m_selection.Front();
  174. SCH_CONNECTION* connection = sch_item->Connection();
  175. if( connection )
  176. m_netFilter->SetValue( connection->Name() );
  177. }
  178. m_netFilterOpt->SetValue( g_filterByNet );
  179. m_textSize.SetValue( INDETERMINATE_ACTION );
  180. m_orientation->SetStringSelection( INDETERMINATE_ACTION );
  181. m_hAlign->SetStringSelection( INDETERMINATE_ACTION );
  182. m_vAlign->SetStringSelection( INDETERMINATE_ACTION );
  183. m_Italic->Set3StateValue( wxCHK_UNDETERMINED );
  184. m_Bold->Set3StateValue( wxCHK_UNDETERMINED );
  185. m_Visible->Set3StateValue( wxCHK_UNDETERMINED );
  186. m_lineWidth.SetValue( INDETERMINATE_ACTION );
  187. m_lineStyle->SetStringSelection( INDETERMINATE_ACTION );
  188. m_junctionSize.SetValue( INDETERMINATE_ACTION );
  189. m_setColor->SetValue( false );
  190. m_setBgColor->SetValue( false );
  191. m_setDotColor->SetValue( false );
  192. return true;
  193. }
  194. void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::OnUpdateUI( wxUpdateUIEvent& )
  195. {
  196. }
  197. void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::processItem( const SCH_SHEET_PATH& aSheetPath,
  198. SCH_ITEM* aItem )
  199. {
  200. if( m_selectedFilterOpt->GetValue() )
  201. {
  202. if( !aItem->IsSelected() && ( !aItem->GetParent() || !aItem->GetParent()->IsSelected() ) )
  203. return;
  204. }
  205. EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( aItem );
  206. SCH_TEXT* sch_text = dynamic_cast<SCH_TEXT*>( aItem );
  207. SCH_LINE* lineItem = dynamic_cast<SCH_LINE*>( aItem );
  208. SCH_JUNCTION* junction = dynamic_cast<SCH_JUNCTION*>( aItem );
  209. m_parent->SaveCopyInUndoList( aSheetPath.LastScreen(), aItem, UNDO_REDO::CHANGED, m_appendUndo );
  210. m_appendUndo = true;
  211. if( eda_text )
  212. {
  213. if( !m_textSize.IsIndeterminate() )
  214. eda_text->SetTextSize( wxSize( m_textSize.GetValue(), m_textSize.GetValue() ) );
  215. if( m_hAlign->GetStringSelection() != INDETERMINATE_ACTION )
  216. eda_text->SetHorizJustify( EDA_TEXT::MapHorizJustify( m_hAlign->GetSelection() - 1 ) );
  217. if( m_vAlign->GetStringSelection() != INDETERMINATE_ACTION )
  218. eda_text->SetVertJustify( EDA_TEXT::MapVertJustify( m_vAlign->GetSelection() - 1 ) );
  219. if( m_Visible->Get3StateValue() != wxCHK_UNDETERMINED )
  220. eda_text->SetVisible( m_Visible->GetValue() );
  221. if( m_Italic->Get3StateValue() != wxCHK_UNDETERMINED )
  222. eda_text->SetItalic( m_Italic->GetValue() );
  223. if( m_Bold->Get3StateValue() != wxCHK_UNDETERMINED )
  224. eda_text->SetBold( m_Bold->GetValue() );
  225. }
  226. // No else! Labels are both.
  227. if( sch_text )
  228. {
  229. if( m_orientation->GetStringSelection() != INDETERMINATE_ACTION )
  230. sch_text->SetLabelSpinStyle( (LABEL_SPIN_STYLE::SPIN) m_orientation->GetSelection() );
  231. }
  232. if( lineItem )
  233. {
  234. if( !m_lineWidth.IsIndeterminate() )
  235. lineItem->SetLineWidth( m_lineWidth.GetValue() );
  236. if( m_lineStyle->GetStringSelection() != INDETERMINATE_ACTION )
  237. {
  238. if( m_lineStyle->GetStringSelection() == DEFAULT_STYLE )
  239. lineItem->SetLineStyle( PLOT_DASH_TYPE::DEFAULT );
  240. else
  241. lineItem->SetLineStyle( m_lineStyle->GetSelection() );
  242. }
  243. if( m_setColor->GetValue() )
  244. lineItem->SetLineColor( m_colorSwatch->GetSwatchColor() );
  245. }
  246. if( junction )
  247. {
  248. if( !m_junctionSize.IsIndeterminate() )
  249. junction->SetDiameter( m_junctionSize.GetValue() );
  250. if( m_setDotColor->GetValue() )
  251. junction->SetColor( m_dotColorSwatch->GetSwatchColor() );
  252. }
  253. }
  254. void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aSheetPath,
  255. SCH_ITEM* aItem )
  256. {
  257. if( m_netFilterOpt->GetValue() && !m_netFilter->GetValue().IsEmpty() )
  258. {
  259. SCH_CONNECTION* connection = aItem->Connection( &aSheetPath );
  260. if( !connection )
  261. return;
  262. if( !WildCompareString( m_netFilter->GetValue(), connection->Name(), false ) )
  263. return;
  264. }
  265. if( m_referenceFilterOpt->GetValue() && !m_referenceFilter->GetValue().IsEmpty() )
  266. {
  267. if( aItem->Type() == SCH_SYMBOL_T )
  268. {
  269. wxString ref = static_cast<SCH_SYMBOL*>( aItem )->GetRef( &aSheetPath );
  270. if( !WildCompareString( m_referenceFilter->GetValue(), ref, false ) )
  271. return;
  272. }
  273. }
  274. if( m_symbolFilterOpt->GetValue() && !m_symbolFilter->GetValue().IsEmpty() )
  275. {
  276. if( aItem->Type() == SCH_SYMBOL_T )
  277. {
  278. wxString id = UnescapeString( static_cast<SCH_SYMBOL*>( aItem )->GetLibId().Format() );
  279. if( !WildCompareString( m_symbolFilter->GetValue(), id, false ) )
  280. return;
  281. }
  282. }
  283. if( m_typeFilterOpt->GetValue() )
  284. {
  285. if( aItem->Type() == SCH_SYMBOL_T )
  286. {
  287. bool isPower = static_cast<SCH_SYMBOL*>( aItem )->GetLibSymbolRef()->IsPower();
  288. if( isPower != ( m_typeFilter->GetSelection() == 1 ) )
  289. return;
  290. }
  291. }
  292. static KICAD_T wireTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LABEL_LOCATE_WIRE_T, EOT };
  293. static KICAD_T busTypes[] = { SCH_LINE_LOCATE_BUS_T, SCH_LABEL_LOCATE_BUS_T, EOT };
  294. static KICAD_T schTextAndGraphics[] = { SCH_TEXT_T, SCH_LINE_LOCATE_GRAPHIC_LINE_T, EOT };
  295. if( aItem->Type() == SCH_SYMBOL_T )
  296. {
  297. SCH_SYMBOL* symbol = (SCH_SYMBOL*) aItem;
  298. if( m_references->GetValue() )
  299. processItem( aSheetPath, symbol->GetField( REFERENCE_FIELD ) );
  300. if( m_values->GetValue() )
  301. processItem( aSheetPath, symbol->GetField( VALUE_FIELD ) );
  302. if( m_otherFields->GetValue() )
  303. {
  304. for( int i = 2; i < symbol->GetFieldCount(); ++i )
  305. {
  306. SCH_FIELD& field = symbol->GetFields()[i];
  307. const wxString& fieldName = field.GetName();
  308. if( !m_fieldnameFilterOpt->GetValue() || m_fieldnameFilter->GetValue().IsEmpty()
  309. || WildCompareString( m_fieldnameFilter->GetValue(), fieldName, false ) )
  310. {
  311. processItem( aSheetPath, &field );
  312. }
  313. }
  314. }
  315. }
  316. else if( aItem->Type() == SCH_SHEET_T )
  317. {
  318. SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
  319. if( m_sheetTitles->GetValue() )
  320. processItem( aSheetPath, &sheet->GetFields()[SHEETNAME] );
  321. if( m_sheetFields->GetValue() )
  322. {
  323. for( SCH_FIELD& field : sheet->GetFields() )
  324. {
  325. if( field.GetId() == SHEETNAME )
  326. continue;
  327. const wxString& fieldName = field.GetName();
  328. if( !m_fieldnameFilterOpt->GetValue() || m_fieldnameFilter->GetValue().IsEmpty()
  329. || WildCompareString( m_fieldnameFilter->GetValue(), fieldName, false ) )
  330. {
  331. processItem( aSheetPath, &field );
  332. }
  333. }
  334. }
  335. if( m_sheetBorders->GetValue() )
  336. {
  337. if( !m_lineWidth.IsIndeterminate() )
  338. sheet->SetBorderWidth( m_lineWidth.GetValue() );
  339. if( m_setColor->GetValue() )
  340. sheet->SetBorderColor( m_colorSwatch->GetSwatchColor() );
  341. if( m_setBgColor->GetValue() )
  342. sheet->SetBackgroundColor( m_bgColorSwatch->GetSwatchColor() );
  343. }
  344. }
  345. else if( aItem->Type() == SCH_JUNCTION_T )
  346. {
  347. SCH_JUNCTION* junction = static_cast<SCH_JUNCTION*>( aItem );
  348. for( SCH_ITEM* item : junction->ConnectedItems( aSheetPath ) )
  349. {
  350. if( item->GetLayer() == LAYER_BUS && m_buses->GetValue() )
  351. {
  352. processItem( aSheetPath, aItem );
  353. break;
  354. }
  355. else if( item->GetLayer() == LAYER_WIRE && m_wires->GetValue() )
  356. {
  357. processItem( aSheetPath, aItem );
  358. break;
  359. }
  360. }
  361. }
  362. else if( m_wires->GetValue() && aItem->IsType( wireTypes ) )
  363. processItem( aSheetPath, aItem );
  364. else if( m_buses->GetValue() && aItem->IsType( busTypes ) )
  365. processItem( aSheetPath, aItem );
  366. else if( m_globalLabels->GetValue() && aItem->Type() == SCH_GLOBAL_LABEL_T )
  367. processItem( aSheetPath, aItem );
  368. else if( m_hierLabels->GetValue() && aItem->Type() == SCH_HIER_LABEL_T )
  369. processItem( aSheetPath, aItem );
  370. else if( m_sheetPins->GetValue() && aItem->Type() == SCH_SHEET_PIN_T )
  371. processItem( aSheetPath, aItem );
  372. else if( m_schTextAndGraphics->GetValue() && aItem->IsType( schTextAndGraphics ) )
  373. processItem( aSheetPath, aItem );
  374. }
  375. bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataFromWindow()
  376. {
  377. if( !m_textSize.Validate( 1.0, 10000.0, EDA_UNITS::MILS ) ) // 1 mil .. 10 inches
  378. return false;
  379. SCH_SHEET_PATH currentSheet = m_parent->GetCurrentSheet();
  380. m_appendUndo = false;
  381. // Go through sheets
  382. for( const SCH_SHEET_PATH& sheetPath : m_parent->Schematic().GetSheets() )
  383. {
  384. SCH_SCREEN* screen = sheetPath.LastScreen();
  385. if( screen )
  386. {
  387. m_parent->SetCurrentSheet( sheetPath );
  388. for( SCH_ITEM* item : screen->Items() )
  389. visitItem( sheetPath, item );
  390. }
  391. }
  392. if( m_appendUndo )
  393. {
  394. m_parent->OnModify();
  395. m_parent->HardRedraw();
  396. }
  397. // Reset the view to where we left the user
  398. m_parent->SetCurrentSheet( currentSheet );
  399. return true;
  400. }
  401. int SCH_EDIT_TOOL::GlobalEdit( const TOOL_EVENT& aEvent )
  402. {
  403. DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS dlg( m_frame );
  404. dlg.ShowModal();
  405. return 0;
  406. }