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.

332 lines
9.3 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 1992-2017 jean-pierre Charras jp.charras at wanadoo.fr
  5. * Copyright (C) 1992-2021 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 <sch_edit_frame.h>
  25. #include <base_units.h>
  26. #include <bitmaps.h>
  27. #include <confirm.h>
  28. #include <dialog_annotate_base.h>
  29. #include <eeschema_settings.h>
  30. #include <kiface_base.h>
  31. #include <widgets/wx_html_report_panel.h>
  32. #include <schematic.h>
  33. // A window name for the annotate dialog to retrieve is if not destroyed
  34. #define DLG_WINDOW_NAME "DialogAnnotateWindowName"
  35. /**
  36. * A dialog to set/clear reference designators of a schematic with different options.
  37. */
  38. class DIALOG_ANNOTATE: public DIALOG_ANNOTATE_BASE
  39. {
  40. public:
  41. DIALOG_ANNOTATE( SCH_EDIT_FRAME* parent, const wxString& message );
  42. ~DIALOG_ANNOTATE();
  43. private:
  44. /// Initialize member variables.
  45. void InitValues();
  46. void OnOptionChanged( wxCommandEvent& event ) override;
  47. void OnClearAnnotationClick( wxCommandEvent& event ) override;
  48. void OnCloseClick( wxCommandEvent& event ) override;
  49. void OnClose( wxCloseEvent& event ) override;
  50. void OnApplyClick( wxCommandEvent& event ) override;
  51. // User functions:
  52. bool GetResetItems();
  53. ANNOTATE_SCOPE_T GetScope();
  54. bool GetRecursive();
  55. ANNOTATE_ORDER_T GetSortOrder();
  56. ANNOTATE_ALGO_T GetAnnotateAlgo();
  57. int GetStartNumber();
  58. SCH_EDIT_FRAME* m_Parent;
  59. };
  60. DIALOG_ANNOTATE::DIALOG_ANNOTATE( SCH_EDIT_FRAME* parent, const wxString& message )
  61. : DIALOG_ANNOTATE_BASE( parent )
  62. {
  63. SetName( DLG_WINDOW_NAME );
  64. m_Parent = parent;
  65. if( !message.IsEmpty() )
  66. {
  67. m_infoBar->RemoveAllButtons();
  68. m_infoBar->ShowMessage( message );
  69. m_rbScope_Schematic->SetValue( true );
  70. m_rbScope_Schematic->Enable( false );
  71. }
  72. m_MessageWindow->SetLabel( _( "Annotation Messages:" ) );
  73. m_MessageWindow->SetFileName( Prj().GetProjectPath() + wxT( "report.txt" ) );
  74. SetupStandardButtons( { { wxID_OK, _( "Annotate" ) },
  75. { wxID_CANCEL, _( "Close" ) } } );
  76. InitValues();
  77. Layout();
  78. // When all widgets have the size fixed, call FinishDialogSettings
  79. finishDialogSettings();
  80. }
  81. DIALOG_ANNOTATE::~DIALOG_ANNOTATE()
  82. {
  83. auto cfg = static_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
  84. cfg->m_AnnotatePanel.sort_order = GetSortOrder();
  85. cfg->m_AnnotatePanel.method = GetAnnotateAlgo();
  86. cfg->m_AnnotatePanel.options = m_rbOptions->GetSelection();
  87. if( m_rbScope_Schematic->IsEnabled() )
  88. {
  89. cfg->m_AnnotatePanel.scope = GetScope();
  90. cfg->m_AnnotatePanel.recursive = GetRecursive();
  91. }
  92. cfg->m_AnnotatePanel.messages_filter = m_MessageWindow->GetVisibleSeverities();
  93. // Get the "start annotation after" value from dialog and update project settings if changed
  94. int startNum = GetStartNumber();
  95. SCH_EDIT_FRAME* schFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_parentFrame );
  96. if( schFrame )
  97. {
  98. SCHEMATIC_SETTINGS& projSettings = schFrame->Schematic().Settings();
  99. // If the user has updated the start annotation number then update the project file.
  100. // We manually update the project file here in case the user has changed the value
  101. // and just clicked the "Close" button on the annotation dialog.
  102. if( projSettings.m_AnnotateStartNum != startNum )
  103. {
  104. projSettings.m_AnnotateStartNum = startNum;
  105. schFrame->SaveProjectSettings();
  106. }
  107. }
  108. }
  109. void DIALOG_ANNOTATE::InitValues()
  110. {
  111. EESCHEMA_SETTINGS* cfg = static_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
  112. int option;
  113. if( m_rbScope_Schematic->IsEnabled() )
  114. {
  115. switch( cfg->m_AnnotatePanel.scope )
  116. {
  117. default:
  118. case ANNOTATE_ALL: m_rbScope_Schematic->SetValue( true ); break;
  119. case ANNOTATE_CURRENT_SHEET: m_rbScope_Sheet->SetValue( true ); break;
  120. case ANNOTATE_SELECTION: m_rbScope_Selection->SetValue( true ); break;
  121. }
  122. m_checkRecursive->SetValue( cfg->m_AnnotatePanel.recursive );
  123. }
  124. m_rbOptions->SetSelection( cfg->m_AnnotatePanel.options );
  125. option = cfg->m_AnnotatePanel.sort_order;
  126. switch( option )
  127. {
  128. default:
  129. case SORT_BY_X_POSITION: m_rbSortBy_X_Position->SetValue( true ); break;
  130. case SORT_BY_Y_POSITION: m_rbSortBy_Y_Position->SetValue( true ); break;
  131. }
  132. option = cfg->m_AnnotatePanel.method;
  133. switch( option )
  134. {
  135. default:
  136. case INCREMENTAL_BY_REF: m_rbFirstFree->SetValue( true ); break;
  137. case SHEET_NUMBER_X_100: m_rbSheetX100->SetValue( true ); break;
  138. case SHEET_NUMBER_X_1000: m_rbSheetX1000->SetValue( true ); break;
  139. }
  140. int annotateStartNum = 0; // Default "start after" value for annotation
  141. // See if we can get a "start after" value from the project settings
  142. SCH_EDIT_FRAME* schFrame = dynamic_cast<SCH_EDIT_FRAME*>( m_parentFrame );
  143. if( schFrame )
  144. {
  145. SCHEMATIC_SETTINGS& projSettings = schFrame->Schematic().Settings();
  146. annotateStartNum = projSettings.m_AnnotateStartNum;
  147. }
  148. m_textNumberAfter->SetValue( wxString::Format( wxT( "%d" ), annotateStartNum ) );
  149. annotate_down_right_bitmap->SetBitmap( KiBitmap( BITMAPS::annotate_down_right ) );
  150. annotate_right_down_bitmap->SetBitmap( KiBitmap( BITMAPS::annotate_right_down ) );
  151. m_MessageWindow->SetVisibleSeverities( cfg->m_AnnotatePanel.messages_filter );
  152. m_MessageWindow->MsgPanelSetMinSize( wxSize( -1, 160 ) );
  153. }
  154. // This is a modeless dialog so we have to handle these ourselves.
  155. void DIALOG_ANNOTATE::OnCloseClick( wxCommandEvent& event )
  156. {
  157. Close();
  158. }
  159. void DIALOG_ANNOTATE::OnClose( wxCloseEvent& event )
  160. {
  161. Destroy();
  162. }
  163. void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event )
  164. {
  165. m_MessageWindow->Clear();
  166. REPORTER& reporter = m_MessageWindow->Reporter();
  167. m_MessageWindow->SetLazyUpdate( true ); // Don't update after each message
  168. m_Parent->AnnotateSymbols( GetScope(), GetSortOrder(), GetAnnotateAlgo(), GetRecursive(),
  169. GetStartNumber(), GetResetItems(), true, reporter );
  170. m_MessageWindow->Flush( true ); // Now update to show all messages
  171. m_Parent->GetCanvas()->Refresh();
  172. m_btnClear->Enable();
  173. m_sdbSizer1Cancel->SetDefault();
  174. // Don't close dialog if there are things the user needs to address
  175. if( reporter.HasMessage() )
  176. return;
  177. if( m_infoBar->IsShown() )
  178. {
  179. // Close the dialog by calling the default handler for a wxID_OK event
  180. event.SetId( wxID_OK );
  181. event.Skip();
  182. }
  183. }
  184. void DIALOG_ANNOTATE::OnClearAnnotationClick( wxCommandEvent& event )
  185. {
  186. bool appendUndo = false;
  187. m_Parent->DeleteAnnotation( GetScope(), GetRecursive(), &appendUndo );
  188. m_btnClear->Enable( false );
  189. }
  190. void DIALOG_ANNOTATE::OnOptionChanged( wxCommandEvent& event )
  191. {
  192. m_sdbSizer1OK->Enable( true );
  193. m_sdbSizer1OK->SetDefault();
  194. }
  195. bool DIALOG_ANNOTATE::GetResetItems()
  196. {
  197. return m_rbOptions->GetSelection() >= 1;
  198. }
  199. ANNOTATE_SCOPE_T DIALOG_ANNOTATE::GetScope()
  200. {
  201. if( m_rbScope_Schematic->GetValue() )
  202. return ANNOTATE_ALL;
  203. else if( m_rbScope_Sheet->GetValue() )
  204. return ANNOTATE_CURRENT_SHEET;
  205. else
  206. return ANNOTATE_SELECTION;
  207. }
  208. bool DIALOG_ANNOTATE::GetRecursive()
  209. {
  210. return m_checkRecursive->GetValue();
  211. }
  212. ANNOTATE_ORDER_T DIALOG_ANNOTATE::GetSortOrder()
  213. {
  214. if( m_rbSortBy_Y_Position->GetValue() )
  215. return SORT_BY_Y_POSITION;
  216. else
  217. return SORT_BY_X_POSITION;
  218. }
  219. ANNOTATE_ALGO_T DIALOG_ANNOTATE::GetAnnotateAlgo()
  220. {
  221. if( m_rbSheetX100->GetValue() )
  222. return SHEET_NUMBER_X_100;
  223. else if( m_rbSheetX1000->GetValue() )
  224. return SHEET_NUMBER_X_1000;
  225. else
  226. return INCREMENTAL_BY_REF;
  227. }
  228. int DIALOG_ANNOTATE::GetStartNumber()
  229. {
  230. return EDA_UNIT_UTILS::UI::ValueFromString( m_textNumberAfter->GetValue() );
  231. }
  232. void SCH_EDIT_FRAME::OnAnnotate( wxCommandEvent& event )
  233. {
  234. DIALOG_ANNOTATE* dlg = static_cast<DIALOG_ANNOTATE*> ( wxWindow::FindWindowByName( DLG_WINDOW_NAME ) );
  235. if( !dlg )
  236. {
  237. dlg = new DIALOG_ANNOTATE( this, wxEmptyString );
  238. dlg->Show( true );
  239. }
  240. else // The dialog is already opened, perhaps not visible
  241. {
  242. dlg->Show( true );
  243. }
  244. }
  245. int SCH_EDIT_FRAME::ModalAnnotate( const wxString& aMessage )
  246. {
  247. DIALOG_ANNOTATE dlg( this, aMessage );
  248. return dlg.ShowModal();
  249. }