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.

142 lines
4.6 KiB

  1. /*
  2. * Copyright (C) 2018 CERN
  3. * Copyright (C) 2018-2019 KiCad Developers, see AUTHORS.txt for contributors.
  4. *
  5. * Author: Maciej Suminski <maciej.suminski@cern.ch>
  6. *
  7. * This program is free software: you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation, either version 3 of the License, or (at your
  10. * option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. // inspired by David Hart's FileDirDlg widget (4Pane project)
  21. #include "dialog_file_dir_picker.h"
  22. #include <wx/filename.h>
  23. DIALOG_FILE_DIR_PICKER::DIALOG_FILE_DIR_PICKER( wxWindow* parent, const wxString& title,
  24. const wxString& defaultPath, const wxString& wildcard, int style )
  25. : DIALOG_SHIM( parent, wxID_ANY, title, wxDefaultPosition,
  26. wxSize( -1, 600 ), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )
  27. {
  28. m_showHidden = nullptr;
  29. wxString path = defaultPath.IsEmpty() ? wxGetCwd() : defaultPath;
  30. m_filesOnly = style & FD_RETURN_FILESONLY;
  31. int m_GDC_style = wxDIRCTRL_3D_INTERNAL | wxDIRCTRL_EDIT_LABELS;
  32. if( !wildcard.IsEmpty() )
  33. m_GDC_style |= wxDIRCTRL_SHOW_FILTERS;
  34. if( style & FD_MULTIPLE )
  35. m_GDC_style |= wxDIRCTRL_MULTIPLE;
  36. SetSizeHints( wxDefaultSize, wxDefaultSize );
  37. wxBoxSizer* mainSizer;
  38. mainSizer = new wxBoxSizer( wxVERTICAL );
  39. m_GDC = new wxGenericDirCtrl( this, wxID_ANY, wxEmptyString,
  40. wxDefaultPosition, wxDefaultSize, m_GDC_style );
  41. m_GDC->ShowHidden( style & FD_SHOW_HIDDEN );
  42. // TODO filter is not applied until it is reselected in the drop-down list, why?
  43. if( !wildcard.IsEmpty() )
  44. m_GDC->SetFilter( wildcard );
  45. mainSizer->Add( m_GDC, 1, wxEXPAND | wxALL, 5 );
  46. // TODO commented out due to string freeze, uncomment in v6
  47. //m_showHidden = new wxCheckBox( this, wxID_ANY, _( "Show Hidden" ), wxDefaultPosition, wxDefaultSize, 0 );
  48. //m_showHidden->SetValue( style & FD_SHOW_HIDDEN );
  49. //mainSizer->Add( m_showHidden, 0, wxALL, 5 );
  50. auto sdbSizer = new wxStdDialogButtonSizer();
  51. sdbSizer->AddButton( new wxButton( this, wxID_OK ) );
  52. sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) );
  53. sdbSizer->Realize();
  54. mainSizer->Add( sdbSizer, 0, wxEXPAND | wxALL, 5 );
  55. SetSizer( mainSizer );
  56. Layout();
  57. Centre( wxBOTH );
  58. // Use Connect() here instead of an event table entry, as otherwise an
  59. // event is fired before the dialog is created and m_GDC and Text initialised
  60. Connect( wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED,
  61. (wxObjectEventFunction) &DIALOG_FILE_DIR_PICKER::onHidden );
  62. // Call SetDirectory() to make the path visible
  63. SetDirectory( path );
  64. }
  65. void DIALOG_FILE_DIR_PICKER::SetDirectory( const wxString& aDirectory ) const
  66. {
  67. // Make the requested path visible. Without scrolling to the bottom, the requested path
  68. // is just below the window.
  69. wxArrayTreeItemIds selections;
  70. auto treeCtrl = m_GDC->GetTreeCtrl();
  71. treeCtrl->UnselectAll();
  72. m_GDC->SetPath( aDirectory );
  73. m_GDC->SetDefaultPath( aDirectory );
  74. treeCtrl->GetSelections( selections );
  75. if( !selections.IsEmpty() && selections[0].IsOk() )
  76. {
  77. auto lastChild = treeCtrl->GetLastChild( treeCtrl->GetRootItem() );
  78. if( lastChild.IsOk() )
  79. treeCtrl->ScrollTo( lastChild );
  80. treeCtrl->ScrollTo( selections[0] );
  81. }
  82. }
  83. wxString DIALOG_FILE_DIR_PICKER::GetDirectory() const
  84. {
  85. wxFileName fileName( m_GDC->GetPath() );
  86. // Strip the file name, if it is included in the path
  87. return fileName.FileExists() ? fileName.GetPath() : fileName.GetFullPath();
  88. }
  89. size_t DIALOG_FILE_DIR_PICKER::GetFilenames( wxArrayString& aFilePaths )
  90. {
  91. wxArrayTreeItemIds selectedIds;
  92. size_t count = m_GDC->GetTreeCtrl()->GetSelections( selectedIds );
  93. for( size_t c = 0; c < count; ++c )
  94. {
  95. wxDirItemData* data = (wxDirItemData*) m_GDC->GetTreeCtrl()->GetItemData( selectedIds[c] );
  96. if( m_filesOnly && wxDirExists( data->m_path ) )
  97. continue; // If we only want files, skip dirs
  98. aFilePaths.Add( data->m_path );
  99. }
  100. return aFilePaths.GetCount();
  101. }
  102. void DIALOG_FILE_DIR_PICKER::onHidden( wxCommandEvent& event )
  103. {
  104. m_GDC->ShowHidden( event.IsChecked() );
  105. }