summaryrefslogtreecommitdiff
path: root/kicad
diff options
context:
space:
mode:
Diffstat (limited to 'kicad')
-rw-r--r--kicad/CMakeLists.txt148
-rw-r--r--kicad/Info.plist34
-rw-r--r--kicad/class_treeproject_item.cpp262
-rw-r--r--kicad/class_treeproject_item.h84
-rw-r--r--kicad/class_treeprojectfiles.cpp112
-rw-r--r--kicad/class_treeprojectfiles.h57
-rw-r--r--kicad/commandframe.cpp116
-rw-r--r--kicad/dialogs/dialog_template_selector.cpp280
-rw-r--r--kicad/dialogs/dialog_template_selector.fbp1105
-rw-r--r--kicad/dialogs/dialog_template_selector.h128
-rw-r--r--kicad/dialogs/dialog_template_selector_base.cpp125
-rw-r--r--kicad/dialogs/dialog_template_selector_base.h110
-rw-r--r--kicad/file_pro.icnsbin0 -> 165611 bytes
-rw-r--r--kicad/files-io.cpp249
-rw-r--r--kicad/kicad.cpp310
-rw-r--r--kicad/kicad.h337
-rw-r--r--kicad/kicad.icnsbin0 -> 130074 bytes
-rw-r--r--kicad/kicad.rc3
-rw-r--r--kicad/kicad_doc.icnsbin0 -> 157065 bytes
-rw-r--r--kicad/logokicad.pngbin0 -> 5450 bytes
-rw-r--r--kicad/mainframe.cpp547
-rw-r--r--kicad/menubar.cpp501
-rw-r--r--kicad/pgm_kicad.h76
-rw-r--r--kicad/preferences.cpp96
-rw-r--r--kicad/prjconfig.cpp398
-rw-r--r--kicad/project_template.cpp236
-rw-r--r--kicad/project_template.h204
-rw-r--r--kicad/tree_project_frame.cpp1093
-rw-r--r--kicad/tree_project_frame.h184
29 files changed, 6795 insertions, 0 deletions
diff --git a/kicad/CMakeLists.txt b/kicad/CMakeLists.txt
new file mode 100644
index 0000000..f0e2438
--- /dev/null
+++ b/kicad/CMakeLists.txt
@@ -0,0 +1,148 @@
+add_definitions( -DKICAD )
+
+include_directories( BEFORE ${INC_BEFORE} )
+include_directories(
+ ${INC_AFTER}
+ )
+
+
+set( KICAD_SRCS
+ class_treeprojectfiles.cpp
+ class_treeproject_item.cpp
+ commandframe.cpp
+ dialogs/dialog_template_selector_base.cpp
+ dialogs/dialog_template_selector.cpp
+ files-io.cpp
+ kicad.cpp
+ mainframe.cpp
+ menubar.cpp
+ preferences.cpp
+ prjconfig.cpp
+ project_template.cpp
+ tree_project_frame.cpp
+ )
+
+if( MINGW )
+ # KICAD_RESOURCES variable is set by the macro.
+ mingw_resource_compiler( kicad )
+else()
+ set( KICAD_RESOURCES kicad.rc )
+endif()
+
+if( APPLE )
+ set( KICAD_RESOURCES kicad.icns kicad_doc.icns )
+ set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/kicad.icns" PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+ set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/kicad_doc.icns" PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+ set( MACOSX_BUNDLE_ICON_FILE kicad.icns )
+ set( MACOSX_BUNDLE_GUI_IDENTIFIER org.kicad-pcb.kicad )
+ set( MACOSX_BUNDLE_NAME kicad )
+endif()
+
+add_executable( kicad WIN32 MACOSX_BUNDLE
+ ${KICAD_SRCS}
+ ${KICAD_EXTRA_SRCS}
+ ${KICAD_RESOURCES}
+ )
+
+if( UNIX )
+ # for build directory: create kiface symlinks so kicad (exe) can be run in-situ
+ add_custom_target( kiface_sym_links
+ COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/eeschema/_eeschema.kiface" "${CMAKE_BINARY_DIR}/kicad/_eeschema.kiface"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/pcbnew/_pcbnew.kiface" "${CMAKE_BINARY_DIR}/kicad/_pcbnew.kiface"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_BINARY_DIR}/cvpcb/_cvpcb.kiface" "${CMAKE_BINARY_DIR}/kicad/_cvpcb.kiface"
+ COMMENT "Making <build-dir>/kicad/<kiface.symlinks>"
+ )
+endif()
+
+if( APPLE )
+ set_target_properties( kicad PROPERTIES
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
+ )
+ target_link_libraries( kicad
+ common
+ bitmaps
+ polygon
+ ${wxWidgets_LIBRARIES}
+ )
+else()
+ target_link_libraries( kicad
+ common
+ bitmaps
+ polygon
+ ${wxWidgets_LIBRARIES}
+ ${GDI_PLUS_LIBRARIES}
+ )
+endif()
+
+install( TARGETS kicad
+ DESTINATION ${KICAD_BIN}
+ COMPONENT binary
+ )
+if( APPLE )
+ # "install( CODE ... )" will launch its own CMake, so no variables from
+ # this CMake instance are accessible... use helper to transfer
+ if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
+ set( SCRIPTING_HELPER "1" )
+ else()
+ set( SCRIPTING_HELPER "0" )
+ endif()
+
+ # make main bundle relocatable
+ install( CODE "
+ # find all libs and modules
+ file( GLOB BUNDLE_FIX_LIBS ${OSX_BUNDLE_INSTALL_KIFACE_DIR}/*.kiface )
+ if( ${SCRIPTING_HELPER} )
+ file( GLOB WXPYTHON_DIR RELATIVE ${OSX_BUNDLE_INSTALL_LIB_DIR}/${PYTHON_LIB_DIR} ${OSX_BUNDLE_INSTALL_LIB_DIR}/${PYTHON_LIB_DIR}/wx-?.?-osx_cocoa )
+ file( GLOB PYTHON_SCRIPTING_SO ${OSX_BUNDLE_INSTALL_LIB_DIR}/${PYTHON_LIB_DIR}/*.so )
+ set( BUNDLE_FIX_LIBS \${BUNDLE_FIX_LIBS} \${PYTHON_SCRIPTING_SO} )
+ file( GLOB PYTHON_SCRIPTING_SO ${OSX_BUNDLE_INSTALL_LIB_DIR}/${PYTHON_LIB_DIR}/\${WXPYTHON_DIR}/wx/*.so )
+ set( BUNDLE_FIX_LIBS \${BUNDLE_FIX_LIBS} \${PYTHON_SCRIPTING_SO} )
+ endif()
+
+ # override default embedded path settings
+ ${OSX_BUNDLE_OVERRIDE_PATHS}
+
+ # do all the work
+ include( BundleUtilities )
+
+ # If `BU_CHMOD_BUNDLE_ITEMS` is not set, `install_name_tool` will fail to re-write some loader paths due to lack of writable permissions if the build dependencies were installed by brew (or didn't have writable permissions)
+ set(BU_CHMOD_BUNDLE_ITEMS ON)
+
+ fixup_bundle( ${OSX_BUNDLE_INSTALL_BIN_DIR}/kicad
+ \"\${BUNDLE_FIX_LIBS}\"
+ \"\"
+ )
+ " COMPONENT Runtime
+ )
+
+ # move all individual app bundles into main bundle
+ install( CODE "
+ # helper function to move a bundle into main bundle
+ function( move_to_main_bundle bundle_name )
+ message( STATUS \"Moving \${bundle_name} into main bundle...\" )
+ file( MAKE_DIRECTORY ${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_APP_DIR} )
+ file( REMOVE_RECURSE ${KICAD_BIN}/\${bundle_name}/${OSX_BUNDLE_LIB_DIR} )
+ file( RENAME ${KICAD_BIN}/\${bundle_name} ${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_APP_DIR}/\${bundle_name} )
+ execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink \"../../../Frameworks\" \"Frameworks\"
+ WORKING_DIRECTORY ${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_APP_DIR}/\${bundle_name}/Contents
+ )
+ # create a top-level link pointing inside main bundle
+ execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink \"${OSX_BUNDLE_MAIN}/${OSX_BUNDLE_APP_DIR}/\${bundle_name}\" \"\${bundle_name}\"
+ WORKING_DIRECTORY ${KICAD_BIN}
+ )
+ endfunction( move_to_main_bundle )
+
+ # move all app bundles
+ move_to_main_bundle( bitmap2component.app )
+ move_to_main_bundle( eeschema.app )
+ move_to_main_bundle( gerbview.app )
+ move_to_main_bundle( pcb_calculator.app )
+ move_to_main_bundle( pcbnew.app )
+ move_to_main_bundle( pl_editor.app )
+ " COMPONENT Runtime
+ )
+endif()
diff --git a/kicad/Info.plist b/kicad/Info.plist
new file mode 100644
index 0000000..9bb140d
--- /dev/null
+++ b/kicad/Info.plist
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeRole</key> <string>Editor</string>
+ <key>CFBundleTypeIconFile</key> <string>kicad_doc.icns</string>
+ <key>CFBundleTypeExtensions</key> <array>
+ <string>pro</string>
+ </array>
+ <key>CFBundleTypeName</key> <string>kicad project files</string>
+ <key>LSHandlerRank</key> <string>Owner</string>
+ </dict>
+ </array>
+ <key>CFBundleDevelopmentRegion</key> <string>English</string>
+ <key>CFBundleExecutable</key> <string>kicad</string>
+ <key>CFBundleGetInfoString</key> <string></string>
+ <key>CFBundleIconFile</key> <string>kicad.icns</string>
+ <key>CFBundleIdentifier</key> <string>org.kicad-pcb.kicad</string>
+ <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string>
+ <key>CFBundleLongVersionString</key> <string></string>
+ <key>CFBundleName</key> <string>KiCad</string>
+ <key>CFBundlePackageType</key> <string>APPL</string>
+ <key>CFBundleShortVersionString</key> <string></string>
+ <key>CFBundleSignature</key> <string>????</string>
+ <key>CFBundleVersion</key> <string></string>
+ <key>CSResourcesFileMapped</key> <true/>
+ <key>LSRequiresCarbon</key> <true/>
+ <key>NSHumanReadableCopyright</key> <string></string>
+ <key>NSHighResolutionCapable</key> <string>True</string>
+</dict>
+</plist>
diff --git a/kicad/class_treeproject_item.cpp b/kicad/class_treeproject_item.cpp
new file mode 100644
index 0000000..56c5709
--- /dev/null
+++ b/kicad/class_treeproject_item.cpp
@@ -0,0 +1,262 @@
+/**
+ * @file class_treeproject_item.cpp
+ *
+ * @brief Class TREEPROJECT_ITEM is a derived class from wxTreeItemData and
+ * store info about a file or directory shown in the KiCad tree project files
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <gestfich.h>
+#include <macros.h>
+
+#include <kicad.h>
+#include <project.h>
+#include <pgm_base.h>
+#include <tree_project_frame.h>
+#include <class_treeprojectfiles.h>
+#include <class_treeproject_item.h>
+#include <wx/imaglist.h>
+
+#include <wx/regex.h>
+#include <wx/dir.h>
+
+TREEPROJECT_ITEM::TREEPROJECT_ITEM( enum TreeFileType type, const wxString& data,
+ wxTreeCtrl* parent ) :
+ wxTreeItemData()
+{
+ m_parent = parent;
+ SetType( type );
+ SetFileName( data );
+ SetRootFile( false ); // true only for the root item of the tree (the project name)
+ SetPopulated( false );
+ m_state = 0;
+}
+
+
+void TREEPROJECT_ITEM::SetState( int state )
+{
+ wxImageList* imglist = m_parent->GetImageList();
+
+ if( !imglist || state < 0 || state >= imglist->GetImageCount() / ( TREE_MAX - 2 ) )
+ return;
+
+ m_state = state;
+ int imgid = m_Type - 1 + state * ( TREE_MAX - 1 );
+ m_parent->SetItemImage( GetId(), imgid );
+ m_parent->SetItemImage( GetId(), imgid, wxTreeItemIcon_Selected );
+}
+
+
+const wxString TREEPROJECT_ITEM::GetDir() const
+{
+ if( TREE_DIRECTORY == m_Type )
+ return GetFileName();
+
+ return wxFileName( GetFileName() ).GetPath();
+}
+
+
+bool TREEPROJECT_ITEM::Rename( const wxString& name, bool check )
+{
+ // this is broken & unsafe to use on linux.
+ if( m_Type == TREE_DIRECTORY )
+ return false;
+
+ if( name.IsEmpty() )
+ return false;
+
+ const wxString sep = wxFileName().GetPathSeparator();
+ wxString newFile;
+ wxString dirs = GetDir();
+
+ if( !dirs.IsEmpty() && GetType() != TREE_DIRECTORY )
+ newFile = dirs + sep + name;
+ else
+ newFile = name;
+
+ if( newFile == GetFileName() )
+ return false;
+
+ wxString ext = TREE_PROJECT_FRAME::GetFileExt( GetType() );
+
+ wxRegEx reg( wxT( "^.*\\" ) + ext + wxT( "$" ), wxRE_ICASE );
+
+ if( check && !ext.IsEmpty() && !reg.Matches( newFile ) )
+ {
+ wxMessageDialog dialog( m_parent, _(
+ "Changing file extension will change file type.\n Do you want to continue ?" ),
+ _( "Rename File" ),
+ wxYES_NO | wxICON_QUESTION );
+
+ if( wxID_YES != dialog.ShowModal() )
+ return false;
+ }
+
+ if( !wxRenameFile( GetFileName(), newFile, false ) )
+ {
+ wxMessageDialog( m_parent, _( "Unable to rename file ... " ),
+ _( "Permission error ?" ), wxICON_ERROR | wxOK );
+ return false;
+ }
+
+ SetFileName( newFile );
+
+ return true;
+}
+
+
+bool TREEPROJECT_ITEM::Delete( bool check )
+{
+ wxString msg = wxString::Format( _(
+ "Do you really want to delete '%s'" ),
+ GetChars( GetFileName() )
+ );
+
+ wxMessageDialog dialog( m_parent, msg,
+ _( "Delete File" ), wxYES_NO | wxICON_QUESTION );
+
+ if( !check || wxID_YES == dialog.ShowModal() )
+ {
+ bool success;
+
+ if( !wxDirExists( GetFileName() ) )
+ success = wxRemoveFile( GetFileName() );
+ else
+ {
+ wxArrayString filelist;
+
+ wxDir::GetAllFiles( GetFileName(), &filelist );
+
+ for( unsigned int i = 0; i < filelist.Count(); i++ )
+ wxRemoveFile( filelist[i] );
+
+ success = wxRmdir( GetFileName() );
+ }
+
+ if( success )
+ m_parent->Delete( GetId() );
+
+ return success;
+ }
+
+ return false;
+}
+
+
+void TREEPROJECT_ITEM::Activate( TREE_PROJECT_FRAME* prjframe )
+{
+ wxString sep = wxFileName().GetPathSeparator();
+ wxString fullFileName = GetFileName();
+ wxTreeItemId id = GetId();
+
+ KICAD_MANAGER_FRAME* frame = prjframe->m_Parent;
+ wxASSERT( frame );
+
+ switch( GetType() )
+ {
+ case TREE_PROJECT:
+ break;
+
+ case TREE_DIRECTORY:
+ m_parent->Toggle( id );
+ break;
+
+ case TREE_SCHEMA:
+ if( fullFileName == frame->SchFileName() )
+ {
+ // the project's schematic is opened using the *.kiface as part of this process.
+ // We do not call frame->RunEeschema( fullFileName ),
+ // because after the double click, for some reason,
+ // the tree project frame is brought to the foreground after Eeschema is called from here.
+ // Instead, we post an event, equivalent to click on the eeschema tool in command frame
+ wxCommandEvent evt( wxEVT_COMMAND_TOOL_CLICKED, ID_TO_SCH );
+ wxPostEvent( frame, evt );
+ }
+ else
+ {
+ // schematics not part of the project are opened in a separate process.
+ frame->Execute( m_parent, EESCHEMA_EXE, fullFileName );
+ }
+ break;
+
+ case TREE_LEGACY_PCB:
+ case TREE_SEXP_PCB:
+ if( fullFileName == frame->PcbFileName() || fullFileName == frame->PcbLegacyFileName() )
+ {
+ // the project's BOARD is opened using the *.kiface as part of this process.
+ // We do not call frame->RunPcbNew( fullFileName ),
+ // because after the double click, for some reason,
+ // the tree project frame is brought to the foreground after PcbNew is called from here.
+ // Instead, we post an event, equivalent to simple click on the pcb editor tool in command frame
+ wxCommandEvent evt( wxEVT_COMMAND_TOOL_CLICKED, ID_TO_PCB );
+ wxPostEvent( frame, evt );
+ }
+ else
+ {
+ // boards not part of the project are opened in a separate process.
+ frame->Execute( m_parent, PCBNEW_EXE, fullFileName );
+ }
+ break;
+
+ case TREE_GERBER:
+ frame->Execute( m_parent, GERBVIEW_EXE, fullFileName );
+ break;
+
+ case TREE_HTML:
+ wxLaunchDefaultBrowser( fullFileName );
+ break;
+
+ case TREE_PDF:
+ OpenPDF( fullFileName );
+ break;
+
+/* No, use a text editor. Netlists can only be handled sanely now from within
+ eeschema's launcher for the *.kiface, NOT THE EXE which is now gone.
+ case TREE_NET:
+ frame->Execute( m_parent, CVPCB_EXE, fullFileName );
+ break;
+*/
+
+ case TREE_TXT:
+ {
+ wxString editorname = Pgm().GetEditorName();
+
+ if( !editorname.IsEmpty() )
+ frame->Execute( m_parent, editorname, fullFileName );
+ }
+ break;
+
+ case TREE_PAGE_LAYOUT_DESCR:
+ frame->Execute( m_parent, PL_EDITOR_EXE, fullFileName );
+ break;
+
+ default:
+ AddDelimiterString( fullFileName );
+ OpenFile( fullFileName );
+ break;
+ }
+}
diff --git a/kicad/class_treeproject_item.h b/kicad/class_treeproject_item.h
new file mode 100644
index 0000000..052f462
--- /dev/null
+++ b/kicad/class_treeproject_item.h
@@ -0,0 +1,84 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras
+ * Copyright (C) 2004-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef TREEPROJECT_ITEM_H_
+#define TREEPROJECT_ITEM_H_
+
+/**
+ * Class TREEPROJECT_ITEM
+ * handles one item (a file or a directory name) for the tree file
+ */
+class TREEPROJECT_ITEM : public wxTreeItemData
+{
+ //friend class KICAD_MANAGER_FRAME;
+
+public:
+
+ TREEPROJECT_ITEM( TreeFileType type, const wxString& data,
+ wxTreeCtrl* parent );
+
+ TREEPROJECT_ITEM() : m_parent( NULL ) { }
+
+ TREEPROJECT_ITEM( const TREEPROJECT_ITEM& src ) :
+ m_Type( src.m_Type ), m_file_name( src.m_file_name ), m_parent( src.m_parent )
+ {
+ SetState( src.m_state );
+ m_IsPopulated = false;
+ }
+
+ TreeFileType GetType() const { return m_Type; }
+ void SetType( TreeFileType aType ) { m_Type = aType; }
+
+ const wxString& GetFileName() const { return m_file_name; }
+ void SetFileName( const wxString& name ) { m_file_name = name; }
+
+ bool IsRootFile() const { return m_IsRootFile; }
+ void SetRootFile( bool aValue ) { m_IsRootFile = aValue; }
+
+ bool IsPopulated() const { return m_IsPopulated; }
+ void SetPopulated( bool aValue ) { m_IsPopulated = aValue; }
+
+ /**
+ * @return the path of an item.
+ * if this item is a directory, returns the stored filename
+ * if this is a file, returns its path
+ */
+ const wxString GetDir() const;
+
+ bool Rename( const wxString& name, bool check = true );
+ bool Delete( bool check = true );
+ void Activate( TREE_PROJECT_FRAME* prjframe );
+ void SetState( int state );
+
+
+private:
+ TreeFileType m_Type; // = TREE_PROJECT, TREE_DIRECTORY ...
+ wxString m_file_name; // Filename for a file, or directory name
+ bool m_IsRootFile; // True if m_Filename is a root schematic (same name as project)
+ bool m_IsPopulated; // True if the name is a directory, and its content was read
+ wxTreeCtrl* m_parent;
+ int m_state;
+};
+
+#endif // TREEPROJECT_ITEM_H_
diff --git a/kicad/class_treeprojectfiles.cpp b/kicad/class_treeprojectfiles.cpp
new file mode 100644
index 0000000..1d2b317
--- /dev/null
+++ b/kicad/class_treeprojectfiles.cpp
@@ -0,0 +1,112 @@
+/**
+ * @file class_treeprojectfiles.cpp
+ * this is the wxTreeCtrl that shows a KiCad tree project files
+ */
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2012 Jean-Pierre Charras
+ * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+
+#include <kicad.h>
+#include <tree_project_frame.h>
+#include <class_treeprojectfiles.h>
+#include <class_treeproject_item.h>
+
+#include <wx/regex.h>
+#include <wx/imaglist.h>
+#include <menus_helpers.h>
+
+
+IMPLEMENT_ABSTRACT_CLASS( TREEPROJECTFILES, wxTreeCtrl )
+
+
+TREEPROJECTFILES::TREEPROJECTFILES( TREE_PROJECT_FRAME* parent ) :
+ wxTreeCtrl( parent, ID_PROJECT_TREE,
+ wxDefaultPosition, wxDefaultSize,
+ wxTR_HAS_BUTTONS, wxDefaultValidator,
+ wxT( "EDATreeCtrl" ) )
+{
+ m_Parent = parent;
+
+ // icons size is not know (depending on they are built)
+ // so get it:
+ wxSize iconsize;
+ wxBitmap dummy = KiBitmap( eeschema_xpm );
+ iconsize.x = dummy.GetWidth();
+ iconsize.y = dummy.GetHeight();
+
+ // Make an image list containing small icons
+ m_ImageList = new wxImageList( iconsize.x, iconsize.y, true, TREE_MAX );
+
+ m_ImageList->Add( KiBitmap( kicad_icon_small_xpm ) ); // TREE_PROJECT
+ m_ImageList->Add( KiBitmap( eeschema_xpm ) ); // TREE_SCHEMA
+ m_ImageList->Add( KiBitmap( pcbnew_xpm ) ); // TREE_LEGACY_PCB
+ m_ImageList->Add( KiBitmap( pcbnew_xpm ) ); // TREE_SFMT_PCB
+ m_ImageList->Add( KiBitmap( icon_gerbview_small_xpm ) ); // TREE_GERBER
+ m_ImageList->Add( KiBitmap( html_xpm ) ); // TREE_HTML
+ m_ImageList->Add( KiBitmap( datasheet_xpm ) ); // TREE_PDF
+ m_ImageList->Add( KiBitmap( icon_txt_xpm ) ); // TREE_TXT
+ m_ImageList->Add( KiBitmap( netlist_xpm ) ); // TREE_NET
+ m_ImageList->Add( KiBitmap( unknown_xpm ) ); // TREE_UNKNOWN
+ m_ImageList->Add( KiBitmap( directory_xpm ) ); // TREE_DIRECTORY
+ m_ImageList->Add( KiBitmap( icon_cvpcb_small_xpm ) ); // TREE_CMP_LINK
+ m_ImageList->Add( KiBitmap( tools_xpm ) ); // TREE_REPORT
+ m_ImageList->Add( KiBitmap( post_compo_xpm ) ); // TREE_POS
+ m_ImageList->Add( KiBitmap( post_drill_xpm ) ); // TREE_DRILL
+ m_ImageList->Add( KiBitmap( svg_file_xpm ) ); // TREE_SVG
+ m_ImageList->Add( KiBitmap( pagelayout_load_default_xpm ) );// TREE_PAGE_LAYOUT_DESCR
+ m_ImageList->Add( KiBitmap( module_xpm ) ); // TREE_FOOTPRINT_FILE
+ m_ImageList->Add( KiBitmap( library_xpm ) ); // TREE_SCHEMATIC_LIBFILE
+
+ SetImageList( m_ImageList );
+}
+
+
+TREEPROJECTFILES::~TREEPROJECTFILES()
+{
+ delete m_ImageList;
+}
+
+
+int TREEPROJECTFILES::OnCompareItems( const wxTreeItemId& item1, const wxTreeItemId& item2 )
+{
+ TREEPROJECT_ITEM* myitem1 = (TREEPROJECT_ITEM*) GetItemData( item1 );
+ TREEPROJECT_ITEM* myitem2 = (TREEPROJECT_ITEM*) GetItemData( item2 );
+
+ if( myitem1->GetType() == TREE_DIRECTORY && myitem2->GetType() != TREE_DIRECTORY )
+ return -1;
+
+ if( myitem2->GetType() == TREE_DIRECTORY && myitem1->GetType() != TREE_DIRECTORY )
+ return 1;
+
+ if( myitem1->IsRootFile() && !myitem2->IsRootFile() )
+ return -1;
+
+ if( myitem2->IsRootFile() && !myitem1->IsRootFile() )
+ return 1;
+
+ return myitem1->GetFileName().CmpNoCase( myitem2->GetFileName() );
+}
+
diff --git a/kicad/class_treeprojectfiles.h b/kicad/class_treeprojectfiles.h
new file mode 100644
index 0000000..d10c53e
--- /dev/null
+++ b/kicad/class_treeprojectfiles.h
@@ -0,0 +1,57 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2010-2014 Jean-Pierre Charras
+ * Copyright (C) 2004-2014 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * file class_treeprojectfiles.h
+ */
+
+#ifndef CLASS_TREEPROJECTFILES_H
+#define CLASS_TREEPROJECTFILES_H
+
+/** Class TREEPROJECTFILES
+ * This is the class to show (as a tree) the files in the project directory
+ */
+class TREEPROJECTFILES : public wxTreeCtrl
+{
+ DECLARE_DYNAMIC_CLASS( TREEPROJECTFILES )
+private:
+ TREE_PROJECT_FRAME* m_Parent;
+ wxImageList* m_ImageList;
+
+public:
+
+ TREE_PROJECT_FRAME* GetParent() const
+ {
+ return m_Parent;
+ }
+
+
+ TREEPROJECTFILES( TREE_PROJECT_FRAME* parent );
+ ~TREEPROJECTFILES();
+private:
+ /* overridden sort function */
+ int OnCompareItems( const wxTreeItemId& item1, const wxTreeItemId& item2 );
+};
+
+#endif // CLASS_TREEPROJECTFILES_H
diff --git a/kicad/commandframe.cpp b/kicad/commandframe.cpp
new file mode 100644
index 0000000..dca9580
--- /dev/null
+++ b/kicad/commandframe.cpp
@@ -0,0 +1,116 @@
+/**
+ * @file commandframe.cpp
+ * @brief Frame showing fast launch buttons and messages box
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2012 Jean-Pierre Charras
+ * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <fctsys.h>
+#include <macros.h>
+
+#include <kicad.h>
+#include <menus_helpers.h>
+
+
+LAUNCHER_PANEL::LAUNCHER_PANEL( wxWindow* parent ) :
+ wxPanel( parent, wxID_ANY )
+{
+ m_bitmapButtons_maxHeigth = 0;
+ m_buttonSeparation = 10; // control of command buttons position
+ m_buttonsListPosition.x = m_buttonSeparation;
+ m_buttonsListPosition.y = m_buttonSeparation;
+ m_buttonLastPosition = m_buttonsListPosition;
+
+ // Add bitmap buttons to launch KiCad utilities:
+ CreateCommandToolbar();
+}
+
+int LAUNCHER_PANEL::GetPanelHeight() const
+{
+ int height = m_buttonsListPosition.y + m_bitmapButtons_maxHeigth
+ + m_buttonSeparation;
+ return height;
+}
+
+/**
+ * Function CreateCommandToolbar
+ * create the buttons to call Eeschema CvPcb, Pcbnew and GerbView
+ */
+void LAUNCHER_PANEL::CreateCommandToolbar()
+{
+ wxBitmapButton* btn;
+
+ btn = AddBitmapButton( ID_TO_SCH, KiBitmap( icon_eeschema_xpm ) );
+ btn->SetToolTip( _( "Eeschema - Electronic schematic editor" ) );
+
+ btn = AddBitmapButton( ID_TO_SCH_LIB_EDITOR, KiBitmap( libedit_icon_xpm ) );
+ btn->SetToolTip( _( "Schematic library editor" ) );
+
+ btn = AddBitmapButton( ID_TO_PCB, KiBitmap( icon_pcbnew_xpm ) );
+ btn->SetToolTip( _( "Pcbnew - Printed circuit board editor" ) );
+
+ btn = AddBitmapButton( ID_TO_PCB_FP_EDITOR, KiBitmap( icon_modedit_xpm ) );
+ btn->SetToolTip( _( "PCB footprint editor" ) );
+
+ btn = AddBitmapButton( ID_TO_GERBVIEW, KiBitmap( icon_gerbview_xpm ) );
+ btn->SetToolTip( _( "GerbView - Gerber viewer" ) );
+
+ btn = AddBitmapButton( ID_TO_BITMAP_CONVERTER, KiBitmap( icon_bitmap2component_xpm ) );
+ btn->SetToolTip( _(
+ "Bitmap2Component - Convert bitmap images to Eeschema\n"
+ "or Pcbnew elements" ) );
+
+ btn = AddBitmapButton( ID_TO_PCB_CALCULATOR, KiBitmap( icon_pcbcalculator_xpm ) );
+ btn->SetToolTip( _( "Pcb calculator - Calculator for components, track width, etc." ) );
+
+ btn = AddBitmapButton( ID_TO_PL_EDITOR, KiBitmap( icon_pagelayout_editor_xpm ) );
+ btn->SetToolTip( _( "Pl editor - Worksheet layout editor" ) );
+}
+
+
+/**
+ * Function AddBitmapButton
+ * add a Bitmap Button (fast launch button) to the buttons panel
+ * @param aId = the button id
+ * @param aBitmap = the wxBitmap used to create the button
+ */
+wxBitmapButton* LAUNCHER_PANEL::AddBitmapButton( wxWindowID aId, const wxBitmap& aBitmap )
+{
+ wxPoint buttPos = m_buttonLastPosition;
+ wxSize buttSize;
+ int btn_margin = 10; // extra margin around the bitmap.
+
+ buttSize.x = aBitmap.GetWidth() + btn_margin;
+ buttSize.y = aBitmap.GetHeight() + btn_margin;
+
+ if( m_bitmapButtons_maxHeigth < buttSize.y )
+ m_bitmapButtons_maxHeigth = buttSize.y;
+
+ wxBitmapButton* btn = new wxBitmapButton( this, aId, aBitmap, buttPos, buttSize );
+ m_buttonLastPosition.x += buttSize.x + m_buttonSeparation;
+
+ return btn;
+}
diff --git a/kicad/dialogs/dialog_template_selector.cpp b/kicad/dialogs/dialog_template_selector.cpp
new file mode 100644
index 0000000..f36f66d
--- /dev/null
+++ b/kicad/dialogs/dialog_template_selector.cpp
@@ -0,0 +1,280 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Brian Sidebotham <brian.sidebotham@gmail.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "dialog_template_selector.h"
+
+#include <wx/dir.h>
+#include <wx/settings.h>
+
+
+TEMPLATE_SELECTION_PANEL::TEMPLATE_SELECTION_PANEL( wxNotebookPage* aParent,
+ const wxString& aPath ) :
+ TEMPLATE_SELECTION_PANEL_BASE( aParent )
+{
+ m_parent = aParent;
+ m_templatesPath = aPath;
+}
+
+
+TEMPLATE_WIDGET::TEMPLATE_WIDGET( wxWindow* aParent, DIALOG_TEMPLATE_SELECTOR* aDialog ) :
+ TEMPLATE_WIDGET_BASE( aParent )
+{
+ m_parent = aParent;
+ m_dialog = aDialog;
+
+ // wxWidgets_3.xx way of doing the same...
+ // Bind(wxEVT_LEFT_DOWN, &TEMPLATE_WIDGET::OnMouse, this );
+
+ m_bitmapIcon->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::OnMouse ), NULL, this );
+ m_staticTitle->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( TEMPLATE_WIDGET::OnMouse ), NULL, this );
+
+ // We're not selected until we're clicked
+ Unselect();
+
+ // Start with template being NULL
+ m_currTemplate = NULL;
+}
+
+
+void TEMPLATE_WIDGET::Select()
+{
+ m_dialog->SetWidget( this );
+ SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNHIGHLIGHT ) );
+ m_selected = true;
+ Refresh();
+}
+
+
+void TEMPLATE_WIDGET::Unselect()
+{
+ SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
+ m_selected = false;
+ Refresh();
+}
+
+
+void TEMPLATE_WIDGET::SetTemplate(PROJECT_TEMPLATE* aTemplate)
+{
+ m_currTemplate = aTemplate;
+ m_staticTitle->SetLabel( *(aTemplate->GetTitle()) );
+ m_bitmapIcon->SetBitmap( *(aTemplate->GetIcon()) );
+}
+
+
+void TEMPLATE_WIDGET::OnMouse( wxMouseEvent& event )
+{
+ // Toggle selection here
+ Select();
+ event.Skip();
+}
+
+
+void DIALOG_TEMPLATE_SELECTOR::onNotebookResize(wxSizeEvent& event)
+{
+ for( size_t i=0; i < m_notebook->GetPageCount(); i++ )
+ {
+ m_panels[i]->SetSize( m_notebook->GetSize().GetWidth() - 6, 140 );
+ m_panels[i]->m_SizerBase->FitInside( m_panels[i] );
+ m_panels[i]->m_scrolledWindow->SetSize( m_panels[i]->GetSize().GetWidth() - 6,
+ m_panels[i]->GetSize().GetHeight() - 6 );
+ m_panels[i]->m_SizerChoice->FitInside( m_panels[i]->m_scrolledWindow );
+ }
+ m_notebook->Refresh();
+
+ event.Skip();
+}
+
+void DIALOG_TEMPLATE_SELECTOR::OnPageChange( wxNotebookEvent& event )
+{
+ int page = m_notebook->GetSelection();
+
+ if( page != wxNOT_FOUND && (unsigned)page < m_panels.size() )
+ m_tcTemplatePath->SetValue( m_panels[page]->GetPath() );
+}
+
+
+DIALOG_TEMPLATE_SELECTOR::DIALOG_TEMPLATE_SELECTOR( wxWindow* aParent ) :
+ DIALOG_TEMPLATE_SELECTOR_BASE( aParent )
+{
+ m_htmlWin->SetPage( _( "<html><h1>Template Selector</h1></html>" ) );
+ m_notebook->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_TEMPLATE_SELECTOR::onNotebookResize ), NULL, this );
+ m_selectedWidget = NULL;
+}
+
+
+void DIALOG_TEMPLATE_SELECTOR::SetWidget( TEMPLATE_WIDGET* aWidget )
+{
+ if( m_selectedWidget != NULL )
+ m_selectedWidget->Unselect();
+
+ m_selectedWidget = aWidget;
+ SetHtml( m_selectedWidget->GetTemplate()->GetHtmlFile() );
+}
+
+void DIALOG_TEMPLATE_SELECTOR::AddTemplate( int aPage, PROJECT_TEMPLATE* aTemplate )
+{
+ TEMPLATE_WIDGET* w = new TEMPLATE_WIDGET( m_panels[aPage]->m_scrolledWindow, this );
+ w->SetTemplate( aTemplate );
+
+ m_panels[aPage]->m_SizerChoice->Add( w );
+ m_panels[aPage]->m_SizerChoice->Layout();
+ m_panels[aPage]->SetSize( m_notebook->GetSize().GetWidth() - 6, 140 );
+ m_panels[aPage]->m_SizerBase->FitInside( m_panels[aPage] );
+ m_panels[aPage]->m_scrolledWindow->SetSize( m_panels[aPage]->GetSize().GetWidth() - 6,
+ m_panels[aPage]->GetSize().GetHeight() - 6 );
+ m_panels[aPage]->m_SizerChoice->FitInside( m_panels[aPage]->m_scrolledWindow );
+
+ m_notebook->Refresh();
+}
+
+
+PROJECT_TEMPLATE* DIALOG_TEMPLATE_SELECTOR::GetSelectedTemplate()
+{
+ return m_selectedWidget? m_selectedWidget->GetTemplate() : NULL;
+}
+
+void DIALOG_TEMPLATE_SELECTOR::AddTemplatesPage( const wxString& aTitle, wxFileName& aPath )
+{
+ wxNotebookPage* newPage = new wxNotebookPage( m_notebook, wxID_ANY );
+
+ aPath.Normalize();
+ wxString path = aPath.GetFullPath(); // caller ensures this ends with file separator.
+
+ TEMPLATE_SELECTION_PANEL* tpanel = new TEMPLATE_SELECTION_PANEL( newPage, path );
+ m_panels.push_back( tpanel );
+
+ m_notebook->AddPage( newPage, aTitle );
+
+ if( m_notebook->GetPageCount() == 1 )
+ m_tcTemplatePath->SetValue( path );
+
+ buildPageContent( path, m_notebook->GetPageCount() - 1 );
+}
+
+void DIALOG_TEMPLATE_SELECTOR::buildPageContent( const wxString& aPath, int aPage )
+{
+ // Get a list of files under the template path to include as choices...
+ wxArrayString files;
+ wxDir dir;
+
+ if( dir.Open( aPath ) )
+ {
+ wxDir sub_dir;
+ wxString sub_name;
+
+ bool cont = dir.GetFirst( &sub_name, wxEmptyString, wxDIR_DIRS );
+ while( cont )
+ {
+ wxString sub_full = aPath + sub_name;
+ if( sub_dir.Open( sub_full ) )
+ {
+ files.Add( sub_name );
+
+ PROJECT_TEMPLATE* pt = new PROJECT_TEMPLATE( sub_full );
+ AddTemplate( aPage, pt );
+ }
+
+ cont = dir.GetNext( &sub_name );
+ }
+ }
+}
+
+
+void DIALOG_TEMPLATE_SELECTOR::onDirectoryBrowseClicked( wxCommandEvent& event )
+{
+ wxFileName fn;
+ fn.AssignDir( m_tcTemplatePath->GetValue() );
+ fn.Normalize();
+ wxString currPath = fn.GetFullPath();
+
+ wxDirDialog dirDialog( this, _( "Select Templates Directory" ),
+ currPath,
+ wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
+
+ if( dirDialog.ShowModal() != wxID_OK )
+ return;
+
+ wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
+
+ m_tcTemplatePath->SetValue( dirName.GetFullPath() );
+
+ if( currPath == m_tcTemplatePath->GetValue() )
+ return; // No change
+
+ // Rebuild the page from the new templates path:
+ replaceCurrentPage();
+}
+
+
+void DIALOG_TEMPLATE_SELECTOR::onValidatePath( wxCommandEvent& event )
+{
+ int page = m_notebook->GetSelection();
+
+ if( page < 0 )
+ return; // Should not happen
+
+ wxString currPath = m_tcTemplatePath->GetValue();
+
+ if( currPath == m_panels[page]->GetPath() ) // No change
+ return;
+
+ wxFileName fn;
+ fn.AssignDir( m_tcTemplatePath->GetValue() );
+ fn.Normalize();
+ currPath = fn.GetFullPath();
+ m_tcTemplatePath->SetValue( currPath );
+
+ replaceCurrentPage();
+}
+
+
+void DIALOG_TEMPLATE_SELECTOR::replaceCurrentPage()
+{
+ // Rebuild the page from the new templates path:
+ int page = m_notebook->GetSelection();
+
+ if( page < 0 )
+ return; // Should not happen
+
+ wxString title = m_notebook->GetPageText( page );
+ wxString currPath = m_tcTemplatePath->GetValue();
+
+ m_notebook->DeletePage( page );
+
+ wxNotebookPage* newPage = new wxNotebookPage( m_notebook, wxID_ANY );
+ TEMPLATE_SELECTION_PANEL* tpanel = new TEMPLATE_SELECTION_PANEL( newPage, currPath );
+ m_panels[page] = tpanel;
+ m_notebook->InsertPage( page, newPage, title, true );
+
+ buildPageContent( m_tcTemplatePath->GetValue(), page );
+
+ m_selectedWidget = NULL;
+}
+
+
+void DIALOG_TEMPLATE_SELECTOR::OnHtmlLinkActivated( wxHtmlLinkEvent& event )
+{
+ wxString url = event.GetLinkInfo().GetHref();
+ wxLaunchDefaultBrowser( url);
+}
diff --git a/kicad/dialogs/dialog_template_selector.fbp b/kicad/dialogs/dialog_template_selector.fbp
new file mode 100644
index 0000000..687a923
--- /dev/null
+++ b/kicad/dialogs/dialog_template_selector.fbp
@@ -0,0 +1,1105 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_template_selector_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_TEMPLATE_SELECTOR_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center">wxBOTH</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">640,480</property>
+ <property name="name">DIALOG_TEMPLATE_SELECTOR_BASE</property>
+ <property name="pos"></property>
+ <property name="size">640,480</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Project Template Selector</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bmainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxNotebook" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmapsize"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size">-1,-1</property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="moveable">1</property>
+ <property name="name">m_notebook</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnNotebookPageChanged">OnPageChange</event>
+ <event name="OnNotebookPageChanging"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxHtmlWindow" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_htmlWin</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxHW_SCROLLBAR_AUTO</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHtmlCellClicked"></event>
+ <event name="OnHtmlCellHover"></event>
+ <event name="OnHtmlLinkClicked">OnHtmlLinkActivated</event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Template path</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTextTpath</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bsizerTemplateSelector</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+ <property name="proportion">1</property>
+ <object class="wxTextCtrl" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_tcTemplatePath</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxTE_PROCESS_ENTER</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="value"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Browse</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonBrowse</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_EXACTFIT</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">onDirectoryBrowseClicked</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT</property>
+ <property name="proportion">0</property>
+ <object class="wxButton" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Validate</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_buttonValidate</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_EXACTFIT</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnButtonClick">onValidatePath</event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticLine" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticline</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxLI_HORIZONTAL</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="1">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_sdbSizer</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick"></event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="Panel" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size">-1,-1</property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">TEMPLATE_SELECTION_PANEL_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,140</property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxNO_BORDER|wxTAB_TRAVERSAL</property>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_SizerBase</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">public</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxEXPAND | wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxScrolledWindow" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_scrolledWindow</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">public</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="scroll_rate_x">5</property>
+ <property name="scroll_rate_y">5</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxHSCROLL</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">m_SizerChoice</property>
+ <property name="orient">wxHORIZONTAL</property>
+ <property name="permission">public</property>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="Panel" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size">74,-1</property>
+ <property name="minimum_size">74,-1</property>
+ <property name="name">TEMPLATE_WIDGET_BASE</property>
+ <property name="pos"></property>
+ <property name="size">74,-1</property>
+ <property name="subclass"></property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style">wxTAB_TRAVERSAL</property>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnInitDialog"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ <object class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bSizer4</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticBitmap" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="bitmap"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_bitmapIcon</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size">64,64</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxStaticText" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Project Template Title</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_staticTitle</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxALIGN_CENTRE</property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">150</property>
+ <event name="OnChar"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/kicad/dialogs/dialog_template_selector.h b/kicad/dialogs/dialog_template_selector.h
new file mode 100644
index 0000000..17a7a62
--- /dev/null
+++ b/kicad/dialogs/dialog_template_selector.h
@@ -0,0 +1,128 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Brian Sidebotham <brian.sidebotham@gmail.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef PROJECT_TEMPLATE_SELECTOR_H
+#define PROJECT_TEMPLATE_SELECTOR_H
+
+#include <dialogs/dialog_template_selector_base.h>
+#include "project_template.h"
+
+class DIALOG_TEMPLATE_SELECTOR;
+
+class TEMPLATE_WIDGET : public TEMPLATE_WIDGET_BASE
+{
+protected:
+ DIALOG_TEMPLATE_SELECTOR* m_dialog;
+ wxWindow* m_parent;
+ wxPanel* m_panel;
+ bool m_selected;
+
+ PROJECT_TEMPLATE* m_currTemplate;
+
+ void OnKillFocus( wxFocusEvent& event );
+ void OnMouse( wxMouseEvent& event );
+
+public:
+ TEMPLATE_WIDGET( wxWindow* aParent, DIALOG_TEMPLATE_SELECTOR* aDialog );
+
+ /**
+ * Set the project template for this widget, which will determine the icon and title
+ * associated with this project template widget
+ */
+ void SetTemplate(PROJECT_TEMPLATE* aTemplate);
+
+ PROJECT_TEMPLATE* GetTemplate() { return m_currTemplate; }
+
+ void Select();
+ void Unselect();
+
+private:
+ bool IsSelected() { return m_selected; }
+};
+
+
+class TEMPLATE_SELECTION_PANEL : public TEMPLATE_SELECTION_PANEL_BASE
+{
+protected:
+ wxNotebookPage* m_parent;
+ wxString m_templatesPath; ///< the path to access to the folder
+ ///< containing the templates (which are also folders)
+
+public:
+ /**
+ * @param aParent The window creating the dialog
+ * @param aPath the path
+ */
+ TEMPLATE_SELECTION_PANEL( wxNotebookPage* aParent, const wxString& aPath );
+
+ const wxString& GetPath() { return m_templatesPath; }
+};
+
+
+class DIALOG_TEMPLATE_SELECTOR : public DIALOG_TEMPLATE_SELECTOR_BASE
+{
+protected:
+ std::vector<TEMPLATE_SELECTION_PANEL*> m_panels;
+ TEMPLATE_WIDGET* m_selectedWidget;
+
+ void AddTemplate( int aPage, PROJECT_TEMPLATE* aTemplate );
+
+public:
+ DIALOG_TEMPLATE_SELECTOR( wxWindow* aParent );
+
+ /**
+ * Add a new page with \a aTitle, populated with templates from \a aPath
+ * - All directories under the path are treated as templates
+ * @param aTitle = the title of the wxNoteBook page
+ * @param aPath = the path of the main folder containing templates
+ */
+ void AddTemplatesPage( const wxString& aTitle, wxFileName& aPath );
+
+ /**
+ * @return the selected template, or NULL
+ */
+ PROJECT_TEMPLATE* GetSelectedTemplate();
+
+private:
+
+ void SetHtml( wxFileName aFilename )
+ {
+ m_htmlWin->LoadPage( aFilename.GetFullPath() );
+ }
+
+public:
+ void SetWidget( TEMPLATE_WIDGET* aWidget );
+
+private:
+ void buildPageContent( const wxString& aPath, int aPage );
+ void replaceCurrentPage();
+
+ void onNotebookResize( wxSizeEvent& event );
+ void OnPageChange( wxNotebookEvent& event );
+ void onDirectoryBrowseClicked( wxCommandEvent& event );
+ void onValidatePath( wxCommandEvent& event );
+ void OnHtmlLinkActivated( wxHtmlLinkEvent& event );
+};
+
+#endif
diff --git a/kicad/dialogs/dialog_template_selector_base.cpp b/kicad/dialogs/dialog_template_selector_base.cpp
new file mode 100644
index 0000000..7328f89
--- /dev/null
+++ b/kicad/dialogs/dialog_template_selector_base.cpp
@@ -0,0 +1,125 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_template_selector_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_TEMPLATE_SELECTOR_BASE::DIALOG_TEMPLATE_SELECTOR_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( 640,480 ), wxDefaultSize );
+
+ wxBoxSizer* bmainSizer;
+ bmainSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ bmainSizer->Add( m_notebook, 0, wxEXPAND | wxALL, 3 );
+
+ m_htmlWin = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxHW_SCROLLBAR_AUTO );
+ bmainSizer->Add( m_htmlWin, 1, wxALL|wxEXPAND, 3 );
+
+ m_staticTextTpath = new wxStaticText( this, wxID_ANY, _("Template path"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticTextTpath->Wrap( -1 );
+ bmainSizer->Add( m_staticTextTpath, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
+
+ wxBoxSizer* bsizerTemplateSelector;
+ bsizerTemplateSelector = new wxBoxSizer( wxHORIZONTAL );
+
+ m_tcTemplatePath = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
+ bsizerTemplateSelector->Add( m_tcTemplatePath, 1, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_buttonBrowse = new wxButton( this, wxID_ANY, _("Browse"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
+ bsizerTemplateSelector->Add( m_buttonBrowse, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
+
+ m_buttonValidate = new wxButton( this, wxID_ANY, _("Validate"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT );
+ bsizerTemplateSelector->Add( m_buttonValidate, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
+
+
+ bmainSizer->Add( bsizerTemplateSelector, 0, wxEXPAND, 5 );
+
+ m_staticline = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
+ bmainSizer->Add( m_staticline, 0, wxEXPAND | wxALL, 5 );
+
+ m_sdbSizer = new wxStdDialogButtonSizer();
+ m_sdbSizerOK = new wxButton( this, wxID_OK );
+ m_sdbSizer->AddButton( m_sdbSizerOK );
+ m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
+ m_sdbSizer->AddButton( m_sdbSizerCancel );
+ m_sdbSizer->Realize();
+
+ bmainSizer->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 3 );
+
+
+ this->SetSizer( bmainSizer );
+ this->Layout();
+
+ this->Centre( wxBOTH );
+
+ // Connect Events
+ m_notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_TEMPLATE_SELECTOR_BASE::OnPageChange ), NULL, this );
+ m_htmlWin->Connect( wxEVT_COMMAND_HTML_LINK_CLICKED, wxHtmlLinkEventHandler( DIALOG_TEMPLATE_SELECTOR_BASE::OnHtmlLinkActivated ), NULL, this );
+ m_buttonBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEMPLATE_SELECTOR_BASE::onDirectoryBrowseClicked ), NULL, this );
+ m_buttonValidate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEMPLATE_SELECTOR_BASE::onValidatePath ), NULL, this );
+}
+
+DIALOG_TEMPLATE_SELECTOR_BASE::~DIALOG_TEMPLATE_SELECTOR_BASE()
+{
+ // Disconnect Events
+ m_notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_TEMPLATE_SELECTOR_BASE::OnPageChange ), NULL, this );
+ m_htmlWin->Disconnect( wxEVT_COMMAND_HTML_LINK_CLICKED, wxHtmlLinkEventHandler( DIALOG_TEMPLATE_SELECTOR_BASE::OnHtmlLinkActivated ), NULL, this );
+ m_buttonBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEMPLATE_SELECTOR_BASE::onDirectoryBrowseClicked ), NULL, this );
+ m_buttonValidate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TEMPLATE_SELECTOR_BASE::onValidatePath ), NULL, this );
+
+}
+
+TEMPLATE_SELECTION_PANEL_BASE::TEMPLATE_SELECTION_PANEL_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
+{
+ m_SizerBase = new wxBoxSizer( wxHORIZONTAL );
+
+ m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL );
+ m_scrolledWindow->SetScrollRate( 5, 5 );
+ m_SizerChoice = new wxBoxSizer( wxHORIZONTAL );
+
+
+ m_scrolledWindow->SetSizer( m_SizerChoice );
+ m_scrolledWindow->Layout();
+ m_SizerChoice->Fit( m_scrolledWindow );
+ m_SizerBase->Add( m_scrolledWindow, 0, wxEXPAND | wxALL, 3 );
+
+
+ this->SetSizer( m_SizerBase );
+ this->Layout();
+}
+
+TEMPLATE_SELECTION_PANEL_BASE::~TEMPLATE_SELECTION_PANEL_BASE()
+{
+}
+
+TEMPLATE_WIDGET_BASE::TEMPLATE_WIDGET_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
+{
+ this->SetMinSize( wxSize( 74,-1 ) );
+ this->SetMaxSize( wxSize( 74,-1 ) );
+
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxVERTICAL );
+
+ m_bitmapIcon = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 64,64 ), 0 );
+ bSizer4->Add( m_bitmapIcon, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3 );
+
+ m_staticTitle = new wxStaticText( this, wxID_ANY, _("Project Template Title"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
+ m_staticTitle->Wrap( 150 );
+ bSizer4->Add( m_staticTitle, 1, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3 );
+
+
+ this->SetSizer( bSizer4 );
+ this->Layout();
+}
+
+TEMPLATE_WIDGET_BASE::~TEMPLATE_WIDGET_BASE()
+{
+}
diff --git a/kicad/dialogs/dialog_template_selector_base.h b/kicad/dialogs/dialog_template_selector_base.h
new file mode 100644
index 0000000..6bfcbea
--- /dev/null
+++ b/kicad/dialogs/dialog_template_selector_base.h
@@ -0,0 +1,110 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_TEMPLATE_SELECTOR_BASE_H__
+#define __DIALOG_TEMPLATE_SELECTOR_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/gdicmn.h>
+#include <wx/notebook.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/string.h>
+#include <wx/html/htmlwin.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/dialog.h>
+#include <wx/scrolwin.h>
+#include <wx/panel.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/statbmp.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_TEMPLATE_SELECTOR_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_TEMPLATE_SELECTOR_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxNotebook* m_notebook;
+ wxHtmlWindow* m_htmlWin;
+ wxStaticText* m_staticTextTpath;
+ wxTextCtrl* m_tcTemplatePath;
+ wxButton* m_buttonBrowse;
+ wxButton* m_buttonValidate;
+ wxStaticLine* m_staticline;
+ wxStdDialogButtonSizer* m_sdbSizer;
+ wxButton* m_sdbSizerOK;
+ wxButton* m_sdbSizerCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnPageChange( wxNotebookEvent& event ) { event.Skip(); }
+ virtual void OnHtmlLinkActivated( wxHtmlLinkEvent& event ) { event.Skip(); }
+ virtual void onDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); }
+ virtual void onValidatePath( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_TEMPLATE_SELECTOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Project Template Selector"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 640,480 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_TEMPLATE_SELECTOR_BASE();
+
+};
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class TEMPLATE_SELECTION_PANEL_BASE
+///////////////////////////////////////////////////////////////////////////////
+class TEMPLATE_SELECTION_PANEL_BASE : public wxPanel
+{
+ private:
+
+ protected:
+
+ public:
+ wxBoxSizer* m_SizerBase;
+ wxScrolledWindow* m_scrolledWindow;
+ wxBoxSizer* m_SizerChoice;
+
+ TEMPLATE_SELECTION_PANEL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,140 ), long style = wxNO_BORDER|wxTAB_TRAVERSAL );
+ ~TEMPLATE_SELECTION_PANEL_BASE();
+
+};
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class TEMPLATE_WIDGET_BASE
+///////////////////////////////////////////////////////////////////////////////
+class TEMPLATE_WIDGET_BASE : public wxPanel
+{
+ private:
+
+ protected:
+ wxStaticBitmap* m_bitmapIcon;
+ wxStaticText* m_staticTitle;
+
+ public:
+
+ TEMPLATE_WIDGET_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 74,-1 ), long style = wxTAB_TRAVERSAL );
+ ~TEMPLATE_WIDGET_BASE();
+
+};
+
+#endif //__DIALOG_TEMPLATE_SELECTOR_BASE_H__
diff --git a/kicad/file_pro.icns b/kicad/file_pro.icns
new file mode 100644
index 0000000..28921b1
--- /dev/null
+++ b/kicad/file_pro.icns
Binary files differ
diff --git a/kicad/files-io.cpp b/kicad/files-io.cpp
new file mode 100644
index 0000000..805c722
--- /dev/null
+++ b/kicad/files-io.cpp
@@ -0,0 +1,249 @@
+/**
+ * @file kicad/files-io.cpp
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2017 Jean-Pierre Charras
+ * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <pgm_kicad.h>
+#include <kiway.h>
+#include <wx/fs_zip.h>
+#include <wx/zipstrm.h>
+#include <wx/docview.h>
+#include <wx/wfstream.h>
+#include <wx/zstream.h>
+#include <wx/dir.h>
+
+#include <confirm.h>
+#include <gestfich.h>
+#include <macros.h>
+
+#include <kicad.h>
+
+#define ZipFileExtension wxT( "zip" )
+#define ZipFileWildcard _( "Zip file (*.zip)|*.zip" )
+
+
+void KICAD_MANAGER_FRAME::OnFileHistory( wxCommandEvent& event )
+{
+ wxString fn = GetFileFromHistory( event.GetId(),
+ _( "KiCad project file" ), &Pgm().GetFileHistory() );
+
+ if( fn.size() )
+ {
+ // Any open KIFACE's must be closed before changing the project.
+ // We never want a KIWAY_PLAYER open on a KIWAY that isn't in the same project,
+ // and then break one project.
+ // Remember when saving files, the full path is build from the current project path
+ // User is prompted here to close those KIWAY_PLAYERs:
+ if( !Kiway.PlayersClose( false ) )
+ return;
+
+ // We can now set the new project filename and load this project
+ SetProjectFileName( fn );
+ wxCommandEvent cmd( 0, wxID_ANY );
+ OnLoadProject( cmd );
+ }
+}
+
+
+void KICAD_MANAGER_FRAME::OnUnarchiveFiles( wxCommandEvent& event )
+{
+ wxFileName fn = GetProjectFileName();
+
+ fn.SetExt( ZipFileExtension );
+
+ wxFileDialog zipfiledlg( this, _( "Unzip Project" ), fn.GetPath(),
+ fn.GetFullName(), ZipFileWildcard,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST );
+
+ if( zipfiledlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ wxString msg = wxString::Format( _("\nOpen '%s'\n" ), GetChars( zipfiledlg.GetPath() ) );
+ PrintMsg( msg );
+
+ wxDirDialog dirDlg( this, _( "Target Directory" ), fn.GetPath(),
+ wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
+
+ if( dirDlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ wxString unzipDir = dirDlg.GetPath() + wxT( "/" );
+ msg.Printf( _( "Unzipping project in '%s'\n" ), GetChars( unzipDir ) );
+ PrintMsg( msg );
+
+ wxFileSystem zipfilesys;
+
+ zipfilesys.AddHandler( new wxZipFSHandler );
+ zipfilesys.ChangePathTo( zipfiledlg.GetPath() + wxT( "#zip:" ), true );
+
+ wxFSFile* zipfile = NULL;
+ wxString localfilename = zipfilesys.FindFirst( wxT( "*.*" ) );
+
+ while( !localfilename.IsEmpty() )
+ {
+ zipfile = zipfilesys.OpenFile( localfilename );
+ if( !zipfile )
+ {
+ DisplayError( this, wxT( "Zip file read error" ) );
+ break;
+ }
+
+ wxFileName uzfn = localfilename.AfterLast( ':' );
+ uzfn.MakeAbsolute( unzipDir );
+ wxString unzipfilename = uzfn.GetFullPath();
+
+ msg.Printf( _( "Extract file '%s'" ), GetChars( unzipfilename ) );
+ PrintMsg( msg );
+
+ wxInputStream* stream = zipfile->GetStream();
+ wxFFileOutputStream* ofile = new wxFFileOutputStream( unzipfilename );
+
+ if( ofile->Ok() )
+ {
+ ofile->Write( *stream );
+ PrintMsg( _( " OK\n" ) );
+ }
+ else
+ PrintMsg( _( " *ERROR*\n" ) );
+
+ delete ofile;
+ delete zipfile;
+
+ localfilename = zipfilesys.FindNext();
+ }
+
+ PrintMsg( wxT( "** end **\n" ) );
+}
+
+
+void KICAD_MANAGER_FRAME::OnArchiveFiles( wxCommandEvent& event )
+{
+ // List of file extensions to save.
+ static const wxChar* extentionList[] = {
+ wxT( "*.sch" ), wxT( "*.lib" ), wxT( "*.mod" ), wxT( "*.cmp" ),
+ wxT( "*.brd" ), wxT( "*.kicad_pcb" ), wxT( "*.gbr" ), wxT( "*.pos" ),
+ wxT( "*.net" ), wxT( "*.pro" ), wxT( "*.drl" ), wxT( "*.py" ),
+ wxT( "*.pdf" ), wxT( "*.txt" ), wxT( "*.dcm" ), wxT( "*.kicad_wks" ),
+ };
+
+ wxString msg;
+ wxFileName fileName = GetProjectFileName();
+ wxString oldCwd = wxGetCwd();
+
+ fileName.SetExt( wxT( "zip" ) );
+
+ wxFileDialog dlg( this, _( "Archive Project Files" ),
+ fileName.GetPath(), fileName.GetFullName(),
+ ZipFileWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ wxFileName zip = dlg.GetPath();
+
+ wxString currdirname = fileName.GetPathWithSep();
+ wxDir dir( currdirname );
+
+ if( !dir.IsOpened() ) // wxWidgets display a error message on issue.
+ return;
+
+ wxSetWorkingDirectory( currdirname );
+
+ // Prepare the zip file
+ wxString zipfilename = zip.GetFullPath();
+
+ wxFFileOutputStream ostream( zipfilename );
+
+ if( !ostream.IsOk() ) // issue to create the file. Perhaps not writable dir
+ {
+ wxMessageBox( wxString::Format( _( "Unable to create zip archive file '%s'" ), zipfilename ) );
+ return;
+ }
+
+ wxZipOutputStream zipstream( ostream );
+
+ // Build list of filenames to put in zip archive
+ wxString currFilename;
+
+ wxArrayString files;
+
+ for( unsigned ii = 0; ii < DIM( extentionList ); ii++ )
+ wxDir::GetAllFiles( currdirname, &files, extentionList[ii] );
+
+ files.Sort();
+
+ int zipBytesCnt = 0;
+
+ for( unsigned ii = 0; ii < files.GetCount(); ii++ )
+ {
+ wxFileSystem fsfile;
+
+ wxFileName curr_fn( files[ii] );
+ curr_fn.MakeRelativeTo( currdirname );
+ currFilename = curr_fn.GetFullPath();
+
+ msg.Printf( _( "Archive file <%s>" ), GetChars( currFilename ) );
+ PrintMsg( msg );
+
+ // Read input file and add it to the zip file:
+ wxFSFile* infile = fsfile.OpenFile( currFilename );
+
+ if( infile )
+ {
+ zipstream.PutNextEntry( currFilename, infile->GetModificationTime() );
+ infile->GetStream()->Read( zipstream );
+ zipstream.CloseEntry();
+ int zippedsize = zipstream.GetSize() - zipBytesCnt;
+ zipBytesCnt = zipstream.GetSize();
+ PrintMsg( wxT(" ") );
+ msg.Printf( _( "(%lu bytes, compressed %d bytes)\n" ),
+ (unsigned long)infile->GetStream()->GetSize(), zippedsize );
+ PrintMsg( msg );
+ delete infile;
+ }
+ else
+ PrintMsg( _( " >>Error\n" ) );
+ }
+
+ zipBytesCnt = ostream.GetSize();
+
+ if( zipstream.Close() )
+ {
+ msg.Printf( _( "\nZip archive <%s> created (%d bytes)" ),
+ GetChars( zipfilename ), zipBytesCnt );
+ PrintMsg( msg );
+ PrintMsg( wxT( "\n** end **\n" ) );
+ }
+ else
+ {
+ msg.Printf( wxT( "Unable to create archive <%s>, abort\n" ),
+ GetChars( zipfilename ) );
+ PrintMsg( msg );
+ }
+
+ wxSetWorkingDirectory( oldCwd );
+}
diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp
new file mode 100644
index 0000000..4a2d25a
--- /dev/null
+++ b/kicad/kicad.cpp
@@ -0,0 +1,310 @@
+/**
+ * @file kicad.cpp
+ * @brief Main KiCad Project manager file
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <macros.h>
+#include <fctsys.h>
+#include <wx/stdpaths.h>
+#include <kicad.h>
+#include <kiway.h>
+#include <pgm_kicad.h>
+#include <tree_project_frame.h>
+#include <online_help.h>
+#include <wildcards_and_files_ext.h>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <hotkeys_basic.h>
+
+#include <build_version.h>
+
+
+// a dummy to quiet linking with EDA_BASE_FRAME::config();
+#include <kiface_i.h>
+KIFACE_I& Kiface()
+{
+ // This function should never be called. It is only referenced from
+ // EDA_BASE_FRAME::config() and this is only provided to satisfy the linker,
+ // not to be actually called.
+ wxLogFatalError( wxT( "Unexpected call to Kiface() in kicad/kicad.cpp" ) );
+
+ return (KIFACE_I&) *(KIFACE_I*) 0;
+}
+
+static PGM_KICAD program;
+
+PGM_KICAD& Pgm()
+{
+ return program;
+}
+
+
+bool PGM_KICAD::OnPgmInit( wxApp* aWxApp )
+{
+ m_wx_app = aWxApp; // first thing.
+
+ wxString absoluteArgv0 = wxStandardPaths::Get().GetExecutablePath();
+
+ if( !wxIsAbsolutePath( absoluteArgv0 ) )
+ {
+ wxLogError( wxT( "No meaningful argv[0]" ) );
+ return false;
+ }
+
+ if( !initPgm() )
+ return false;
+
+ m_bm.Init();
+
+ // Add search paths to feed the PGM_KICAD::SysSearch() function,
+ // currenly limited in support to only look for project templates
+ {
+ SEARCH_STACK bases;
+
+ SystemDirsAppend( &bases );
+
+ // DBG( bases.Show( (std::string(__func__) + " bases").c_str() );)
+
+ for( unsigned i = 0; i < bases.GetCount(); ++i )
+ {
+ wxFileName fn( bases[i], wxEmptyString );
+
+ // Add KiCad template file path to search path list.
+ fn.AppendDir( wxT( "template" ) );
+ m_bm.m_search.AddPaths( fn.GetPath() );
+ }
+
+ //DBG( m_bm.m_search.Show( (std::string( __func__ ) + " SysSearch()").c_str() );)
+ }
+
+ // Must be called before creating the main frame in order to
+ // display the real hotkeys in menus or tool tips
+ extern struct EDA_HOTKEY_CONFIG kicad_Manager_Hokeys_Descr[];
+ ReadHotkeyConfig( KICAD_MANAGER_FRAME_NAME, kicad_Manager_Hokeys_Descr );
+
+ KICAD_MANAGER_FRAME* frame = new KICAD_MANAGER_FRAME( NULL, wxT( "KiCad" ),
+ wxDefaultPosition, wxDefaultSize );
+ App().SetTopWindow( frame );
+
+ Kiway.SetTop( frame );
+
+ bool prjloaded = false; // true when the project is loaded
+
+ if( App().argc > 1 )
+ frame->SetProjectFileName( App().argv[1] );
+
+ else if( GetFileHistory().GetCount() )
+ {
+ wxString last_pro = GetFileHistory().GetHistoryFile( 0 );
+
+ if( !wxFileExists( last_pro ) )
+ {
+ GetFileHistory().RemoveFileFromHistory( 0 );
+
+ wxFileName namelessProject( wxStandardPaths::Get().GetDocumentsDir(), NAMELESS_PROJECT,
+ ProjectFileExtension );
+
+ frame->SetProjectFileName( namelessProject.GetFullPath() );
+ }
+ else
+ {
+ // Try to open the last opened project,
+ // if a project name is not given when starting Kicad
+ frame->SetProjectFileName( last_pro );
+
+ wxCommandEvent cmd( 0, wxID_FILE1 );
+
+ frame->OnFileHistory( cmd );
+ prjloaded = true; // OnFileHistory() loads the project
+ }
+ }
+ else // there is no history
+ {
+ wxFileName namelessProject( wxStandardPaths::Get().GetDocumentsDir(), NAMELESS_PROJECT,
+ ProjectFileExtension );
+
+ frame->SetProjectFileName( namelessProject.GetFullPath() );
+ }
+
+ if( !prjloaded )
+ {
+ wxCommandEvent cmd( 0, wxID_ANY );
+
+ frame->OnLoadProject( cmd );
+ }
+
+ frame->Show( true );
+ frame->Raise();
+
+ return true;
+}
+
+
+void PGM_KICAD::OnPgmExit()
+{
+ Kiway.OnKiwayEnd();
+
+ saveCommonSettings();
+
+ // write common settings to disk, and destroy everything in PGM_KICAD,
+ // especially wxSingleInstanceCheckerImpl earlier than wxApp and earlier
+ // than static destruction would.
+ destroy();
+}
+
+
+void PGM_KICAD::MacOpenFile( const wxString& aFileName )
+{
+#if defined(__WXMAC__)
+
+ KICAD_MANAGER_FRAME* frame = (KICAD_MANAGER_FRAME*) App().GetTopWindow();
+
+ frame->SetProjectFileName( aFileName );
+
+ wxCommandEvent loadEvent( 0, wxID_ANY );
+
+ frame->OnLoadProject( loadEvent );
+#endif
+}
+
+
+void PGM_KICAD::destroy()
+{
+ // unlike a normal destructor, this is designed to be called more
+ // than once safely:
+
+ m_bm.End();
+
+ PGM_BASE::destroy();
+}
+
+
+KIWAY Kiway( &Pgm(), KFCTL_CPP_PROJECT_SUITE );
+
+
+/**
+ * Struct APP_KICAD
+ * is not publicly visible because most of the action is in PGM_KICAD these days.
+ */
+struct APP_KICAD : public wxApp
+{
+#if defined (__LINUX__)
+ APP_KICAD(): wxApp()
+ {
+ // Disable proxy menu in Unity window manager. Only usual menubar works with wxWidgets (at least <= 3.1)
+ // When the proxy menu menubar is enable, some important things for us do not work: menuitems UI events and shortcuts.
+ wxString wm;
+
+ if( wxGetEnv( wxT( "XDG_CURRENT_DESKTOP" ), &wm ) && wm.CmpNoCase( wxT( "Unity" ) ) == 0 )
+ {
+ wxSetEnv ( wxT("UBUNTU_MENUPROXY" ), wxT( "0" ) );
+ }
+ }
+#endif
+
+ bool OnInit() // overload wxApp virtual
+ {
+ // if( Kiways.OnStart( this ) )
+ {
+ return Pgm().OnPgmInit( this );
+ }
+ return false;
+ }
+
+ int OnExit() // overload wxApp virtual
+ {
+ // Kiways.OnEnd();
+
+ Pgm().OnPgmExit();
+
+ return wxApp::OnExit();
+ }
+
+ int OnRun() // overload wxApp virtual
+ {
+ try
+ {
+ return wxApp::OnRun();
+ }
+ catch( const std::exception& e )
+ {
+ wxLogError( wxT( "Unhandled exception class: %s what: %s" ),
+ GetChars( FROM_UTF8( typeid(e).name() )),
+ GetChars( FROM_UTF8( e.what() ) ) );
+ }
+ catch( const IO_ERROR& ioe )
+ {
+ wxLogError( GetChars( ioe.errorText ) );
+ }
+ catch(...)
+ {
+ wxLogError( wxT( "Unhandled exception of unknown type" ) );
+ }
+
+ return -1;
+ }
+
+ /**
+ * Function MacOpenFile
+ * is specific to MacOSX (not used under Linux or Windows).
+ * MacOSX requires it for file association.
+ * @see http://wiki.wxwidgets.org/WxMac-specific_topics
+ */
+ void MacOpenFile( const wxString& aFileName ) // overload wxApp virtual
+ {
+ Pgm().MacOpenFile( aFileName );
+ }
+};
+
+IMPLEMENT_APP( APP_KICAD );
+
+
+// The C++ project manager supports one open PROJECT, so Prj() calls within
+// this link image need this function.
+PROJECT& Prj()
+{
+ return Kiway.Prj();
+}
+
+
+#if 0 // there can be only one in C++ project manager.
+
+bool KIWAY_MGR::OnStart( wxApp* aProcess )
+{
+ // The C++ project manager supports only one open PROJECT
+ // We should need no copy constructor for KIWAY to push a pointer.
+ m_kiways.push_back( new KIWAY() );
+
+ return true;
+}
+
+
+void KIWAY_MGR::OnEnd()
+{
+}
+
+#endif
diff --git a/kicad/kicad.h b/kicad/kicad.h
new file mode 100644
index 0000000..aa98820
--- /dev/null
+++ b/kicad/kicad.h
@@ -0,0 +1,337 @@
+/**
+ * @file kicad/kicad.h
+ * @brief KICAD_MANAGER_FRAME is the KiCad main frame.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2013 CERN (www.cern.ch)
+ * Copyright (C) 2015 KiCad Developers, see CHANGELOG.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef KICAD_H
+#define KICAD_H
+
+#include <vector>
+
+#include <wx/treectrl.h>
+#include <wx/dragimag.h>
+#include <wx/filename.h>
+#include <wx/process.h>
+
+#include <id.h>
+#include <wxstruct.h>
+
+#define KICAD_MANAGER_FRAME_NAME wxT( "KicadFrame" )
+
+class LAUNCHER_PANEL;
+class TREEPROJECTFILES;
+class TREE_PROJECT_FRAME;
+
+// Enum to identify the type of files handled by Kicad manager
+//
+// When changing this enum please verify (and perhaps update)
+// TREE_PROJECT_FRAME::GetFileExt(),
+// s_AllowedExtensionsToList[]
+
+enum TreeFileType {
+ TREE_PROJECT = 1,
+ TREE_SCHEMA, // Schematic file (.sch)
+ TREE_LEGACY_PCB, // board file (.brd) legacy format
+ TREE_SEXP_PCB, // board file (.kicad_brd) new s expression format
+ TREE_GERBER, // Gerber file (.pho, .g*)
+ TREE_HTML, // HTML file (.htm, *.html)
+ TREE_PDF, // PDF file (.pdf)
+ TREE_TXT, // ascii text file (.txt)
+ TREE_NET, // netlist file (.net)
+ TREE_UNKNOWN,
+ TREE_DIRECTORY,
+ TREE_CMP_LINK, // cmp/footprint link file (.cmp)
+ TREE_REPORT, // report file (.rpt)
+ TREE_FP_PLACE, // fooprints position (place) file (.pos)
+ TREE_DRILL, // Excellon drill file (.drl)
+ TREE_SVG, // SVG file (.svg)
+ TREE_PAGE_LAYOUT_DESCR, // Page layout and title block descr file (.kicad_wks)
+ TREE_FOOTPRINT_FILE, // footprint file (.kicad_mod)
+ TREE_SCHEMATIC_LIBFILE, // schematic library file (.lib)
+ TREE_MAX
+};
+
+
+/**
+ * Command IDs for KiCad.
+ *
+ * Please add IDs that are unique to Kicad here and not in the global id.h file.
+ * This will prevent the entire project from being rebuilt when adding
+ * new commands to KiCad.
+ *
+ * However, now the Kicad manager and other sub applications are running inside
+ * the same application, these IDs are kept unique inside the whole Kicad code
+ * See the global id.h which reserves room for the Kicad manager IDs
+ * and expand this room if needed
+ *
+ * We have experienced issues with duplicate menus IDs between frames
+ * because wxUpdateUIEvent events are sent to parent frames, when a wxUpdateUIEvent
+ * event function does not exists for some menuitems ID, and therefore
+ * with duplicate menuitems IDs in different frames, the wrong menuitem can be used
+ * by a function called by the wxUpdateUIEvent event loop.
+ *
+ * The number of items in this list should be less than ROOM_FOR_KICADMANAGER (see id.h)
+ */
+
+enum id_kicad_frm {
+ ID_LEFT_FRAME = ID_KICAD_MANAGER_START,
+ ID_PROJECT_TREE,
+ ID_PROJECT_TXTEDIT,
+ ID_PROJECT_TREE_REFRESH,
+ ID_PROJECT_NEWDIR,
+ ID_PROJECT_DELETE,
+ ID_PROJECT_RENAME,
+ ID_PROJECT_OPEN_FILE_WITH_TEXT_EDITOR,
+
+ ID_TO_SCH,
+ ID_TO_SCH_LIB_EDITOR,
+ ID_TO_PCB,
+ ID_TO_PCB_FP_EDITOR,
+ ID_TO_CVPCB,
+ ID_TO_GERBVIEW,
+ ID_TO_BITMAP_CONVERTER,
+ ID_TO_PCB_CALCULATOR,
+ ID_TO_PL_EDITOR,
+
+ ID_TO_TEXT_EDITOR,
+ ID_BROWSE_AN_SELECT_FILE,
+ ID_SELECT_PREFERED_EDITOR,
+ ID_SELECT_PREFERED_PDF_BROWSER_NAME,
+ ID_SELECT_PREFERED_PDF_BROWSER,
+ ID_SELECT_DEFAULT_PDF_BROWSER,
+ ID_SAVE_AND_ZIP_FILES,
+ ID_READ_ZIP_ARCHIVE,
+ ID_INIT_WATCHED_PATHS,
+
+ // Please, verify: the number of items in this list should be
+ // less than ROOM_FOR_KICADMANAGER (see id.h)
+ ID_KICADMANAGER_END_LIST
+};
+
+
+/**
+ * Class KICAD_MANAGER_FRAME
+ * is the main KiCad project manager frame. It is not a KIWAY_PLAYER.
+ */
+class KICAD_MANAGER_FRAME : public EDA_BASE_FRAME
+{
+public:
+ KICAD_MANAGER_FRAME( wxWindow* parent, const wxString& title,
+ const wxPoint& pos, const wxSize& size );
+
+ ~KICAD_MANAGER_FRAME();
+
+ void OnCloseWindow( wxCloseEvent& Event );
+ void OnSize( wxSizeEvent& event );
+
+ /**
+ * Function OnLoadProject
+ * loads an exiting or creates a new project (.pro) file.
+ */
+ void OnLoadProject( wxCommandEvent& event );
+
+ /**
+ * Function OnCreateProjectFromTemplate
+ * Creates a new project folder, copy a template into this new folder.
+ * and open this new projrct as working project
+ */
+ void OnCreateProjectFromTemplate( wxCommandEvent& event );
+
+ /**
+ * Function OnSaveProject
+ * is the command event hendler to Save the project (.pro) file containing the top level
+ * configuration parameters.
+ */
+ void OnSaveProject( wxCommandEvent& event );
+
+ void OnArchiveFiles( wxCommandEvent& event );
+ void OnUnarchiveFiles( wxCommandEvent& event );
+
+ void OnRunEeschema( wxCommandEvent& event );
+ void OnRunSchLibEditor( wxCommandEvent& event );
+ void OnRunPcbNew( wxCommandEvent& event );
+ void OnRunPcbFpEditor( wxCommandEvent& event );
+ void OnRunGerbview( wxCommandEvent& event );
+ void OnRunBitmapConverter( wxCommandEvent& event );
+ void OnRunPcbCalculator( wxCommandEvent& event );
+ void OnRunPageLayoutEditor( wxCommandEvent& event );
+
+ void OnConfigurePaths( wxCommandEvent& aEvent );
+ void OnOpenTextEditor( wxCommandEvent& event );
+ void OnOpenFileInTextEditor( wxCommandEvent& event );
+ void OnOpenFileInEditor( wxCommandEvent& event );
+
+ void OnFileHistory( wxCommandEvent& event );
+ void OnExit( wxCommandEvent& event );
+ void Process_Preferences( wxCommandEvent& event );
+
+ void Process_Config( wxCommandEvent& event );
+
+ void ReCreateMenuBar();
+ void RecreateBaseHToolbar();
+
+ /**
+ * Function PrintMsg
+ * displays \a aText in the text panel.
+ *
+ * @param aText The text to display.
+ */
+ void PrintMsg( const wxString& aText );
+
+ /**
+ * a minor helper function:
+ * Prints the Current Working Dir name and the projet name on the text panel.
+ */
+ void PrintPrjInfo();
+
+ /**
+ * a minor helper function:
+ * Erase the text panel.
+ */
+ void ClearMsg();
+
+ void OnRefresh( wxCommandEvent& event );
+ void OnSelectDefaultPdfBrowser( wxCommandEvent& event );
+ void OnSelectPreferredPdfBrowser( wxCommandEvent& event );
+
+ void OnUpdateDefaultPdfBrowser( wxUpdateUIEvent& event );
+ void OnUpdatePreferredPdfBrowser( wxUpdateUIEvent& event );
+ void OnUpdateRequiresProject( wxUpdateUIEvent& event );
+
+ void CreateNewProject( const wxString& aPrjFullFileName, bool aTemplateSelector );
+
+ void LoadSettings( wxConfigBase* aCfg );
+
+ void SaveSettings( wxConfigBase* aCfg );
+
+ /**
+ * Function Execute
+ * opens another KiCad application and logs a message.
+ * @param frame = owner frame.
+ * @param execFile = name of the executable file.
+ * @param param = parameters to be passed to the executable.
+ */
+ void Execute( wxWindow* frame, const wxString& execFile,
+ wxString param = wxEmptyString );
+
+ class TERMINATE_HANDLER : public wxProcess
+ {
+ private:
+ wxString appName;
+
+ public:
+ TERMINATE_HANDLER( const wxString& appName ) :
+ appName(appName)
+ {
+ }
+
+ void OnTerminate( int pid, int status );
+ };
+
+ /**
+ * Called by sending a event with id = ID_INIT_WATCHED_PATHS
+ * rebuild the list of wahtched paths
+ */
+ void OnChangeWatchedPaths(wxCommandEvent& aEvent );
+
+
+ void SetProjectFileName( const wxString& aFullProjectProFileName );
+ const wxString GetProjectFileName();
+
+ // read only accessors
+ const wxString SchFileName();
+ const wxString PcbFileName();
+ const wxString PcbLegacyFileName();
+
+ void ReCreateTreePrj();
+
+ /// Call this only for a PCB associated with the current project. That is,
+ /// it must have the same path and name as the project *.pro file.
+ void RunPcbNew( const wxString& aProjectBoardFileName );
+
+ /// Call this only for a SCH associated with the current project. That is,
+ /// it must have the same path and name as the project *.pro file.
+ void RunEeschema( const wxString& aProjectSchematicFileName );
+
+ DECLARE_EVENT_TABLE()
+
+private:
+
+ wxConfigBase* config(); // override EDA_BASE_FRAME virtual
+
+ const SEARCH_STACK& sys_search(); // override EDA_BASE_FRAME virtual
+
+ wxString help_name(); // override EDA_BASE_FRAME virtual
+
+ TREE_PROJECT_FRAME* m_LeftWin;
+ LAUNCHER_PANEL* m_Launcher;
+ wxTextCtrl* m_MessagesBox;
+ wxAuiToolBar* m_VToolBar; // Vertical toolbar (not used)
+
+ int m_leftWinWidth;
+ EDA_HOTKEY_CONFIG* m_manager_Hokeys_Descr;
+
+ void language_change( wxCommandEvent& event );
+
+ bool m_active_project;
+};
+
+
+/** class LAUNCHER_PANEL
+ */
+class LAUNCHER_PANEL : public wxPanel
+{
+private:
+ int m_buttonSeparation; // button distance in pixels
+ wxPoint m_buttonsListPosition; /* position of the left bottom corner
+ * of the first bitmap button
+ */
+ wxPoint m_buttonLastPosition; // position of the last button in the window
+ int m_bitmapButtons_maxHeigth; // height of bigger bitmap buttons
+ // Used to calculate the height of the panel.
+
+public: LAUNCHER_PANEL( wxWindow* parent );
+ ~LAUNCHER_PANEL() { };
+
+ int GetPanelHeight() const;
+
+private:
+
+ /**
+ * Function CreateCommandToolbar
+ * creates the main tool bar buttons (fast launch buttons)
+ */
+ void CreateCommandToolbar( void );
+
+ wxBitmapButton* AddBitmapButton( wxWindowID aId, const wxBitmap& aBitmap );
+};
+
+// The C++ project manager includes a single PROJECT in its link image.
+class PROJECT;
+extern PROJECT& Prj();
+
+#endif
diff --git a/kicad/kicad.icns b/kicad/kicad.icns
new file mode 100644
index 0000000..01307df
--- /dev/null
+++ b/kicad/kicad.icns
Binary files differ
diff --git a/kicad/kicad.rc b/kicad/kicad.rc
new file mode 100644
index 0000000..578d82c
--- /dev/null
+++ b/kicad/kicad.rc
@@ -0,0 +1,3 @@
+icon_kicad ICON "../bitmaps_png/icons/icon_kicad.ico"
+
+#include "wx/msw/wx.rc"
diff --git a/kicad/kicad_doc.icns b/kicad/kicad_doc.icns
new file mode 100644
index 0000000..b877d8c
--- /dev/null
+++ b/kicad/kicad_doc.icns
Binary files differ
diff --git a/kicad/logokicad.png b/kicad/logokicad.png
new file mode 100644
index 0000000..a7e5f82
--- /dev/null
+++ b/kicad/logokicad.png
Binary files differ
diff --git a/kicad/mainframe.cpp b/kicad/mainframe.cpp
new file mode 100644
index 0000000..df0122a
--- /dev/null
+++ b/kicad/mainframe.cpp
@@ -0,0 +1,547 @@
+/**
+ * @file kicad/mainframe.cpp
+ * @brief KICAD_MANAGER_FRAME is the KiCad main frame.
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2013 CERN (www.cern.ch)
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <pgm_kicad.h>
+#include <draw_frame.h>
+#include <kiway.h>
+#include <kiway_player.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <macros.h>
+
+#include <kicad.h>
+#include <tree_project_frame.h>
+#include <wildcards_and_files_ext.h>
+#include <menus_helpers.h>
+#include <dialog_hotkeys_editor.h>
+
+#include <wx/filefn.h>
+
+
+#define TREE_FRAME_WIDTH_ENTRY wxT( "LeftWinWidth" )
+
+KICAD_MANAGER_FRAME::KICAD_MANAGER_FRAME( wxWindow* parent,
+ const wxString& title, const wxPoint& pos, const wxSize& size ) :
+ EDA_BASE_FRAME( parent, KICAD_MAIN_FRAME_T, title, pos, size,
+ KICAD_DEFAULT_DRAWFRAME_STYLE, KICAD_MANAGER_FRAME_NAME )
+{
+ m_active_project = false;
+ m_leftWinWidth = 60;
+ m_manager_Hokeys_Descr = NULL;
+
+ // Create the status line (bottom of the frame
+ static const int dims[3] = { -1, -1, 100 };
+
+ CreateStatusBar( 3 );
+ SetStatusWidths( 3, dims );
+
+ // Give an icon
+ wxIcon icon;
+ icon.CopyFromBitmap( KiBitmap( icon_kicad_xpm ) );
+ SetIcon( icon );
+
+ // Give the last sise and pos to main window
+ LoadSettings( config() );
+ SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
+
+ // Left window: is the box which display tree project
+ m_LeftWin = new TREE_PROJECT_FRAME( this );
+
+ // Right top Window: buttons to launch applications
+ m_Launcher = new LAUNCHER_PANEL( this );
+
+ // Add the wxTextCtrl showing all messages from KiCad:
+ m_MessagesBox = new wxTextCtrl( this, wxID_ANY, wxEmptyString,
+ wxDefaultPosition, wxDefaultSize,
+ wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY );
+
+ RecreateBaseHToolbar();
+ ReCreateMenuBar();
+
+ m_auimgr.SetManagedWindow( this );
+
+ EDA_PANEINFO horiztb;
+ horiztb.HorizontalToolbarPane();
+
+ EDA_PANEINFO info;
+ info.InfoToolbarPane();
+
+ m_auimgr.AddPane( m_mainToolBar,
+ wxAuiPaneInfo( horiztb ).Name( wxT( "m_mainToolBar" ) ).Top() );
+
+ m_auimgr.AddPane( m_LeftWin,
+ wxAuiPaneInfo(info).Name( wxT( "m_LeftWin" ) ).Left().
+ BestSize( m_leftWinWidth, -1 ).
+ Layer( 1 ) );
+
+ m_auimgr.AddPane( m_Launcher, wxTOP );
+ m_auimgr.GetPane( m_Launcher).CaptionVisible( false ).Row(1)
+ .BestSize( -1, m_Launcher->GetPanelHeight() ).PaneBorder( false ).Resizable( false );
+
+ m_auimgr.AddPane( m_MessagesBox,
+ wxAuiPaneInfo().Name( wxT( "m_MessagesBox" ) ).CentrePane().Layer( 2 ) );
+
+ m_auimgr.GetPane( m_LeftWin ).MinSize( wxSize( 80, -1) );
+ m_auimgr.GetPane( m_LeftWin ).BestSize(wxSize(m_leftWinWidth, -1) );
+
+ m_auimgr.Update();
+}
+
+
+KICAD_MANAGER_FRAME::~KICAD_MANAGER_FRAME()
+{
+ m_auimgr.UnInit();
+}
+
+
+wxConfigBase* KICAD_MANAGER_FRAME::config()
+{
+ wxConfigBase* ret = Pgm().PgmSettings();
+ wxASSERT( ret );
+ return ret;
+}
+
+
+void KICAD_MANAGER_FRAME::SetProjectFileName( const wxString& aFullProjectProFileName )
+{
+ // ensure file name is absolute:
+ wxFileName fn( aFullProjectProFileName );
+
+ if( !fn.IsAbsolute() )
+ fn.MakeAbsolute();
+
+ Prj().SetProjectFullName( fn.GetFullPath() );
+}
+
+
+const wxString KICAD_MANAGER_FRAME::GetProjectFileName()
+{
+ return Prj().GetProjectFullName();
+}
+
+
+const wxString KICAD_MANAGER_FRAME::SchFileName()
+{
+ wxFileName fn( GetProjectFileName() );
+
+ fn.SetExt( SchematicFileExtension );
+
+ return fn.GetFullPath();
+}
+
+
+const wxString KICAD_MANAGER_FRAME::PcbFileName()
+{
+ wxFileName fn( GetProjectFileName() );
+
+ fn.SetExt( PcbFileExtension );
+
+ return fn.GetFullPath();
+}
+
+
+const wxString KICAD_MANAGER_FRAME::PcbLegacyFileName()
+{
+ wxFileName fn( GetProjectFileName() );
+
+ fn.SetExt( LegacyPcbFileExtension );
+
+ return fn.GetFullPath();
+}
+
+
+void KICAD_MANAGER_FRAME::ReCreateTreePrj()
+{
+ m_LeftWin->ReCreateTreePrj();
+}
+
+
+const SEARCH_STACK& KICAD_MANAGER_FRAME::sys_search()
+{
+ return Pgm().SysSearch();
+}
+
+
+wxString KICAD_MANAGER_FRAME::help_name()
+{
+ return Pgm().GetHelpFileName();
+}
+
+
+void KICAD_MANAGER_FRAME::PrintMsg( const wxString& aText )
+{
+ m_MessagesBox->AppendText( aText );
+}
+
+
+void KICAD_MANAGER_FRAME::OnSize( wxSizeEvent& event )
+{
+ if( m_auimgr.GetManagedWindow() )
+ m_auimgr.Update();
+
+ event.Skip();
+}
+
+
+void KICAD_MANAGER_FRAME::OnCloseWindow( wxCloseEvent& Event )
+{
+ if( Kiway.PlayersClose( false ) )
+ {
+ int px, py;
+
+ UpdateFileHistory( GetProjectFileName(), &Pgm().GetFileHistory() );
+
+ if( !IsIconized() ) // save main frame position and size
+ {
+ GetPosition( &px, &py );
+ m_FramePos.x = px;
+ m_FramePos.y = py;
+
+ GetSize( &px, &py );
+ m_FrameSize.x = px;
+ m_FrameSize.y = py;
+ }
+
+ Event.SetCanVeto( true );
+
+ m_LeftWin->Show( false );
+
+ Destroy();
+ }
+}
+
+
+void KICAD_MANAGER_FRAME::OnExit( wxCommandEvent& event )
+{
+ Close( true );
+}
+
+
+void KICAD_MANAGER_FRAME::TERMINATE_HANDLER::OnTerminate( int pid, int status )
+{
+ wxString msg = wxString::Format( _( "%s closed [pid=%d]\n" ),
+ GetChars( appName ), pid );
+
+ wxWindow* window = wxWindow::FindWindowByName( KICAD_MANAGER_FRAME_NAME );
+
+ if( window ) // Should always happen.
+ {
+ // Be sure the kicad frame manager is found
+ // This dynamic cast is not really mandatory, but ...
+ KICAD_MANAGER_FRAME* frame = dynamic_cast<KICAD_MANAGER_FRAME*> (window);
+
+ if( frame )
+ frame->PrintMsg( msg );
+ }
+
+ delete this;
+}
+
+
+void KICAD_MANAGER_FRAME::Execute( wxWindow* frame, const wxString& execFile,
+ wxString params )
+{
+ if( params.size() )
+ AddDelimiterString( params );
+
+ TERMINATE_HANDLER* callback = new TERMINATE_HANDLER( execFile );
+
+ long pid = ExecuteFile( frame, execFile, params, callback );
+
+ if( pid > 0 )
+ {
+ wxString msg = wxString::Format( _( "%s %s opened [pid=%ld]\n" ),
+ GetChars( execFile ), GetChars( params ), pid );
+
+ PrintMsg( msg );
+ }
+ else
+ {
+ delete callback;
+ }
+}
+
+
+void KICAD_MANAGER_FRAME::RunEeschema( const wxString& aProjectSchematicFileName )
+{
+ KIWAY_PLAYER* frame = Kiway.Player( FRAME_SCH, false );
+
+ // Please: note: DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::initBuffers() calls
+ // Kiway.Player( FRAME_SCH, true )
+ // therefore, the schematic editor is sometimes running, but the schematic project
+ // is not loaded, if the library editor was called, and the dialog field editor was used.
+ // On linux, it happens the first time the schematic editor is launched, if
+ // library editor was running, and the dialog field editor was open
+ // On Windows, it happens always after the library editor was called,
+ // and the dialog field editor was used
+ if( !frame )
+ {
+ frame = Kiway.Player( FRAME_SCH, true );
+ }
+
+ if( !frame->IsShown() ) // the frame exists, (created by the dialog field editor)
+ // but no project loaded.
+ {
+ frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectSchematicFileName ) );
+ frame->Show( true );
+ }
+
+ // On Windows, Raise() does not bring the window on screen, when iconized or not shown
+ // On linux, Raise() brings the window on screen, but this code works fine
+ if( frame->IsIconized() )
+ frame->Iconize( false );
+
+ frame->Raise();
+}
+
+
+void KICAD_MANAGER_FRAME::OnRunEeschema( wxCommandEvent& event )
+{
+ wxFileName fn( GetProjectFileName() );
+ fn.SetExt( SchematicFileExtension );
+ RunEeschema( fn.GetFullPath() );
+}
+
+
+void KICAD_MANAGER_FRAME::OnRunSchLibEditor( wxCommandEvent& event )
+{
+ KIWAY_PLAYER* frame = Kiway.Player( FRAME_SCH_LIB_EDITOR, false );
+
+ if( !frame )
+ {
+ frame = Kiway.Player( FRAME_SCH_LIB_EDITOR, true );
+ // frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectSchematicFileName ) );
+ frame->Show( true );
+ }
+
+ // On Windows, Raise() does not bring the window on screen, when iconized
+ if( frame->IsIconized() )
+ frame->Iconize( false );
+
+ frame->Raise();
+}
+
+
+void KICAD_MANAGER_FRAME::RunPcbNew( const wxString& aProjectBoardFileName )
+{
+ KIWAY_PLAYER* frame = Kiway.Player( FRAME_PCB, true );
+
+ // a pcb frame can be already existing, but not yet used.
+ // this is the case when running the footprint editor, or the footprint viewer first
+ // if the frame is not visible, the board is not yet loaded
+ if( !frame->IsVisible() )
+ {
+ frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectBoardFileName ) );
+ frame->Show( true );
+ }
+
+ // On Windows, Raise() does not bring the window on screen, when iconized
+ if( frame->IsIconized() )
+ frame->Iconize( false );
+
+ frame->Raise();
+}
+
+
+void KICAD_MANAGER_FRAME::OnRunPcbNew( wxCommandEvent& event )
+{
+ wxFileName kicad_board( PcbFileName() );
+ wxFileName legacy_board( PcbLegacyFileName() );
+
+ wxFileName& board = ( !legacy_board.FileExists() || kicad_board.FileExists() ) ?
+ kicad_board : legacy_board;
+
+ RunPcbNew( board.GetFullPath() );
+}
+
+
+void KICAD_MANAGER_FRAME::OnRunPcbFpEditor( wxCommandEvent& event )
+{
+ KIWAY_PLAYER* frame = Kiway.Player( FRAME_PCB_MODULE_EDITOR, false );
+
+ if( !frame )
+ {
+ frame = Kiway.Player( FRAME_PCB_MODULE_EDITOR, true );
+// frame->OpenProjectFiles( std::vector<wxString>( 1, aProjectBoardFileName ) );
+ frame->Show( true );
+ }
+
+ // On Windows, Raise() does not bring the window on screen, when iconized
+ if( frame->IsIconized() )
+ frame->Iconize( false );
+
+ frame->Raise();
+}
+
+
+void KICAD_MANAGER_FRAME::OnRunBitmapConverter( wxCommandEvent& event )
+{
+ Execute( this, BITMAPCONVERTER_EXE );
+}
+
+
+void KICAD_MANAGER_FRAME::OnRunPcbCalculator( wxCommandEvent& event )
+{
+ Execute( this, PCB_CALCULATOR_EXE );
+}
+
+
+void KICAD_MANAGER_FRAME::OnRunPageLayoutEditor( wxCommandEvent& event )
+{
+ Execute( this, PL_EDITOR_EXE );
+}
+
+
+
+void KICAD_MANAGER_FRAME::OnRunGerbview( wxCommandEvent& event )
+{
+ // Gerbview is called without any file to open, because we do not know
+ // the list and the name of files to open (if any...).
+ // however we run it in the path of the project
+ Execute( this, GERBVIEW_EXE, Prj().GetProjectPath() );
+}
+
+
+void KICAD_MANAGER_FRAME::OnOpenTextEditor( wxCommandEvent& event )
+{
+ wxString editorname = Pgm().GetEditorName();
+
+ if( !editorname.IsEmpty() )
+ Execute( this, editorname, wxEmptyString );
+}
+
+
+void KICAD_MANAGER_FRAME::OnOpenFileInTextEditor( wxCommandEvent& event )
+{
+ wxString mask( wxT( "*" ) );
+
+#ifdef __WINDOWS__
+ mask += wxT( ".*" );
+#endif
+
+ mask = _( "Text file (" ) + mask + wxT( ")|" ) + mask;
+ wxString default_dir = Prj().GetProjectPath();
+
+ wxFileDialog dlg( this, _( "Load File to Edit" ), default_dir,
+ wxEmptyString, mask, wxFD_OPEN );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ wxString filename = wxT( "\"" );
+ filename += dlg.GetPath() + wxT( "\"" );
+
+ if( !dlg.GetPath().IsEmpty() && !Pgm().GetEditorName().IsEmpty() )
+ Execute( this, Pgm().GetEditorName(), filename );
+}
+
+
+void KICAD_MANAGER_FRAME::OnRefresh( wxCommandEvent& event )
+{
+ m_LeftWin->ReCreateTreePrj();
+}
+
+
+void KICAD_MANAGER_FRAME::language_change( wxCommandEvent& event )
+{
+ int id = event.GetId();
+
+ Kiway.SetLanguage( id );
+}
+
+
+void KICAD_MANAGER_FRAME::ClearMsg()
+{
+ m_MessagesBox->Clear();
+}
+
+
+void KICAD_MANAGER_FRAME::LoadSettings( wxConfigBase* aCfg )
+{
+ EDA_BASE_FRAME::LoadSettings( aCfg );
+ aCfg->Read( TREE_FRAME_WIDTH_ENTRY, &m_leftWinWidth );
+}
+
+
+void KICAD_MANAGER_FRAME::SaveSettings( wxConfigBase* aCfg )
+{
+ EDA_BASE_FRAME::SaveSettings( aCfg );
+ aCfg->Write( TREE_FRAME_WIDTH_ENTRY, m_LeftWin->GetSize().x );
+}
+
+
+/**
+ * a minor helper function:
+ * Prints the Current Project full name on the text panel.
+ */
+void KICAD_MANAGER_FRAME::PrintPrjInfo()
+{
+ wxString msg = wxString::Format( _( "Project name:\n%s\n" ),
+ GetChars( GetProjectFileName() ) );
+ PrintMsg( msg );
+}
+
+void KICAD_MANAGER_FRAME::Process_Config( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ wxFileName fn;
+
+ switch( id )
+ {
+ // Hotkey IDs
+ case ID_PREFERENCES_HOTKEY_SHOW_EDITOR:
+ InstallHotkeyFrame( this, m_manager_Hokeys_Descr );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_EXPORT_CONFIG:
+ ExportHotkeyConfigToFile( m_manager_Hokeys_Descr, wxT( "kicad" ) );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_IMPORT_CONFIG:
+ ImportHotkeyConfigFromFile( m_manager_Hokeys_Descr, wxT( "kicad" ) );
+ break;
+
+ case ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST:
+ // Display current hotkey list for LibEdit.
+ DisplayHotkeyList( this, m_manager_Hokeys_Descr );
+ break;
+
+ default:
+ wxFAIL_MSG( wxT( "KICAD_MANAGER_FRAME::Process_Config error" ) );
+ break;
+ }
+}
+
+
+void KICAD_MANAGER_FRAME::OnConfigurePaths( wxCommandEvent& aEvent )
+{
+ Pgm().ConfigurePaths( this );
+}
diff --git a/kicad/menubar.cpp b/kicad/menubar.cpp
new file mode 100644
index 0000000..130b661
--- /dev/null
+++ b/kicad/menubar.cpp
@@ -0,0 +1,501 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2009-2015 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file kicad/menubar.cpp
+ * @brief (Re)Create the project manager menubar for KiCad
+ */
+#include <fctsys.h>
+#include <pgm_kicad.h>
+#include <kicad.h>
+#include <menus_helpers.h>
+#include <tree_project_frame.h>
+#include <hotkeys_basic.h>
+
+// Menubar and toolbar event table
+BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
+ // Window events
+ EVT_SIZE( KICAD_MANAGER_FRAME::OnSize )
+ EVT_CLOSE( KICAD_MANAGER_FRAME::OnCloseWindow )
+
+ // Toolbar events
+ EVT_TOOL( ID_NEW_PROJECT, KICAD_MANAGER_FRAME::OnLoadProject )
+ EVT_TOOL( ID_NEW_PROJECT_FROM_TEMPLATE, KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate )
+ EVT_TOOL( ID_LOAD_PROJECT, KICAD_MANAGER_FRAME::OnLoadProject )
+
+ // Menu events
+ EVT_MENU( ID_SAVE_PROJECT, KICAD_MANAGER_FRAME::OnSaveProject )
+ EVT_MENU( wxID_EXIT, KICAD_MANAGER_FRAME::OnExit )
+ EVT_MENU( ID_TO_TEXT_EDITOR, KICAD_MANAGER_FRAME::OnOpenTextEditor )
+ EVT_MENU( ID_BROWSE_AN_SELECT_FILE, KICAD_MANAGER_FRAME::OnOpenFileInTextEditor )
+ EVT_MENU( ID_PREFERENCES_CONFIGURE_PATHS, KICAD_MANAGER_FRAME::OnConfigurePaths )
+ EVT_MENU( ID_SELECT_PREFERED_EDITOR, EDA_BASE_FRAME::OnSelectPreferredEditor )
+ EVT_MENU( ID_SELECT_DEFAULT_PDF_BROWSER, KICAD_MANAGER_FRAME::OnSelectDefaultPdfBrowser )
+ EVT_MENU( ID_SELECT_PREFERED_PDF_BROWSER, KICAD_MANAGER_FRAME::OnSelectPreferredPdfBrowser )
+ EVT_MENU( ID_SELECT_PREFERED_PDF_BROWSER_NAME,
+ KICAD_MANAGER_FRAME::OnSelectPreferredPdfBrowser )
+ EVT_MENU( ID_SAVE_AND_ZIP_FILES, KICAD_MANAGER_FRAME::OnArchiveFiles )
+ EVT_MENU( ID_READ_ZIP_ARCHIVE, KICAD_MANAGER_FRAME::OnUnarchiveFiles )
+ EVT_MENU( ID_PROJECT_TREE_REFRESH, KICAD_MANAGER_FRAME::OnRefresh )
+ EVT_MENU( wxID_HELP, KICAD_MANAGER_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_INDEX, KICAD_MANAGER_FRAME::GetKicadHelp )
+ EVT_MENU( wxID_ABOUT, KICAD_MANAGER_FRAME::GetKicadAbout )
+
+ // Range menu events
+ EVT_MENU_RANGE( ID_LANGUAGE_CHOICE, ID_LANGUAGE_CHOICE_END, KICAD_MANAGER_FRAME::language_change )
+
+ EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, KICAD_MANAGER_FRAME::OnFileHistory )
+
+ // Hotkey management (show list, edit ...) events
+ EVT_MENU_RANGE( ID_PREFERENCES_HOTKEY_START, ID_PREFERENCES_HOTKEY_END,
+ KICAD_MANAGER_FRAME::Process_Config )
+
+
+ // Special functions
+ EVT_MENU( ID_INIT_WATCHED_PATHS, KICAD_MANAGER_FRAME::OnChangeWatchedPaths )
+
+ // Button events (in command frame), and menu events equivalent to buttons
+ EVT_BUTTON( ID_TO_SCH, KICAD_MANAGER_FRAME::OnRunEeschema )
+ EVT_MENU( ID_TO_SCH, KICAD_MANAGER_FRAME::OnRunEeschema )
+
+ EVT_BUTTON( ID_TO_SCH_LIB_EDITOR, KICAD_MANAGER_FRAME::OnRunSchLibEditor )
+ EVT_MENU( ID_TO_SCH_LIB_EDITOR, KICAD_MANAGER_FRAME::OnRunSchLibEditor )
+
+ EVT_BUTTON( ID_TO_PCB, KICAD_MANAGER_FRAME::OnRunPcbNew )
+ EVT_MENU( ID_TO_PCB, KICAD_MANAGER_FRAME::OnRunPcbNew )
+
+ EVT_BUTTON( ID_TO_PCB_FP_EDITOR, KICAD_MANAGER_FRAME::OnRunPcbFpEditor )
+ EVT_MENU( ID_TO_PCB_FP_EDITOR, KICAD_MANAGER_FRAME::OnRunPcbFpEditor )
+
+ EVT_BUTTON( ID_TO_GERBVIEW, KICAD_MANAGER_FRAME::OnRunGerbview )
+ EVT_MENU( ID_TO_GERBVIEW, KICAD_MANAGER_FRAME::OnRunGerbview )
+
+ EVT_BUTTON( ID_TO_BITMAP_CONVERTER, KICAD_MANAGER_FRAME::OnRunBitmapConverter )
+ EVT_MENU( ID_TO_BITMAP_CONVERTER, KICAD_MANAGER_FRAME::OnRunBitmapConverter )
+
+ EVT_BUTTON( ID_TO_PCB_CALCULATOR, KICAD_MANAGER_FRAME::OnRunPcbCalculator )
+ EVT_MENU( ID_TO_PCB_CALCULATOR, KICAD_MANAGER_FRAME::OnRunPcbCalculator )
+
+ EVT_BUTTON( ID_TO_PL_EDITOR, KICAD_MANAGER_FRAME::OnRunPageLayoutEditor )
+ EVT_MENU( ID_TO_PL_EDITOR, KICAD_MANAGER_FRAME::OnRunPageLayoutEditor )
+
+ EVT_UPDATE_UI( ID_SELECT_DEFAULT_PDF_BROWSER, KICAD_MANAGER_FRAME::OnUpdateDefaultPdfBrowser )
+ EVT_UPDATE_UI( ID_SELECT_PREFERED_PDF_BROWSER,
+ KICAD_MANAGER_FRAME::OnUpdatePreferredPdfBrowser )
+ EVT_UPDATE_UI_RANGE( ID_TO_SCH, ID_TO_PCB_FP_EDITOR,
+ KICAD_MANAGER_FRAME::OnUpdateRequiresProject )
+
+END_EVENT_TABLE()
+
+enum hotkey_id_commnand
+{
+ HK_RUN_EESCHEMA = HK_COMMON_END,
+ HK_LOAD_PROJECT,
+ HK_SAVE_PROJECT,
+ HK_NEW_PRJ,
+ HK_NEW_PRJ_TEMPLATE,
+ HK_RUN_LIBEDIT,
+ HK_RUN_PCBNEW,
+ HK_RUN_FPEDITOR,
+ HK_RUN_GERBVIEW,
+ HK_RUN_BM2COMPONENT,
+ HK_RUN_PCBCALCULATOR,
+ HK_RUN_PLEDITOR
+};
+
+///////////// Hotkeys management ///////////////////////////////////////
+
+// Remark: the hotkey message info is used as keyword in hotkey config files and
+// as comments in help windows, therefore translated only when displayed
+// they are marked _HKI to be extracted by translation tools
+// See hotkeys_basic.h for more info
+
+// hotkeys command:
+static EDA_HOTKEY HkHelp( _HKI( "Help (this window)" ), HK_HELP, '?' );
+static EDA_HOTKEY HkLoadPrj( _HKI( "Load project" ), HK_LOAD_PROJECT, 'O' + GR_KB_CTRL );
+static EDA_HOTKEY HkSavePrj( _HKI( "Save project" ), HK_SAVE_PROJECT, 'S' + GR_KB_CTRL );
+static EDA_HOTKEY HkNewProject( _HKI( "New Project" ), HK_NEW_PRJ, 'N' + GR_KB_CTRL );
+static EDA_HOTKEY HkNewPrjFromTemplate( _HKI( "New Prj From Template" ),
+ HK_NEW_PRJ_TEMPLATE, 'T' + GR_KB_CTRL );
+
+static EDA_HOTKEY HkRunEeschema( _HKI( "Run Eeschema" ), HK_RUN_EESCHEMA, 'E' + GR_KB_CTRL, 0 );
+static EDA_HOTKEY HkRunLibedit( _HKI( "Run LibEdit" ), HK_RUN_LIBEDIT, 'L' + GR_KB_CTRL, 0 );
+static EDA_HOTKEY HkRunPcbnew( _HKI( "Run Pcbnew" ), HK_RUN_PCBNEW, 'P' + GR_KB_CTRL, 0 );
+static EDA_HOTKEY HkRunModedit( _HKI( "Run FpEditor" ), HK_RUN_FPEDITOR, 'F' + GR_KB_CTRL, 0 );
+static EDA_HOTKEY HkRunGerbview( _HKI( "Run Gerbview" ), HK_RUN_GERBVIEW, 'G' + GR_KB_CTRL, 0 );
+static EDA_HOTKEY HkRunBm2Cmp( _HKI( "Run Bitmap2Component" ),
+ HK_RUN_BM2COMPONENT, 'B' + GR_KB_CTRL, 0 );
+static EDA_HOTKEY HkRunPcbCalc( _HKI( "Run PcbCalculator" ),
+ HK_RUN_PCBCALCULATOR, 'C' + GR_KB_CTRL, 0 );
+static EDA_HOTKEY HkRunPleditor( _HKI( "Run PlEditor" ), HK_RUN_PLEDITOR, 'Y' + GR_KB_CTRL, 0 );
+
+// List of hotkey descriptors
+EDA_HOTKEY* common_Hotkey_List[] =
+{
+ &HkHelp,
+ &HkLoadPrj, &HkSavePrj, &HkNewProject, &HkNewPrjFromTemplate,
+ &HkRunEeschema, &HkRunLibedit,
+ &HkRunPcbnew, &HkRunModedit, &HkRunGerbview,
+ &HkRunBm2Cmp, &HkRunPcbCalc, &HkRunPleditor,
+ NULL
+};
+
+// list of sections and corresponding hotkey list for Kicad
+// (used to create an hotkey config file, and edit hotkeys )
+// here we have only one section.
+static wxString sectionTitle( _HKI( "Kicad Manager Hotkeys" ) );
+
+struct EDA_HOTKEY_CONFIG kicad_Manager_Hokeys_Descr[] = {
+ { &g_CommonSectionTag, common_Hotkey_List, &sectionTitle },
+ { NULL, NULL, NULL }
+};
+///////////// End hotkeys management ///////////////////////////////////////
+
+
+/**
+ * @brief (Re)Create the menubar
+ */
+void KICAD_MANAGER_FRAME::ReCreateMenuBar()
+{
+ wxString msg;
+ static wxMenu* openRecentMenu; // Open Recent submenu,
+ // static to remember this menu
+
+ m_manager_Hokeys_Descr = kicad_Manager_Hokeys_Descr;
+
+ // Create and try to get the current menubar
+ wxMenuBar* menuBar = GetMenuBar();
+
+ if( !menuBar )
+ menuBar = new wxMenuBar();
+
+ // Delete all existing menus so they can be rebuilt.
+ // This allows language changes of the menu text on the fly.
+ menuBar->Freeze();
+
+ // Before deleting, remove the menus managed by m_fileHistory
+ // (the file history will be updated when adding/removing files in history)
+ if( openRecentMenu )
+ Pgm().GetFileHistory().RemoveMenu( openRecentMenu );
+
+ // Delete all existing menus
+ while( menuBar->GetMenuCount() )
+ delete menuBar->Remove( 0 );
+
+ // Recreate all menus:
+
+ // Menu File:
+ wxMenu* fileMenu = new wxMenu;
+
+ // Open
+ msg = AddHotkeyName( _( "&Open Project" ), kicad_Manager_Hokeys_Descr, HK_LOAD_PROJECT );
+ AddMenuItem( fileMenu, ID_LOAD_PROJECT, msg,
+ _( "Open existing project" ),
+ KiBitmap( open_project_xpm ) );
+
+ // File history
+ openRecentMenu = new wxMenu();
+ Pgm().GetFileHistory().UseMenu( openRecentMenu );
+ Pgm().GetFileHistory().AddFilesToMenu( );
+ AddMenuItem( fileMenu, openRecentMenu,
+ wxID_ANY,
+ _( "Open &Recent" ),
+ _( "Open recent schematic project" ),
+ KiBitmap( open_project_xpm ) );
+
+ // New project creation
+ wxMenu* newprjSubMenu = new wxMenu();
+
+ msg = AddHotkeyName( _( "&New Project" ), kicad_Manager_Hokeys_Descr, HK_NEW_PRJ );
+ AddMenuItem( newprjSubMenu, ID_NEW_PROJECT, msg,
+ _( "Create new blank project" ),
+ KiBitmap( new_project_xpm ) );
+
+ msg = AddHotkeyName( _( "New Project from &Template" ),
+ kicad_Manager_Hokeys_Descr, HK_NEW_PRJ_TEMPLATE );
+ AddMenuItem( newprjSubMenu, ID_NEW_PROJECT_FROM_TEMPLATE, msg,
+ _( "Create a new project from a template" ),
+ KiBitmap( new_project_with_template_xpm ) );
+
+ AddMenuItem( fileMenu, newprjSubMenu,
+ wxID_ANY,
+ _( "New Project" ),
+ _( "Create new project" ),
+ KiBitmap( new_project_xpm ) );
+
+ // Currently there is nothing to save
+ // (Kicad manager does not save any info in .pro file)
+#if 0
+ // Save
+ msg = AddHotkeyName( _( "&Save" ), kicad_Manager_Hokeys_Descr, HK_SAVE_PROJECT );
+ AddMenuItem( fileMenu, ID_SAVE_PROJECT, msg,
+ _( "Save current project" ),
+ KiBitmap( save_project_xpm ) );
+#endif
+
+ // Archive
+ fileMenu->AppendSeparator();
+ AddMenuItem( fileMenu,
+ ID_SAVE_AND_ZIP_FILES,
+ _( "&Archive" ),
+ _( "Archive project files in zip archive" ),
+ KiBitmap( zip_xpm ) );
+
+ // Unarchive
+ AddMenuItem( fileMenu,
+ ID_READ_ZIP_ARCHIVE,
+ _( "&Unarchive" ),
+ _( "Unarchive project files from zip file" ),
+ KiBitmap( unzip_xpm ) );
+
+ // Separator
+ fileMenu->AppendSeparator();
+
+ // Quit
+ AddMenuItem( fileMenu,
+ wxID_EXIT,
+ _( "&Close" ),
+ _( "Close KiCad" ),
+ KiBitmap( exit_xpm ) );
+
+ // Menu Browse:
+ wxMenu* browseMenu = new wxMenu();
+
+ // Text editor
+ AddMenuItem( browseMenu,
+ ID_TO_TEXT_EDITOR,
+ _( "Open Text E&ditor" ),
+ _( "Launch preferred text editor" ),
+ KiBitmap( editor_xpm ) );
+
+ // View file
+ AddMenuItem( browseMenu,
+ ID_BROWSE_AN_SELECT_FILE,
+ _( "&Open Local File" ),
+ _( "Edit local file" ),
+ KiBitmap( browse_files_xpm ) );
+
+ // Menu Preferences:
+ wxMenu* preferencesMenu = new wxMenu;
+
+ // Path configuration edit dialog.
+ AddMenuItem( preferencesMenu,
+ ID_PREFERENCES_CONFIGURE_PATHS,
+ _( "Configure Pa&ths" ),
+ _( "Edit path configuration environment variables" ),
+ KiBitmap( editor_xpm ) );
+
+ // Text editor
+ AddMenuItem( preferencesMenu,
+ ID_SELECT_PREFERED_EDITOR,
+ _( "&Set Text Editor" ),
+ _( "Set your preferred text editor" ),
+ KiBitmap( editor_xpm ) );
+
+ // PDF Viewer submenu:System browser or user defined checkbox
+ wxMenu* SubMenuPdfBrowserChoice = new wxMenu;
+
+ // Default
+ AddMenuItem( SubMenuPdfBrowserChoice, ID_SELECT_DEFAULT_PDF_BROWSER,
+ _( "System &Default PDF Viewer" ),
+ _( "Use system default PDF viewer" ),
+ KiBitmap( datasheet_xpm ),
+ wxITEM_CHECK );
+ SubMenuPdfBrowserChoice->Check( ID_SELECT_DEFAULT_PDF_BROWSER,
+ Pgm().UseSystemPdfBrowser() );
+
+ // Favourite
+ AddMenuItem( SubMenuPdfBrowserChoice, ID_SELECT_PREFERED_PDF_BROWSER,
+ _( "&Favourite PDF Viewer" ),
+ _( "Use favourite PDF viewer" ),
+ KiBitmap( datasheet_xpm ),
+ wxITEM_CHECK );
+ SubMenuPdfBrowserChoice->Check( ID_SELECT_PREFERED_PDF_BROWSER,
+ !Pgm().UseSystemPdfBrowser() );
+
+ SubMenuPdfBrowserChoice->AppendSeparator();
+ // Append PDF Viewer submenu to preferences
+ AddMenuItem( SubMenuPdfBrowserChoice,
+ ID_SELECT_PREFERED_PDF_BROWSER_NAME,
+ _( "Set &PDF Viewer" ),
+ _( "Set favourite PDF viewer" ),
+ KiBitmap( datasheet_xpm ) );
+
+ // PDF viewer submenu
+ AddMenuItem( preferencesMenu, SubMenuPdfBrowserChoice, -1,
+ _( "&PDF Viewer" ),
+ _( "PDF viewer preferences" ),
+ KiBitmap( datasheet_xpm ) );
+
+ // Hotkey submenu
+ preferencesMenu->AppendSeparator();
+ AddHotkeyConfigMenu( preferencesMenu );
+
+ // Language submenu
+ preferencesMenu->AppendSeparator();
+ Pgm().AddMenuLanguageList( preferencesMenu );
+
+ // Menu Tools:
+ wxMenu* toolsMenu = new wxMenu;
+
+ msg = AddHotkeyName( _( "Run Eeschema" ), kicad_Manager_Hokeys_Descr, HK_RUN_EESCHEMA );
+ AddMenuItem( toolsMenu, ID_TO_SCH, msg, KiBitmap( eeschema_xpm ) );
+
+ msg = AddHotkeyName( _( "Run Library Editor" ),
+ kicad_Manager_Hokeys_Descr, HK_RUN_LIBEDIT );
+ AddMenuItem( toolsMenu, ID_TO_SCH_LIB_EDITOR, msg, KiBitmap( libedit_xpm ) );
+
+ msg = AddHotkeyName( _( "Run Pcbnew" ),
+ kicad_Manager_Hokeys_Descr, HK_RUN_PCBNEW );
+ AddMenuItem( toolsMenu, ID_TO_PCB, msg, KiBitmap( pcbnew_xpm ) );
+
+ msg = AddHotkeyName( _( "Run Footprint Editor" ),
+ kicad_Manager_Hokeys_Descr, HK_RUN_FPEDITOR );
+ AddMenuItem( toolsMenu, ID_TO_PCB_FP_EDITOR, msg, KiBitmap( module_editor_xpm ) );
+
+ msg = AddHotkeyName( _( "Run Gerbview" ),
+ kicad_Manager_Hokeys_Descr, HK_RUN_GERBVIEW );
+ AddMenuItem( toolsMenu, ID_TO_GERBVIEW, msg, KiBitmap( icon_gerbview_small_xpm ) );
+
+ msg = AddHotkeyName( _( "Run Bitmap2Component" ),
+ kicad_Manager_Hokeys_Descr, HK_RUN_BM2COMPONENT );
+ AddMenuItem( toolsMenu, ID_TO_BITMAP_CONVERTER, msg,
+ _( "Bitmap2Component - Convert bitmap images to Eeschema\n"
+ "or Pcbnew elements" ),
+ KiBitmap( image_xpm ) );
+
+ msg = AddHotkeyName( _( "Run Pcb Calculator" ), kicad_Manager_Hokeys_Descr, HK_RUN_PCBCALCULATOR );
+ AddMenuItem( toolsMenu, ID_TO_PCB_CALCULATOR, msg,
+ _( "Pcb calculator - Calculator for components, track width, etc." ),
+ KiBitmap( options_module_xpm ) );
+
+ msg = AddHotkeyName( _( "Run Page Layout Editor" ), kicad_Manager_Hokeys_Descr, HK_RUN_PLEDITOR );
+ AddMenuItem( toolsMenu, ID_TO_PL_EDITOR, msg,
+ _( "Pl editor - Worksheet layout editor" ),
+ KiBitmap( pagelayout_load_xpm ) );
+
+ // Menu Help:
+ wxMenu* helpMenu = new wxMenu;
+
+ // Version info
+ AddHelpVersionInfoMenuEntry( helpMenu );
+
+ // Contents
+ AddMenuItem( helpMenu, wxID_HELP,
+ _( "KiCad &Manual" ),
+ _( "Open KiCad user manual" ),
+ KiBitmap( online_help_xpm ) );
+
+ AddMenuItem( helpMenu, wxID_INDEX,
+ _( "&Getting Started in KiCad" ),
+ _( "Open \"Getting Started in KiCad\" guide for beginners" ),
+ KiBitmap( help_xpm ) );
+
+ // Separator
+ helpMenu->AppendSeparator();
+
+ // About
+ AddMenuItem( helpMenu, wxID_ABOUT,
+ _( "&About KiCad" ),
+ _( "About KiCad" ),
+ KiBitmap( info_xpm ) );
+
+ // Create the menubar and append all submenus
+ menuBar->Append( fileMenu, _( "&File" ) );
+ menuBar->Append( browseMenu, _( "&Browse" ) );
+ menuBar->Append( preferencesMenu, _( "&Preferences" ) );
+ menuBar->Append( toolsMenu, _( "&Tools" ) );
+ menuBar->Append( helpMenu, _( "&Help" ) );
+
+ menuBar->Thaw();
+
+ // Associate the menu bar with the frame, if no previous menubar
+ if( GetMenuBar() == NULL )
+ SetMenuBar( menuBar );
+ else
+ menuBar->Refresh();
+
+ // Add the hotkey to the "show hotkey list" menu, because we do not have
+ // a management of the keyboard keys in Kicad.
+ // So all hotheys should be added to the menubar
+ // Note Use wxMenuBar::SetLabel only after the menubar
+ // has been associated with a frame. (see wxWidgets doc)
+ msg = AddHotkeyName( menuBar->GetLabel( ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST ),
+ kicad_Manager_Hokeys_Descr, HK_HELP );
+ menuBar->SetLabel( ID_PREFERENCES_HOTKEY_SHOW_CURRENT_LIST, msg );
+}
+
+
+/**
+ * @brief (Re)Create the horizontal toolbar
+ */
+void KICAD_MANAGER_FRAME::RecreateBaseHToolbar()
+{
+ // Check if toolbar is not already created
+ if( m_mainToolBar != NULL )
+ return;
+
+ // Allocate memory for m_mainToolBar
+ m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
+ wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
+
+ // New
+ m_mainToolBar->AddTool( ID_NEW_PROJECT, wxEmptyString,
+ KiBitmap( new_project_xpm ),
+ _( "Create new project" ) );
+
+ m_mainToolBar->AddTool( ID_NEW_PROJECT_FROM_TEMPLATE, wxEmptyString,
+ KiBitmap( new_project_with_template_xpm ),
+ _( "Create new project from template" ) );
+
+ // Load
+ m_mainToolBar->AddTool( ID_LOAD_PROJECT, wxEmptyString,
+ KiBitmap( open_project_xpm ),
+ _( "Open existing project" ) );
+
+ // Save
+ m_mainToolBar->AddTool( ID_SAVE_PROJECT, wxEmptyString,
+ KiBitmap( save_project_xpm ),
+ _( "Save current project" ) );
+
+ // Separator
+ m_mainToolBar->AddSeparator();
+
+ // Archive
+ m_mainToolBar->AddTool( ID_SAVE_AND_ZIP_FILES, wxEmptyString,
+ KiBitmap( zip_xpm ),
+ _( "Archive all project files" ) );
+
+ // Separator
+ m_mainToolBar->AddSeparator();
+
+ // Refresh project tree
+ m_mainToolBar->AddTool( ID_PROJECT_TREE_REFRESH, wxEmptyString,
+ KiBitmap( reload_xpm ),
+ _( "Refresh project tree" ) );
+
+ // Create m_mainToolBar
+ m_mainToolBar->Realize();
+}
diff --git a/kicad/pgm_kicad.h b/kicad/pgm_kicad.h
new file mode 100644
index 0000000..bb1069e
--- /dev/null
+++ b/kicad/pgm_kicad.h
@@ -0,0 +1,76 @@
+#ifndef PGM_KICAD_H_
+#define PGM_KICAD_H_
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include <pgm_base.h>
+#include <bin_mod.h>
+
+
+/**
+ * Class PGM_KICAD
+ * extends PGM_BASE to bring in FileHistory() and PdfBrowser() which were moved
+ * from EDA_APP into KIFACE_I. KIFACE_I is not applicable in the project manager
+ * since it is not a KIFACE. This header is in the kicad directory since nobody
+ * else needs to know about it.
+ */
+class PGM_KICAD : public PGM_BASE
+{
+public:
+ PGM_KICAD() :
+ m_bm( "kicad" ) // indicates a "$HOME/.kicad wxConfig like" config file.
+ {}
+
+ ~PGM_KICAD()
+ {
+ destroy();
+ }
+
+ bool OnPgmInit( wxApp* aWxApp ); // overload PGM_BASE virtual
+ void OnPgmExit(); // overload PGM_BASE virtual
+ void MacOpenFile( const wxString& aFileName ); // overload PGM_BASE virtual
+
+ wxFileHistory& GetFileHistory() { return m_bm.m_history; }
+
+ wxConfigBase* PgmSettings() { return m_bm.m_config; }
+
+ SEARCH_STACK& SysSearch() { return m_bm.m_search; }
+
+ wxString GetHelpFileName() { return m_bm.m_help_file; }
+
+protected:
+
+ // The PGM_* classes can have difficulties at termination if they
+ // are not destroyed soon enough. Relying on a static destructor can be
+ // too late for contained objects like wxSingleInstanceChecker.
+ void destroy();
+
+ BIN_MOD m_bm;
+};
+
+
+extern PGM_KICAD& Pgm();
+
+#endif // PGM_KICAD_H_
diff --git a/kicad/preferences.cpp b/kicad/preferences.cpp
new file mode 100644
index 0000000..2f0e02c
--- /dev/null
+++ b/kicad/preferences.cpp
@@ -0,0 +1,96 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2008-2014 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * @file preferences.cpp
+ */
+
+#include <fctsys.h>
+#include <pgm_kicad.h>
+#include <confirm.h>
+#include <gestfich.h>
+
+#include <kicad.h>
+
+#include <wx/fontdlg.h>
+
+
+void KICAD_MANAGER_FRAME::OnUpdateDefaultPdfBrowser( wxUpdateUIEvent& event )
+{
+ event.Check( Pgm().UseSystemPdfBrowser() );
+}
+
+
+void KICAD_MANAGER_FRAME::OnSelectDefaultPdfBrowser( wxCommandEvent& event )
+{
+ Pgm().ForceSystemPdfBrowser( true );
+ Pgm().WritePdfBrowserInfos();
+}
+
+
+void KICAD_MANAGER_FRAME::OnUpdatePreferredPdfBrowser( wxUpdateUIEvent& event )
+{
+ event.Check( !Pgm().UseSystemPdfBrowser() );
+}
+
+
+void KICAD_MANAGER_FRAME::OnSelectPreferredPdfBrowser( wxCommandEvent& event )
+{
+ bool setPdfBrowserName = event.GetId() == ID_SELECT_PREFERED_PDF_BROWSER_NAME;
+
+ if( !Pgm().GetPdfBrowserName() && !setPdfBrowserName )
+ {
+ DisplayError( this,
+ _( "You must choose a PDF viewer before using this option." ) );
+ setPdfBrowserName = true;
+ }
+
+ if( setPdfBrowserName )
+ {
+ wxString mask( wxT( "*" ) );
+
+ #ifdef __WINDOWS__
+ mask += wxT( ".exe" );
+ #endif
+
+ wxString wildcard = _( "Executable files (" ) + mask + wxT( ")|" ) + mask;
+
+ Pgm().ReadPdfBrowserInfos();
+ wxFileName fn = Pgm().GetPdfBrowserName();
+
+ wxFileDialog dlg( this, _( "Select Preferred PDF Browser" ), fn.GetPath(),
+ fn.GetFullPath(), wildcard,
+ wxFD_OPEN | wxFD_FILE_MUST_EXIST );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ Pgm().SetPdfBrowserName( dlg.GetPath() );
+ }
+
+ Pgm().ForceSystemPdfBrowser( false );
+ Pgm().WritePdfBrowserInfos();
+}
+
diff --git a/kicad/prjconfig.cpp b/kicad/prjconfig.cpp
new file mode 100644
index 0000000..c8ed495
--- /dev/null
+++ b/kicad/prjconfig.cpp
@@ -0,0 +1,398 @@
+/**
+ * @file prjconfig.cpp
+ * Load and save project configuration files (*.pro)
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2004-2015 Jean-Pierre Charras
+ * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <pgm_kicad.h>
+#include <kiway.h>
+#include <project.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <kicad.h>
+#include <config_params.h>
+#include <project_template.h>
+#include <tree_project_frame.h>
+#include <wildcards_and_files_ext.h>
+#include <vector>
+#include <build_version.h>
+#include <macros.h>
+#include <common.h>
+
+#include <wx/dir.h>
+#include <wx/filename.h>
+#include <wx/stdpaths.h>
+
+#include "dialogs/dialog_template_selector.h"
+
+#define SEP() wxFileName::GetPathSeparator()
+
+// Not really useful, provided to save/restore params in project config file,
+// (Add them in s_KicadManagerParams if any)
+// Used also to create new .pro files from the kicad.pro template file
+// for new projects
+#define GeneralGroupName wxT( "/general" )
+
+PARAM_CFG_ARRAY s_KicadManagerParams;
+
+void KICAD_MANAGER_FRAME::CreateNewProject( const wxString& aPrjFullFileName,
+ bool aTemplateSelector = false )
+{
+ wxFileName newProjectName = aPrjFullFileName;
+ wxChar sep[2] = { SEP(), 0 }; // nul terminated separator wxChar string.
+
+ ClearMsg();
+
+ // If we are creating a project from a template, make sure the template directory is sane
+ if( aTemplateSelector )
+ {
+ DIALOG_TEMPLATE_SELECTOR* ps = new DIALOG_TEMPLATE_SELECTOR( this );
+
+ wxFileName templatePath;
+ wxString envStr;
+
+#ifndef __WXMAC__
+ wxGetEnv( wxT( "KICAD" ), &envStr );
+
+ // Add a new tab for system templates
+ if( !envStr.empty() )
+ {
+ // user may or may not have including terminating separator.
+ if( !envStr.EndsWith( sep ) )
+ envStr += sep;
+
+ templatePath = envStr + wxT( "template" ) + sep;
+ }
+ else
+ {
+ // The standard path should be in the share directory for kicad. As
+ // it is normal on Windows to only have the share directory and not
+ // the kicad sub-directory we fall back to that if the directory
+ // doesn't exist
+ templatePath = wxPathOnly( wxStandardPaths::Get().GetExecutablePath() ) +
+ sep + wxT( ".." ) + sep + wxT( "share" ) + sep + wxT( "kicad" ) +
+ sep + wxT( "template" ) + sep;
+
+ if( !wxDirExists( templatePath.GetFullPath() ) )
+ {
+ templatePath = wxPathOnly( wxStandardPaths::Get().GetExecutablePath() ) +
+ sep + wxT( ".." ) + sep + wxT( "share" ) + sep + wxT( "template" ) + sep;
+ }
+ }
+#else
+ // Use what is provided in the bundle data dir
+ templatePath = GetOSXKicadDataDir() + sep + wxT( "template" );
+#endif
+
+ ps->AddTemplatesPage( _( "System Templates" ), templatePath );
+
+ // Add a new tab for user templates
+ wxFileName userPath = wxStandardPaths::Get().GetDocumentsDir() +
+ sep + wxT( "kicad" ) + sep + wxT( "template" ) + sep;
+
+ ps->AddTemplatesPage( _( "User Templates" ), userPath );
+
+ // Check to see if a custom template location is available and setup a
+ // new selection tab if there is.
+ envStr.clear();
+ wxGetEnv( wxT( "KICAD_PTEMPLATES" ), &envStr );
+
+ if( !envStr.empty() )
+ {
+ if( !envStr.EndsWith( sep ) )
+ envStr += sep;
+
+ wxFileName envPath = envStr;
+
+ ps->AddTemplatesPage( _( "Portable Templates" ), envPath );
+ }
+
+ // Show the project template selector dialog
+ int result = ps->ShowModal();
+
+ if( ( result != wxID_OK ) || ( ps->GetSelectedTemplate() == NULL ) )
+ {
+ if( ps->GetSelectedTemplate() == NULL )
+ {
+ wxMessageBox( _( "No project template was selected. Cannot generate new "
+ "project." ),
+ _( "Error" ),
+ wxOK | wxICON_ERROR,
+ this );
+ }
+ }
+ else
+ {
+ // The selected template widget contains the template we're attempting to use to
+ // create a project
+ if( !ps->GetSelectedTemplate()->CreateProject( newProjectName ) )
+ {
+ wxMessageBox( _( "Problem whilst creating new project from template!" ),
+ _( "Template Error" ),
+ wxOK | wxICON_ERROR,
+ this );
+ }
+ }
+ }
+
+ // Init project filename
+ SetProjectFileName( newProjectName.GetFullPath() );
+
+ // Write settings to project file
+ // was: wxGetApp().WriteProjectConfig( aPrjFullFileName, GeneralGroupName, s_KicadManagerParams );
+ Prj().ConfigSave( Pgm().SysSearch(), GeneralGroupName, s_KicadManagerParams );
+
+ // Ensure a "stub" for a schematic root sheet and a board exist.
+ // It will avoid messages from the schematic editor or the board editor to create a new file
+ // And forces the user to create main files under the right name for the project manager
+ wxFileName fn( newProjectName.GetFullPath() );
+ fn.SetExt( SchematicFileExtension );
+
+ // If a <project>.sch file does not exist, create a "stub" file
+ if( !fn.FileExists() )
+ {
+ wxFile file( fn.GetFullPath(), wxFile::write );
+
+ if( file.IsOpened() )
+ file.Write( wxT( "EESchema Schematic File Version 2\n" ) );
+
+ // wxFile dtor will close the file
+ }
+
+ // If a <project>.kicad_pcb or <project>.brd file does not exist,
+ // create a .kicad_pcb "stub" file
+ fn.SetExt( KiCadPcbFileExtension );
+ wxFileName leg_fn( fn );
+ leg_fn.SetExt( LegacyPcbFileExtension );
+
+ if( !fn.FileExists() && !leg_fn.FileExists() )
+ {
+ wxFile file( fn.GetFullPath(), wxFile::write );
+
+ if( file.IsOpened() )
+ file.Write( wxT( "(kicad_pcb (version 4) (host kicad \"dummy file\") )\n" ) );
+
+ // wxFile dtor will close the file
+ }
+
+ // Enable the toolbar and menubar buttons and clear the help text.
+ m_active_project = true;
+ m_MessagesBox->Clear();
+}
+
+
+void KICAD_MANAGER_FRAME::OnLoadProject( wxCommandEvent& event )
+{
+ // Any open KIFACE's must be closed if they are not part of the new project.
+ // (We never want a KIWAY_PLAYER open on a KIWAY that isn't in the same project.)
+ // User is prompted here to close those KIWAY_PLAYERs:
+ if( !Kiway.PlayersClose( false ) )
+ return;
+
+ // evt_id can be one of:
+ // ID_NEW_PROJECT, ID_NEW_PROJECT_FROM_TEMPLATE, ID_LOAD_PROJECT, and
+ // wxID_ANY from 3 different places.
+ int evt_id = event.GetId();
+
+ wxString title;
+
+ ClearMsg();
+
+ bool newProject = ( evt_id == ID_NEW_PROJECT ) ||
+ ( evt_id == ID_NEW_PROJECT_FROM_TEMPLATE );
+
+ if( evt_id != wxID_ANY )
+ {
+ int style;
+
+ if( newProject )
+ {
+ title = _( "Create New Project" );
+ style = wxFD_SAVE | wxFD_OVERWRITE_PROMPT;
+ }
+ else
+ {
+ title = _( "Open Existing Project" );
+ style = wxFD_OPEN | wxFD_FILE_MUST_EXIST;
+ }
+
+ wxString default_dir = GetMruPath();
+ wxFileDialog dlg( this, title, default_dir, wxEmptyString,
+ ProjectFileWildcard, style );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ //DBG( printf( "%s: wxFileDialog::GetPath=%s\n", __func__, TO_UTF8( dlg.GetPath() ) );)
+
+ wxFileName pro( dlg.GetPath() );
+ pro.SetExt( ProjectFileExtension ); // enforce extension
+
+ if( !pro.IsAbsolute() )
+ pro.MakeAbsolute();
+
+ if( newProject )
+ {
+ // Check if the project directory is empty
+ wxDir directory( pro.GetPath() );
+
+ if( directory.HasFiles() )
+ {
+ wxString msg = _( "The selected directory is not empty. We recommend you "
+ "create projects in their own clean directory.\n\nDo you "
+ "want to create a new empty directory for the project?" );
+
+ if( IsOK( this, msg ) )
+ {
+ // Append a new directory with the same name of the project file
+ // and try to create it
+ pro.AppendDir( pro.GetName() );
+
+ if( !wxMkdir( pro.GetPath() ) )
+ // There was a problem, undo
+ pro.RemoveLastDir();
+ }
+ }
+
+ if( evt_id == ID_NEW_PROJECT )
+ {
+ CreateNewProject( pro.GetFullPath() );
+ }
+ else if( evt_id == ID_NEW_PROJECT_FROM_TEMPLATE )
+ {
+ // Launch the template selector dialog
+ CreateNewProject( pro.GetFullPath(), true );
+ }
+ }
+
+ SetProjectFileName( pro.GetFullPath() );
+ }
+
+ wxString prj_filename = GetProjectFileName();
+
+ wxString nameless_prj = NAMELESS_PROJECT wxT( ".pro" );
+
+ wxLogDebug( wxT( "%s: %s" ),
+ GetChars( wxFileName( prj_filename ).GetFullName() ),
+ GetChars( nameless_prj ) );
+
+ // Check if project file exists and if it is not noname.pro
+ if( !wxFileExists( prj_filename )
+ && !wxFileName( prj_filename ).GetFullName().IsSameAs( nameless_prj ) )
+ {
+ wxString msg = wxString::Format( _(
+ "KiCad project file '%s' not found" ),
+ GetChars( prj_filename ) );
+
+ DisplayError( this, msg );
+ return;
+ }
+
+ // Either this is the first time kicad has been run or one of the projects in the
+ // history list is no longer valid. This prevents kicad from automatically creating
+ // a noname.pro file in the same folder as the kicad binary.
+ if( wxFileName( prj_filename ).GetFullName().IsSameAs( nameless_prj ) && !newProject )
+ {
+ m_active_project = false;
+ m_MessagesBox->SetValue( _( "To proceed, you can use the File menu to start a new project." ) );
+ return;
+ }
+ else
+ {
+ m_active_project = true;
+ m_MessagesBox->Clear();
+ }
+
+ Prj().ConfigLoad( Pgm().SysSearch(), GeneralGroupName, s_KicadManagerParams );
+
+ title = wxT( "KiCad " ) + GetBuildVersion() + wxT( ' ' ) + prj_filename;
+
+ if( !wxFileName( prj_filename ).IsDirWritable() )
+ title += _( " [Read Only]" );
+ else
+ SetMruPath( Prj().GetProjectPath() ); // Only set MRU path if we have write access.
+
+ SetTitle( title );
+
+ if( !prj_filename.IsSameAs( nameless_prj ) )
+ UpdateFileHistory( prj_filename, &Pgm().GetFileHistory() );
+
+ m_LeftWin->ReCreateTreePrj();
+
+ // Rebuild the list of watched paths.
+ // however this is possible only when the main loop event handler is running,
+ // so we use it to run the rebuild function.
+ wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED, ID_INIT_WATCHED_PATHS );
+
+ wxPostEvent( this, cmd );
+
+ PrintPrjInfo();
+}
+
+
+/* Creates a new project folder, copy a template into this new folder.
+ * and open this new project as working project
+ */
+void KICAD_MANAGER_FRAME::OnCreateProjectFromTemplate( wxCommandEvent& event )
+{
+ wxString default_dir = wxFileName( Prj().GetProjectFullName() ).GetPathWithSep();
+ wxString title = _("New Project Folder");
+ wxDirDialog dlg( this, title, default_dir );
+
+ if( dlg.ShowModal() == wxID_CANCEL )
+ return;
+
+ // Builds the project .pro filename, from the new project folder name
+ wxFileName fn;
+ fn.AssignDir( dlg.GetPath() );
+ fn.SetName( dlg.GetPath().AfterLast( SEP() ) );
+ fn.SetExt( wxT( "pro" ) );
+
+ // Launch the template selector dialog, and copy files
+ CreateNewProject( fn.GetFullPath(), true );
+
+ // Initialize the project
+ event.SetId( wxID_ANY );
+ OnLoadProject( event );
+}
+
+
+void KICAD_MANAGER_FRAME::OnSaveProject( wxCommandEvent& event )
+{
+ if( !wxIsWritable( GetProjectFileName() ) )
+ return;
+
+ // was: wxGetApp().WriteProjectConfig( m_ProjectFileName.GetFullPath(),
+ // GeneralGroupName, s_KicadManagerParams );
+ Prj().ConfigSave( Pgm().SysSearch(), GeneralGroupName, s_KicadManagerParams );
+}
+
+
+void KICAD_MANAGER_FRAME::OnUpdateRequiresProject( wxUpdateUIEvent& event )
+{
+ event.Enable( m_active_project );
+}
diff --git a/kicad/project_template.cpp b/kicad/project_template.cpp
new file mode 100644
index 0000000..b4f088c
--- /dev/null
+++ b/kicad/project_template.cpp
@@ -0,0 +1,236 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Brian Sidebotham <brian.sidebotham@gmail.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "project_template.h"
+
+#include <vector>
+
+#include <wx/wx.h>
+#include <wx/arrstr.h>
+#include <wx/dir.h>
+#include <wx/filename.h>
+#include <wx/txtstrm.h>
+#include <wx/wfstream.h>
+
+#include <macros.h>
+
+
+#define SEP() wxFileName::GetPathSeparator()
+
+
+PROJECT_TEMPLATE::PROJECT_TEMPLATE( const wxString& aPath )
+{
+ templateBasePath = wxFileName::DirName( aPath );
+ templateMetaPath = wxFileName::DirName( aPath + SEP() + METADIR );
+ templateMetaHtmlFile = wxFileName::FileName( aPath + SEP() + METADIR + SEP() +
+ METAFILE_INFO_HTML );
+ templateMetaIconFile = wxFileName::FileName( aPath + SEP() + METADIR + SEP() + METAFILE_ICON );
+
+ title = wxEmptyString;
+
+ // Test the project template requirements to make sure aPath is a valid
+ // template structure
+ if( !wxFileName::DirExists( templateBasePath.GetPath() ) )
+ {
+ // Error, the path doesn't exist!
+ title = wxT( "Could open the template path! " + aPath );
+ }
+ else if( !wxFileName::DirExists( templateMetaPath.GetPath() ) )
+ {
+ // Error, the meta information directory doesn't exist!
+ title = wxT( "Couldn't open the meta information directory for this template! " +
+ templateMetaPath.GetPath() );
+ }
+ else if( !wxFileName::FileExists( templateMetaHtmlFile.GetFullPath() ) )
+ {
+ // Error, the meta information directory doesn't contain the informational html file!
+ title = wxT( "Cound't find the meta html information file for this template!" );
+ }
+
+ // Try to load an icon
+ metaIcon = new wxBitmap( templateMetaIconFile.GetFullPath(), wxBITMAP_TYPE_PNG );
+}
+
+std::vector<wxFileName> PROJECT_TEMPLATE::GetFileList()
+{
+ std::vector<wxFileName> files;
+ wxString f = templateBasePath.GetPath();
+ wxArrayString allfiles;
+ wxFileName p;
+
+ wxDir::GetAllFiles( f, &allfiles );
+
+ // Create the vector and ignore all of the meta data files!
+ for( size_t i=0; i < allfiles.size(); i++ )
+ {
+ p = allfiles[i];
+
+ // Files that are in the meta directory must not be included
+ if( !p.GetPath().StartsWith( templateMetaPath.GetPath() ) )
+ files.push_back(allfiles[i]);
+ }
+
+ return files;
+}
+
+
+wxString PROJECT_TEMPLATE::GetPrjDirName()
+{
+ return templateBasePath.GetDirs()[ templateBasePath.GetDirCount()-1 ];
+}
+
+
+PROJECT_TEMPLATE::~PROJECT_TEMPLATE()
+{
+
+}
+
+
+wxFileName PROJECT_TEMPLATE::GetHtmlFile()
+{
+ return templateMetaHtmlFile;
+}
+
+
+wxBitmap* PROJECT_TEMPLATE::GetIcon()
+{
+ return metaIcon;
+}
+
+
+bool PROJECT_TEMPLATE::CreateProject( wxFileName& aNewProjectPath )
+{
+ // CreateProject copy the files from template to the new project folder
+ // and rename files which have the same name as the template .pro file
+ bool result = true;
+
+ std::vector<wxFileName> srcFiles = GetFileList();
+
+ // Find the template file name base. this is the name of the .pro templte file
+ wxString basename;
+ for( size_t i=0; i < srcFiles.size(); i++ )
+ {
+ if( srcFiles[i].GetExt() == wxT( "pro" ) )
+ {
+ basename = srcFiles[i].GetName();
+ break;
+ }
+ }
+
+ for( size_t i=0; i < srcFiles.size(); i++ )
+ {
+ // Replace the template path
+ wxFileName destination = srcFiles[i];
+
+ // Replace the template filename with the project filename for the new project creation
+ wxString currname = destination.GetName();
+ currname.Replace( basename, aNewProjectPath.GetName() );
+ destination.SetName( currname );
+
+ // Replace the template path with the project path for the new project creation
+ // but keep the sub directory name, if exists
+ wxString destpath = destination.GetPathWithSep();
+ destpath.Replace( templateBasePath.GetPathWithSep(), aNewProjectPath.GetPathWithSep() );
+
+ // Check to see if the path already exists, if not attempt to create it here. Don't worry
+ // about error checking, if the path isn't created the file copy will fail anyway
+
+ if( !wxFileName::DirExists( destpath ) )
+ wxFileName::Mkdir( destpath, 0777, wxPATH_MKDIR_FULL );
+
+ destination.SetPath( destpath );
+
+ wxString srcFile = srcFiles[i].GetFullPath();
+ wxString dstFile = destination.GetFullPath();
+
+ if( !wxCopyFile( srcFile, dstFile ) )
+ {
+ result = false;
+ break;
+ }
+ }
+
+ return result;
+}
+
+
+wxString* PROJECT_TEMPLATE::GetTitle(void)
+{
+ wxFileInputStream input( GetHtmlFile().GetFullPath() );
+ wxString separator( wxT( "\x9" ) );
+ wxTextInputStream text( input, separator, wxConvUTF8 );
+
+ /* Open HTML file and get the text between the title tags */
+ if( title == wxEmptyString )
+ {
+ int start = 0;
+ int finish = 0;
+ bool done = false;
+
+ while( input.IsOk() && !input.Eof() && !done )
+ {
+ wxString line = text.ReadLine();
+
+ start = line.Find( wxT( "<title>" ) );
+ if( start == wxNOT_FOUND )
+ start = line.Find( wxT( "<TITLE>" ) );
+
+ finish = line.Find( wxT( "</title>" ) );
+ if( finish == wxNOT_FOUND )
+ finish = line.Find( wxT( "</TITLE>" ) );
+
+ // find the opening tag
+ if( start != wxNOT_FOUND )
+ {
+ if( finish != wxNOT_FOUND )
+ {
+ title = line.SubString( start + 7, finish );
+ }
+ else
+ {
+ title = line.SubString( start + 7, line.Len() - 1 );
+ done = true;
+ }
+ }
+ else
+ {
+ if( finish != wxNOT_FOUND )
+ {
+ title += line.SubString( 0, finish );
+ done = true;
+ }
+ else
+ {
+ title += line;
+ }
+ }
+
+ // Remove line endings
+ title.Replace( wxT( "\r" ), wxT( "" ) );
+ title.Replace( wxT( "\n" ), wxT( "" ) );
+ }
+ }
+
+ return &title;
+}
diff --git a/kicad/project_template.h b/kicad/project_template.h
new file mode 100644
index 0000000..aaef83e
--- /dev/null
+++ b/kicad/project_template.h
@@ -0,0 +1,204 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 Brian Sidebotham <brian.sidebotham@gmail.com>
+ * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ @page prj_tmp Project Templates
+
+ Author: Brian Sidebotham
+
+ Proposal
+ --------
+
+ To add new project template functionality to KiCad to facilitate the easy setup of projects
+ which have common attributes such as pre-defined board outlines, connector positions,
+ schematic elements, design rules, etc.
+
+
+ Definitions
+ -----------
+
+ A template is a directory of files, which includes a directory of metadata. The template system
+ name (SYSNAME) is the directory name under which the template files are stored. The metadata
+ directory (METADIR) contains pre-defined files which provide information about the template.
+
+ All files and directories in a template are copied to the new project path when a project is
+ created using a template, except METADIR.
+
+ All files and directories which start with SYSNAME will have SYSNAME replaced by the new
+ project file name, excluding the file extension.
+
+
+ Metadata
+ --------
+
+ A template's METADIR must contain the required files, and might optionally contain any of the
+ optional files
+
+ Required Files
+ ~~~~~~~~~~~~~~
+
+ /info.html - Contains html formatted information about the template which is used by the
+ user to determine if the template is what they are after. The &lt;title&gt; tag
+ determines the actual name of the template that is exposed to the user for
+ template selection. Using html to format this document means that images can
+ be in-lined without having to invent a new scheme. Only HTML supported by
+ wxHTML can be used to format this document.
+
+ Optional Files
+ ~~~~~~~~~~~~~~
+
+ /icon.png - A 64 x 64px PNG icon file which is used as a clickable icon in the template
+ selection dialog.
+
+
+ Operation
+ ---------
+
+ The KiCad File menu will be modified to change New from a menu item to a pop-out menu item, in
+ the same manor as Open Recent. There will be two options on the pop-out menu:
+
+ Blank -> Will act exactly the same as the current new menu item so that anyone who wishes to
+ create a blank project won't have their settings lost or feel alienated.
+
+ From Template -> Will open the template selection dialog.
+
+ The template selection dialog will have a list of icons on the left, and a wxHTML window to the
+ right. A single click on a template's icon on the left will load that templates info.html
+ metadata file and display it in the wxHTML window.
+
+ A double click on a template's icon will start the new project creation and will open a new
+ file dialog. If the user selects a valid location for the new project, the template will be
+ copied to the new project location ( excluding METADIR as mentioned earlier ) and any files
+ that match the string replacement rules will be renamed to reflect the new project's name.
+
+ The list of available templates will be gathered from the following sources:
+
+ wxStandardPaths::GetExecutableDir()/../share/template/
+ wxStandardPaths::GetUserDataDir()/templates/
+ wxGetEnv(wxT("KICAD_PTEMPLATES"))
+ wxGetEnv(wxT("KICAD"))/template/
+
+*/
+
+#ifndef PROJECT_TEMPLATE_H
+#define PROJECT_TEMPLATE_H
+
+#include <vector>
+
+#include <wx/wx.h>
+#include <wx/image.h>
+#include <wx/filename.h>
+
+/**
+ * @brief A directory which contains information about the project template and does not get
+ * copied. This define is the default filename for this directory
+ *
+ */
+#define METADIR wxT("meta")
+
+
+/**
+ * @brief A required html formatted file which contains information about the project template.
+ * This define is the default filename for this file
+ *
+ */
+#define METAFILE_INFO_HTML wxT("info.html")
+
+
+/**
+ * @brief An optional png icon, exactly 64px x 64px which is used in the template selector if
+ * present. This define is the default filename for this file
+ *
+ */
+#define METAFILE_ICON wxT("icon.png")
+
+/**
+ * @brief A class which provides project template functionality.
+ *
+ *
+ *
+ */
+class PROJECT_TEMPLATE {
+private:
+protected:
+ wxFileName templateBasePath;
+ wxFileName templateMetaPath;
+ wxFileName templateMetaHtmlFile;
+ wxFileName templateMetaIconFile;
+ wxBitmap* metaIcon;
+ wxString title;
+
+public:
+
+ /**
+ * @brief Create a new project instance from \a aPath. \a aPath should be a directory that
+ * conforms to the project template requirements
+ *
+ * @param aPath Should be a directory containing the template
+ */
+ PROJECT_TEMPLATE( const wxString& aPath );
+
+ /**
+ * @brief Non-virtual destructor (so no dervied classes)
+ */
+ ~PROJECT_TEMPLATE();
+
+ /**
+ * @brief Get the dir name of the project template
+ * (i.e. the name of the last folder containing the template files)
+ * @return the dir name of the template
+ */
+ wxString GetPrjDirName();
+
+ /**
+ * @brief Get the full Html filename for the project template
+ * @return the html meta information file for this template
+ */
+ wxFileName GetHtmlFile();
+
+ /**
+ * @brief Copies and renames all template files to create a new project.
+ * @param aNewProjectPath The full path of the new project file to create
+ */
+ bool CreateProject( wxFileName& aNewProjectPath );
+
+ /**
+ * @brief Get the 64px^2 icon for the project template
+ * @return an image file of 64px x 64px which is the templates icon
+ */
+ wxBitmap* GetIcon();
+
+ /**
+ * @brief Get the title of the project (extracted from the html title tag)
+ */
+ wxString* GetTitle();
+
+ /**
+ * @brief Get a vector list of filenames for the template. The files are the source files,
+ * and have not yet been through any renaming
+ */
+ std::vector<wxFileName> GetFileList();
+};
+
+#endif
diff --git a/kicad/tree_project_frame.cpp b/kicad/tree_project_frame.cpp
new file mode 100644
index 0000000..88df16a
--- /dev/null
+++ b/kicad/tree_project_frame.cpp
@@ -0,0 +1,1093 @@
+/**
+ * @file tree_project_frame.cpp
+ * @brief Function to build the tree of files in the current project directory
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2016 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <fctsys.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <pgm_base.h>
+#include <macros.h>
+
+#include <tree_project_frame.h>
+#include <class_treeprojectfiles.h>
+#include <class_treeproject_item.h>
+#include <wildcards_and_files_ext.h>
+
+#include <wx/regex.h>
+#include <wx/dir.h>
+#include <wx/imaglist.h>
+#include <wx/stdpaths.h>
+#include <menus_helpers.h>
+#include <stack>
+
+
+/* Note about the tree project build process:
+ * Building the tree project can be *very* long if there are a lot of subdirectories
+ * in the working directory.
+ * Unfortunately, this happens easily if the project file *.pro is in the home directory
+ * So the tree project is built "on demand":
+ * First the tree is built from the current directory and shows files and subdirs.
+ * > First level subdirs trees are built (i.e subdirs contents are not read)
+ * > When expanding a subdir, each subdir contains is read,
+ * and the corresponding sub tree is populated on the fly.
+ */
+
+// list of files extensions listed in the tree project window
+// *.sch files are always allowed, do not add here
+// Add extensions in a compatible regex format to see others files types
+static const wxChar* s_allowedExtensionsToList[] =
+{
+ wxT( "^.*\\.pro$" ),
+ wxT( "^.*\\.pdf$" ),
+ wxT( "^[^$].*\\.brd$" ), // Legacy Pcbnew files
+ wxT( "^[^$].*\\.kicad_pcb$" ), // S format Pcbnew board files
+ wxT( "^[^$].*\\.kicad_wks$" ), // S format kicad page layout descr files
+ wxT( "^[^$].*\\.kicad_mod$" ), // S format kicad footprint files, currently not listed
+ wxT( "^.*\\.net$" ),
+ wxT( "^.*\\.lib$" ), // Schematic library file
+ wxT( "^.*\\.txt$" ),
+ wxT( "^.*\\.pho$" ), // Gerber file (Old Kicad extension)
+ wxT( "^.*\\.gbr$" ), // Gerber file
+ wxT( "^.*\\.gb[alops]$" ), // Gerber back (or bottom) layer file
+ wxT( "^.*\\.gt[alops]$" ), // Gerber front (or top) layer file
+ wxT( "^.*\\.g[0-9]{1,2}$" ), // Gerber inner layer file
+ wxT( "^.*\\.odt$" ),
+ wxT( "^.*\\.htm$" ),
+ wxT( "^.*\\.html$" ),
+ wxT( "^.*\\.rpt$" ), // Report files
+ wxT( "^.*\\.csv$" ), // Report files in comma separated format
+ wxT( "^.*\\.pos$" ), // Footprint position files
+ wxT( "^.*\\.cmp$" ), // Cvpcb cmp/footprint link files
+ wxT( "^.*\\.drl$" ), // Excellon drill files
+ wxT( "^.*\\.svg$" ), // SVG print/plot files
+ NULL // end of list
+};
+
+
+/* TODO: Check if these file extension and wildcard definitions are used
+ * in any of the other KiCad programs and move them into the common
+ * library as required.
+ */
+
+// File extension definitions.
+const wxChar TextFileExtension[] = wxT( "txt" );
+
+// File wildcard definitions.
+const wxChar TextFileWildcard[] = wxT( "Text files (*.txt)|*.txt" );
+
+
+/**
+ * @brief class TREE_PROJECT_FRAME is the frame that shows the tree list
+ * of files and subdirs inside the working directory
+ * Files are filtered (see s_allowedExtensionsToList) so
+ * only useful files are shown.
+ */
+
+
+BEGIN_EVENT_TABLE( TREE_PROJECT_FRAME, wxSashLayoutWindow )
+ EVT_TREE_ITEM_ACTIVATED( ID_PROJECT_TREE, TREE_PROJECT_FRAME::OnSelect )
+ EVT_TREE_ITEM_EXPANDED( ID_PROJECT_TREE, TREE_PROJECT_FRAME::OnExpand )
+ EVT_TREE_ITEM_RIGHT_CLICK( ID_PROJECT_TREE, TREE_PROJECT_FRAME::OnRight )
+ EVT_MENU( ID_PROJECT_TXTEDIT, TREE_PROJECT_FRAME::OnOpenSelectedFileWithTextEditor )
+ EVT_MENU( ID_PROJECT_NEWDIR, TREE_PROJECT_FRAME::OnCreateNewDirectory )
+ EVT_MENU( ID_PROJECT_DELETE, TREE_PROJECT_FRAME::OnDeleteFile )
+ EVT_MENU( ID_PROJECT_RENAME, TREE_PROJECT_FRAME::OnRenameFile )
+END_EVENT_TABLE()
+
+
+TREE_PROJECT_FRAME::TREE_PROJECT_FRAME( KICAD_MANAGER_FRAME* parent ) :
+ wxSashLayoutWindow( parent,
+ ID_LEFT_FRAME,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxNO_BORDER | wxSW_3D | wxTAB_TRAVERSAL )
+{
+ m_Parent = parent;
+ m_TreeProject = NULL;
+
+ m_watcher = NULL;
+ Connect( wxEVT_FSWATCHER,
+ wxFileSystemWatcherEventHandler( TREE_PROJECT_FRAME::OnFileSystemEvent ) );
+
+ /*
+ * Filtering is now inverted: the filters are actually used to _enable_ support
+ * for a given file type.
+ */
+
+ // NOTE: sch filter must be first because of a test in AddFile() below
+ m_filters.push_back( wxT( "^.*\\.sch$" ) );
+
+ for( int ii = 0; s_allowedExtensionsToList[ii] != NULL; ii++ )
+ m_filters.push_back( s_allowedExtensionsToList[ii] );
+
+ m_filters.push_back( wxT( "^no KiCad files found" ) );
+
+ ReCreateTreePrj();
+}
+
+
+TREE_PROJECT_FRAME::~TREE_PROJECT_FRAME()
+{
+ if( m_watcher )
+ {
+ m_watcher->RemoveAll();
+ m_watcher->SetOwner( NULL );
+ delete m_watcher;
+ }
+}
+
+
+void TREE_PROJECT_FRAME::RemoveFilter( const wxString& filter )
+{
+ for( unsigned int i = 0; i < m_filters.size(); i++ )
+ {
+ if( filter == m_filters[i] )
+ {
+ m_filters.erase( m_filters.begin() + i );
+ return;
+ }
+ }
+}
+
+
+void TREE_PROJECT_FRAME::OnCreateNewDirectory( wxCommandEvent& event )
+{
+ // Get the root directory name:
+ TREEPROJECT_ITEM* treeData = GetSelectedData();
+
+ if( !treeData )
+ return;
+
+ TreeFileType rootType = treeData->GetType();
+ wxTreeItemId root;
+
+ if( TREE_DIRECTORY == rootType )
+ {
+ root = m_TreeProject->GetSelection();
+ }
+ else
+ {
+ root = m_TreeProject->GetItemParent( m_TreeProject->GetSelection() );
+
+ if( !root.IsOk() )
+ root = m_TreeProject->GetSelection();
+ }
+
+ wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() );
+
+ // Ask for the new sub directory name
+ wxString curr_dir = treeData->GetDir();
+
+ if( !curr_dir.IsEmpty() ) // A subdir is selected
+ {
+ // Make this subdir name relative to the current path.
+ // It will be more easy to read by the user, in the next dialog
+ wxFileName fn;
+ fn.AssignDir( curr_dir );
+ fn.MakeRelativeTo( prj_dir );
+ curr_dir = fn.GetPath();
+
+ if( !curr_dir.IsEmpty() )
+ curr_dir += wxFileName::GetPathSeparator();
+ }
+
+ wxString msg = wxString::Format( _( "Current project directory:\n%s" ), GetChars( prj_dir ) );
+ wxString subdir = wxGetTextFromUser( msg, _( "Create New Directory" ), curr_dir );
+
+ if( subdir.IsEmpty() )
+ return;
+
+ wxString full_dirname = prj_dir + wxFileName::GetPathSeparator() + subdir;
+
+ if( wxMkdir( full_dirname ) )
+ {
+ // the new itel will be added by the file watcher
+ // AddItemToTreeProject( subdir, root );
+ }
+}
+
+
+wxString TREE_PROJECT_FRAME::GetFileExt( TreeFileType type )
+{
+ wxString ext;
+
+ switch( type )
+ {
+ case TREE_PROJECT:
+ ext = ProjectFileExtension;
+ break;
+
+ case TREE_SCHEMA:
+ ext = SchematicFileExtension;
+ break;
+
+ case TREE_LEGACY_PCB:
+ ext = LegacyPcbFileExtension;
+ break;
+
+ case TREE_SEXP_PCB:
+ ext = KiCadPcbFileExtension;
+ break;
+
+ case TREE_GERBER:
+ ext = GerberFileExtension;
+ break;
+
+ case TREE_HTML:
+ ext = HtmlFileExtension;
+ break;
+
+ case TREE_PDF:
+ ext = PdfFileExtension;
+ break;
+
+ case TREE_TXT:
+ ext = TextFileExtension;
+ break;
+
+ case TREE_NET:
+ ext = NetlistFileExtension;
+ break;
+
+ case TREE_CMP_LINK:
+ ext = ComponentFileExtension;
+ break;
+
+ case TREE_REPORT:
+ ext = ReportFileExtension;
+ break;
+
+ case TREE_FP_PLACE:
+ ext = FootprintPlaceFileExtension;
+ break;
+
+ case TREE_DRILL:
+ ext = DrillFileExtension;
+ break;
+
+ case TREE_SVG:
+ ext = SVGFileExtension;
+ break;
+
+ case TREE_PAGE_LAYOUT_DESCR:
+ ext = PageLayoutDescrFileExtension;
+ break;
+
+ case TREE_FOOTPRINT_FILE:
+ ext = KiCadFootprintFileExtension;
+ break;
+
+ case TREE_SCHEMATIC_LIBFILE:
+ ext = SchematicLibraryFileExtension;
+ break;
+
+ default: // Eliminates unnecessary GCC warning.
+ break;
+ }
+
+ return ext;
+}
+
+
+/*
+ * Return the wxFileDialog wildcard string for the selected file type.
+ */
+wxString TREE_PROJECT_FRAME::GetFileWildcard( TreeFileType type )
+{
+ wxString ext;
+
+ switch( type )
+ {
+ case TREE_PROJECT:
+ ext = ProjectFileWildcard;
+ break;
+
+ case TREE_SCHEMA:
+ ext = SchematicFileWildcard;
+ break;
+
+ case TREE_LEGACY_PCB:
+ case TREE_SEXP_PCB:
+ ext = PcbFileWildcard;
+ break;
+
+ case TREE_GERBER:
+ ext = GerberFileWildcard;
+ break;
+
+ case TREE_HTML:
+ ext = HtmlFileWildcard;
+ break;
+
+ case TREE_PDF:
+ ext = PdfFileWildcard;
+ break;
+
+ case TREE_TXT:
+ ext = TextFileWildcard;
+ break;
+
+ case TREE_NET:
+ ext = NetlistFileWildcard;
+ break;
+
+ case TREE_CMP_LINK:
+ ext = ComponentFileWildcard;
+ break;
+
+ case TREE_REPORT:
+ ext = ReportFileWildcard;
+ break;
+
+ case TREE_FP_PLACE:
+ ext = FootprintPlaceFileWildcard;
+ break;
+
+ case TREE_DRILL:
+ ext = DrillFileWildcard;
+ break;
+
+ case TREE_SVG:
+ ext = SVGFileWildcard;
+ break;
+
+ case TREE_PAGE_LAYOUT_DESCR:
+ ext = PageLayoutDescrFileWildcard;
+ break;
+
+ case TREE_FOOTPRINT_FILE:
+ ext = KiCadFootprintLibFileWildcard;
+ break;
+
+ case TREE_SCHEMATIC_LIBFILE:
+ ext = SchematicLibraryFileWildcard;
+ break;
+
+ default: // Eliminates unnecessary GCC warning.
+ break;
+ }
+
+ return ext;
+}
+
+
+bool TREE_PROJECT_FRAME::AddItemToTreeProject( const wxString& aName,
+ wxTreeItemId& aRoot, bool aRecurse )
+{
+ wxTreeItemId cellule;
+
+ // Check the file type
+ TreeFileType type = TREE_UNKNOWN;
+
+ // Skip not visible files and dirs
+ wxFileName fn( aName );
+
+ // Files/dirs names starting by "." are not visible files under unices.
+ // Skip them also under Windows
+ if( fn.GetName().StartsWith( wxT( "." ) ) )
+ return false;
+
+ if( wxDirExists( aName ) )
+ {
+ type = TREE_DIRECTORY;
+ }
+ else
+ {
+ // Filter
+ wxRegEx reg;
+
+ bool isSchematic = false;
+ bool addFile = false;
+
+ for( unsigned i = 0; i < m_filters.size(); i++ )
+ {
+ wxCHECK2_MSG( reg.Compile( m_filters[i], wxRE_ICASE ), continue,
+ wxT( "Regular expression " ) + m_filters[i] +
+ wxT( " failed to compile." ) );
+
+ if( reg.Matches( aName ) )
+ {
+ addFile = true;
+
+ if( i==0 )
+ isSchematic = true;
+
+ break;
+ }
+ }
+
+ if( !addFile )
+ return false;
+
+ // only show the schematic if it is a top level schematic. Eeschema
+ // cannot open a schematic and display it properly unless it starts
+ // at the top of the hierarchy. The schematic is top level only if
+ // there is a line in the header saying:
+ // "Sheet 1 "
+ // However if the file has the same name as the project, it is always
+ // shown, because it is expected the root sheet.
+ // (and to fix an issue (under XP but could exist under other OS),
+ // when a .sch file is created, the file
+ // create is sent to the wxFileSystemWatcher, but the file still has 0 byte
+ // so it cannot detected as root sheet
+ // This is an ugly fix.
+ if( isSchematic )
+ {
+ wxString fullFileName = aName.BeforeLast( '.' );
+ wxString rootName;
+ TREEPROJECT_ITEM* itemData = GetItemIdData( m_root );
+ if( itemData )
+ rootName = itemData->GetFileName().BeforeLast( '.' );
+
+ if( fullFileName != rootName )
+ {
+ char line[128]; // small because we just need a few bytes from the start of a line
+ FILE* fp;
+
+ fullFileName = aName;
+ fp = wxFopen( fullFileName, wxT( "rt" ) );
+
+ if( fp == NULL )
+ return false;
+
+ addFile = false;
+
+ // check the first 100 lines for the "Sheet 1" string
+ for( int i = 0; i<100; ++i )
+ {
+ if( !fgets( line, sizeof(line), fp ) )
+ break;
+
+ if( !strncmp( line, "Sheet 1 ", 8 ) )
+ {
+ addFile = true;
+ break;
+ }
+ }
+
+ fclose( fp );
+
+ if( !addFile )
+ return false; // it is a non-top-level schematic
+ }
+ }
+
+ for( int i = TREE_PROJECT; i < TREE_MAX; i++ )
+ {
+ wxString ext = GetFileExt( (TreeFileType) i );
+
+ if( ext == wxT( "" ) )
+ continue;
+
+ reg.Compile( wxString::FromAscii( "^.*\\" ) + ext +
+ wxString::FromAscii( "$" ), wxRE_ICASE );
+
+ if( reg.Matches( aName ) )
+ {
+ type = (TreeFileType) i;
+ break;
+ }
+ }
+ }
+
+ // also check to see if it is already there.
+ wxTreeItemIdValue cookie;
+ wxTreeItemId kid = m_TreeProject->GetFirstChild( aRoot, cookie );
+
+ while( kid.IsOk() )
+ {
+ TREEPROJECT_ITEM* itemData = GetItemIdData( kid );
+
+ if( itemData )
+ {
+ if( itemData->GetFileName() == aName )
+ {
+ return true; // well, we would have added it, but it is already here!
+ }
+ }
+
+ kid = m_TreeProject->GetNextChild( aRoot, cookie );
+ }
+
+ // Append the item (only appending the filename not the full path):
+ wxString file = wxFileNameFromPath( aName );
+ cellule = m_TreeProject->AppendItem( aRoot, file );
+ TREEPROJECT_ITEM* data = new TREEPROJECT_ITEM( type, aName, m_TreeProject );
+
+ m_TreeProject->SetItemData( cellule, data );
+ data->SetState( 0 );
+
+ // Mark root files (files which have the same aName as the project)
+ wxFileName project( m_Parent->GetProjectFileName() );
+ wxFileName currfile( file );
+
+ if( currfile.GetName().CmpNoCase( project.GetName() ) == 0 )
+ data->SetRootFile( true );
+ else
+ data->SetRootFile( false );
+
+ // This section adds dirs and files found in the subdirs
+ // in this case AddFile is recursive, but for the first level only.
+ if( TREE_DIRECTORY == type && aRecurse )
+ {
+ wxDir dir( aName );
+
+ if( dir.IsOpened() ) // protected dirs will not open properly.
+ {
+ wxString dir_filename;
+
+ data->SetPopulated( true );
+
+ if( dir.GetFirst( &dir_filename ) )
+ {
+ do // Add name in tree, but do not recurse
+ {
+ wxString path = aName + wxFileName::GetPathSeparator() + dir_filename;
+ AddItemToTreeProject( path, cellule, false );
+ } while( dir.GetNext( &dir_filename ) );
+ }
+ }
+
+ // Sort filenames by alphabetic order
+ m_TreeProject->SortChildren( cellule );
+ }
+
+ return true;
+}
+
+
+void TREE_PROJECT_FRAME::ReCreateTreePrj()
+{
+ wxTreeItemId rootcellule;
+ bool prjOpened = false;
+ wxString pro_dir = m_Parent->GetProjectFileName();
+
+ if( !m_TreeProject )
+ m_TreeProject = new TREEPROJECTFILES( this );
+ else
+ m_TreeProject->DeleteAllItems();
+
+ if( !pro_dir ) // This is empty from TREE_PROJECT_FRAME constructor
+ return;
+
+ wxFileName fn = pro_dir;
+
+ if( !fn.IsOk() )
+ {
+ fn.Clear();
+ fn.SetPath( wxStandardPaths::Get().GetDocumentsDir() );
+ fn.SetName( NAMELESS_PROJECT );
+ fn.SetExt( ProjectFileExtension );
+ }
+
+ prjOpened = fn.FileExists();
+
+ // root tree:
+ m_root = rootcellule = m_TreeProject->AddRoot( fn.GetFullName(),
+ TREE_PROJECT - 1,
+ TREE_PROJECT - 1 );
+
+ m_TreeProject->SetItemBold( rootcellule, true );
+
+ m_TreeProject->SetItemData( rootcellule,
+ new TREEPROJECT_ITEM( TREE_PROJECT,
+ fn.GetFullPath(),
+ m_TreeProject ) );
+
+ // Now adding all current files if available
+ if( prjOpened )
+ {
+ wxString pro_dir = wxPathOnly( m_Parent->GetProjectFileName() );
+ wxDir dir( pro_dir );
+
+ if( dir.IsOpened() ) // protected dirs will not open, see "man opendir()"
+ {
+ wxString filename;
+ bool cont = dir.GetFirst( &filename );
+
+ while( cont )
+ {
+ if( filename != fn.GetFullName() )
+ {
+ wxString name = dir.GetName() + wxFileName::GetPathSeparator() + filename;
+ AddItemToTreeProject( name, m_root );
+ }
+
+ cont = dir.GetNext( &filename );
+ }
+ }
+ }
+ else
+ {
+ m_TreeProject->AppendItem( m_root, wxT( "Empty project" ) );
+ }
+
+ m_TreeProject->Expand( rootcellule );
+
+ // Sort filenames by alphabetic order
+ m_TreeProject->SortChildren( m_root );
+}
+
+
+void TREE_PROJECT_FRAME::OnRight( wxTreeEvent& Event )
+{
+ int tree_id;
+ TREEPROJECT_ITEM* tree_data;
+ wxString fullFileName;
+ wxTreeItemId curr_item = Event.GetItem();
+
+ // Ensure item is selected (Under Windows right click does not select the item)
+ m_TreeProject->SelectItem( curr_item );
+
+ tree_data = GetSelectedData();
+
+ if( !tree_data )
+ return;
+
+ tree_id = tree_data->GetType();
+ fullFileName = tree_data->GetFileName();
+
+ wxMenu popupMenu;
+
+ switch( tree_id )
+ {
+ case TREE_PROJECT:
+ AddMenuItem( &popupMenu, ID_PROJECT_NEWDIR,
+ _( "New D&irectory" ),
+ _( "Create a New Directory" ),
+ KiBitmap( directory_xpm ) );
+ break;
+
+ case TREE_DIRECTORY:
+ AddMenuItem( &popupMenu, ID_PROJECT_NEWDIR,
+ _( "New D&irectory" ),
+ _( "Create a New Directory" ),
+ KiBitmap( directory_xpm ) );
+ AddMenuItem( &popupMenu, ID_PROJECT_DELETE,
+ _( "&Delete Directory" ),
+ _( "Delete the Directory and its content" ),
+ KiBitmap( delete_xpm ) );
+ break;
+
+ default:
+ AddMenuItem( &popupMenu, ID_PROJECT_TXTEDIT,
+ _( "&Edit in a text editor" ),
+ _( "Open the file in a Text Editor" ),
+ KiBitmap( icon_txt_xpm ) );
+ AddMenuItem( &popupMenu, ID_PROJECT_RENAME,
+ _( "&Rename file" ),
+ _( "Rename file" ),
+ KiBitmap( right_xpm ) );
+ AddMenuItem( &popupMenu, ID_PROJECT_DELETE,
+ _( "&Delete File" ),
+ _( "Delete the Directory and its content" ),
+ KiBitmap( delete_xpm ) );
+ break;
+ }
+
+ PopupMenu( &popupMenu );
+}
+
+
+void TREE_PROJECT_FRAME::OnOpenSelectedFileWithTextEditor( wxCommandEvent& event )
+{
+ TREEPROJECT_ITEM* tree_data = GetSelectedData();
+
+ if( !tree_data )
+ return;
+
+ if( tree_data->GetType() == TREE_DIRECTORY )
+ return;
+
+ wxString fullFileName = tree_data->GetFileName();
+ AddDelimiterString( fullFileName );
+ wxString editorname = Pgm().GetEditorName();
+
+ if( !editorname.IsEmpty() )
+ ExecuteFile( this, editorname, fullFileName );
+}
+
+
+void TREE_PROJECT_FRAME::OnDeleteFile( wxCommandEvent& )
+{
+ TREEPROJECT_ITEM* tree_data = GetSelectedData();
+
+ if( !tree_data )
+ return;
+
+ tree_data->Delete();
+}
+
+
+void TREE_PROJECT_FRAME::OnRenameFile( wxCommandEvent& )
+{
+ wxTreeItemId curr_item = m_TreeProject->GetSelection();
+ TREEPROJECT_ITEM* tree_data = GetSelectedData();
+
+ if( !tree_data )
+ return;
+
+ wxString buffer = m_TreeProject->GetItemText( curr_item );
+ wxString msg = wxString::Format(
+ _( "Change filename: '%s'" ),
+ GetChars( tree_data->GetFileName() ) );
+
+ wxTextEntryDialog dlg( this, msg, _( "Change filename" ), buffer );
+
+ if( dlg.ShowModal() != wxID_OK )
+ return; // canceled by user
+
+ buffer = dlg.GetValue();
+ buffer.Trim( true );
+ buffer.Trim( false );
+
+ if( buffer.IsEmpty() )
+ return; // empty file name not allowed
+
+ if( tree_data->Rename( buffer, true ) )
+ m_TreeProject->SetItemText( curr_item, buffer );
+}
+
+
+void TREE_PROJECT_FRAME::OnSelect( wxTreeEvent& Event )
+{
+ TREEPROJECT_ITEM* tree_data = GetSelectedData();
+
+ if( !tree_data )
+ return;
+
+ tree_data->Activate( this );
+}
+
+
+void TREE_PROJECT_FRAME::OnExpand( wxTreeEvent& Event )
+{
+ wxTreeItemId itemId = Event.GetItem();
+ TREEPROJECT_ITEM* tree_data = GetItemIdData( itemId );
+
+ if( !tree_data )
+ return;
+
+ if( tree_data->GetType() != TREE_DIRECTORY )
+ return;
+
+ // explore list of non populated subdirs, and populate them
+ wxTreeItemIdValue cookie;
+ wxTreeItemId kid = m_TreeProject->GetFirstChild( itemId, cookie );
+
+ bool subdir_populated = false;
+
+ for( ; kid.IsOk(); kid = m_TreeProject->GetNextChild( itemId, cookie ) )
+ {
+ TREEPROJECT_ITEM* itemData = GetItemIdData( kid );
+
+ if( !itemData || itemData->GetType() != TREE_DIRECTORY )
+ continue;
+
+ if( itemData->IsPopulated() )
+ continue;
+
+ wxString fileName = itemData->GetFileName();
+ wxDir dir( fileName );
+
+ if( dir.IsOpened() )
+ {
+ wxString dir_filename;
+
+ if( dir.GetFirst( &dir_filename ) )
+ {
+ do // Add name to tree item, but do not recurse in subdirs:
+ {
+ wxString name = fileName + wxFileName::GetPathSeparator() + dir_filename;
+ AddItemToTreeProject( name, kid, false );
+ } while( dir.GetNext( &dir_filename ) );
+ }
+
+ itemData->SetPopulated( true ); // set state to populated
+ subdir_populated = true;
+ }
+
+ // Sort filenames by alphabetic order
+ m_TreeProject->SortChildren( kid );
+ }
+
+ if( subdir_populated )
+ {
+ #ifndef __WINDOWS__
+ FileWatcherReset();
+ #endif
+ }
+}
+
+
+TREEPROJECT_ITEM* TREE_PROJECT_FRAME::GetSelectedData()
+{
+ return dynamic_cast<TREEPROJECT_ITEM*>( m_TreeProject->GetItemData
+ ( m_TreeProject->GetSelection() ) );
+}
+
+
+TREEPROJECT_ITEM* TREE_PROJECT_FRAME::GetItemIdData( wxTreeItemId aId )
+{
+ return dynamic_cast<TREEPROJECT_ITEM*>( m_TreeProject->GetItemData( aId ) );
+}
+
+
+wxTreeItemId TREE_PROJECT_FRAME::findSubdirTreeItem( const wxString& aSubDir )
+{
+ wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() );
+
+ // If the subdir is the current working directory, return m_root
+ // in main list:
+ if( prj_dir == aSubDir )
+ return m_root;
+
+ // The subdir is in the main tree or in a subdir: Locate it
+ wxTreeItemIdValue cookie;
+ wxTreeItemId root_id = m_root;
+ std::stack < wxTreeItemId > subdirs_id;
+
+ wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie );
+
+ while( 1 )
+ {
+ if( ! kid.IsOk() )
+ {
+ if( subdirs_id.empty() ) // all items were explored
+ {
+ root_id = kid; // Not found: return an invalid wxTreeItemId
+ break;
+ }
+ else
+ {
+ root_id = subdirs_id.top();
+ subdirs_id.pop();
+ kid = m_TreeProject->GetFirstChild( root_id, cookie );
+
+ if( ! kid.IsOk() )
+ continue;
+ }
+ }
+
+ TREEPROJECT_ITEM* itemData = GetItemIdData( kid );
+
+ if( itemData && ( itemData->GetType() == TREE_DIRECTORY ) )
+ {
+ if( itemData->GetFileName() == aSubDir ) // Found!
+ {
+ root_id = kid;
+ break;
+ }
+
+ // kid is a subdir, push in list to explore it later
+ if( itemData->IsPopulated() )
+ subdirs_id.push( kid );
+ }
+
+ kid = m_TreeProject->GetNextChild( root_id, cookie );
+ }
+
+ return root_id;
+}
+
+
+void TREE_PROJECT_FRAME::OnFileSystemEvent( wxFileSystemWatcherEvent& event )
+{
+ wxFileName pathModified = event.GetPath();
+ wxString subdir = pathModified.GetPath();
+ wxString fn = pathModified.GetFullPath();
+
+ switch( event.GetChangeType() )
+ {
+ case wxFSW_EVENT_DELETE:
+ break;
+
+ case wxFSW_EVENT_CREATE:
+ break;
+
+ case wxFSW_EVENT_RENAME:
+ break;
+
+ case wxFSW_EVENT_MODIFY:
+ case wxFSW_EVENT_ACCESS:
+ default:
+ return;
+ }
+
+ wxTreeItemId root_id = findSubdirTreeItem( subdir );
+
+ if( !root_id.IsOk() )
+ return;
+
+ wxTreeItemIdValue cookie; // dummy variable needed by GetFirstChild()
+ wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie );
+
+ switch( event.GetChangeType() )
+ {
+ case wxFSW_EVENT_CREATE:
+ AddItemToTreeProject( pathModified.GetFullPath(), root_id, false );
+ break;
+
+ case wxFSW_EVENT_DELETE:
+ while( kid.IsOk() )
+ {
+ TREEPROJECT_ITEM* itemData = GetItemIdData( kid );
+
+ if( itemData && itemData->GetFileName() == fn )
+ {
+ m_TreeProject->Delete( kid );
+ return;
+ }
+ kid = m_TreeProject->GetNextChild( root_id, cookie );
+ }
+ break;
+
+ case wxFSW_EVENT_RENAME :
+ {
+ wxFileName newpath = event.GetNewPath();
+ wxString newfn = newpath.GetFullPath();
+
+ while( kid.IsOk() )
+ {
+ TREEPROJECT_ITEM* itemData = GetItemIdData( kid );
+
+ if( itemData && itemData->GetFileName() == fn )
+ {
+ m_TreeProject->Delete( kid );
+ break;
+ }
+
+ kid = m_TreeProject->GetNextChild( root_id, cookie );
+ }
+
+ AddItemToTreeProject( newfn, root_id, false );
+ }
+ break;
+ }
+
+ // Sort filenames by alphabetic order
+ m_TreeProject->SortChildren( root_id );
+}
+
+
+void TREE_PROJECT_FRAME::FileWatcherReset()
+{
+ // Prepare file watcher:
+ if( m_watcher )
+ {
+ m_watcher->RemoveAll();
+ }
+ else
+ {
+ m_watcher = new wxFileSystemWatcher();
+ m_watcher->SetOwner( this );
+ }
+
+ // Add directories which should be monitored.
+ // under windows, we add the curr dir and all subdirs
+ // under unix, we add only the curr dir and the populated subdirs
+ // see http://docs.wxwidgets.org/trunk/classwx_file_system_watcher.htm
+ // under unix, the file watcher needs more work to be efficient
+ // moreover, under wxWidgets 2.9.4, AddTree does not work properly.
+
+ // We can see wxString under a debugger, not a wxFileName
+ wxString prj_dir = wxPathOnly( m_Parent->GetProjectFileName() );
+ wxFileName fn;
+ fn.AssignDir( prj_dir );
+ fn.DontFollowLink();
+
+#ifdef __WINDOWS__
+ m_watcher->AddTree( fn );
+#else
+ m_watcher->Add( fn );
+
+ // Add subdirs
+ wxTreeItemIdValue cookie;
+ wxTreeItemId root_id = m_root;
+
+ std::stack < wxTreeItemId > subdirs_id;
+
+ wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie );
+
+ while( 1 )
+ {
+ if( !kid.IsOk() )
+ {
+ if( subdirs_id.empty() ) // all items were explored
+ break;
+ else
+ {
+ root_id = subdirs_id.top();
+ subdirs_id.pop();
+ kid = m_TreeProject->GetFirstChild( root_id, cookie );
+
+ if( !kid.IsOk() )
+ continue;
+ }
+ }
+
+ TREEPROJECT_ITEM* itemData = GetItemIdData( kid );
+
+ if( itemData && itemData->GetType() == TREE_DIRECTORY )
+ {
+ // we can see wxString under a debugger, not a wxFileName
+ wxString path = itemData->GetFileName();
+
+ wxLogDebug( "%s: add '%s'\n", __func__, TO_UTF8( path ) );
+
+ if( wxFileName::IsDirReadable( path ) ) // linux whines about watching protected dir
+ {
+ fn.AssignDir( path );
+ m_watcher->Add( fn );
+
+ // if kid is a subdir, push in list to explore it later
+ if( itemData->IsPopulated() && m_TreeProject->GetChildrenCount( kid ) )
+ subdirs_id.push( kid );
+ }
+ }
+
+ kid = m_TreeProject->GetNextChild( root_id, cookie );
+ }
+#endif
+
+#if defined(DEBUG) && 1
+ wxArrayString paths;
+ m_watcher->GetWatchedPaths( &paths );
+ wxLogDebug( "%s: watched paths:", __func__ );
+
+ for( unsigned ii = 0; ii < paths.GetCount(); ii++ )
+ wxLogDebug( " %s\n", TO_UTF8( paths[ii] ) );
+#endif
+}
+
+
+void KICAD_MANAGER_FRAME::OnChangeWatchedPaths( wxCommandEvent& aEvent )
+{
+ m_LeftWin->FileWatcherReset();
+}
diff --git a/kicad/tree_project_frame.h b/kicad/tree_project_frame.h
new file mode 100644
index 0000000..908e8a3
--- /dev/null
+++ b/kicad/tree_project_frame.h
@@ -0,0 +1,184 @@
+/**
+ * @file tree_project_frame.h
+ */
+
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef TREEPRJ_FRAME_H
+#define TREEPRJ_FRAME_H
+
+#include <kicad.h>
+#include <wx/fswatcher.h>
+
+
+class TREEPROJECT_ITEM;
+
+/** class TREE_PROJECT_FRAME
+ * Window to display the tree files
+ */
+class TREE_PROJECT_FRAME : public wxSashLayoutWindow
+{
+ friend class TREEPROJECT_ITEM;
+public:
+ KICAD_MANAGER_FRAME* m_Parent;
+ TREEPROJECTFILES* m_TreeProject;
+
+private:
+ wxTreeItemId m_root;
+ std::vector<wxString> m_filters;
+ wxFileSystemWatcher* m_watcher; // file system watcher (since wxWidgets 2.9.2)
+
+public:
+ TREE_PROJECT_FRAME( KICAD_MANAGER_FRAME* parent );
+ ~TREE_PROJECT_FRAME();
+
+ /**
+ * Create or modify the tree showing project file names
+ */
+ void ReCreateTreePrj();
+
+ /**
+ * Reinit the watched paths
+ * Should be called after opening a new project to
+ * rebuild the list of watched paths.
+ * Should be called *atfer* the main loop event handler is started
+ */
+ void FileWatcherReset();
+
+protected:
+ static wxString GetFileExt( TreeFileType type );
+ static wxString GetFileWildcard( TreeFileType type );
+
+ /**
+ * Function GetSelectedData
+ * return the item data from item currently selected (highlighted)
+ * Note this is not necessary the "clicked" item,
+ * because when expanding, collapsing an item this item is not selected
+ */
+ TREEPROJECT_ITEM* GetSelectedData();
+
+ /**
+ * Function GetItemIdData
+ * return the item data corresponding to a wxTreeItemId identifier
+ * @param aId = the wxTreeItemId identifier.
+ * @return a TREEPROJECT_ITEM pointer correspondinfg to item id aId
+ */
+ TREEPROJECT_ITEM* GetItemIdData( wxTreeItemId aId );
+
+private:
+ /**
+ * Called on a double click on an item
+ */
+ void OnSelect( wxTreeEvent& Event );
+
+ /**
+ * Called on a click on the + or - button of an item with children
+ */
+ void OnExpand( wxTreeEvent& Event );
+
+ /**
+ * Called on a right click on an item
+ */
+ void OnRight( wxTreeEvent& Event );
+
+ /**
+ * Function OnOpenSelectedFileWithTextEditor
+ * Called via the popup menu, when right clicking on a file name
+ * Call the text editor to open the selected file
+ * in the tree project
+ */
+ void OnOpenSelectedFileWithTextEditor( wxCommandEvent& event );
+
+ /**
+ * Function OnDeleteFile
+ * Called via the popup menu, when right clicking on a file name
+ * or a directory name to delete the selected file or directory
+ * in the tree project
+ */
+ void OnDeleteFile( wxCommandEvent& event );
+
+ /**
+ * Function OnRenameFile
+ * Called via the popup menu, when right clicking on a file name
+ * or a directory name to rename the selected file or directory
+ * in the tree project
+ */
+ void OnRenameFile( wxCommandEvent& event );
+
+ /**
+ * Function OnCreateNewDirectory
+ * Creates a new subdirectory inside the current kicad project directory
+ * the user is prompted to enter a directory name
+ */
+ void OnCreateNewDirectory( wxCommandEvent& event );
+
+ void ClearFilters()
+ {
+ m_filters.clear();
+ }
+
+ const std::vector<wxString>& GetFilters()
+ {
+ return m_filters;
+ }
+
+ void RemoveFilter( const wxString& filter );
+
+ /**
+ * Function AddItemToTreeProject
+ * @brief Add the file or directory aName to the project tree
+ * @param aName = the filename or the directory name to add in tree
+ * @param aRoot = the wxTreeItemId item where to add sub tree items
+ * @param aRecurse = true to add file or subdir names to the current tree item
+ * false to stop file add.
+ * @return true if the file (or directory) is added.
+ */
+ bool AddItemToTreeProject( const wxString& aName,
+ wxTreeItemId& aRoot,
+ bool aRecurse = true );
+
+ /**
+ * Function findSubdirTreeItem
+ * searches for the item in tree project which is the
+ * node of the subdirectory aSubDir
+ * @param aSubDir = the directory to find in tree
+ * @return the opaque reference to the tree item.
+ * if not found, return an invalid tree item.
+ * therefore wxTreeItemId::IsOk should be used to test
+ * the returned value
+ */
+ wxTreeItemId findSubdirTreeItem( const wxString& aSubDir );
+
+ /**
+ * called when a file or directory is modified/created/deleted
+ * The tree project is modified when a file or directory
+ * is created/deleted/renamed to reflect the file change
+ */
+ void OnFileSystemEvent( wxFileSystemWatcherEvent& event );
+
+ DECLARE_EVENT_TABLE()
+};
+
+#endif // TREEPRJ_FRAME_H