diff --git a/gerbview/files.cpp b/gerbview/files.cpp
index 4fc9bd206a..45513a71ba 100644
--- a/gerbview/files.cpp
+++ b/gerbview/files.cpp
@@ -39,19 +39,19 @@ void WinEDA_GerberFrame::Files_io( wxCommandEvent& event )
switch( id )
{
case wxID_FILE:
- {
Erase_Current_Layer( false );
LoadGerberFiles( wxEmptyString );
break;
- }
case ID_MENU_INC_LAYER_AND_APPEND_FILE:
case ID_INC_LAYER_AND_APPEND_FILE:
{
- int origLayer = getActiveLayer();
- if( origLayer < NB_LAYERS )
+ int origLayer = getNextAvailableLayer();
+
+ if( origLayer != NO_AVAILABLE_LAYERS )
{
- setActiveLayer(origLayer+1);
+ setActiveLayer( origLayer );
+
Erase_Current_Layer( false );
if( !LoadGerberFiles( wxEmptyString ) )
@@ -61,7 +61,7 @@ void WinEDA_GerberFrame::Files_io( wxCommandEvent& event )
{
wxString msg;
msg.Printf( _( "GerbView only supports a maximum of %d layers. You must first \
-delete an existing layer to load any new layers." ), NB_LAYERS );
+clear an existing layer to load any new layers." ), NB_LAYERS );
wxMessageBox( msg );
}
}
@@ -96,7 +96,7 @@ bool WinEDA_GerberFrame::LoadGerberFiles( const wxString& aFullFileName )
wxFileName filename = aFullFileName;
wxString currentPath;
- if( ! filename.IsOk() )
+ if( !filename.IsOk() )
{
/* Standard gerber filetypes
* (See http://en.wikipedia.org/wiki/Gerber_File)
@@ -144,7 +144,7 @@ bool WinEDA_GerberFrame::LoadGerberFiles( const wxString& aFullFileName )
if( dlg.ShowModal() == wxID_CANCEL )
return false;
- dlg.GetFilenames( filenamesList );
+ dlg.GetPaths( filenamesList );
currentPath = wxGetCwd();
}
else
@@ -160,18 +160,32 @@ bool WinEDA_GerberFrame::LoadGerberFiles( const wxString& aFullFileName )
for( unsigned ii = 0; ii < filenamesList.GetCount(); ii++ )
{
wxFileName filename = filenamesList[ii];
- filename.SetPath( currentPath );
+
+ if( !filename.IsAbsolute() )
+ filename.SetPath( currentPath );
+
+ if( !filename.HasExt() )
+ filename.SetExt( g_PenFilenameExt );
+
GetScreen()->SetFileName( filename.GetFullPath() );
- filename.SetExt( g_PenFilenameExt );
setActiveLayer( layer, false );
- if( Read_GERBER_File( GetScreen()->GetFileName(), filename.GetFullPath() ) )
+ if( Read_GERBER_File( filename.GetFullPath(), filename.GetFullPath() ) )
{
SetLastProject( GetScreen()->GetFileName() );
- layer++;
- if( layer >= NB_LAYERS )
- layer = 0;
+
+ layer = getNextAvailableLayer( layer );
+
+ if( layer == NO_AVAILABLE_LAYERS )
+ {
+ wxString msg = wxT( "No more empty layers are available. The remaining gerber " );
+ msg += wxT( "files will not be loaded." );
+ wxMessageBox( msg );
+ break;
+ }
+
+ setActiveLayer( layer, false );
}
}
@@ -179,7 +193,7 @@ bool WinEDA_GerberFrame::LoadGerberFiles( const wxString& aFullFileName )
g_SaveTime = time( NULL );
// Synchronize layers tools with actual active layer:
- setActiveLayer(getActiveLayer());
+ setActiveLayer( getActiveLayer() );
syncLayerBox();
return true;
diff --git a/gerbview/gerberframe.cpp b/gerbview/gerberframe.cpp
index eefe5a53be..d763c211c8 100644
--- a/gerbview/gerberframe.cpp
+++ b/gerbview/gerberframe.cpp
@@ -404,6 +404,27 @@ void WinEDA_GerberFrame::SetElementVisibility( int aGERBER_VISIBLE, bool aNewSta
}
+int WinEDA_GerberFrame::getNextAvailableLayer( int aLayer ) const
+{
+ int layer = aLayer;
+
+ for( int i = 0; i < NB_LAYERS; i++ )
+ {
+ GERBER_IMAGE* gerber = g_GERBER_List[ layer ];
+
+ if( gerber == NULL || gerber->m_FileName.IsEmpty() )
+ return layer;
+
+ layer++;
+
+ if( layer >= NB_LAYERS )
+ layer = 0;
+ }
+
+ return NO_AVAILABLE_LAYERS;
+}
+
+
void WinEDA_GerberFrame::syncLayerWidget()
{
m_LayersManager->SelectLayer( getActiveLayer() );
diff --git a/gerbview/wxGerberFrame.h b/gerbview/wxGerberFrame.h
index f281dab2c0..6ce8c8d074 100644
--- a/gerbview/wxGerberFrame.h
+++ b/gerbview/wxGerberFrame.h
@@ -10,6 +10,10 @@
#include "class_gerbview_layer_widget.h"
#include "class_layerchoicebox.h"
+
+#define NO_AVAILABLE_LAYERS -1
+
+
/**
* Command IDs for the gerber file viewer.
*
@@ -33,9 +37,10 @@ enum id_gerbview_frm {
class DCODE_SELECTION_BOX;
+
/******************************************************************
-* class WinEDA_GerberFrame: this is the main window used in gerbview
-******************************************************************/
+ * class WinEDA_GerberFrame: this is the main window used in gerbview
+ ******************************************************************/
class WinEDA_GerberFrame : public PCB_BASE_FRAME
{
@@ -53,16 +58,17 @@ public:
private:
int m_displayMode; // Gerber images ("layers" in Gerbview) can be drawn:
- // - in fast mode (write mode) but if there are negative items
- // only the last image is correctly drawn
- // (no problem to see only one image or when no negative items)
+ // - in fast mode (write mode) but if there are negative
+ // items only the last image is correctly drawn (no
+ // problem to see only one image or when no negative items)
// - in "exact" mode (but slower) in write mode:
// last image covers previous images
// - in "exact" mode (also slower) in OR mode
// (transparency mode)
// m_displayMode = 0, 1 or 2
bool m_show_layer_manager_tools;
- wxArrayString m_Messages; // An array sting to store warning messages when reaging a gerber file
+ wxArrayString m_Messages; // An array sting to store warning messages when reaging
+ // a gerber file
public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
const wxPoint& pos, const wxSize& size,
@@ -130,7 +136,7 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
* Function GetGridColor() , virtual
* @return the color of the grid
*/
- virtual int GetGridColor();
+ virtual int GetGridColor();
/**
* Function SetGridColor() , virtual
@@ -198,6 +204,17 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
}
+ /**
+ * Function getNextAvailableLayer
+ * finds the next empty layer starting at \a aLayer and returns it to the caller. If no
+ * empty layers are found, NO_AVAILABLE_LAYERS is return.
+ * @param aLayer The first layer to search.
+ * @return The first empty layer found or NO_AVAILABLE_LAYERS.
+ */
+ int getNextAvailableLayer( int aLayer = 0 ) const;
+
+ bool hasAvailableLayers() const { return getNextAvailableLayer() != NO_AVAILABLE_LAYERS; }
+
/**
* Function syncLayerWidget
* updates the currently "selected" layer within the PCB_LAYER_WIDGET.
@@ -206,7 +223,7 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
* This function cannot be inline without including layer_widget.h in
* here and we do not want to do that.
*/
- void syncLayerWidget();
+ void syncLayerWidget();
/**
* Function syncLayerBox
@@ -214,7 +231,7 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
* The currently active layer, as defined by the return value of
* getActiveLayer(). And updates the colored icon in the toolbar.
*/
- void syncLayerBox();
+ void syncLayerBox();
/**
* Function UpdateTitleAndInfo
@@ -225,7 +242,7 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
* Name of the Image (found in the gerber file: IN <name> command) in the status bar
* and other data in toolbar
*/
- void UpdateTitleAndInfo();
+ void UpdateTitleAndInfo();
/**
* Load applications settings specific to the PCBNew.
@@ -236,7 +253,7 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
* drawing frames. Please put your application settings for PCBNew here
* to avoid having application settings loaded all over the place.
*/
- virtual void LoadSettings();
+ virtual void LoadSettings();
/**
* Save applications settings common to PCB draw frame objects.
@@ -247,25 +264,25 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
* drawing frames. Please put your application settings for PCBNew here
* to avoid having application settings saved all over the place.
*/
- virtual void SaveSettings();
+ virtual void SaveSettings();
/**
* Function SetLanguage
* called on a language menu selection
*/
- virtual void SetLanguage( wxCommandEvent& event );
+ virtual void SetLanguage( wxCommandEvent& event );
- void Process_Special_Functions( wxCommandEvent& event );
- void RedrawActiveWindow( wxDC* DC, bool EraseBg );
- void ReCreateHToolbar();
- void ReCreateVToolbar();
- void ReCreateOptToolbar();
- void ReCreateMenuBar();
- void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
- void OnLeftDClick( wxDC* DC, const wxPoint& MousePos );
- bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
- int BestZoom();
- void OnSelectOptionToolbar( wxCommandEvent& event );
+ void Process_Special_Functions( wxCommandEvent& event );
+ void RedrawActiveWindow( wxDC* DC, bool EraseBg );
+ void ReCreateHToolbar();
+ void ReCreateVToolbar();
+ void ReCreateOptToolbar();
+ void ReCreateMenuBar();
+ void OnLeftClick( wxDC* DC, const wxPoint& MousePos );
+ void OnLeftDClick( wxDC* DC, const wxPoint& MousePos );
+ bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu );
+ int BestZoom();
+ void OnSelectOptionToolbar( wxCommandEvent& event );
/**
* Function OnSelectDisplayMode
@@ -273,31 +290,31 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
* Mode selection can be fast display,
* or exact mode with stacked images or with transparency
*/
- void OnSelectDisplayMode( wxCommandEvent& event );
- void OnHotKey( wxDC* DC, int hotkey, EDA_ITEM* DrawStruct );
+ void OnSelectDisplayMode( wxCommandEvent& event );
+ void OnHotKey( wxDC* DC, int hotkey, EDA_ITEM* DrawStruct );
GERBER_DRAW_ITEM* GerberGeneralLocateAndDisplay();
GERBER_DRAW_ITEM* Locate( const wxPoint& aPosition, int typeloc );
- void Process_Settings( wxCommandEvent& event );
- void Process_Config( wxCommandEvent& event );
- void InstallConfigFrame( const wxPoint& pos );
- void InstallGerberOptionsDialog( wxCommandEvent& event );
- void InstallPcbGlobalDeleteFrame( const wxPoint& pos );
+ void Process_Settings( wxCommandEvent& event );
+ void Process_Config( wxCommandEvent& event );
+ void InstallConfigFrame( const wxPoint& pos );
+ void InstallGerberOptionsDialog( wxCommandEvent& event );
+ void InstallPcbGlobalDeleteFrame( const wxPoint& pos );
- void OnUpdateDrawMode( wxUpdateUIEvent& aEvent );
- void OnUpdateFlashedItemsDrawMode( wxUpdateUIEvent& aEvent );
- void OnUpdateLinesDrawMode( wxUpdateUIEvent& aEvent );
- void OnUpdatePolygonsDrawMode( wxUpdateUIEvent& aEvent );
- void OnUpdateShowDCodes( wxUpdateUIEvent& aEvent );
- void OnUpdateShowLayerManager( wxUpdateUIEvent& aEvent );
- void OnUpdateSelectDCode( wxUpdateUIEvent& aEvent );
- void OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent );
+ void OnUpdateDrawMode( wxUpdateUIEvent& aEvent );
+ void OnUpdateFlashedItemsDrawMode( wxUpdateUIEvent& aEvent );
+ void OnUpdateLinesDrawMode( wxUpdateUIEvent& aEvent );
+ void OnUpdatePolygonsDrawMode( wxUpdateUIEvent& aEvent );
+ void OnUpdateShowDCodes( wxUpdateUIEvent& aEvent );
+ void OnUpdateShowLayerManager( wxUpdateUIEvent& aEvent );
+ void OnUpdateSelectDCode( wxUpdateUIEvent& aEvent );
+ void OnUpdateLayerSelectBox( wxUpdateUIEvent& aEvent );
/* handlers for block commands */
- virtual int ReturnBlockCommand( int key );
- virtual void HandleBlockPlace( wxDC* DC );
- virtual bool HandleBlockEnd( wxDC* DC );
+ virtual int ReturnBlockCommand( int key );
+ virtual void HandleBlockPlace( wxDC* DC );
+ virtual bool HandleBlockEnd( wxDC* DC );
/* Block operations: */
@@ -308,7 +325,7 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
*
* @param DC A device context to draw on.
*/
- void Block_Delete( wxDC* DC );
+ void Block_Delete( wxDC* DC );
/**
* Function Block_Move
@@ -319,7 +336,7 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
*
* @param DC A device context to draw on.
*/
- void Block_Move( wxDC* DC );
+ void Block_Move( wxDC* DC );
/**
* Function Block_Duplicate
@@ -330,54 +347,51 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
*
* @param DC A device context to draw on.
*/
- void Block_Duplicate( wxDC* DC );
+ void Block_Duplicate( wxDC* DC );
- void ToPostProcess( wxCommandEvent& event );
+ void ToPostProcess( wxCommandEvent& event );
/**
* Function ToPlotter
* Open a dialog frame to create plot and drill files
* relative to the current board
*/
- void ToPlotter( wxCommandEvent& event );
+ void ToPlotter( wxCommandEvent& event );
/**
* Function ToPrinter
* Open a dialog frame to print layers
*/
- void ToPrinter( wxCommandEvent& event );
+ void ToPrinter( wxCommandEvent& event );
- void Genere_HPGL( const wxString& FullFileName, int Layers );
- void Genere_GERBER( const wxString& FullFileName, int Layers );
- void Genere_PS( const wxString& FullFileName, int Layers );
- void Plot_Layer_HPGL( FILE* File, int masque_layer,
- int garde, bool trace_via,
- GRTraceMode trace_mode );
- void Plot_Layer_GERBER( FILE* File, int masque_layer,
- int garde, bool trace_via,
- GRTraceMode trace_mode );
- int Gen_D_CODE_File( const wxString& Name_File );
- void Plot_Layer_PS( FILE* File, int masque_layer,
- int garde, bool trace_via,
- GRTraceMode trace_mode );
+ void Genere_HPGL( const wxString& FullFileName, int Layers );
+ void Genere_GERBER( const wxString& FullFileName, int Layers );
+ void Genere_PS( const wxString& FullFileName, int Layers );
+ void Plot_Layer_HPGL( FILE* File, int masque_layer,int garde, bool trace_via,
+ GRTraceMode trace_mode );
+ void Plot_Layer_GERBER( FILE* File, int masque_layer, int garde, bool trace_via,
+ GRTraceMode trace_mode );
+ int Gen_D_CODE_File( const wxString& Name_File );
+ void Plot_Layer_PS( FILE* File, int masque_layer, int garde, bool trace_via,
+ GRTraceMode trace_mode );
- void Files_io( wxCommandEvent& event );
- void OnFileHistory( wxCommandEvent& event );
+ void Files_io( wxCommandEvent& event );
+ void OnFileHistory( wxCommandEvent& event );
/**
* function LoadGerberFiles
* Load a photoplot (Gerber) file or many files.
- * @param aFileName - void string or file name with full path to open or empty string to open a new
- * file. In this case one one file is loaded
+ * @param aFileName - void string or file name with full path to open or empty string to
+ * open a new file. In this case one one file is loaded
* if void string: user will be prompted for filename(s)
* @return true if file was opened successfully.
*/
- bool LoadGerberFiles( const wxString& aFileName );
- int ReadGerberFile( FILE* File, bool Append );
- bool Read_GERBER_File( const wxString& GERBER_FullFileName,
- const wxString& D_Code_FullFileName );
+ bool LoadGerberFiles( const wxString& aFileName );
+ int ReadGerberFile( FILE* File, bool Append );
+ bool Read_GERBER_File( const wxString& GERBER_FullFileName,
+ const wxString& D_Code_FullFileName );
- void GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey = 0 );
+ void GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey = 0 );
/**
* Function Read_D_Code_File
@@ -402,26 +416,25 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
* g_GERBER_List[]
* 1 = read OK
*/
- int Read_D_Code_File( const wxString& D_Code_FullFileName );
- void CopyDCodesSizeToItems();
- void Liste_D_Codes();
+ int Read_D_Code_File( const wxString& D_Code_FullFileName );
+ void CopyDCodesSizeToItems();
+ void Liste_D_Codes();
// PCB handling
- bool Clear_Pcb( bool query );
- void Erase_Current_Layer( bool query );
- void Delete_DCode_Items( wxDC* DC, int dcode_value, int layer_number );
+ bool Clear_Pcb( bool query );
+ void Erase_Current_Layer( bool query );
+ void Delete_DCode_Items( wxDC* DC, int dcode_value, int layer_number );
// Conversion function
- void ExportDataInPcbnewFormat( wxCommandEvent& event );
+ void ExportDataInPcbnewFormat( wxCommandEvent& event );
/* SaveCopyInUndoList() virtual
* currently: do nothing in gerbview.
* but must be defined because it is a pure virtual in PCB_BASE_FRAME
*/
- virtual void SaveCopyInUndoList(
- BOARD_ITEM* aItemToCopy,
- UndoRedoOpType aTypeCommand = UR_UNSPECIFIED,
- const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) { }
+ virtual void SaveCopyInUndoList( BOARD_ITEM* aItemToCopy,
+ UndoRedoOpType aTypeCommand = UR_UNSPECIFIED,
+ const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) { }
/**
* Function SaveCopyInUndoList (overloaded).
@@ -432,15 +445,13 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
* @param aTransformPoint = the reference point of the transformation,
* for commands like move
*/
- virtual void SaveCopyInUndoList(
- PICKED_ITEMS_LIST& aItemsList,
- UndoRedoOpType aTypeCommand,
- const wxPoint& aTransformPoint = wxPoint( 0, 0 ) )
+ virtual void SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
+ UndoRedoOpType aTypeCommand,
+ const wxPoint& aTransformPoint = wxPoint( 0, 0 ) )
{
// currently: do nothing in gerbview.
}
-
/** Virtual function PrintPage
* used to print a page
* @param aDC = wxDC given by the calling print function
@@ -448,8 +459,7 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
* @param aPrintMirrorMode = not used here (Set when printing in mirror mode)
* @param aData = a pointer on an auxiliary data (not always used, NULL if not used)
*/
- virtual void PrintPage( wxDC* aDC,
- int aPrintMasklayer, bool aPrintMirrorMode,
+ virtual void PrintPage( wxDC* aDC, int aPrintMasklayer, bool aPrintMirrorMode,
void* aData = NULL );
/**
@@ -458,7 +468,7 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
* between gerber layers and pcbnew layers
* @return the "lookup table" if ok, or NULL
*/
- int* InstallDialogLayerPairChoice();
+ int* InstallDialogLayerPairChoice();
/**
* Function DrawItemsDCodeID
@@ -467,7 +477,7 @@ public: WinEDA_GerberFrame( wxWindow* father, const wxString& title,
* @param aDC = the current device contect
* @param aDrawMode = GR_COPY, GR_OR ...
*/
- void DrawItemsDCodeID( wxDC* aDC, int aDrawMode );
+ void DrawItemsDCodeID( wxDC* aDC, int aDrawMode );
DECLARE_EVENT_TABLE()
};