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
156 case wxID_OPEN:
157 {
158 wxFileDialog openFileDialog( this, _( "Open Drawing Sheet" ), wxEmptyString, wxEmptyString,
160
161 if( openFileDialog.ShowModal() == wxID_CANCEL )
162 return;
163
164 filename = openFileDialog.GetPath();
165
166 if( !LoadDrawingSheetFile( filename ) )
167 {
168 msg.Printf( _( "Unable to load %s file" ), filename );
169 DisplayErrorMessage( this, msg );
170 }
171 else
172 {
174 msg.Printf( _( "File '%s' saved." ), filename );
175 SetStatusText( msg );
176 }
177
178 break;
179 }
180
181 case wxID_SAVE:
182 if( !SaveDrawingSheetFile( filename ) )
183 {
184 msg.Printf( _( "Unable to write '%s'." ), filename );
185 DisplayErrorMessage( this, msg );
186 }
187 else
188 {
189 msg.Printf( _("File '%s' saved."), filename );
190 SetStatusText( msg );
191 }
192
193 break;
194
195 case wxID_SAVEAS:
196 {
197 wxString dir = PATHS::GetUserTemplatesPath();
198 wxFileDialog openFileDialog( this, _( "Save Drawing Sheet As" ), dir, wxEmptyString,
200 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
201
202 if( openFileDialog.ShowModal() == wxID_CANCEL )
203 return;
204
205 filename = openFileDialog.GetPath();
206 // Ensure the file has the right extension:
207 // because a name like name.subname.subsubname is legal,
208 // add the right extension without replacing the wxFileName
209 // extension
210 wxFileName fn(filename);
211
212 if( fn.GetExt() != FILEEXT::DrawingSheetFileExtension )
213 filename << wxT( "." ) << FILEEXT::DrawingSheetFileExtension;
214
215 if( !SaveDrawingSheetFile( filename ) )
216 {
217 msg.Printf( _( "Failed to create file '%s'." ), filename );
218 DisplayErrorMessage( this, msg );
219 }
220 else
221 {
222 msg.Printf( _( "File '%s' saved." ), filename );
223 SetStatusText( msg );
224
225 SetCurrentFileName( filename );
227 }
228
229 break;
230 }
231
232 default:
233 break;
234 }
235}
236
237
238bool PL_EDITOR_FRAME::LoadDrawingSheetFile( const wxString& aFullFileName )
239{
240 if( wxFileExists( aFullFileName ) )
241 {
242 wxString msg;
243
244 if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( aFullFileName, &msg ) )
245 {
247 wxString::Format( _( "Error loading drawing sheet '%s'." ),
248 aFullFileName ),
249 msg );
250 return false;
251 }
252
253 SetCurrentFileName( aFullFileName );
254 UpdateFileHistory( aFullFileName );
255 GetScreen()->SetContentModified( false );
256
257 wxFileName fn = aFullFileName;
258 m_infoBar->Dismiss();
259
260 if( DS_DATA_MODEL::GetTheInstance().GetFileFormatVersionAtLoad() < SEXPR_WORKSHEET_FILE_VERSION )
261 {
262 m_infoBar->RemoveAllButtons();
263 m_infoBar->AddCloseButton();
264 m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
265 "It will be converted to the new format when saved." ),
267 }
268
269 if( fn.FileExists() && !fn.IsFileWritable() )
270 {
271 m_infoBar->RemoveAllButtons();
272 m_infoBar->AddCloseButton();
273 m_infoBar->ShowMessage( _( "Layout file is read only." ),
275 }
276
277 return true;
278 }
279
280 return false;
281}
282
283
284bool PL_EDITOR_FRAME::InsertDrawingSheetFile( const wxString& aFullFileName )
285{
286 if( wxFileExists( aFullFileName ) )
287 {
288 const bool append = true;
290 DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( aFullFileName, nullptr, append );
291 return true;
292 }
293
294 return false;
295}
296
297
298bool PL_EDITOR_FRAME::SaveDrawingSheetFile( const wxString& aFullFileName )
299{
300 if( !aFullFileName.IsEmpty() )
301 {
302 wxString tempFile = wxFileName::CreateTempFileName( "pledit" );
303
304 try
305 {
307 }
308 catch( const IO_ERROR& )
309 {
310 // In case we started a file but didn't fully write it, clean up
311 wxRemoveFile( tempFile);
312
313 return false;
314 }
315
316 // Preserve the permissions of the current file
317 KIPLATFORM::IO::DuplicatePermissions( aFullFileName, tempFile );
318
319 if( !wxRenameFile( tempFile, aFullFileName ) )
320 return false;
321
322 if( m_infoBar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE )
323 m_infoBar->Dismiss();
324
325 GetScreen()->SetContentModified( false );
327 return true;
328 }
329
330 return false;
331}
332
334{
335 for( const wxFileName& file : m_AcceptedFiles )
336 OpenProjectFiles( { file.GetFullPath() }, KICTL_CREATE );
337}
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: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.
@ 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:131
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:202
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.