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, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <confirm.h>
28#include <gestfich.h>
31#include <paths.h>
32#include <widgets/wx_infobar.h>
34
35#include <kiplatform/io.h>
36
37#include "pl_editor_frame.h"
38#include "pl_editor_id.h"
39#include "properties_frame.h"
40
41#include <wx/filedlg.h>
42#include <wx/filename.h>
43#include <wx/stdpaths.h>
44
46{
47 wxCommandEvent saveEvent;
48 saveEvent.SetId( wxID_SAVE );
49 Files_io( saveEvent );
50
51 return !IsContentModified();
52}
53
54
55void PL_EDITOR_FRAME::OnFileHistory( wxCommandEvent& event )
56{
57 wxString filename;
58
59 filename = GetFileFromHistory( event.GetId(), _( "Drawing Sheet File" ) );
60
61 if( filename != wxEmptyString )
62 {
63 if( IsContentModified() )
64 {
65 if( !HandleUnsavedChanges( this, _( "The current drawing sheet has been modified. "
66 "Save changes?" ),
67 [&]() -> bool
68 {
69 return saveCurrentPageLayout();
70 } ) )
71 {
72 return;
73 }
74 }
75
76 ::wxSetWorkingDirectory( ::wxPathOnly( filename ) );
77
78 if( LoadDrawingSheetFile( filename ) )
79 {
80 wxString msg;
81 msg.Printf( _( "File '%s' loaded"), filename );
82 SetStatusText( msg );
83 }
84
86 }
87}
88
89
90void PL_EDITOR_FRAME::OnClearFileHistory( wxCommandEvent& aEvent )
91{
93}
94
95
96/* File commands. */
97void PL_EDITOR_FRAME::Files_io( wxCommandEvent& event )
98{
99 wxString msg;
100 int id = event.GetId();
101 wxString filename = GetCurrentFileName();
103
104 if( filename.IsEmpty() && id == wxID_SAVE )
105 id = wxID_SAVEAS;
106
107 if( ( id == wxID_NEW || id == wxID_OPEN ) && IsContentModified() )
108 {
109 if( !HandleUnsavedChanges( this, _( "The current drawing sheet has been modified. "
110 "Save changes?" ),
111 [&]() -> bool
112 {
113 return saveCurrentPageLayout();
114 } ) )
115 {
116 return;
117 }
118 }
119
120 switch( id )
121 {
122 case wxID_NEW:
123 pglayout.AllowVoidList( true );
124 SetCurrentFileName( wxEmptyString );
125 pglayout.ClearList();
127 break;
128
130 {
131 wxFileDialog openFileDialog( this, _( "Append Existing Drawing Sheet" ),
132 wxEmptyString, wxEmptyString,
134
135 if( openFileDialog.ShowModal() == wxID_CANCEL )
136 return;
137
138 filename = openFileDialog.GetPath();
139
140 if( !InsertDrawingSheetFile( filename ) )
141 {
142 msg.Printf( _( "Unable to load %s file" ), filename );
143 DisplayErrorMessage( this, msg );
144 }
145 else
146 {
148 HardRedraw();
149 msg.Printf( _( "File '%s' inserted" ), filename );
150 SetStatusText( msg );
151 }
152 }
153 break;
154
155 case wxID_OPEN:
156 {
157 wxFileDialog openFileDialog( this, _( "Open Drawing Sheet" ), wxEmptyString, wxEmptyString,
159
160 if( openFileDialog.ShowModal() == wxID_CANCEL )
161 return;
162
163 filename = openFileDialog.GetPath();
164
165 if( !LoadDrawingSheetFile( filename ) )
166 {
167 msg.Printf( _( "Unable to load %s file" ), filename );
168 DisplayErrorMessage( this, msg );
169 }
170 else
171 {
173 msg.Printf( _( "File '%s' saved." ), filename );
174 SetStatusText( msg );
175 }
176 }
177 break;
178
179 case wxID_SAVE:
180 if( !SaveDrawingSheetFile( filename ) )
181 {
182 msg.Printf( _( "Unable to write '%s'." ), filename );
183 DisplayErrorMessage( this, msg );
184 }
185 else
186 {
187 msg.Printf( _("File '%s' saved."), filename );
188 SetStatusText( msg );
189 }
190 break;
191
192 case wxID_SAVEAS:
193 {
194 wxString dir = PATHS::GetUserTemplatesPath();
195 wxFileDialog openFileDialog( this, _( "Save Drawing Sheet As" ), dir, wxEmptyString,
197 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
198
199 if( openFileDialog.ShowModal() == wxID_CANCEL )
200 return;
201
202 filename = openFileDialog.GetPath();
203 // Ensure the file has the right extension:
204 // because a name like name.subname.subsubname is legal,
205 // add the right extension without replacing the wxFileName
206 // extension
207 wxFileName fn(filename);
208
209 if( fn.GetExt() != FILEEXT::DrawingSheetFileExtension )
210 filename << wxT( "." ) << FILEEXT::DrawingSheetFileExtension;
211
212 if( !SaveDrawingSheetFile( filename ) )
213 {
214 msg.Printf( _( "Failed to create file '%s'." ), filename );
215 DisplayErrorMessage( this, msg );
216 }
217 else
218 {
219 msg.Printf( _( "File '%s' saved." ), filename );
220 SetStatusText( msg );
221
222 SetCurrentFileName( filename );
224 }
225 }
226 break;
227
228 default:
229 break;
230 }
231}
232
233
234bool PL_EDITOR_FRAME::LoadDrawingSheetFile( const wxString& aFullFileName )
235{
236 if( wxFileExists( aFullFileName ) )
237 {
238 wxString msg;
239
240 if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( aFullFileName, &msg ) )
241 {
243 wxString::Format( _( "Error loading drawing sheet '%s'." ),
244 aFullFileName ),
245 msg );
246 return false;
247 }
248
249 SetCurrentFileName( aFullFileName );
250 UpdateFileHistory( aFullFileName );
251 GetScreen()->SetContentModified( false );
252
253 wxFileName fn = aFullFileName;
254 m_infoBar->Dismiss();
255
256 if( DS_DATA_MODEL::GetTheInstance().GetFileFormatVersionAtLoad() < SEXPR_WORKSHEET_FILE_VERSION )
257 {
258 m_infoBar->RemoveAllButtons();
259 m_infoBar->AddCloseButton();
260 m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
261 "It will be converted to the new format when saved." ),
263 }
264
265 if( fn.FileExists() && !fn.IsFileWritable() )
266 {
267 m_infoBar->RemoveAllButtons();
268 m_infoBar->AddCloseButton();
269 m_infoBar->ShowMessage( _( "Layout file is read only." ),
271 }
272
273 return true;
274 }
275
276 return false;
277}
278
279
280bool PL_EDITOR_FRAME::InsertDrawingSheetFile( const wxString& aFullFileName )
281{
282 if( wxFileExists( aFullFileName ) )
283 {
284 const bool append = true;
286 DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( aFullFileName, nullptr, append );
287 return true;
288 }
289
290 return false;
291}
292
293
294bool PL_EDITOR_FRAME::SaveDrawingSheetFile( const wxString& aFullFileName )
295{
296 if( !aFullFileName.IsEmpty() )
297 {
298 wxString tempFile = wxFileName::CreateTempFileName( "pledit" );
299
300 try
301 {
303 }
304 catch( const IO_ERROR& )
305 {
306 // In case we started a file but didn't fully write it, clean up
307 wxRemoveFile( tempFile);
308
309 return false;
310 }
311
312 // Preserve the permissions of the current file
313 KIPLATFORM::IO::DuplicatePermissions( aFullFileName, tempFile );
314
315 if( !wxRenameFile( tempFile, aFullFileName ) )
316 return false;
317
318 if( m_infoBar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE )
319 m_infoBar->Dismiss();
320
321 GetScreen()->SetContentModified( false );
323 return true;
324 }
325
326 return false;
327}
328
330{
331 for( const wxFileName& file : m_AcceptedFiles )
332 OpenProjectFiles( { file.GetFullPath() }, KICTL_CREATE );
333}
void SetContentModified(bool aModified=true)
Definition base_screen.h:59
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:70
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.
@ OUTDATED_SAVE
OUTDATED_SAVE Messages that should be cleared on save.
Definition wx_infobar.h:96
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:129
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:194
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:47
@ ID_APPEND_DESCR_FILE
Definition of file extensions used in Kicad.