2016-01-25 04:55:36 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
2016-07-19 17:35:25 +00:00
|
|
|
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
2016-01-25 04:55:36 +00:00
|
|
|
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
2022-08-14 17:36:40 +00:00
|
|
|
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
2016-01-25 04:55:36 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, you may find one here:
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2016-04-17 22:35:32 +00:00
|
|
|
#include <set>
|
2021-06-19 17:28:45 +00:00
|
|
|
#include "dialog_select_3d_model.h"
|
2016-01-25 04:55:36 +00:00
|
|
|
#include "project.h"
|
|
|
|
#include "3d_cache/3d_info.h"
|
|
|
|
#include "3d_cache/3d_cache.h"
|
2016-01-26 00:50:01 +00:00
|
|
|
#include "3d_cache_dialogs.h"
|
2021-06-19 17:28:45 +00:00
|
|
|
#include <3d_model_viewer/eda_3d_model_viewer.h>
|
2021-01-03 22:23:00 +00:00
|
|
|
#include <common_ogl/ogl_attr_list.h>
|
2020-01-15 23:32:05 +00:00
|
|
|
#include <filename_resolver.h>
|
2020-11-12 20:19:22 +00:00
|
|
|
#include <pcbnew/footprint.h>
|
2022-08-14 17:36:40 +00:00
|
|
|
#include <wx_filename.h>
|
2016-01-26 00:50:01 +00:00
|
|
|
|
2020-10-18 11:31:07 +00:00
|
|
|
#include <wx/filedlg.h>
|
|
|
|
|
2020-10-17 21:55:38 +00:00
|
|
|
#include <kiplatform/ui.h>
|
|
|
|
|
2016-01-25 04:55:36 +00:00
|
|
|
|
2021-06-19 17:28:45 +00:00
|
|
|
DIALOG_SELECT_3DMODEL::DIALOG_SELECT_3DMODEL( wxWindow* aParent, S3D_CACHE* aCacheManager,
|
|
|
|
FP_3DMODEL* aModelItem, wxString& prevModelSelectDir,
|
|
|
|
int& prevModelWildcard ) :
|
|
|
|
DIALOG_SELECT_3D_MODEL_BASE( aParent ),
|
|
|
|
m_model( aModelItem ),
|
|
|
|
m_cache( aCacheManager ),
|
|
|
|
m_resolver( aCacheManager ? aCacheManager->GetResolver() : nullptr ),
|
|
|
|
m_previousDir( prevModelSelectDir ),
|
|
|
|
m_modelViewer( nullptr )
|
2016-01-25 04:55:36 +00:00
|
|
|
{
|
2021-06-19 17:28:45 +00:00
|
|
|
m_modelViewer = new EDA_3D_MODEL_VIEWER( m_pane3Dviewer,
|
|
|
|
OGL_ATT_LIST::GetAttributesList( ANTIALIASING_MODE::AA_8X ),
|
|
|
|
m_cache );
|
2020-11-16 12:29:07 +00:00
|
|
|
m_modelViewer->SetMinSize( wxSize( 400, -1 ) );
|
|
|
|
m_Sizer3Dviewer->Add( m_modelViewer, 1, wxEXPAND|wxRIGHT, 5 );
|
2016-01-25 04:55:36 +00:00
|
|
|
|
|
|
|
// create the filter list
|
|
|
|
if( NULL != m_cache )
|
|
|
|
{
|
|
|
|
std::list< wxString > const* fl = m_cache->GetFileFilters();
|
|
|
|
std::list< wxString >::const_iterator sL = fl->begin();
|
2020-04-30 17:49:41 +00:00
|
|
|
|
|
|
|
// The files filter string build from list of loaded plugins:
|
2016-01-25 04:55:36 +00:00
|
|
|
wxString filter;
|
|
|
|
|
2020-04-30 17:49:41 +00:00
|
|
|
// The files filter extensions only build from list of loaded plugins:
|
|
|
|
wxString ext_list;
|
|
|
|
|
|
|
|
while( sL != fl->end() )
|
2016-01-25 04:55:36 +00:00
|
|
|
{
|
2020-04-30 17:49:41 +00:00
|
|
|
if( !filter.IsEmpty() )
|
|
|
|
filter.Append( "|" );
|
|
|
|
|
2016-01-25 04:55:36 +00:00
|
|
|
filter.Append( *sL );
|
|
|
|
|
2020-04-30 17:49:41 +00:00
|
|
|
if( !ext_list.IsEmpty() )
|
|
|
|
ext_list.Append( ";" );
|
|
|
|
|
|
|
|
wxString ext = sL->AfterLast( '|' );
|
2016-01-25 04:55:36 +00:00
|
|
|
|
2020-04-30 17:49:41 +00:00
|
|
|
if( ext.Len() > 3 ) // Skip *.*
|
|
|
|
ext_list.Append( ext );
|
|
|
|
|
|
|
|
++sL;
|
2016-01-25 04:55:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if( !filter.empty() )
|
2020-04-30 17:49:41 +00:00
|
|
|
{
|
|
|
|
if( !ext_list.empty() )
|
|
|
|
{
|
|
|
|
wxString full_filter;
|
2020-04-30 19:03:03 +00:00
|
|
|
full_filter.Printf( _( "All supported files (%s)" ), ext_list );
|
|
|
|
full_filter << '|' << ext_list << '|' << filter;
|
2020-04-30 17:49:41 +00:00
|
|
|
m_FileTree->SetFilter( full_filter );
|
|
|
|
}
|
|
|
|
else
|
2021-06-19 17:28:45 +00:00
|
|
|
{
|
2020-04-30 17:49:41 +00:00
|
|
|
m_FileTree->SetFilter( filter );
|
2021-06-19 17:28:45 +00:00
|
|
|
}
|
2020-04-30 17:49:41 +00:00
|
|
|
}
|
2016-01-25 04:55:36 +00:00
|
|
|
else
|
2021-06-19 17:28:45 +00:00
|
|
|
{
|
2019-01-06 04:23:13 +00:00
|
|
|
m_FileTree->SetFilter( wxFileSelectorDefaultWildcardStr );
|
2021-06-19 17:28:45 +00:00
|
|
|
}
|
2016-01-25 04:55:36 +00:00
|
|
|
|
|
|
|
if( prevModelWildcard >= 0 && prevModelWildcard < (int)fl->size() )
|
2021-06-19 17:28:45 +00:00
|
|
|
{
|
2016-01-25 04:55:36 +00:00
|
|
|
m_FileTree->SetFilterIndex( prevModelWildcard );
|
2021-06-19 17:28:45 +00:00
|
|
|
}
|
2016-01-25 04:55:36 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
prevModelWildcard = 0;
|
|
|
|
m_FileTree->SetFilterIndex( 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-01-06 04:23:13 +00:00
|
|
|
m_FileTree->SetFilter( wxFileSelectorDefaultWildcardStr );
|
2016-01-25 04:55:36 +00:00
|
|
|
prevModelWildcard = 0;
|
|
|
|
m_FileTree->SetFilterIndex( 0 );
|
|
|
|
}
|
|
|
|
|
2020-11-16 12:29:07 +00:00
|
|
|
// Fix the filter box on the file selector widget so that it always shows the start of
|
|
|
|
// the filter string in the combobox. Otherwise it will only show the end of the string,
|
|
|
|
// which is empty for all but the all supported filters option.
|
2020-10-17 21:55:38 +00:00
|
|
|
wxChoice* filterBox = m_FileTree->GetFilterListCtrl();
|
|
|
|
KIPLATFORM::UI::EllipsizeChoiceBox( filterBox );
|
|
|
|
|
2020-04-30 17:49:41 +00:00
|
|
|
m_FileTree->SetPath( m_previousDir );
|
2016-01-26 00:50:01 +00:00
|
|
|
updateDirChoiceList();
|
2016-01-25 04:55:36 +00:00
|
|
|
|
2016-07-19 17:35:25 +00:00
|
|
|
m_modelViewer->Refresh();
|
|
|
|
m_modelViewer->SetFocus();
|
2020-04-30 17:49:41 +00:00
|
|
|
|
2020-11-16 11:16:44 +00:00
|
|
|
finishDialogSettings();
|
2016-01-25 04:55:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-19 17:28:45 +00:00
|
|
|
bool DIALOG_SELECT_3DMODEL::TransferDataFromWindow()
|
2016-01-25 04:55:36 +00:00
|
|
|
{
|
2020-04-30 17:49:41 +00:00
|
|
|
if( !m_model || !m_FileTree )
|
2016-01-25 04:55:36 +00:00
|
|
|
return true;
|
|
|
|
|
2016-07-19 17:35:25 +00:00
|
|
|
m_model->m_Scale.x = 1.0;
|
|
|
|
m_model->m_Scale.y = 1.0;
|
|
|
|
m_model->m_Scale.z = 1.0;
|
2016-01-25 04:55:36 +00:00
|
|
|
|
2016-07-19 17:35:25 +00:00
|
|
|
m_model->m_Rotation.x = 0.0;
|
|
|
|
m_model->m_Rotation.y = 0.0;
|
|
|
|
m_model->m_Rotation.z = 0.0;
|
2016-01-25 04:55:36 +00:00
|
|
|
|
2016-07-19 17:35:25 +00:00
|
|
|
m_model->m_Offset = m_model->m_Rotation;
|
|
|
|
m_model->m_Filename.clear();
|
2016-01-25 04:55:36 +00:00
|
|
|
|
2016-07-19 17:35:25 +00:00
|
|
|
wxString name = m_FileTree->GetFilePath();
|
2016-01-25 04:55:36 +00:00
|
|
|
|
2016-07-19 17:35:25 +00:00
|
|
|
if( name.empty() )
|
2016-01-25 04:55:36 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
m_previousDir = m_FileTree->GetPath();
|
|
|
|
|
2016-07-19 17:35:25 +00:00
|
|
|
// file selection mode: retrieve the filename and specify a
|
|
|
|
// path relative to one of the config paths
|
|
|
|
wxFileName fname = m_FileTree->GetFilePath();
|
2022-08-14 17:36:40 +00:00
|
|
|
fname.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
|
2016-07-19 17:35:25 +00:00
|
|
|
m_model->m_Filename = m_resolver->ShortenPath( fname.GetFullPath() );
|
2016-01-25 04:55:36 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-19 17:28:45 +00:00
|
|
|
void DIALOG_SELECT_3DMODEL::OnSelectionChanged( wxCommandEvent& event )
|
2016-01-25 04:55:36 +00:00
|
|
|
{
|
2016-07-19 17:35:25 +00:00
|
|
|
if( m_modelViewer )
|
|
|
|
m_modelViewer->Set3DModel( m_FileTree->GetFilePath() );
|
2016-01-25 04:55:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-19 17:28:45 +00:00
|
|
|
void DIALOG_SELECT_3DMODEL::OnFileActivated( wxCommandEvent& event )
|
2016-01-25 04:55:36 +00:00
|
|
|
{
|
2016-07-19 17:35:25 +00:00
|
|
|
if( m_modelViewer )
|
|
|
|
m_modelViewer->Set3DModel( m_FileTree->GetFilePath() );
|
2016-01-25 04:55:36 +00:00
|
|
|
|
2021-01-13 14:20:05 +00:00
|
|
|
EmulateButtonClickIfPresent( wxID_OK );
|
2016-01-25 04:55:36 +00:00
|
|
|
}
|
2016-01-26 00:50:01 +00:00
|
|
|
|
|
|
|
|
2021-06-19 17:28:45 +00:00
|
|
|
void DIALOG_SELECT_3DMODEL::SetRootDir( wxCommandEvent& event )
|
2016-01-26 00:50:01 +00:00
|
|
|
{
|
2020-04-30 17:49:41 +00:00
|
|
|
if( m_FileTree && m_dirChoices->GetSelection() > 0 )
|
|
|
|
m_FileTree->SetPath( m_dirChoices->GetString( m_dirChoices->GetSelection() ) );
|
2016-01-26 00:50:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-19 17:28:45 +00:00
|
|
|
void DIALOG_SELECT_3DMODEL::Cfg3DPaths( wxCommandEvent& event )
|
2016-01-26 00:50:01 +00:00
|
|
|
{
|
|
|
|
if( S3D::Configure3DPaths( this, m_resolver ) )
|
|
|
|
updateDirChoiceList();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-19 17:28:45 +00:00
|
|
|
void DIALOG_SELECT_3DMODEL::updateDirChoiceList( void )
|
2016-01-26 00:50:01 +00:00
|
|
|
{
|
2020-04-30 17:49:41 +00:00
|
|
|
if( !m_FileTree || !m_resolver || !m_dirChoices )
|
2016-01-26 00:50:01 +00:00
|
|
|
return;
|
|
|
|
|
2018-03-07 13:05:12 +00:00
|
|
|
std::list< SEARCH_PATH > const* md = m_resolver->GetPaths();
|
|
|
|
std::list< SEARCH_PATH >::const_iterator sL = md->begin();
|
2016-04-17 22:35:32 +00:00
|
|
|
std::set< wxString > cl;
|
|
|
|
wxString prjDir;
|
|
|
|
|
|
|
|
// extract the current project dir
|
2020-04-30 17:49:41 +00:00
|
|
|
if( sL != md->end() )
|
2016-04-17 22:35:32 +00:00
|
|
|
{
|
2020-11-16 11:16:44 +00:00
|
|
|
prjDir = sL->m_Pathexp;
|
2016-04-17 22:35:32 +00:00
|
|
|
++sL;
|
|
|
|
}
|
2016-01-26 00:50:01 +00:00
|
|
|
|
2020-04-30 17:49:41 +00:00
|
|
|
while( sL != md->end() )
|
2016-01-26 00:50:01 +00:00
|
|
|
{
|
2020-11-16 11:16:44 +00:00
|
|
|
if( !sL->m_Pathexp.empty() && sL->m_Pathexp.compare( prjDir ) )
|
|
|
|
cl.insert( sL->m_Pathexp );
|
2016-01-26 00:50:01 +00:00
|
|
|
|
|
|
|
++sL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !cl.empty() )
|
|
|
|
{
|
2019-06-21 03:10:25 +00:00
|
|
|
unsigned int choice = 0;
|
2020-04-30 17:49:41 +00:00
|
|
|
m_dirChoices->Clear();
|
|
|
|
m_dirChoices->Append( "" ); //Insert a blank string at the beginning to allow selection
|
2016-04-17 22:35:32 +00:00
|
|
|
|
|
|
|
if( !prjDir.empty() )
|
2019-06-21 03:10:25 +00:00
|
|
|
{
|
2020-04-30 17:49:41 +00:00
|
|
|
m_dirChoices->Append( prjDir );
|
2016-04-17 22:35:32 +00:00
|
|
|
|
2019-06-21 03:10:25 +00:00
|
|
|
if( prjDir == m_FileTree->GetPath() )
|
|
|
|
choice = 1;
|
|
|
|
}
|
|
|
|
|
2016-04-17 22:35:32 +00:00
|
|
|
std::set< wxString >::const_iterator sI = cl.begin();
|
|
|
|
|
2020-04-30 17:49:41 +00:00
|
|
|
while( sI != cl.end() )
|
2016-04-17 22:35:32 +00:00
|
|
|
{
|
2019-06-21 03:10:25 +00:00
|
|
|
if( *sI == m_FileTree->GetPath() )
|
2020-04-30 17:49:41 +00:00
|
|
|
choice = m_dirChoices->GetCount();
|
2019-06-21 03:10:25 +00:00
|
|
|
|
2020-04-30 17:49:41 +00:00
|
|
|
m_dirChoices->Append( *sI );
|
2016-04-17 22:35:32 +00:00
|
|
|
++sI;
|
|
|
|
}
|
|
|
|
|
2020-04-30 17:49:41 +00:00
|
|
|
m_dirChoices->SetSelection( choice );
|
2016-01-26 00:50:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|