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.

286 lines
8.6 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 "widgets/listbox_tricks.h"
  24. #include <wx/clipbrd.h>
  25. #include <wx/listbox.h>
  26. #include <wx/menu.h>
  27. #include <wx/window.h>
  28. #include <bitmaps.h>
  29. #include <bitmaps/bitmaps_list.h>
  30. #include <widgets/ui_common.h>
  31. wxDEFINE_EVENT( EDA_EVT_LISTBOX_COPY, wxCommandEvent );
  32. wxDEFINE_EVENT( EDA_EVT_LISTBOX_CUT, wxCommandEvent );
  33. wxDEFINE_EVENT( EDA_EVT_LISTBOX_PASTE, wxCommandEvent );
  34. wxDEFINE_EVENT( EDA_EVT_LISTBOX_DELETE, wxCommandEvent );
  35. wxDEFINE_EVENT( EDA_EVT_LISTBOX_DUPLICATE, wxCommandEvent );
  36. wxDEFINE_EVENT( EDA_EVT_LISTBOX_CHANGED, wxCommandEvent );
  37. LISTBOX_TRICKS::LISTBOX_TRICKS( wxWindow& aParent, wxListBox& aListBox ) :
  38. m_parent( aParent ),
  39. m_listBox( aListBox )
  40. {
  41. m_listBox.Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( LISTBOX_TRICKS::OnListBoxRDown ),
  42. nullptr, this );
  43. m_listBox.Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( LISTBOX_TRICKS::OnListBoxKeyDown ),
  44. nullptr, this );
  45. Connect( EDA_EVT_LISTBOX_DELETE, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxDelete ) );
  46. Connect( EDA_EVT_LISTBOX_COPY, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxCopy ) );
  47. Connect( EDA_EVT_LISTBOX_CUT, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxCut ) );
  48. Connect( EDA_EVT_LISTBOX_PASTE, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxPaste ) );
  49. Connect( EDA_EVT_LISTBOX_DUPLICATE, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxDuplicate ) );
  50. }
  51. LISTBOX_TRICKS::~LISTBOX_TRICKS()
  52. {
  53. m_listBox.Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( LISTBOX_TRICKS::OnListBoxRDown ),
  54. nullptr, this );
  55. m_listBox.Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( LISTBOX_TRICKS::OnListBoxKeyDown ),
  56. nullptr, this );
  57. Disconnect( EDA_EVT_LISTBOX_DELETE, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxDelete ) );
  58. Disconnect( EDA_EVT_LISTBOX_COPY, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxCopy ) );
  59. Disconnect( EDA_EVT_LISTBOX_CUT, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxCut ) );
  60. Disconnect( EDA_EVT_LISTBOX_PASTE, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxPaste ) );
  61. Disconnect( EDA_EVT_LISTBOX_DUPLICATE, wxCommandEventHandler( LISTBOX_TRICKS::OnListBoxDuplicate ) );
  62. }
  63. wxArrayInt LISTBOX_TRICKS::listBoxDeleteSelected()
  64. {
  65. wxArrayInt selections;
  66. m_listBox.GetSelections( selections );
  67. if( selections.GetCount() == 0 ) // Nothing to remove
  68. return selections;
  69. std::sort( selections.begin(), selections.end() );
  70. for( int ii = selections.GetCount() - 1; ii >= 0; ii-- )
  71. m_listBox.Delete( selections[ii] );
  72. m_listBox.SetSelection( wxNOT_FOUND );
  73. if( m_listBox.GetCount() > 0 )
  74. m_listBox.SetSelection( std::max( 0, selections[0] - 1 ) );
  75. wxPostEvent( &m_listBox, wxCommandEvent( EDA_EVT_LISTBOX_CHANGED ) );
  76. return selections;
  77. }
  78. wxArrayString LISTBOX_TRICKS::listBoxGetSelected() const
  79. {
  80. wxArrayInt selections;
  81. m_listBox.GetSelections( selections );
  82. wxArrayString result;
  83. for( size_t ii = 0; ii < selections.GetCount(); ii++ )
  84. result.Add( m_listBox.GetString( selections[ii] ) );
  85. return result;
  86. }
  87. void LISTBOX_TRICKS::listBoxDuplicateSelected()
  88. {
  89. wxArrayInt selections;
  90. m_listBox.GetSelections( selections );
  91. int insertAt = selections.GetCount() > 0 ? selections.back() + 1 : m_listBox.GetCount();
  92. m_listBox.SetSelection( wxNOT_FOUND );
  93. for( size_t ii = 0; ii < selections.GetCount(); ii++ )
  94. {
  95. wxString filter = m_listBox.GetString( selections[ii] );
  96. m_listBox.Insert( filter, insertAt );
  97. m_listBox.SetSelection( insertAt );
  98. insertAt++;
  99. }
  100. wxPostEvent( &m_listBox, wxCommandEvent( EDA_EVT_LISTBOX_CHANGED ) );
  101. }
  102. void LISTBOX_TRICKS::listBoxCopy()
  103. {
  104. wxArrayString filters = listBoxGetSelected();
  105. wxString result;
  106. for( const wxString& filter : filters )
  107. result += filter + wxT( "\n" );
  108. if( wxTheClipboard->Open() )
  109. {
  110. wxTheClipboard->SetData( new wxTextDataObject( result ) );
  111. wxTheClipboard->Close();
  112. }
  113. }
  114. void LISTBOX_TRICKS::listBoxPaste()
  115. {
  116. wxArrayString lines;
  117. if( wxTheClipboard->Open() )
  118. {
  119. wxTextDataObject data;
  120. wxTheClipboard->GetData( data );
  121. wxString text = data.GetText();
  122. text.Trim( false );
  123. text.Trim( true );
  124. lines = wxSplit( text, '\n' );
  125. wxTheClipboard->Close();
  126. }
  127. if( lines.IsEmpty() )
  128. return;
  129. wxArrayInt selections;
  130. m_listBox.GetSelections( selections );
  131. int insertAt = selections.GetCount() > 0 ? (int) selections.back() + 1 : (int) m_listBox.GetCount();
  132. for( wxString& line : lines )
  133. {
  134. line.Trim( false );
  135. line.Trim( true );
  136. }
  137. m_listBox.InsertItems( lines, insertAt );
  138. m_listBox.SetSelection( wxNOT_FOUND );
  139. for( size_t ii = insertAt; ii < insertAt + lines.GetCount(); ii++ )
  140. m_listBox.SetSelection( ii );
  141. wxPostEvent( &m_listBox, wxCommandEvent( EDA_EVT_LISTBOX_CHANGED ) );
  142. }
  143. void LISTBOX_TRICKS::listBoxCut()
  144. {
  145. listBoxCopy();
  146. wxArrayInt deleted = listBoxDeleteSelected();
  147. size_t select = deleted.GetCount() > 0 ? deleted[0] : m_listBox.GetCount();
  148. m_listBox.SetSelection( wxNOT_FOUND );
  149. m_listBox.SetSelection( std::min( select, (size_t) m_listBox.GetCount() - 1 ) );
  150. }
  151. void LISTBOX_TRICKS::OnListBoxRDown( wxMouseEvent& aEvent )
  152. {
  153. wxMenu menu;
  154. KIUI::AddMenuItem( &menu, ID_COPY, _( "Copy" ) + "\tCtrl+C", KiBitmap( BITMAPS::copy ) );
  155. KIUI::AddMenuItem( &menu, ID_CUT, _( "Cut" ) + "\tCtrl+X", KiBitmap( BITMAPS::cut ) );
  156. KIUI::AddMenuItem( &menu, ID_PASTE, _( "Paste" ) + "\tCtrl+V", KiBitmap( BITMAPS::paste ) );
  157. KIUI::AddMenuItem( &menu, ID_DUPLICATE, _( "Duplicate" ) + "\tCtrl+D", KiBitmap( BITMAPS::duplicate ) );
  158. KIUI::AddMenuItem( &menu, ID_DELETE, _( "Delete" ) + "\tDel", KiBitmap( BITMAPS::trash ) );
  159. menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
  160. [&]( wxCommandEvent& aCmd )
  161. {
  162. switch( aEvent.GetId() )
  163. {
  164. case ID_COPY: listBoxCopy(); break;
  165. case ID_PASTE: listBoxPaste(); break;
  166. case ID_CUT: listBoxCut(); break;
  167. case ID_DELETE: listBoxDeleteSelected(); break;
  168. case ID_DUPLICATE: listBoxDuplicateSelected(); break;
  169. default: aEvent.Skip();
  170. }
  171. } );
  172. m_parent.PopupMenu( &menu );
  173. }
  174. void LISTBOX_TRICKS::OnListBoxKeyDown( wxKeyEvent& aEvent )
  175. {
  176. if( aEvent.GetKeyCode() == WXK_DELETE )
  177. {
  178. listBoxDeleteSelected();
  179. }
  180. else
  181. {
  182. if( aEvent.ControlDown() )
  183. {
  184. switch( aEvent.GetKeyCode() )
  185. {
  186. case 'C': listBoxCopy(); break;
  187. case 'V': listBoxPaste(); break;
  188. case 'X': listBoxCut(); break;
  189. case 'D': listBoxDuplicateSelected(); break;
  190. default: aEvent.Skip();
  191. }
  192. }
  193. else
  194. {
  195. aEvent.Skip();
  196. }
  197. }
  198. }
  199. void LISTBOX_TRICKS::OnListBoxDelete( wxCommandEvent& aEvent )
  200. {
  201. listBoxDeleteSelected();
  202. }
  203. void LISTBOX_TRICKS::OnListBoxCopy( wxCommandEvent& aEvent )
  204. {
  205. listBoxCopy();
  206. }
  207. void LISTBOX_TRICKS::OnListBoxCut( wxCommandEvent& aEvent )
  208. {
  209. listBoxCut();
  210. }
  211. void LISTBOX_TRICKS::OnListBoxPaste( wxCommandEvent& aEvent )
  212. {
  213. listBoxPaste();
  214. }
  215. void LISTBOX_TRICKS::OnListBoxDuplicate( wxCommandEvent& aEvent )
  216. {
  217. listBoxDuplicateSelected();
  218. }