30#include <wx/clipbrd.h>
32#include <wx/filedlg.h>
33#include <wx/filename.h>
36#include <wx/wfstream.h>
37#include <wx/wupdlock.h>
51 if(
const int row = aEvent.GetRow(); row >= 0 && row < m_grid->GetNumberRows() )
55 _(
"Copy the reference for this embedded file" ) );
56 menu.AppendSeparator();
74 if( wxTheClipboard->Open() )
76 wxTheClipboard->SetData(
new wxTextDataObject( cellValue ) );
77 wxTheClipboard->Close();
92 std::vector<const EMBEDDED_FILES*> aInheritedFiles ) :
100 for(
auto& [
name, file] :
m_files->EmbeddedFileMap() )
102 EMBEDDED_FILES::EMBEDDED_FILE* newFile = new EMBEDDED_FILES::EMBEDDED_FILE( *file );
103 m_localFiles->AddFile( newFile );
108 for( auto& [name, file] : inheritedFiles->EmbeddedFileMap() )
110 if( m_localFiles->HasFile( name ) )
113 EMBEDDED_FILES::EMBEDDED_FILE* newFile = new EMBEDDED_FILES::EMBEDDED_FILE( *file );
114 m_localFiles->AddFile( newFile );
115 m_inheritedFileNames.insert( name );
121 m_filesGridSizer->Detach( m_files_grid );
122 m_filesGridSizer->Add( m_files_grid, 5, wxEXPAND, 5 );
124 m_buttonsSizer->Detach( m_browse_button );
125 m_buttonsSizer->Prepend( m_browse_button, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
127 m_buttonsSizer->Detach( m_export );
128 m_buttonsSizer->Add( m_export, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
134 m_files_grid->SetMargins( 0 - wxSYS_VSCROLL_X, 0 );
135 m_files_grid->EnableAlternateRowColors();
138 m_files_grid->SetupColumnAutosizer( 1 );
140 m_localFiles->SetFileAddedCallback(
143 for(
int ii = 0; ii < m_files_grid->GetNumberRows(); ii++ )
145 if( m_files_grid->GetCellValue( ii, 1 ) == file->
GetLink() )
147 m_files_grid->DeleteRows( ii );
152 m_files_grid->AppendRows( 1 );
153 int ii = m_files_grid->GetNumberRows() - 1;
154 m_files_grid->SetCellValue( ii, 0, file->
name );
155 m_files_grid->SetCellValue( ii, 1, file->
GetLink() );
194 std::optional<bool> deleteReferences;
201 if( parent->Type() ==
PCB_T )
203 return IsOK( m_parent,
_(
"Deleted embedded files are also referenced in some footprints.\n"
204 "Delete from footprints as well?" ) );
208 return IsOK( m_parent,
_(
"Deleted embedded files are also referenced in some symbols.\n"
209 "Delete from symbols as well?" ) );
213 wxFAIL_MSG( wxT(
"Unexpected embedded files owner" ) );
217 for(
const auto& [
name, file] :
m_files->EmbeddedFileMap() )
221 m_files->RunOnNestedEmbeddedFiles(
226 if( !deleteReferences.has_value() )
227 deleteReferences = confirmDelete();
229 if( deleteReferences.value() )
235 if( deleteReferences.has_value() && deleteReferences.value() ==
false )
241 std::vector<EMBEDDED_FILES::EMBEDDED_FILE*> files;
244 files.push_back( file );
263 wxWindowUpdateLocker updateLock(
this );
272 for(
int ii = 0; ii <
m_files_grid->GetNumberRows(); ii++ )
288 std::set<KIFONT::OUTLINE_FONT*>
fonts =
m_files->GetFonts();
296 wxLogTrace( wxT(
"KICAD_EMBED" ), wxString::Format(
"Could not embed font %s",
297 font->GetFileName() ) );
305 col_pos = std::max( std::min( col_pos,
m_files_grid->GetNumberCols() - 1 ), 0 );
306 row_pos = std::max( std::min( row_pos,
m_files_grid->GetNumberRows() - 1 ), 0 );
309 for(
int ii = 0; ii <
m_files_grid->GetNumberRows(); ++ii )
323 wxFileName fileName( aFile );
324 wxString
name = fileName.GetFullName();
329 std::string newFileHash;
333 wxString msg = wxString::Format(
_(
"Failed to read file '%s'." ),
name );
334 KIDIALOG errorDlg( m_parent, msg,
_(
"Error" ), wxOK | wxICON_ERROR );
339 if( existingFile && existingFile->
data_hash == newFileHash )
344 wxString msg = wxString::Format(
345 _(
"A file named '%s' is already embedded, but the file on disk has different "
346 "content.\n\nDo you want to replace the embedded file with the new version?" ),
349 KIDIALOG dlg( m_parent, msg,
_(
"Embedded File Conflict" ),
350 wxYES_NO | wxCANCEL | wxICON_WARNING );
351 dlg.SetYesNoLabels(
_(
"Replace" ),
_(
"Reuse Existing" ) );
355 if(
result == wxID_CANCEL )
363 for(
int ii = 0; ii <
m_files_grid->GetNumberRows(); ii++ )
377 wxString msg = wxString::Format(
_(
"Failed to add file '%s'." ),
name );
379 KIDIALOG errorDlg( m_parent, msg,
_(
"Error" ), wxOK | wxICON_ERROR );
391 wxFileDialog fileDialog(
this,
_(
"Select a file to embed" ), wxEmptyString, wxEmptyString,
392 _(
"All Files" ) + wxT(
" (*.*)|*.*" ),
393 wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE );
397 if( fileDialog.ShowModal() == wxID_OK )
400 fileDialog.GetPaths( paths );
402 for(
const wxString&
path : paths )
410 wxString
name = aFileName;
417 wxString msg =
_(
"Embedded files inherited from a parent symbol cannot be removed." );
423 int row = std::max( 0,
m_files_grid->GetGridCursorRow() );
425 for(
int ii = 0; ii <
m_files_grid->GetNumberRows(); ii++ )
432 if( row < m_files_grid->GetNumberRows() )
459 wxDirDialog dirDialog(
this,
_(
"Select a directory to export files" ) );
461 if( dirDialog.ShowModal() != wxID_OK )
464 wxString
path = dirDialog.GetPath();
470 if( fileName.FileExists() )
472 wxString msg = wxString::Format(
_(
"File '%s' already exists." ), fileName.GetFullName() );
474 KIDIALOG errorDlg( m_parent, msg,
_(
"Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
482 bool skip_file =
false;
486 if( !fileName.IsDirWritable() )
489 wxString msg = wxString::Format(
_(
"Directory '%s' is not writable." ), fileName.GetFullName() );
491 wxString msg = wxString::Format(
_(
"Folder '%s' is not writable." ), fileName.GetPath() );
494 KIDIALOG errorDlg( m_parent, msg,
_(
"Error" ), wxYES_NO | wxCANCEL | wxICON_ERROR );
495 errorDlg.SetYesNoCancelLabels(
_(
"Retry" ),
_(
"Skip" ),
_(
"Cancel" ) );
499 if(
result == wxID_CANCEL )
503 else if(
result == wxID_NO )
519 wxFFileOutputStream out( fileName.GetFullPath() );
523 wxString msg = wxString::Format(
_(
"Failed to open file '%s'." ), fileName.GetFullName() );
525 KIDIALOG errorDlg( m_parent, msg,
_(
"Error" ), wxOK | wxICON_ERROR );
534 wxString msg = wxString::Format(
_(
"Failed to write file '%s'." ), fileName.GetFullName() );
536 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.