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.

281 lines
7.4 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  5. * Copyright (C) 2013 CERN
  6. * Copyright (C) 2013-2023 KiCad Developers, see change_log.txt for contributors.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. #include <dialogs/dialog_plugin_options.h>
  26. #include <grid_tricks.h>
  27. #include <lib_table_base.h>
  28. #include <widgets/wx_grid.h>
  29. #include <widgets/std_bitmap_button.h>
  30. #include <bitmaps.h>
  31. #include <string_utils.h>
  32. #define INITIAL_HELP \
  33. _( "Select an <b>Option Choice</b> in the listbox above, and then click the <b>Append Selected Option</b> button." )
  34. DIALOG_PLUGIN_OPTIONS::DIALOG_PLUGIN_OPTIONS( wxWindow* aParent,
  35. const wxString& aNickname,
  36. const std::map<std::string, UTF8>& aPluginOptions,
  37. const wxString& aFormattedOptions,
  38. wxString* aResult ) :
  39. DIALOG_PLUGIN_OPTIONS_BASE( aParent ),
  40. m_callers_options( aFormattedOptions ),
  41. m_result( aResult ),
  42. m_choices( aPluginOptions ),
  43. m_initial_help( INITIAL_HELP ),
  44. m_grid_widths_dirty( true )
  45. {
  46. SetTitle( wxString::Format( _( "Options for Library '%s'" ), aNickname ) );
  47. // Give a bit more room for combobox editors
  48. m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
  49. m_grid->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows );
  50. // add Cut, Copy, and Paste to wxGrid
  51. m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
  52. // Option Choices Panel:
  53. if( m_choices.size() )
  54. {
  55. unsigned int row = 0;
  56. for( std::map<std::string, UTF8>::const_iterator it = m_choices.begin(); it != m_choices.end();
  57. ++it, ++row )
  58. {
  59. wxString item = From_UTF8( it->first.c_str() );
  60. m_listbox->InsertItems( 1, &item, row );
  61. }
  62. }
  63. m_html->SetPage( m_initial_help );
  64. // Configure button logos
  65. m_append_button->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
  66. m_delete_button->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
  67. // initial focus on the grid please.
  68. SetInitialFocus( m_grid );
  69. SetupStandardButtons();
  70. }
  71. DIALOG_PLUGIN_OPTIONS ::~DIALOG_PLUGIN_OPTIONS()
  72. {
  73. // destroy GRID_TRICKS before m_grid.
  74. m_grid->PopEventHandler( true );
  75. }
  76. bool DIALOG_PLUGIN_OPTIONS::TransferDataToWindow()
  77. {
  78. if( !DIALOG_SHIM::TransferDataToWindow() )
  79. return false;
  80. // Fill the grid with existing aOptions
  81. std::string options = TO_UTF8( m_callers_options );
  82. std::map<std::string, UTF8>* props = LIB_TABLE::ParseOptions( options );
  83. if( props )
  84. {
  85. if( (int) props->size() > m_grid->GetNumberRows() )
  86. m_grid->AppendRows( props->size() - m_grid->GetNumberRows() );
  87. int row = 0;
  88. for( std::map<std::string, UTF8>::const_iterator it = props->begin(); it != props->end();
  89. ++it, ++row )
  90. {
  91. m_grid->SetCellValue( row, 0, From_UTF8( it->first.c_str() ) );
  92. m_grid->SetCellValue( row, 1, it->second );
  93. }
  94. delete props;
  95. }
  96. return true;
  97. }
  98. bool DIALOG_PLUGIN_OPTIONS::TransferDataFromWindow()
  99. {
  100. if( !m_grid->CommitPendingChanges() )
  101. return false;
  102. if( !DIALOG_SHIM::TransferDataFromWindow() )
  103. return false;
  104. std::map<std::string, UTF8> props;
  105. const int rowCount = m_grid->GetNumberRows();
  106. for( int row = 0; row<rowCount; ++row )
  107. {
  108. std::string name = TO_UTF8( m_grid->GetCellValue( row, 0 ).Trim( false ).Trim() );
  109. UTF8 value = m_grid->GetCellValue( row, 1 ).Trim( false ).Trim();
  110. if( name.size() )
  111. {
  112. props[name] = value;
  113. }
  114. }
  115. *m_result = LIB_TABLE::FormatOptions( &props ).wx_str();
  116. return true;
  117. }
  118. int DIALOG_PLUGIN_OPTIONS::appendRow()
  119. {
  120. int row = m_grid->GetNumberRows();
  121. m_grid->AppendRows( 1 );
  122. // wx documentation is wrong, SetGridCursor does not make visible.
  123. m_grid->MakeCellVisible( row, 0 );
  124. m_grid->SetGridCursor( row, 0 );
  125. return row;
  126. }
  127. void DIALOG_PLUGIN_OPTIONS::appendOption()
  128. {
  129. int selected_row = m_listbox->GetSelection();
  130. if( selected_row != wxNOT_FOUND )
  131. {
  132. wxString option = m_listbox->GetString( selected_row );
  133. int row_count = m_grid->GetNumberRows();
  134. int row;
  135. for( row=0; row<row_count; ++row )
  136. {
  137. wxString col0 = m_grid->GetCellValue( row, 0 );
  138. if( !col0 ) // empty col0
  139. break;
  140. }
  141. if( row == row_count )
  142. row = appendRow();
  143. m_grid->SetCellValue( row, 0, option );
  144. m_grid_widths_dirty = true;
  145. }
  146. }
  147. //-----<event handlers>------------------------------------------------------
  148. void DIALOG_PLUGIN_OPTIONS::onListBoxItemSelected( wxCommandEvent& event )
  149. {
  150. // change the help text based on the m_listbox selection:
  151. if( event.IsSelection() )
  152. {
  153. std::string option = TO_UTF8( event.GetString() );
  154. if( auto it = m_choices.find( option ); it != m_choices.end() )
  155. m_html->SetPage( it->second );
  156. else
  157. m_html->SetPage( m_initial_help );
  158. }
  159. }
  160. void DIALOG_PLUGIN_OPTIONS::onListBoxItemDoubleClicked( wxCommandEvent& event )
  161. {
  162. appendOption();
  163. }
  164. void DIALOG_PLUGIN_OPTIONS::onAppendOption( wxCommandEvent& )
  165. {
  166. if( !m_grid->CommitPendingChanges() )
  167. return;
  168. appendOption();
  169. }
  170. void DIALOG_PLUGIN_OPTIONS::onAppendRow( wxCommandEvent& )
  171. {
  172. if( !m_grid->CommitPendingChanges() )
  173. return;
  174. appendRow();
  175. }
  176. void DIALOG_PLUGIN_OPTIONS::onDeleteRow( wxCommandEvent& )
  177. {
  178. if( !m_grid->CommitPendingChanges() )
  179. return;
  180. int curRow = m_grid->GetGridCursorRow();
  181. m_grid->DeleteRows( curRow );
  182. m_grid_widths_dirty = true;
  183. curRow = std::max( 0, curRow - 1 );
  184. m_grid->MakeCellVisible( curRow, m_grid->GetGridCursorCol() );
  185. m_grid->SetGridCursor( curRow, m_grid->GetGridCursorCol() );
  186. }
  187. void DIALOG_PLUGIN_OPTIONS::onGridCellChange( wxGridEvent& aEvent )
  188. {
  189. m_grid_widths_dirty = true;
  190. aEvent.Skip();
  191. }
  192. void DIALOG_PLUGIN_OPTIONS::onUpdateUI( wxUpdateUIEvent& )
  193. {
  194. if( m_grid_widths_dirty && !m_grid->IsCellEditControlShown() )
  195. {
  196. int width = m_grid->GetClientRect().GetWidth();
  197. m_grid->AutoSizeColumn( 0 );
  198. m_grid->SetColSize( 0, std::max( 72, m_grid->GetColSize( 0 ) ) );
  199. m_grid->SetColSize( 1, std::max( 120, width - m_grid->GetColSize( 0 ) ) );
  200. m_grid_widths_dirty = false;
  201. }
  202. }
  203. void DIALOG_PLUGIN_OPTIONS::onSize( wxSizeEvent& aEvent )
  204. {
  205. m_grid_widths_dirty = true;
  206. aEvent.Skip();
  207. }