KiCad PCB EDA Suite
Loading...
Searching...
No Matches
project_tree_item.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 2
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, see <https://www.gnu.org/licenses/>.
18 */
19
24
25
26#include <wx/regex.h>
27#include <wx/textfile.h>
28#include <wx/filename.h>
29
30#include <set>
31
32#include <confirm.h>
33#include <mail_type.h>
34#include <gestfich.h>
36#include <kiplatform/io.h>
37#include <kiway.h>
38#include <tool/tool_manager.h>
40#include <wx/msgdlg.h>
41
42#include "kicad_manager_frame.h"
43#include "project_tree.h"
44#include "pgm_kicad.h"
45#include "project_tree_pane.h"
46#include "project_tree_item.h"
47#include "kicad_id.h"
48
49
51 wxTreeCtrl* parent ) :
52 wxTreeItemData()
53{
54 m_parent = parent;
55 SetType( type );
56 SetFileName( data );
57 SetRootFile( false ); // true only for the root item of the tree (the project name)
58 SetPopulated( false );
59 m_state = 0;
60}
61
62
64{
65 int treeEnumMax = static_cast<int>( TREE_FILE_TYPE::MAX );
66
67 if( state < 0 || state >= m_parent->GetImageCount() / ( treeEnumMax - 2 ) )
68 return;
69
70 m_state = state;
71 int imgid = static_cast<int>( m_type ) - 1 + state * ( treeEnumMax - 1 );
72 m_parent->SetItemImage( GetId(), imgid );
73 m_parent->SetItemImage( GetId(), imgid, wxTreeItemIcon_Selected );
74}
75
76
95
96
97const wxString PROJECT_TREE_ITEM::GetDir() const
98{
100 return GetFileName();
101
102 return wxFileName( GetFileName() ).GetPath();
103}
104
105
106bool PROJECT_TREE_ITEM::Rename( const wxString& name, bool check )
107{
108 // this is broken & unsafe to use on linux.
109 if( !CanRename() )
110 return false;
111
112 if( name.IsEmpty() )
113 return false;
114
115 const wxString sep = wxFileName().GetPathSeparator();
116 wxString newFile;
117 wxString dirs = GetDir();
118
119 if( !dirs.IsEmpty() && GetType() != TREE_FILE_TYPE::DIRECTORY )
120 newFile = dirs + sep + name;
121 else
122 newFile = name;
123
124 if( newFile == GetFileName() )
125 return false;
126
127 // If required, prompt the user if the filename extension has changed:
128 wxString ext = PROJECT_TREE_PANE::GetFileExt( GetType() ).Lower();
129 wxString full_ext = wxT( "." ) + ext;
130
131 if( check && !ext.IsEmpty() && !newFile.Lower().EndsWith( full_ext ) )
132 {
133 KICAD_MESSAGE_DIALOG dialog( m_parent, _( "Changing file extension will change file type.\n"
134 "Do you want to continue ?" ),
135 _( "Rename File" ), wxYES_NO | wxICON_QUESTION );
136
137 if( wxID_YES != dialog.ShowModal() )
138 return false;
139 }
140
141 if( !wxRenameFile( GetFileName(), newFile, false ) )
142 {
143 KICAD_MESSAGE_DIALOG( m_parent, _( "Unable to rename file ... " ), _( "Permission denied" ),
144 wxICON_ERROR | wxOK );
145 return false;
146 }
147
148 return true;
149}
150
151
153{
154 if( !CanDelete() )
155 return;
156
157 wxString errMsg;
158
159 if( !KIPLATFORM::ENV::MoveToTrash( GetFileName(), errMsg ) )
160 {
161#ifdef __WINDOWS__
162 wxString dialogMsg = wxString::Format( _( "Can not move '%s' to recycle bin."),
163 GetFileName() );
164#else
165 wxString dialogMsg = wxString::Format( _( "Can not move '%s' to trash."),
166 GetFileName() );
167#endif
168
169 DisplayErrorMessage( m_parent, dialogMsg, errMsg );
170 return;
171 }
172
173 m_parent->Delete( GetId() );
174}
175
176
187static void ScanSchematicHierarchy( const wxString& aRootSchematic,
188 std::set<wxString>& aSheetFiles )
189{
190 if( aSheetFiles.count( aRootSchematic ) )
191 return;
192
193 aSheetFiles.insert( aRootSchematic );
194
195 wxTextFile file;
196
197 if( !file.Open( aRootSchematic ) )
198 return;
199
200 wxFileName rootFn( aRootSchematic );
201 wxString rootDir = rootFn.GetPath();
202
203 // Look for: (property "Sheetfile" "filename.kicad_sch"
204 wxRegEx sheetfileRe( "\\(property\\s+\"Sheetfile\"\\s+\"([^\"]+)\"" );
205
206 for( wxString line = file.GetFirstLine(); !file.Eof(); line = file.GetNextLine() )
207 {
208 if( sheetfileRe.Matches( line ) )
209 {
210 wxString sheetFile = sheetfileRe.GetMatch( line, 1 );
211
212 // Resolve relative path
213 wxFileName sheetFn( sheetFile );
214
215 if( !sheetFn.IsAbsolute() )
216 sheetFn.MakeAbsolute( rootDir );
217
218 wxString fullPath = sheetFn.GetFullPath();
219
220 if( wxFileExists( fullPath ) )
221 ScanSchematicHierarchy( fullPath, aSheetFiles );
222 }
223 }
224}
225
226
228{
229 wxString fullFileName = GetFileName();
230 wxTreeItemId id = GetId();
231 std::string packet;
232
233 KICAD_MANAGER_FRAME* frame = aTreePrjFrame->m_Parent;
234 TOOL_MANAGER* toolMgr = frame->GetToolManager();
235 KIWAY& kiway = frame->Kiway();
236
237 switch( GetType() )
238 {
241 // Select a new project if this is not the current project:
242 if( id != aTreePrjFrame->m_TreeProject->GetRootItem() )
243 frame->LoadProject( fullFileName );
244
245 break;
246
248 frame->OpenJobsFile( fullFileName );
249
250 break;
251
253 m_parent->Toggle( id );
254 break;
255
258 {
259 wxString rootSchematic = frame->SchFileName();
260
261 if( rootSchematic.IsEmpty() )
262 rootSchematic = frame->SchLegacyFileName();
263
264 if( fullFileName == rootSchematic )
265 {
267 }
268 else
269 {
270 // Check if this file is part of the project hierarchy by scanning the schematic files
271 std::set<wxString> hierarchyFiles;
272
273 if( !rootSchematic.IsEmpty() && wxFileExists( rootSchematic ) )
274 ScanSchematicHierarchy( rootSchematic, hierarchyFiles );
275
276 bool isInHierarchy = hierarchyFiles.count( fullFileName ) > 0;
277
278 if( isInHierarchy )
279 {
280 // Open root schematic and navigate to the target sheet
281 KIWAY_PLAYER* schFrame = kiway.Player( FRAME_SCH, false );
282
283 if( !schFrame )
284 {
285 // Launch eeschema with the root schematic
287 schFrame = kiway.Player( FRAME_SCH, false );
288 }
289
290 if( schFrame )
291 {
292 packet = fullFileName.ToStdString();
294 }
295 }
296 else
297 {
298 // Not in hierarchy, open as standalone schematic
299 toolMgr->RunAction<wxString*>( KICAD_MANAGER_ACTIONS::editOtherSch, &fullFileName );
300 }
301 }
302
303 break;
304 }
305
308 // Boards not part of the project are opened in a separate process.
309 if( fullFileName == frame->PcbFileName() || fullFileName == frame->PcbLegacyFileName() )
311 else
312 toolMgr->RunAction<wxString*>( KICAD_MANAGER_ACTIONS::editOtherPCB, &fullFileName );
313
314 break;
315
321 toolMgr->RunAction<wxString*>( KICAD_MANAGER_ACTIONS::viewGerbers, &fullFileName );
322 break;
323
325 wxLaunchDefaultBrowser( fullFileName );
326 break;
327
329 OpenPDF( fullFileName );
330 break;
331
336 toolMgr->RunAction<wxString*>( KICAD_MANAGER_ACTIONS::openTextEditor, &fullFileName );
337 break;
338
340 toolMgr->RunAction<wxString*>( KICAD_MANAGER_ACTIONS::editDrawingSheet, &fullFileName );
341 break;
342
345 packet = fullFileName.ToStdString();
347 break;
348
352 packet = fullFileName.ToStdString();
354 break;
355
356 default:
357 wxLaunchDefaultApplication( fullFileName );
358 break;
359 }
360}
const char * name
static TOOL_ACTION editOtherPCB
static TOOL_ACTION editOtherSch
static TOOL_ACTION editSchematic
static TOOL_ACTION openTextEditor
static TOOL_ACTION editDrawingSheet
static TOOL_ACTION editFootprints
static TOOL_ACTION viewGerbers
static TOOL_ACTION editSymbols
The main KiCad project manager frame.
const wxString SchLegacyFileName()
void OpenJobsFile(const wxFileName &aFileName, bool aCreate=false, bool aResaveProjectPreferences=true)
const wxString PcbLegacyFileName()
bool LoadProject(const wxFileName &aProjectFileName)
Loads a new project.
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:311
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition kiway.cpp:398
virtual void ExpressMail(FRAME_T aDestination, MAIL_T aCommand, std::string &aPayload, wxWindow *aSource=nullptr, bool aFromOtherThread=false)
Send aPayload to aDestination from aSource.
Definition kiway.cpp:496
bool CanDelete() const
Determine if a file can be deleted via the project tree pane.
void SetRootFile(bool aValue)
TREE_FILE_TYPE m_type
bool Rename(const wxString &name, bool check=true)
void SetState(int state)
const wxString & GetFileName() const
void SetType(TREE_FILE_TYPE aType)
void SetPopulated(bool aValue)
TREE_FILE_TYPE GetType() const
void SetFileName(const wxString &name)
const wxString GetDir() const
void Activate(PROJECT_TREE_PANE *aTreePrjFrame)
PROJECT_TREE_PANE Window to display the tree files.
PROJECT_TREE * m_TreeProject
KICAD_MANAGER_FRAME * m_Parent
static wxString GetFileExt(TREE_FILE_TYPE type)
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Master controller class:
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
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 KICAD_MESSAGE_DIALOG
Definition confirm.h:48
#define _(s)
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:31
@ FRAME_SCH
Definition frame_type.h:30
@ FRAME_FOOTPRINT_EDITOR
Definition frame_type.h:39
bool OpenPDF(const wxString &file)
Run the PDF viewer and display a PDF file.
Definition gestfich.cpp:271
@ MAIL_LIB_EDIT
Definition mail_type.h:52
@ MAIL_FP_EDIT
Definition mail_type.h:53
@ MAIL_SCH_NAVIGATE_TO_SHEET
Definition mail_type.h:57
bool MoveToTrash(const wxString &aPath, wxString &aError)
Move the specified file/directory to the trash bin/recycle bin.
static void ScanSchematicHierarchy(const wxString &aRootSchematic, std::set< wxString > &aSheetFiles)
Scan a schematic file hierarchy to collect all sheet file paths.
TREE_FILE_TYPE