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.

665 lines
23 KiB

7 years ago
7 years ago
7 years ago
5 years ago
7 years ago
5 years ago
5 years ago
5 years ago
7 years ago
7 years ago
7 years ago
7 years ago
5 years ago
5 years ago
5 years ago
6 years ago
7 years ago
7 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2019 CERN
  5. * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #include <kiway.h>
  25. #include <sch_painter.h>
  26. #include <tool/tool_manager.h>
  27. #include <tools/ee_actions.h>
  28. #include <tools/symbol_editor_control.h>
  29. #include <symbol_edit_frame.h>
  30. #include <symbol_library_manager.h>
  31. #include <symbol_viewer_frame.h>
  32. #include <symbol_tree_model_adapter.h>
  33. #include <wildcards_and_files_ext.h>
  34. #include <wildcards_and_files_ext.h>
  35. #include <bitmaps/bitmap_types.h>
  36. #include <confirm.h>
  37. #include <wx/filedlg.h>
  38. #include "wx/generic/textdlgg.h"
  39. #include "string_utils.h"
  40. bool SYMBOL_EDITOR_CONTROL::Init()
  41. {
  42. m_frame = getEditFrame<SCH_BASE_FRAME>();
  43. m_selectionTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
  44. m_isSymbolEditor = m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR );
  45. if( m_isSymbolEditor )
  46. {
  47. CONDITIONAL_MENU& ctxMenu = m_menu.GetMenu();
  48. SYMBOL_EDIT_FRAME* editFrame = getEditFrame<SYMBOL_EDIT_FRAME>();
  49. wxCHECK( editFrame, false );
  50. auto libSelectedCondition =
  51. [ editFrame ]( const SELECTION& aSel )
  52. {
  53. LIB_ID sel = editFrame->GetTreeLIBID();
  54. return !sel.GetLibNickname().empty() && sel.GetLibItemName().empty();
  55. };
  56. // The libInferredCondition allows you to do things like New Symbol and Paste with a
  57. // symbol selected (in other words, when we know the library context even if the library
  58. // itself isn't selected.
  59. auto libInferredCondition =
  60. [ editFrame ]( const SELECTION& aSel )
  61. {
  62. LIB_ID sel = editFrame->GetTreeLIBID();
  63. return !sel.GetLibNickname().empty();
  64. };
  65. auto pinnedLibSelectedCondition =
  66. [ editFrame ]( const SELECTION& aSel )
  67. {
  68. LIB_TREE_NODE* current = editFrame->GetCurrentTreeNode();
  69. return current && current->m_Type == LIB_TREE_NODE::LIB && current->m_Pinned;
  70. };
  71. auto unpinnedLibSelectedCondition =
  72. [ editFrame ](const SELECTION& aSel )
  73. {
  74. LIB_TREE_NODE* current = editFrame->GetCurrentTreeNode();
  75. return current && current->m_Type == LIB_TREE_NODE::LIB && !current->m_Pinned;
  76. };
  77. auto symbolSelectedCondition =
  78. [ editFrame ]( const SELECTION& aSel )
  79. {
  80. LIB_ID sel = editFrame->GetTreeLIBID();
  81. return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
  82. };
  83. auto saveSymbolAsCondition =
  84. [ editFrame ]( const SELECTION& aSel )
  85. {
  86. LIB_ID sel = editFrame->GetTargetLibId();
  87. return !sel.GetLibNickname().empty() && !sel.GetLibItemName().empty();
  88. };
  89. ctxMenu.AddItem( ACTIONS::pinLibrary, unpinnedLibSelectedCondition );
  90. ctxMenu.AddItem( ACTIONS::unpinLibrary, pinnedLibSelectedCondition );
  91. ctxMenu.AddSeparator();
  92. ctxMenu.AddItem( EE_ACTIONS::newSymbol, libInferredCondition );
  93. ctxMenu.AddSeparator();
  94. ctxMenu.AddItem( ACTIONS::save, symbolSelectedCondition || libInferredCondition );
  95. ctxMenu.AddItem( EE_ACTIONS::saveLibraryAs, libSelectedCondition );
  96. ctxMenu.AddItem( EE_ACTIONS::saveSymbolAs, saveSymbolAsCondition );
  97. ctxMenu.AddItem( ACTIONS::revert, symbolSelectedCondition || libInferredCondition );
  98. ctxMenu.AddSeparator();
  99. ctxMenu.AddItem( EE_ACTIONS::cutSymbol, symbolSelectedCondition );
  100. ctxMenu.AddItem( EE_ACTIONS::copySymbol, symbolSelectedCondition );
  101. ctxMenu.AddItem( EE_ACTIONS::pasteSymbol, libInferredCondition );
  102. ctxMenu.AddItem( EE_ACTIONS::duplicateSymbol, symbolSelectedCondition );
  103. ctxMenu.AddItem( EE_ACTIONS::renameSymbol, symbolSelectedCondition );
  104. ctxMenu.AddItem( EE_ACTIONS::deleteSymbol, symbolSelectedCondition );
  105. ctxMenu.AddSeparator();
  106. ctxMenu.AddItem( EE_ACTIONS::importSymbol, libInferredCondition );
  107. ctxMenu.AddItem( EE_ACTIONS::exportSymbol, symbolSelectedCondition );
  108. // If we've got nothing else to show, at least show a hide tree option
  109. ctxMenu.AddItem( EE_ACTIONS::hideSymbolTree, !libInferredCondition );
  110. }
  111. return true;
  112. }
  113. int SYMBOL_EDITOR_CONTROL::AddLibrary( const TOOL_EVENT& aEvent )
  114. {
  115. bool createNew = aEvent.IsAction( &ACTIONS::newLibrary );
  116. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  117. static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->AddLibraryFile( createNew );
  118. return 0;
  119. }
  120. int SYMBOL_EDITOR_CONTROL::EditSymbol( const TOOL_EVENT& aEvent )
  121. {
  122. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  123. {
  124. SYMBOL_EDIT_FRAME* editFrame = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
  125. int unit = 0;
  126. LIB_ID partId = editFrame->GetTreeLIBID( &unit );
  127. editFrame->LoadSymbol( partId.GetLibItemName(), partId.GetLibNickname(), unit );
  128. }
  129. return 0;
  130. }
  131. int SYMBOL_EDITOR_CONTROL::AddSymbol( const TOOL_EVENT& aEvent )
  132. {
  133. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  134. {
  135. SYMBOL_EDIT_FRAME* editFrame = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
  136. LIB_ID sel = editFrame->GetTreeLIBID();
  137. const wxString& libName = sel.GetLibNickname();
  138. wxString msg;
  139. if( libName.IsEmpty() )
  140. {
  141. msg.Printf( _( "No symbol library selected." ) );
  142. m_frame->ShowInfoBarError( msg );
  143. return 0;
  144. }
  145. if( editFrame->GetLibManager().IsLibraryReadOnly( libName ) )
  146. {
  147. msg.Printf( _( "Symbol library '%s' is not writable." ), libName );
  148. m_frame->ShowInfoBarError( msg );
  149. return 0;
  150. }
  151. if( aEvent.IsAction( &EE_ACTIONS::newSymbol ) )
  152. editFrame->CreateNewSymbol();
  153. else if( aEvent.IsAction( &EE_ACTIONS::importSymbol ) )
  154. editFrame->ImportSymbol();
  155. }
  156. return 0;
  157. }
  158. int SYMBOL_EDITOR_CONTROL::Save( const TOOL_EVENT& aEvt )
  159. {
  160. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  161. {
  162. SYMBOL_EDIT_FRAME* editFrame = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
  163. if( aEvt.IsAction( &EE_ACTIONS::save ) )
  164. editFrame->Save();
  165. else if( aEvt.IsAction( &EE_ACTIONS::saveLibraryAs ) )
  166. editFrame->SaveLibraryAs();
  167. else if( aEvt.IsAction( &EE_ACTIONS::saveSymbolAs ) )
  168. editFrame->SaveSymbolAs();
  169. else if( aEvt.IsAction( &EE_ACTIONS::saveAll ) )
  170. editFrame->SaveAll();
  171. }
  172. return 0;
  173. }
  174. int SYMBOL_EDITOR_CONTROL::Revert( const TOOL_EVENT& aEvent )
  175. {
  176. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  177. static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->Revert();
  178. return 0;
  179. }
  180. int SYMBOL_EDITOR_CONTROL::ExportSymbol( const TOOL_EVENT& aEvent )
  181. {
  182. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  183. static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->ExportSymbol();
  184. return 0;
  185. }
  186. int SYMBOL_EDITOR_CONTROL::CutCopyDelete( const TOOL_EVENT& aEvt )
  187. {
  188. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  189. {
  190. SYMBOL_EDIT_FRAME* editFrame = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
  191. if( aEvt.IsAction( &EE_ACTIONS::cutSymbol ) || aEvt.IsAction( &EE_ACTIONS::copySymbol ) )
  192. editFrame->CopySymbolToClipboard();
  193. if( aEvt.IsAction( &EE_ACTIONS::cutSymbol ) || aEvt.IsAction( &EE_ACTIONS::deleteSymbol ) )
  194. {
  195. LIB_ID sel = editFrame->GetTreeLIBID();
  196. const wxString& libName = sel.GetLibNickname();
  197. wxString msg;
  198. if( editFrame->GetLibManager().IsLibraryReadOnly( libName ) )
  199. {
  200. msg.Printf( _( "Symbol library '%s' is not writable." ), libName );
  201. m_frame->ShowInfoBarError( msg );
  202. return 0;
  203. }
  204. editFrame->DeleteSymbolFromLibrary();
  205. }
  206. }
  207. return 0;
  208. }
  209. int SYMBOL_EDITOR_CONTROL::DuplicateSymbol( const TOOL_EVENT& aEvent )
  210. {
  211. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  212. {
  213. SYMBOL_EDIT_FRAME* editFrame = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
  214. LIB_ID sel = editFrame->GetTargetLibId();
  215. // DuplicateSymbol() is called to duplicate a symbol, or to paste a previously
  216. // saved symbol in clipboard
  217. bool isPasteAction = aEvent.IsAction( &EE_ACTIONS::pasteSymbol );
  218. wxString msg;
  219. if( !sel.IsValid() && !isPasteAction )
  220. {
  221. // When duplicating a symbol, a source symbol must exists.
  222. msg.Printf( _( "No symbol selected" ) );
  223. m_frame->ShowInfoBarError( msg );
  224. return 0;
  225. }
  226. const wxString& libName = sel.GetLibNickname();
  227. if( editFrame->GetLibManager().IsLibraryReadOnly( libName ) )
  228. {
  229. msg.Printf( _( "Symbol library '%s' is not writable." ), libName );
  230. m_frame->ShowInfoBarError( msg );
  231. return 0;
  232. }
  233. editFrame->DuplicateSymbol( isPasteAction );
  234. }
  235. return 0;
  236. }
  237. int SYMBOL_EDITOR_CONTROL::RenameSymbol( const TOOL_EVENT& aEvent )
  238. {
  239. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  240. {
  241. SYMBOL_EDIT_FRAME* editFrame = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
  242. SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
  243. LIB_ID libId = editFrame->GetTreeLIBID();
  244. wxString libName = libId.GetLibNickname();
  245. wxString symbolName = libId.GetLibItemName();
  246. wxString newName = symbolName;
  247. bool done = false;
  248. if( !libMgr.LibraryExists( libName ) )
  249. return 0;
  250. while( !done )
  251. {
  252. wxTextEntryDialog dlg( m_frame, _( "New name:" ), _( "Change Symbol Name" ), newName );
  253. if( dlg.ShowModal() != wxID_OK )
  254. return 0; // canceled by user
  255. newName = dlg.GetValue();
  256. newName.Trim( true ).Trim( false );
  257. if( newName.IsEmpty() )
  258. {
  259. DisplayErrorMessage( editFrame, _( "Symbol name cannot be empty." ) );
  260. }
  261. else if( libMgr.SymbolExists( newName, libName ) )
  262. {
  263. DisplayErrorMessage( editFrame, wxString::Format( _( "Symbol name '%s' already "
  264. "in use in library '%s'." ),
  265. UnescapeString( newName ),
  266. libName ) );
  267. newName = symbolName;
  268. }
  269. else
  270. {
  271. done = true;
  272. }
  273. }
  274. wxString oldName = symbolName;
  275. LIB_SYMBOL* libSymbol = nullptr;
  276. if( editFrame->IsCurrentSymbol( libId ) )
  277. {
  278. // Update buffered copy
  279. libSymbol = libMgr.GetBufferedSymbol( oldName, libName );
  280. libSymbol->SetName( newName );
  281. libSymbol->GetFieldById( VALUE_FIELD )->SetText( newName );
  282. libMgr.UpdateSymbolAfterRename( libSymbol, newName, libName );
  283. // Now update canvasy copy
  284. libSymbol = editFrame->GetCurSymbol();
  285. libSymbol->SetName( newName );
  286. libSymbol->GetFieldById( VALUE_FIELD )->SetText( newName );
  287. editFrame->RebuildView();
  288. editFrame->OnModify();
  289. // N.B. The view needs to be rebuilt first as the Symbol Properties change may
  290. // invalidate the view pointers by rebuilting the field table
  291. editFrame->UpdateMsgPanel();
  292. }
  293. else
  294. {
  295. libSymbol = libMgr.GetBufferedSymbol( oldName, libName );
  296. libSymbol->SetName( newName );
  297. libSymbol->GetFieldById( VALUE_FIELD )->SetText( newName );
  298. libMgr.UpdateSymbolAfterRename( libSymbol, newName, libName );
  299. libMgr.SetSymbolModified( newName, libName );
  300. }
  301. wxDataViewItem treeItem = libMgr.GetAdapter()->FindItem( libId );
  302. editFrame->UpdateLibraryTree( treeItem, libSymbol );
  303. editFrame->FocusOnLibId( LIB_ID( libName, newName ) );
  304. }
  305. return 0;
  306. }
  307. int SYMBOL_EDITOR_CONTROL::OnDeMorgan( const TOOL_EVENT& aEvent )
  308. {
  309. int convert = aEvent.IsAction( &EE_ACTIONS::showDeMorganStandard ) ?
  310. LIB_ITEM::LIB_CONVERT::BASE : LIB_ITEM::LIB_CONVERT::DEMORGAN;
  311. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  312. {
  313. m_toolMgr->RunAction( ACTIONS::cancelInteractive, true );
  314. m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
  315. SYMBOL_EDIT_FRAME* symbolEditor = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
  316. symbolEditor->SetConvert( convert );
  317. m_toolMgr->ResetTools( TOOL_BASE::MODEL_RELOAD );
  318. symbolEditor->RebuildView();
  319. }
  320. else if( m_frame->IsType( FRAME_SCH_VIEWER ) || m_frame->IsType( FRAME_SCH_VIEWER_MODAL ) )
  321. {
  322. SYMBOL_VIEWER_FRAME* symbolViewer = static_cast<SYMBOL_VIEWER_FRAME*>( m_frame );
  323. symbolViewer->SetUnitAndConvert( symbolViewer->GetUnit(), convert );
  324. }
  325. return 0;
  326. }
  327. int SYMBOL_EDITOR_CONTROL::PinLibrary( const TOOL_EVENT& aEvent )
  328. {
  329. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  330. {
  331. SYMBOL_EDIT_FRAME* editFrame = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
  332. LIB_TREE_NODE* currentNode = editFrame->GetCurrentTreeNode();
  333. if( currentNode && !currentNode->m_Pinned )
  334. {
  335. currentNode->m_Pinned = true;
  336. editFrame->RegenerateLibraryTree();
  337. }
  338. }
  339. return 0;
  340. }
  341. int SYMBOL_EDITOR_CONTROL::UnpinLibrary( const TOOL_EVENT& aEvent )
  342. {
  343. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  344. {
  345. SYMBOL_EDIT_FRAME* editFrame = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
  346. LIB_TREE_NODE* currentNode = editFrame->GetCurrentTreeNode();
  347. if( currentNode && currentNode->m_Pinned )
  348. {
  349. currentNode->m_Pinned = false;
  350. editFrame->RegenerateLibraryTree();
  351. }
  352. }
  353. return 0;
  354. }
  355. int SYMBOL_EDITOR_CONTROL::ToggleSymbolTree( const TOOL_EVENT& aEvent )
  356. {
  357. if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
  358. {
  359. wxCommandEvent dummy;
  360. static_cast<SYMBOL_EDIT_FRAME*>( m_frame )->OnToggleSymbolTree( dummy );
  361. }
  362. return 0;
  363. }
  364. int SYMBOL_EDITOR_CONTROL::ShowElectricalTypes( const TOOL_EVENT& aEvent )
  365. {
  366. KIGFX::SCH_RENDER_SETTINGS* renderSettings = m_frame->GetRenderSettings();
  367. renderSettings->m_ShowPinsElectricalType = !renderSettings->m_ShowPinsElectricalType;
  368. // Update canvas
  369. m_frame->GetCanvas()->GetView()->UpdateAllItems( KIGFX::REPAINT );
  370. m_frame->GetCanvas()->Refresh();
  371. return 0;
  372. }
  373. int SYMBOL_EDITOR_CONTROL::ToggleSyncedPinsMode( const TOOL_EVENT& aEvent )
  374. {
  375. if( !m_isSymbolEditor )
  376. return 0;
  377. SYMBOL_EDIT_FRAME* editFrame = getEditFrame<SYMBOL_EDIT_FRAME>();
  378. editFrame->m_SyncPinEdit = !editFrame->m_SyncPinEdit;
  379. return 0;
  380. }
  381. int SYMBOL_EDITOR_CONTROL::ExportView( const TOOL_EVENT& aEvent )
  382. {
  383. if( !m_isSymbolEditor )
  384. return 0;
  385. SYMBOL_EDIT_FRAME* editFrame = getEditFrame<SYMBOL_EDIT_FRAME>();
  386. LIB_SYMBOL* symbol = editFrame->GetCurSymbol();
  387. if( !symbol )
  388. {
  389. wxMessageBox( _( "No symbol to export" ) );
  390. return 0;
  391. }
  392. wxString file_ext = wxT( "png" );
  393. wxString mask = wxT( "*." ) + file_ext;
  394. wxFileName fn( symbol->GetName() );
  395. fn.SetExt( "png" );
  396. wxString projectPath = wxPathOnly( m_frame->Prj().GetProjectFullName() );
  397. wxFileDialog dlg( editFrame, _( "Image File Name" ), projectPath, fn.GetFullName(),
  398. PngFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
  399. if( dlg.ShowModal() == wxID_OK && !dlg.GetPath().IsEmpty() )
  400. {
  401. // calling wxYield is mandatory under Linux, after closing the file selector dialog
  402. // to refresh the screen before creating the PNG or JPEG image from screen
  403. wxYield();
  404. if( !SaveCanvasImageToFile( editFrame, dlg.GetPath(), BITMAP_TYPE::PNG ) )
  405. {
  406. wxMessageBox( wxString::Format( _( "Can't save file '%s'." ), dlg.GetPath() ) );
  407. }
  408. }
  409. return 0;
  410. }
  411. int SYMBOL_EDITOR_CONTROL::ExportSymbolAsSVG( const TOOL_EVENT& aEvent )
  412. {
  413. if( !m_isSymbolEditor )
  414. return 0;
  415. SYMBOL_EDIT_FRAME* editFrame = getEditFrame<SYMBOL_EDIT_FRAME>();
  416. LIB_SYMBOL* symbol = editFrame->GetCurSymbol();
  417. if( !symbol )
  418. {
  419. wxMessageBox( _( "No symbol to export" ) );
  420. return 0;
  421. }
  422. wxString file_ext = SVGFileExtension;
  423. wxFileName fn( symbol->GetName() );
  424. fn.SetExt( SVGFileExtension );
  425. wxString pro_dir = wxPathOnly( m_frame->Prj().GetProjectFullName() );
  426. wxString fullFileName = wxFileSelector( _( "SVG File Name" ), pro_dir, fn.GetFullName(),
  427. SVGFileExtension, SVGFileWildcard(), wxFD_SAVE,
  428. m_frame );
  429. if( !fullFileName.IsEmpty() )
  430. {
  431. PAGE_INFO pageSave = editFrame->GetScreen()->GetPageSettings();
  432. PAGE_INFO pageTemp = pageSave;
  433. VECTOR2I symbolSize = symbol->GetUnitBoundingBox( editFrame->GetUnit(),
  434. editFrame->GetConvert() ).GetSize();
  435. // Add a small margin to the plot bounding box
  436. pageTemp.SetWidthMils( int( symbolSize.x * 1.2 ) );
  437. pageTemp.SetHeightMils( int( symbolSize.y * 1.2 ) );
  438. editFrame->GetScreen()->SetPageSettings( pageTemp );
  439. editFrame->SVGPlotSymbol( fullFileName );
  440. editFrame->GetScreen()->SetPageSettings( pageSave );
  441. }
  442. return 0;
  443. }
  444. int SYMBOL_EDITOR_CONTROL::AddSymbolToSchematic( const TOOL_EVENT& aEvent )
  445. {
  446. LIB_SYMBOL* libSymbol = nullptr;
  447. LIB_ID libId;
  448. int unit, convert;
  449. if( m_isSymbolEditor )
  450. {
  451. SYMBOL_EDIT_FRAME* editFrame = getEditFrame<SYMBOL_EDIT_FRAME>();
  452. libSymbol = editFrame->GetCurSymbol();
  453. unit = editFrame->GetUnit();
  454. convert = editFrame->GetConvert();
  455. if( libSymbol )
  456. libId = libSymbol->GetLibId();
  457. }
  458. else
  459. {
  460. SYMBOL_VIEWER_FRAME* viewerFrame = getEditFrame<SYMBOL_VIEWER_FRAME>();
  461. if( viewerFrame->IsModal() )
  462. {
  463. // if we're modal then we just need to return the symbol selection; the caller is
  464. // already in a EE_ACTIONS::placeSymbol coroutine.
  465. viewerFrame->FinishModal();
  466. return 0;
  467. }
  468. else
  469. {
  470. libSymbol = viewerFrame->GetSelectedSymbol();
  471. unit = viewerFrame->GetUnit();
  472. convert = viewerFrame->GetConvert();
  473. if( libSymbol )
  474. libId = libSymbol->GetLibId();
  475. }
  476. }
  477. if( libSymbol )
  478. {
  479. SCH_EDIT_FRAME* schframe = (SCH_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH, false );
  480. if( !schframe ) // happens when the schematic editor is not active (or closed)
  481. {
  482. DisplayErrorMessage( m_frame, _( "No schematic currently open." ) );
  483. return 0;
  484. }
  485. wxCHECK( libSymbol->GetLibId().IsValid(), 0 );
  486. SCH_SYMBOL* symbol = new SCH_SYMBOL( *libSymbol, libId, &schframe->GetCurrentSheet(),
  487. unit, convert );
  488. symbol->SetParent( schframe->GetScreen() );
  489. if( schframe->eeconfig()->m_AutoplaceFields.enable )
  490. symbol->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
  491. schframe->Raise();
  492. schframe->GetToolManager()->RunAction( EE_ACTIONS::placeSymbol, true, symbol );
  493. }
  494. return 0;
  495. }
  496. void SYMBOL_EDITOR_CONTROL::setTransitions()
  497. {
  498. Go( &SYMBOL_EDITOR_CONTROL::AddLibrary, ACTIONS::newLibrary.MakeEvent() );
  499. Go( &SYMBOL_EDITOR_CONTROL::AddLibrary, ACTIONS::addLibrary.MakeEvent() );
  500. Go( &SYMBOL_EDITOR_CONTROL::AddSymbol, EE_ACTIONS::newSymbol.MakeEvent() );
  501. Go( &SYMBOL_EDITOR_CONTROL::AddSymbol, EE_ACTIONS::importSymbol.MakeEvent() );
  502. Go( &SYMBOL_EDITOR_CONTROL::EditSymbol, EE_ACTIONS::editSymbol.MakeEvent() );
  503. Go( &SYMBOL_EDITOR_CONTROL::Save, ACTIONS::save.MakeEvent() );
  504. Go( &SYMBOL_EDITOR_CONTROL::Save, EE_ACTIONS::saveLibraryAs.MakeEvent() );
  505. Go( &SYMBOL_EDITOR_CONTROL::Save, EE_ACTIONS::saveSymbolAs.MakeEvent() );
  506. Go( &SYMBOL_EDITOR_CONTROL::Save, ACTIONS::saveAll.MakeEvent() );
  507. Go( &SYMBOL_EDITOR_CONTROL::Revert, ACTIONS::revert.MakeEvent() );
  508. Go( &SYMBOL_EDITOR_CONTROL::DuplicateSymbol, EE_ACTIONS::duplicateSymbol.MakeEvent() );
  509. Go( &SYMBOL_EDITOR_CONTROL::RenameSymbol, EE_ACTIONS::renameSymbol.MakeEvent() );
  510. Go( &SYMBOL_EDITOR_CONTROL::CutCopyDelete, EE_ACTIONS::deleteSymbol.MakeEvent() );
  511. Go( &SYMBOL_EDITOR_CONTROL::CutCopyDelete, EE_ACTIONS::cutSymbol.MakeEvent() );
  512. Go( &SYMBOL_EDITOR_CONTROL::CutCopyDelete, EE_ACTIONS::copySymbol.MakeEvent() );
  513. Go( &SYMBOL_EDITOR_CONTROL::DuplicateSymbol, EE_ACTIONS::pasteSymbol.MakeEvent() );
  514. Go( &SYMBOL_EDITOR_CONTROL::ExportSymbol, EE_ACTIONS::exportSymbol.MakeEvent() );
  515. Go( &SYMBOL_EDITOR_CONTROL::ExportView, EE_ACTIONS::exportSymbolView.MakeEvent() );
  516. Go( &SYMBOL_EDITOR_CONTROL::ExportSymbolAsSVG, EE_ACTIONS::exportSymbolAsSVG.MakeEvent() );
  517. Go( &SYMBOL_EDITOR_CONTROL::AddSymbolToSchematic, EE_ACTIONS::addSymbolToSchematic.MakeEvent() );
  518. Go( &SYMBOL_EDITOR_CONTROL::OnDeMorgan, EE_ACTIONS::showDeMorganStandard.MakeEvent() );
  519. Go( &SYMBOL_EDITOR_CONTROL::OnDeMorgan, EE_ACTIONS::showDeMorganAlternate.MakeEvent() );
  520. Go( &SYMBOL_EDITOR_CONTROL::ShowElectricalTypes, EE_ACTIONS::showElectricalTypes.MakeEvent() );
  521. Go( &SYMBOL_EDITOR_CONTROL::PinLibrary, ACTIONS::pinLibrary.MakeEvent() );
  522. Go( &SYMBOL_EDITOR_CONTROL::UnpinLibrary, ACTIONS::unpinLibrary.MakeEvent() );
  523. Go( &SYMBOL_EDITOR_CONTROL::ToggleSymbolTree, EE_ACTIONS::showSymbolTree.MakeEvent() );
  524. Go( &SYMBOL_EDITOR_CONTROL::ToggleSymbolTree, EE_ACTIONS::hideSymbolTree.MakeEvent() );
  525. Go( &SYMBOL_EDITOR_CONTROL::ToggleSyncedPinsMode, EE_ACTIONS::toggleSyncedPinsMode.MakeEvent() );
  526. }