34#include <wx/clipbrd.h>
36#include <wx/filedlg.h>
37#include <wx/filename.h>
40#include <wx/wfstream.h>
41#include <wx/wupdlock.h>
55 if(
const int row = aEvent.GetRow(); row >= 0 && row < m_grid->GetNumberRows() )
59 _(
"Copy the reference for this embedded file" ) );
60 menu.AppendSeparator();
78 if( wxTheClipboard->Open() )
80 wxTheClipboard->SetData(
new wxTextDataObject( cellValue ) );
81 wxTheClipboard->Close();
96 std::vector<const EMBEDDED_FILES*> aInheritedFiles ) :
104 for(
auto& [
name, file] :
m_files->EmbeddedFileMap() )
106 EMBEDDED_FILES::EMBEDDED_FILE* newFile = new EMBEDDED_FILES::EMBEDDED_FILE( *file );
107 m_localFiles->AddFile( newFile );
112 for( auto& [name, file] : inheritedFiles->EmbeddedFileMap() )
114 if( m_localFiles->HasFile( name ) )
117 EMBEDDED_FILES::EMBEDDED_FILE* newFile = new EMBEDDED_FILES::EMBEDDED_FILE( *file );
118 m_localFiles->AddFile( newFile );
119 m_inheritedFileNames.insert( name );
125 m_filesGridSizer->Detach( m_files_grid );
126 m_filesGridSizer->Add( m_files_grid, 5, wxEXPAND, 5 );
128 m_buttonsSizer->Detach( m_browse_button );
129 m_buttonsSizer->Prepend( m_browse_button, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
131 m_buttonsSizer->Detach( m_export );
132 m_buttonsSizer->Add( m_export, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
138 m_files_grid->SetMargins( 0 - wxSYS_VSCROLL_X, 0 );
139 m_files_grid->EnableAlternateRowColors();
142 m_files_grid->SetupColumnAutosizer( 1 );
144 m_localFiles->SetFileAddedCallback(
147 for(
int ii = 0; ii < m_files_grid->GetNumberRows(); ii++ )
149 if( m_files_grid->GetCellValue( ii, 1 ) == file->
GetLink() )
151 m_files_grid->DeleteRows( ii );
156 m_files_grid->AppendRows( 1 );
157 int ii = m_files_grid->GetNumberRows() - 1;
158 m_files_grid->SetCellValue( ii, 0, file->
name );
159 m_files_grid->SetCellValue( ii, 1, file->
GetLink() );
198 std::optional<bool> deleteReferences;
205 if( parent->Type() ==
PCB_T )
207 return IsOK( m_parent,
_(
"Deleted embedded files are also referenced in some footprints.\n"
208 "Delete from footprints as well?" ) );
212 return IsOK( m_parent,
_(
"Deleted embedded files are also referenced in some symbols.\n"
213 "Delete from symbols as well?" ) );
217 wxFAIL_MSG( wxT(
"Unexpected embedded files owner" ) );
221 for(
const auto& [
name, file] :
m_files->EmbeddedFileMap() )
225 m_files->RunOnNestedEmbeddedFiles(
230 if( !deleteReferences.has_value() )
231 deleteReferences = confirmDelete();
233 if( deleteReferences.value() )
239 if( deleteReferences.has_value() && deleteReferences.value() ==
false )
245 std::vector<EMBEDDED_FILES::EMBEDDED_FILE*> files;
248 files.push_back( file );
267 wxWindowUpdateLocker updateLock(
this );
276 for(
int ii = 0; ii <
m_files_grid->GetNumberRows(); ii++ )
292 std::set<KIFONT::OUTLINE_FONT*>
fonts =
m_files->GetFonts();
300 wxLogTrace( wxT(
"KICAD_EMBED" ), wxString::Format(
"Could not embed font %s",
301 font->GetFileName() ) );
309 col_pos = std::max( std::min( col_pos,
m_files_grid->GetNumberCols() - 1 ), 0 );
310 row_pos = std::max( std::min( row_pos,
m_files_grid->GetNumberRows() - 1 ), 0 );
313 for(
int ii = 0; ii <
m_files_grid->GetNumberRows(); ++ii )
327 wxFileName fileName( aFile );
328 wxString
name = fileName.GetFullName();
333 std::string newFileHash;
337 wxString msg = wxString::Format(
_(
"Failed to read file '%s'." ),
name );
338 KIDIALOG errorDlg( m_parent, msg,
_(
"Error" ), wxOK | wxICON_ERROR );
343 if( existingFile && existingFile->
data_hash == newFileHash )
348 wxString msg = wxString::Format(
349 _(
"A file named '%s' is already embedded, but the file on disk has different "
350 "content.\n\nDo you want to replace the embedded file with the new version?" ),
353 KIDIALOG dlg( m_parent, msg,
_(
"Embedded File Conflict" ),
354 wxYES_NO | wxCANCEL | wxICON_WARNING );
355 dlg.SetYesNoLabels(
_(
"Replace" ),
_(
"Reuse Existing" ) );
359 if(
result == wxID_CANCEL )
367 for(
int ii = 0; ii <
m_files_grid->GetNumberRows(); ii++ )
381 wxString msg = wxString::Format(
_(
"Failed to add file '%s'." ),
name );
383 KIDIALOG errorDlg( m_parent, msg,
_(
"Error" ), wxOK | wxICON_ERROR );
395 wxFileDialog fileDialog(
this,
_(
"Select a file to embed" ), wxEmptyString, wxEmptyString,
396 _(
"All Files" ) + wxT(
" (*.*)|*.*" ),
397 wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE );
401 if( fileDialog.ShowModal() == wxID_OK )
404 fileDialog.GetPaths( paths );
406 for(
const wxString&
path : paths )
414 wxString
name = aFileName;
421 wxString msg =
_(
"Embedded files inherited from a parent symbol cannot be removed." );
427 int row = std::max( 0,
m_files_grid->GetGridCursorRow() );
429 for(
int ii = 0; ii <
m_files_grid->GetNumberRows(); ii++ )
436 if( row < m_files_grid->GetNumberRows() )
463 wxDirDialog dirDialog(
this,
_(
"Select a directory to export files" ) );
465 if( dirDialog.ShowModal() != wxID_OK )
468 wxString
path = dirDialog.GetPath();
474 if( fileName.FileExists() )
476 wxString msg = wxString::Format(
_(
"File '%s' already exists." ), fileName.GetFullName() );
478 KIDIALOG errorDlg( m_parent, msg,
_(
"Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
486 bool skip_file =
false;
490 if( !fileName.IsDirWritable() )
493 wxString msg = wxString::Format(
_(
"Directory '%s' is not writable." ), fileName.GetFullName() );
495 wxString msg = wxString::Format(
_(
"Folder '%s' is not writable." ), fileName.GetPath() );
498 KIDIALOG errorDlg( m_parent, msg,
_(
"Error" ), wxYES_NO | wxCANCEL | wxICON_ERROR );
499 errorDlg.SetYesNoCancelLabels(
_(
"Retry" ),
_(
"Skip" ),
_(
"Cancel" ) );
503 if(
result == wxID_CANCEL )
507 else if(
result == wxID_NO )
523 wxFFileOutputStream out( fileName.GetFullPath() );
527 wxString msg = wxString::Format(
_(
"Failed to open file '%s'." ), fileName.GetFullName() );
529 KIDIALOG errorDlg( m_parent, msg,
_(
"Error" ), wxOK | wxICON_ERROR );
538 wxString msg = wxString::Format(
_(
"Failed to write file '%s'." ), fileName.GetFullName() );
540 KIDIALOG errorDlg( m_parent, msg,
_(
"Error" ), wxOK | wxICON_ERROR );
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
A base class for most all the KiCad significant classes used in schematics and boards.
@ EMBEDDED_FILES_GRID_TRICKS_COPY_FILENAME
EMBEDDED_FILES_GRID_TRICKS(WX_GRID *aGrid)
void doPopupSelection(wxCommandEvent &event) override
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
void RemoveFile(const wxString &name, bool aErase=true)
Remove a file from the collection and frees the memory.
static RETURN_CODE ComputeFileHash(const wxFileName &aFileName, std::string &aHash)
Compute the hash of a file on disk without fully embedding it.
bool HasFile(const wxString &name) const
GRID_TRICKS(WX_GRID *aGrid)
virtual void doPopupSelection(wxCommandEvent &event)
virtual void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent)
WX_GRID * m_grid
I don't own the grid, but he owns me.
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox.
bool SetOKCancelLabels(const ButtonLabel &ok, const ButtonLabel &cancel) override
Class OUTLINE_FONT implements outline font drawing.
wxCheckBox * m_cbEmbedFonts
PANEL_EMBEDDED_FILES_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
PANEL_EMBEDDED_FILES(wxWindow *aParent, EMBEDDED_FILES *aFiles, int aFlags=0, std::vector< const EMBEDDED_FILES * > aInheritedFiles={})
bool RemoveEmbeddedFile(const wxString &aFileName)
std::set< wxString > m_inheritedFileNames
void onFontEmbedClick(wxCommandEvent &event) override
void onAddEmbeddedFiles(wxCommandEvent &event) override
std::vector< const EMBEDDED_FILES * > m_inheritedFiles
void onDeleteEmbeddedFile(wxCommandEvent &event) override
~PANEL_EMBEDDED_FILES() override
bool TransferDataToWindow() override
EMBEDDED_FILES * m_localFiles
void onExportFiles(wxCommandEvent &event) override
EMBEDDED_FILES::EMBEDDED_FILE * AddEmbeddedFile(const wxString &aFileName)
bool TransferDataFromWindow() override
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
static const std::string KiCadUriPrefix
std::vector< char > decompressedData
wxString result
Test unit parsing edge cases and error handling.