KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pagelayout_editor/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 (C) 2013 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Jean-Pierre Charras, jp.charras at wanadoo.fr
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
23#include <confirm.h>
24#include <gestfich.h>
27#include <paths.h>
28#include <widgets/wx_infobar.h>
30
31#include <kiplatform/io.h>
32
33#include "pl_editor_frame.h"
34#include "pl_editor_id.h"
35#include "properties_frame.h"
36
37#include <wx/filedlg.h>
38#include <wx/filename.h>
39#include <wx/stdpaths.h>
40#include <kiplatform/ui.h>
41
43{
44 wxCommandEvent saveEvent;
45 saveEvent.SetId( wxID_SAVE );
46 Files_io( saveEvent );
47
48 return !IsContentModified();
49}
50
51
52void PL_EDITOR_FRAME::OnFileHistory( wxCommandEvent& event )
53{
54 wxString filename;
55
56 filename = GetFileFromHistory( event.GetId(), _( "Drawing Sheet File" ) );
57
58 if( !filename.IsEmpty() )
59 {
60 if( IsContentModified() )
61 {
62 if( !HandleUnsavedChanges( this, _( "The current drawing sheet has been modified. "
63 "Save changes?" ),
64 [&]() -> bool
65 {
66 return saveCurrentPageLayout();
67 } ) )
68 {
69 return;
70 }
71 }
72
73 ::wxSetWorkingDirectory( ::wxPathOnly( filename ) );
74
75 if( LoadDrawingSheetFile( filename ) )
76 {
77 wxString msg;
78 msg.Printf( _( "File '%s' loaded"), filename );
79 SetStatusText( msg );
80 }
81
83 }
84}
85
86
87void PL_EDITOR_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
88{
90}
91
92
93/* File commands. */
94void PL_EDITOR_FRAME::Files_io( wxCommandEvent& event )
95{
96 wxString msg;
97 int id = event.GetId();
98 wxString filename = GetCurrentFileName();
100
101 if( filename.IsEmpty() && id == wxID_SAVE )
102 id = wxID_SAVEAS;
103
104 if( ( id == wxID_NEW || id == wxID_OPEN ) && IsContentModified() )
105 {
106 if( !HandleUnsavedChanges( this, _( "The current drawing sheet has been modified. "
107 "Save changes?" ),
108 [&]() -> bool
109 {
110 return saveCurrentPageLayout();
111 } ) )
112 {
113 return;
114 }
115 }
116
117 switch( id )
118 {
119 case wxID_NEW:
120 pglayout.AllowVoidList( true );
121 SetCurrentFileName( wxEmptyString );
122 pglayout.ClearList();
124 break;
125
127 {
128 wxFileDialog openFileDialog( this, _( "Append Existing Drawing Sheet" ),
129 wxEmptyString, wxEmptyString,
131
133
134 if( openFileDialog.ShowModal() == wxID_CANCEL )
135 return;
136
137 filename = openFileDialog.GetPath();
138
139 if( !InsertDrawingSheetFile( filename ) )
140 {
141 msg.Printf( _( "Unable to load %s file" ), filename );
142 DisplayErrorMessage( this, msg );
143 }
144 else
145 {
147 HardRedraw();
148 msg.Printf( _( "File '%s' inserted" ), filename );
149 SetStatusText( msg );
150 }
151
152 break;
153 }
154
155 case wxID_OPEN:
156 {
157 wxFileDialog openFileDialog( this, _( "Open Drawing Sheet" ), wxEmptyString, wxEmptyString,
159
161
162 if( openFileDialog.ShowModal() == wxID_CANCEL )
163 return;
164
165 filename = openFileDialog.GetPath();
166
167 if( !LoadDrawingSheetFile( filename ) )
168 {
169 msg.Printf( _( "Unable to load %s file" ), filename );
170 DisplayErrorMessage( this, msg );
171 }
172 else
173 {
175 msg.Printf( _( "File '%s' saved." ), filename );
176 SetStatusText( msg );
177 }
178
179 break;
180 }
181
182 case wxID_SAVE:
183 if( !SaveDrawingSheetFile( filename ) )
184 {
185 msg.Printf( _( "Unable to write '%s'." ), filename );
186 DisplayErrorMessage( this, msg );
187 }
188 else
189 {
190 msg.Printf( _("File '%s' saved."), filename );
191 SetStatusText( msg );
192 }
193
194 break;
195
196 case wxID_SAVEAS:
197 {
198 wxString dir = PATHS::GetUserTemplatesPath();
199 wxFileDialog openFileDialog( this, _( "Save Drawing Sheet As" ), dir, wxEmptyString,
201 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
202
204
205 if( openFileDialog.ShowModal() == wxID_CANCEL )
206 return;
207
208 filename = openFileDialog.GetPath();
209 // Ensure the file has the right extension:
210 // because a name like name.subname.subsubname is legal,
211 // add the right extension without replacing the wxFileName
212 // extension
213 wxFileName fn(filename);
214
215 if( fn.GetExt() != FILEEXT::DrawingSheetFileExtension )
216 filename << wxT( "." ) << FILEEXT::DrawingSheetFileExtension;
217
218 if( !SaveDrawingSheetFile( filename ) )
219 {
220 msg.Printf( _( "Failed to create file '%s'." ), filename );
221 DisplayErrorMessage( this, msg );
222 }
223 else
224 {
225 msg.Printf( _( "File '%s' saved." ), filename );
226 SetStatusText( msg );
227
228 SetCurrentFileName( filename );
230 }
231
232 break;
233 }
234
235 default:
236 break;
237 }
238}
239
240
241bool PL_EDITOR_FRAME::LoadDrawingSheetFile( const wxString& aFullFileName )
242{
243 if( wxFileExists( aFullFileName ) )
244 {
245 wxString msg;
246
247 if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( aFullFileName, &msg ) )
248 {
250 wxString::Format( _( "Error loading drawing sheet '%s'." ),
251 aFullFileName ),
252 msg );
253 return false;
254 }
255
256 SetCurrentFileName( aFullFileName );
257 UpdateFileHistory( aFullFileName );
258 GetScreen()->SetContentModified( false );
259
260 wxFileName fn = aFullFileName;
261 m_infoBar->Dismiss();
262
263 if( DS_DATA_MODEL::GetTheInstance().GetFileFormatVersionAtLoad() < SEXPR_WORKSHEET_FILE_VERSION )
264 {
265 m_infoBar->RemoveAllButtons();
266 m_infoBar->AddCloseButton();
267 m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
268 "It will be converted to the new format when saved." ),
269 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
270 }
271
272 if( fn.FileExists() && !fn.IsFileWritable() )
273 {
274 m_infoBar->RemoveAllButtons();
275 m_infoBar->AddCloseButton();
276 m_infoBar->ShowMessage( _( "Layout file is read only." ),
277 wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
278 }
279
280 return true;
281 }
282
283 return false;
284}
285
286
287bool PL_EDITOR_FRAME::InsertDrawingSheetFile( const wxString& aFullFileName )
288{
289 if( wxFileExists( aFullFileName ) )
290 {
291 const bool append = true;
293 DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( aFullFileName, nullptr, append );
294 return true;
295 }
296
297 return false;
298}
299
300
301bool PL_EDITOR_FRAME::SaveDrawingSheetFile( const wxString& aFullFileName )
302{
303 if( !aFullFileName.IsEmpty() )
304 {
305 wxString tempFile = wxFileName::CreateTempFileName( "pledit" );
306
307 try
308 {
310 }
311 catch( const IO_ERROR& )
312 {
313 // In case we started a file but didn't fully write it, clean up
314 wxRemoveFile( tempFile);
315
316 return false;
317 }
318
319 // Preserve the permissions of the current file
320 KIPLATFORM::IO::DuplicatePermissions( aFullFileName, tempFile );
321
322 if( !wxRenameFile( tempFile, aFullFileName ) )
323 return false;
324
325 if( m_infoBar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE )
326 m_infoBar->Dismiss();
327
328 GetScreen()->SetContentModified( false );
330 return true;
331 }
332
333 return false;
334}
335
337{
338 for( const wxFileName& file : m_AcceptedFiles )
339 OpenProjectFiles( { file.GetFullPath() }, KICTL_CREATE );
340}
void SetContentModified(bool aModified=true)
Definition base_screen.h:55
Handle the graphic items list to draw/plot the frame and title block.
bool LoadDrawingSheet(const wxString &aFullFileName, wxString *aMsg, bool aAppend=false)
Populate the list with a custom layout or the default layout if no custom layout is available.
static DS_DATA_MODEL & GetTheInstance()
Return the instance of DS_DATA_MODEL used in the application.
void AllowVoidList(bool Allow)
In KiCad applications, a drawing sheet is needed So if the list is empty, a default drawing sheet is ...
void ClearList()
Erase the list of items.
void Save(const wxString &aFullFileName)
Save the description in a file.
std::vector< wxFileName > m_AcceptedFiles
WX_INFOBAR * m_infoBar
void UpdateFileHistory(const wxString &FullFileName, FILE_HISTORY *aFileHistory=nullptr)
Update the list of recently opened files.
virtual void ClearFileHistory()
Remove all files from the file history.
wxString GetFileFromHistory(int cmdId, const wxString &type, FILE_HISTORY *aFileHistory=nullptr)
Fetch the file name from the file history list.
virtual BASE_SCREEN * GetScreen() const
Return a pointer to a BASE_SCREEN or one of its derivatives.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
static wxString GetUserTemplatesPath()
Gets the user path for custom templates.
Definition paths.cpp:71
bool OpenProjectFiles(const std::vector< wxString > &aFileSet, int aCtl) override
Open a project or set of files given by aFileList.
void OnNewDrawingSheet()
Must be called to initialize parameters when a new drawing sheet is loaded.
void SetCurrentFileName(const wxString &aName)
Store the current layout description file filename.
bool IsContentModified() const override
Get if the drawing sheet has been modified but not saved.
void Files_io(wxCommandEvent &event)
void OnClearFileHistory(wxCommandEvent &aEvent)
wxString GetCurrentFileName() const override
void OnFileHistory(wxCommandEvent &event)
void DoWithAcceptedFiles() override
Execute action on accepted dropped file.
void UpdateTitleAndInfo()
Display the short filename (if exists) loaded file on the caption of the main window.
bool SaveDrawingSheetFile(const wxString &aFullFileName)
Save the current layout in a .kicad_wks drawing sheet file.
bool InsertDrawingSheetFile(const wxString &aFullFileName)
Load a .kicad_wks drawing sheet file, and add items to the current layout list.
void SaveCopyInUndoList()
Save a copy of the description (in a S expr string) for Undo/redo commands.
void HardRedraw() override
Refresh the library tree and redraw the window.
bool LoadDrawingSheetFile(const wxString &aFullFileName)
Load a .kicad_wks drawing sheet file.
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
Definition confirm.cpp:146
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
This file is part of the common library.
#define SEXPR_WORKSHEET_FILE_VERSION
This file contains the file format version information for the s-expression drawing sheet file format...
#define _(s)
static const std::string DrawingSheetFileExtension
static wxString DrawingSheetFileWildcard()
#define KICTL_CREATE
caller thinks requested project files may not exist.
bool DuplicatePermissions(const wxString &aSrc, const wxString &aDest)
Duplicates the file security data from one file to another ensuring that they are the same between bo...
Definition unix/io.cpp:55
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:448
@ ID_APPEND_DESCR_FILE
Definition of file extensions used in Kicad.