KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_embedded_files.cpp
Go to the documentation of this file.
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 3
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/gpl-3.0.html
19 * or you may search the http://www.gnu.org website for the version 3 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
24#include <bitmaps.h>
26#include <embedded_files.h>
27#include <font/outline_font.h>
28#include <kidialog.h>
30#include <widgets/wx_grid.h>
31
32#include <wx/clipbrd.h>
33#include <wx/dirdlg.h>
34#include <wx/ffile.h>
35#include <wx/filedlg.h>
36#include <wx/filename.h>
37#include <wx/log.h>
38#include <wx/menu.h>
39
40/* ---------- GRID_TRICKS for embedded files grid ---------- */
41
43 GRID_TRICKS( aGrid ), m_curRow( -1 )
44{
45}
46
47
48void EMBEDDED_FILES_GRID_TRICKS::showPopupMenu( wxMenu& menu, wxGridEvent& aEvent )
49{
50 if( const int row = aEvent.GetRow(); row >= 0 && row < m_grid->GetNumberRows() )
51 {
52 m_curRow = row;
53 menu.Append( EMBEDDED_FILES_GRID_TRICKS_COPY_FILENAME, _( "Copy Embedded Reference" ),
54 _( "Copy the reference for this embedded file" ) );
55 menu.AppendSeparator();
56 GRID_TRICKS::showPopupMenu( menu, aEvent );
57 }
58 else
59 {
60 m_curRow = -1;
61 }
62}
63
64
66{
67 if( event.GetId() == EMBEDDED_FILES_GRID_TRICKS_COPY_FILENAME )
68 {
69 if( m_curRow >= 0 )
70 {
71 const wxString cellValue = m_grid->GetCellValue( m_curRow, 1 );
72
73 if( wxTheClipboard->Open() )
74 {
75 wxTheClipboard->SetData( new wxTextDataObject( cellValue ) );
76 wxTheClipboard->Close();
77 }
78 }
79 }
80 else
81 {
83 }
84}
85
86
87/* ---------- End of GRID_TRICKS for embedded files grid ---------- */
88
89
91 PANEL_EMBEDDED_FILES_BASE( parent ), m_files( aFiles ), m_localFiles( new EMBEDDED_FILES() )
92{
93 for( auto& [name, file] : m_files->EmbeddedFileMap() )
94 {
96 m_localFiles->AddFile( newFile );
97 }
98
99 // Set up the standard buttons
100 m_delete_button->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
101 m_browse_button->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
102 m_files_grid->SetMargins( 0 - wxSYS_VSCROLL_X, 0 );
104
105 m_files_grid->PushEventHandler( new EMBEDDED_FILES_GRID_TRICKS( m_files_grid ) );
106}
107
108
110{
111 // Remove the GRID_TRICKS handler
112 m_files_grid->PopEventHandler( true );
113}
114
115
116void PANEL_EMBEDDED_FILES::onSize( wxSizeEvent& event )
117{
118 resizeGrid();
119}
120
121
123{
124 int panel_width = GetClientRect().GetWidth();
125 int first_width = m_files_grid->GetColSize( 0 );
126 int second_width = m_files_grid->GetColSize( 1 );
127
128 double ratio;
129
130 if( first_width + second_width > 0 )
131 ratio = (double)first_width / (double)( first_width + second_width );
132 else
133 ratio = 0.3;
134
135
136 m_files_grid->SetColSize( 0, panel_width * ratio );
137 m_files_grid->SetColSize( 1, panel_width * ( 1 - ratio ) );
138 Layout();
139}
140
141
143{
144 m_files_grid->ClearGrid();
145
146 if( m_files_grid->GetNumberRows() > 0 )
147 m_files_grid->DeleteRows( 0, m_files_grid->GetNumberRows() );
148
149 int ii = 0;
150 for( auto& [name, file] : m_localFiles->EmbeddedFileMap() )
151 {
152 while( m_files_grid->GetNumberRows() < ii + 1 )
153 m_files_grid->AppendRows( 1 );
154
155 m_files_grid->SetCellValue( ii, 0, name );
156 m_files_grid->SetCellValue( ii, 1, file->GetLink() );
157
158 ii++;
159 }
160
162
163 resizeGrid();
164
165 return true;
166}
167
168
170{
172
173 std::vector<EMBEDDED_FILES::EMBEDDED_FILE*> files;
174
175 for( auto it = m_localFiles->EmbeddedFileMap().begin();
176 it != m_localFiles->EmbeddedFileMap().end(); it++ )
177 files.push_back( it->second );
178
179 for( auto& file : files )
180 {
181 m_files->AddFile( file );
182 m_localFiles->RemoveFile( file->name, false );
183 }
184
186
187 return true;
188}
189
190
191void PANEL_EMBEDDED_FILES::onFontEmbedClick( wxCommandEvent& event )
192{
193 Freeze();
194 int row_pos = m_files_grid->GetGridCursorRow();
195 int col_pos = m_files_grid->GetGridCursorCol();
196 wxString row_name;
197
198 if( row_pos >= 0 )
199 row_name = m_files_grid->GetCellValue( row_pos, 0 );
200
201 for( int ii = 0; ii < m_files_grid->GetNumberRows(); ii++ )
202 {
203 wxString name = m_files_grid->GetCellValue( ii, 0 );
204
206
208 {
209 m_files_grid->DeleteRows( ii );
210 ii--;
212 }
213 }
214
215 if( m_cbEmbedFonts->IsChecked() )
216 {
217 std::set<KIFONT::OUTLINE_FONT*> fonts = m_files->GetFonts();
218
219 for( KIFONT::OUTLINE_FONT* font : fonts )
220 {
222 m_localFiles->AddFile( font->GetFileName(), true );
223
224 if( !result )
225 {
226 wxLogTrace( wxT( "KICAD_EMBED" ), wxString::Format( "Could not embed font %s",
227 font->GetFileName() ) );
228 continue;
229 }
230
231 m_files_grid->AppendRows( 1 );
232 int ii = m_files_grid->GetNumberRows() - 1;
233 m_files_grid->SetCellValue( ii, 0, result->name );
234 m_files_grid->SetCellValue( ii, 1, result->GetLink() );
235 }
236 }
237
238 if( row_pos >= 0 )
239 {
240 col_pos = std::max( std::min( col_pos, m_files_grid->GetNumberCols() - 1 ), 0 );
241 row_pos = std::max( std::min( row_pos, m_files_grid->GetNumberRows() - 1 ), 0 );
242 m_files_grid->SetGridCursor( row_pos, col_pos );
243
244 for( int ii = 0; ii < m_files_grid->GetNumberRows(); ++ii )
245 {
246 if( m_files_grid->GetCellValue( ii, 0 ) == row_name )
247 {
248 m_files_grid->SetGridCursor( ii, col_pos );
249 break;
250 }
251 }
252 }
253
254 Thaw();
255}
256
257
258void PANEL_EMBEDDED_FILES::onAddEmbeddedFile( wxCommandEvent& event )
259{
260 wxFileDialog fileDialog( this, _( "Select a file to embed" ), wxEmptyString, wxEmptyString,
261 _( "All files|*.*" ), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
262
263 if( fileDialog.ShowModal() == wxID_OK )
264 {
265 wxFileName fileName( fileDialog.GetPath() );
266 wxString name = fileName.GetFullName();
267
268 if( m_localFiles->HasFile( name ) )
269 {
270 wxString msg = wxString::Format( _( "File '%s' already exists." ), name );
271
272 KIDIALOG errorDlg( m_parent, msg, _( "Confirmation" ),
273 wxOK | wxCANCEL | wxICON_WARNING );
274 errorDlg.SetOKLabel( _( "Overwrite" ) );
275
276 if( errorDlg.ShowModal() != wxID_OK )
277 return;
278
279 for( int ii = 0; ii < m_files_grid->GetNumberRows(); ii++ )
280 {
281 if( m_files_grid->GetCellValue( ii, 0 ) == name )
282 {
283 m_files_grid->DeleteRows( ii );
284 break;
285 }
286 }
287 }
288
289 EMBEDDED_FILES::EMBEDDED_FILE* result = m_localFiles->AddFile( fileName, true );
290
291 if( !result )
292 {
293 wxString msg = wxString::Format( _( "Failed to add file '%s'." ),
294 name );
295
296 KIDIALOG errorDlg( m_parent, msg, _( "Error" ), wxOK | wxICON_ERROR );
297 errorDlg.ShowModal();
298 return;
299 }
300
301 m_files_grid->AppendRows( 1 );
302 int ii = m_files_grid->GetNumberRows() - 1;
303 m_files_grid->SetCellValue( ii, 0, name );
304 m_files_grid->SetCellValue( ii, 1, result->GetLink() );
305 }
306}
307
309{
310 int row = m_files_grid->GetGridCursorRow();
311
312 if( row < 0 )
313 return;
314
315 wxString name = m_files_grid->GetCellValue( row, 0 );
316
318
319 m_files_grid->DeleteRows( row );
320
321 if( row < m_files_grid->GetNumberRows() )
322 m_files_grid->SetGridCursor( row, 0 );
323 else if( m_files_grid->GetNumberRows() > 0 )
324 m_files_grid->SetGridCursor( m_files_grid->GetNumberRows() - 1, 0 );
325}
326
327
328void PANEL_EMBEDDED_FILES::onExportFiles( wxCommandEvent& event )
329{
330 wxDirDialog dirDialog( this, _( "Select a directory to export files" ) );
331
332 if( dirDialog.ShowModal() != wxID_OK )
333 return;
334
335 wxString path = dirDialog.GetPath();
336
337 for( auto& [name, file] : m_localFiles->EmbeddedFileMap() )
338 {
339 wxFileName fileName( path, name );
340
341 if( fileName.FileExists() )
342 {
343 wxString msg = wxString::Format( _( "File '%s' already exists." ),
344 fileName.GetFullName() );
345
346 KIDIALOG errorDlg( m_parent, msg, _( "Confirmation" ),
347 wxOK | wxCANCEL | wxICON_WARNING );
348 errorDlg.SetOKCancelLabels( _( "Overwrite" ), _( "Skip" ) );
349 errorDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
350
351 if( errorDlg.ShowModal() != wxID_OK )
352 continue;
353 }
354
355 bool skip_file = false;
356
357 while( 1 )
358 {
359 if( !fileName.IsDirWritable() )
360 {
361#ifndef __WXMAC__
362 wxString msg = wxString::Format( _( "Directory '%s' is not writable." ),
363 fileName.GetFullName() );
364#else
365 wxString msg = wxString::Format( _( "Folder '%s' is not writable." ),
366 fileName.GetPath() );
367#endif
368 // Don't set a 'do not show again' checkbox for this dialog
369 KIDIALOG errorDlg( m_parent, msg, _( "Error" ), wxYES_NO | wxCANCEL | wxICON_ERROR );
370 errorDlg.SetYesNoCancelLabels( _( "Retry" ), _( "Skip" ), _( "Cancel" ) );
371
372 int result = errorDlg.ShowModal();
373
374 if( result == wxID_CANCEL )
375 {
376 return;
377 }
378 else if( result == wxID_NO )
379 {
380 skip_file = true;
381 break;
382 }
383 }
384 else
385 {
386 break;
387 }
388 }
389
390 if( skip_file )
391 continue;
392
393 wxFFile ffile( fileName.GetFullPath(), wxT( "w" ) );
394
395 if( !ffile.IsOpened() )
396 {
397 wxString msg = wxString::Format( _( "Failed to open file '%s'." ),
398 fileName.GetFullName() );
399
400 KIDIALOG errorDlg( m_parent, msg, _( "Error" ), wxOK | wxICON_ERROR );
401 errorDlg.ShowModal();
402 continue;
403 }
404
405 if( !ffile.Write( file->decompressedData.data(), file->decompressedData.size() ) )
406 {
407 wxString msg = wxString::Format( _( "Failed to write file '%s'." ),
408 fileName.GetFullName() );
409
410 KIDIALOG errorDlg( m_parent, msg, _( "Error" ), wxOK | wxICON_ERROR );
411 errorDlg.ShowModal();
412 }
413 }
414}
const char * name
Definition: DXF_plotter.cpp:59
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
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.
EMBEDDED_FILE * GetEmbeddedFile(const wxString &aName) const
Returns the embedded file with the given name or nullptr if it does not exist.
bool HasFile(const wxString &name) const
void ClearEmbeddedFiles(bool aDeleteFiles=true)
virtual std::set< KIFONT::OUTLINE_FONT * > GetFonts() const
EMBEDDED_FILE * AddFile(const wxFileName &aName, bool aOverwrite)
Load a file from disk and adds it to the collection.
const std::map< wxString, EMBEDDED_FILE * > & EmbeddedFileMap() const
void SetAreFontsEmbedded(bool aEmbedFonts)
bool GetAreFontsEmbedded() const
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
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.
Definition: grid_tricks.h:125
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: kidialog.h:43
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox.
Definition: kidialog.cpp:51
bool SetOKCancelLabels(const ButtonLabel &ok, const ButtonLabel &cancel) override
Definition: kidialog.h:53
int ShowModal() override
Definition: kidialog.cpp:95
Class OUTLINE_FONT implements outline font drawing.
Definition: outline_font.h:53
Class PANEL_EMBEDDED_FILES_BASE.
EMBEDDED_FILES * m_files
PANEL_EMBEDDED_FILES(wxWindow *parent, EMBEDDED_FILES *aFiles)
void onFontEmbedClick(wxCommandEvent &event) override
void onDeleteEmbeddedFile(wxCommandEvent &event) override
bool TransferDataToWindow() override
void onSize(wxSizeEvent &event) override
EMBEDDED_FILES * m_localFiles
void onExportFiles(wxCommandEvent &event) override
void onAddEmbeddedFile(wxCommandEvent &event) override
bool TransferDataFromWindow() override
void SetBitmap(const wxBitmapBundle &aBmp)
void EnableAlternateRowColors(bool aEnable=true)
Enable alternate row highlighting, where every odd row has a different background color than the even...
Definition: wx_grid.cpp:313
#define _(s)
This file is part of the common library.