Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
2be24e1f
Commit
2be24e1f
authored
Jan 06, 2009
by
charras
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added comments about complex hierarchy handling. some code cleaning.
parent
b6035803
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
251 additions
and
112 deletions
+251
-112
annotate.cpp
eeschema/annotate.cpp
+4
-4
backanno.cpp
eeschema/backanno.cpp
+1
-1
build_BOM.cpp
eeschema/build_BOM.cpp
+3
-3
class_drawsheet.cpp
eeschema/class_drawsheet.cpp
+15
-5
class_drawsheet.h
eeschema/class_drawsheet.h
+12
-1
class_drawsheetpath.cpp
eeschema/class_drawsheetpath.cpp
+93
-25
class_drawsheetpath.h
eeschema/class_drawsheetpath.h
+96
-26
delsheet.cpp
eeschema/delsheet.cpp
+0
-26
erc.cpp
eeschema/erc.cpp
+1
-1
find.cpp
eeschema/find.cpp
+3
-3
hierarch.cpp
eeschema/hierarch.cpp
+1
-1
netform.cpp
eeschema/netform.cpp
+5
-5
netlist.cpp
eeschema/netlist.cpp
+1
-1
schedit.cpp
eeschema/schedit.cpp
+3
-0
schematic_undo_redo.cpp
eeschema/schematic_undo_redo.cpp
+9
-6
schframe.cpp
eeschema/schframe.cpp
+4
-4
No files found.
eeschema/annotate.cpp
View file @
2be24e1f
...
@@ -55,8 +55,8 @@ void WinEDA_SchematicFrame::UpdateSheetNumberAndDate()
...
@@ -55,8 +55,8 @@ void WinEDA_SchematicFrame::UpdateSheetNumberAndDate()
****************************************************************************/
****************************************************************************/
void
ReAnnotatePowerSymbolsOnly
(
void
)
void
ReAnnotatePowerSymbolsOnly
(
void
)
{
{
/* Build the
sheet list
(sheet, not screen) */
/* Build the
whole sheet list in hierarchy
(sheet, not screen) */
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
DrawSheetPath
*
sheet
;
DrawSheetPath
*
sheet
;
int
CmpNumber
=
1
;
int
CmpNumber
=
1
;
...
@@ -250,7 +250,7 @@ void AnnotateComponents( WinEDA_SchematicFrame* parent,
...
@@ -250,7 +250,7 @@ void AnnotateComponents( WinEDA_SchematicFrame* parent,
parent
->
DeleteAnnotation
(
!
annotateSchematic
,
false
);
parent
->
DeleteAnnotation
(
!
annotateSchematic
,
false
);
/* Build the sheet list */
/* Build the sheet list */
EDA_SheetList
SheetList
(
g_RootSheet
)
;
EDA_SheetList
SheetList
;
/* Update the sheet number, sheet count and date */
/* Update the sheet number, sheet count and date */
parent
->
UpdateSheetNumberAndDate
();
parent
->
UpdateSheetNumberAndDate
();
...
@@ -615,7 +615,7 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
...
@@ -615,7 +615,7 @@ int CheckAnnotate( WinEDA_SchematicFrame* frame, bool oneSheetOnly )
wxString
msg
,
cmpref
;
wxString
msg
,
cmpref
;
/* build the screen list */
/* build the screen list */
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
std
::
vector
<
OBJ_CMP_TO_LIST
>
ComponentsList
;
std
::
vector
<
OBJ_CMP_TO_LIST
>
ComponentsList
;
...
...
eeschema/backanno.cpp
View file @
2be24e1f
...
@@ -34,7 +34,7 @@ bool WinEDA_SchematicFrame::FillFootprintFieldForAllInstancesofComponent(
...
@@ -34,7 +34,7 @@ bool WinEDA_SchematicFrame::FillFootprintFieldForAllInstancesofComponent(
{
{
DrawSheetPath
*
sheet
;
DrawSheetPath
*
sheet
;
SCH_ITEM
*
DrawList
=
NULL
;
SCH_ITEM
*
DrawList
=
NULL
;
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
SCH_COMPONENT
*
Cmp
;
SCH_COMPONENT
*
Cmp
;
bool
found
=
false
;
bool
found
=
false
;
...
...
eeschema/build_BOM.cpp
View file @
2be24e1f
...
@@ -264,7 +264,7 @@ void BuildComponentsListFromSchematic( std::vector <OBJ_CMP_TO_LIST>& aList )
...
@@ -264,7 +264,7 @@ void BuildComponentsListFromSchematic( std::vector <OBJ_CMP_TO_LIST>& aList )
DrawSheetPath
*
sheet
;
DrawSheetPath
*
sheet
;
/* Build the sheet (not screen) list */
/* Build the sheet (not screen) list */
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
{
{
...
@@ -303,8 +303,8 @@ static void GenListeGLabels( std::vector <LABEL_OBJECT>& aList )
...
@@ -303,8 +303,8 @@ static void GenListeGLabels( std::vector <LABEL_OBJECT>& aList )
Hierarchical_PIN_Sheet_Struct
*
PinLabel
;
Hierarchical_PIN_Sheet_Struct
*
PinLabel
;
DrawSheetPath
*
sheet
;
DrawSheetPath
*
sheet
;
/* Build the s
creen
list */
/* Build the s
heet
list */
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
LABEL_OBJECT
labet_object
;
LABEL_OBJECT
labet_object
;
...
...
eeschema/class_drawsheet.cpp
View file @
2be24e1f
...
@@ -218,12 +218,13 @@ void DrawSheetStruct::SwapData( DrawSheetStruct* copyitem )
...
@@ -218,12 +218,13 @@ void DrawSheetStruct::SwapData( DrawSheetStruct* copyitem )
}
}
/****************************************************************/
/****************************************************************
****
/
void
DrawSheetStruct
::
Place
(
WinEDA_SchematicFrame
*
frame
,
wxDC
*
DC
)
void
DrawSheetStruct
::
Place
(
WinEDA_SchematicFrame
*
frame
,
wxDC
*
DC
)
/****************************************************************/
/****************************************************************
****
/
{
{
/* Placement en liste des structures si nouveau composant:*/
/* Placement en liste des structures si nouveau composant:*/
if
(
m_Flags
&
IS_NEW
)
bool
isnew
=
(
m_Flags
&
IS_NEW
)
?
true
:
false
;
if
(
isnew
)
{
{
if
(
!
frame
->
EditSheet
(
this
,
DC
)
)
if
(
!
frame
->
EditSheet
(
this
,
DC
)
)
{
{
...
@@ -237,6 +238,10 @@ void DrawSheetStruct::Place( WinEDA_SchematicFrame* frame, wxDC* DC )
...
@@ -237,6 +238,10 @@ void DrawSheetStruct::Place( WinEDA_SchematicFrame* frame, wxDC* DC )
}
}
SCH_ITEM
::
Place
(
frame
,
DC
);
//puts it on the EEDrawList.
SCH_ITEM
::
Place
(
frame
,
DC
);
//puts it on the EEDrawList.
if
(
isnew
)
{
frame
->
SetSheetNumberAndCount
();
}
}
}
...
@@ -540,6 +545,11 @@ bool DrawSheetStruct::Load( WinEDA_SchematicFrame* aFrame )
...
@@ -540,6 +545,11 @@ bool DrawSheetStruct::Load( WinEDA_SchematicFrame* aFrame )
/**********************************/
/**********************************/
int
DrawSheetStruct
::
CountSheets
()
int
DrawSheetStruct
::
CountSheets
()
/**********************************/
/**********************************/
/** Function CountSheets
* calculates the number of sheets found in "this"
* this number includes the full subsheets count
* @return the full count of sheets+subsheets contained by "this"
*/
{
{
int
count
=
1
;
//1 = this!!
int
count
=
1
;
//1 = this!!
...
@@ -550,8 +560,8 @@ int DrawSheetStruct::CountSheets()
...
@@ -550,8 +560,8 @@ int DrawSheetStruct::CountSheets()
{
{
if
(
strct
->
Type
()
==
DRAW_SHEET_STRUCT_TYPE
)
if
(
strct
->
Type
()
==
DRAW_SHEET_STRUCT_TYPE
)
{
{
DrawSheetStruct
*
s
s
=
(
DrawSheetStruct
*
)
strct
;
DrawSheetStruct
*
s
ubsheet
=
(
DrawSheetStruct
*
)
strct
;
count
+=
s
s
->
CountSheets
();
count
+=
s
ubsheet
->
CountSheets
();
}
}
}
}
}
}
...
...
eeschema/class_drawsheet.h
View file @
2be24e1f
...
@@ -137,7 +137,7 @@ public:
...
@@ -137,7 +137,7 @@ public:
/** Function ComponentCount
/** Function ComponentCount
* count our own components, without the power components.
* count our own components, without the power components.
* @return the co
p
ponent count.
* @return the co
m
ponent count.
*/
*/
int
ComponentCount
();
int
ComponentCount
();
...
@@ -169,7 +169,18 @@ public:
...
@@ -169,7 +169,18 @@ public:
* @return true if found
* @return true if found
*/
*/
bool
LocatePathOfScreen
(
SCH_SCREEN
*
aScreen
,
DrawSheetPath
*
aList
);
bool
LocatePathOfScreen
(
SCH_SCREEN
*
aScreen
,
DrawSheetPath
*
aList
);
/** Function CountSheets
* calculates the number of sheets found in "this"
* this number includes the full subsheets count
* @return the full count of sheets+subsheets contained by "this"
*/
int
CountSheets
();
int
CountSheets
();
/** Function GetFileName
* return the filename corresponding to this sheet
* @return a wxString containing the filename
*/
wxString
GetFileName
(
void
);
wxString
GetFileName
(
void
);
// Set a new filename without changing anything else
// Set a new filename without changing anything else
...
...
eeschema/class_drawsheetpath.cpp
View file @
2be24e1f
...
@@ -43,19 +43,27 @@ DrawSheetPath::DrawSheetPath()
...
@@ -43,19 +43,27 @@ DrawSheetPath::DrawSheetPath()
}
}
int
DrawSheetPath
::
Cmp
(
const
DrawSheetPath
&
d
)
const
/*******************************************************************/
int
DrawSheetPath
::
Cmp
(
const
DrawSheetPath
&
aSheetPathToTest
)
const
/********************************************************************/
/** Function Cmp
* Compare if this is the same sheet path as aSheetPathToTest
* @param aSheetPathToTest = sheet path to compare
* @return -1 if differents, 0 if same
*/
{
{
if
(
m_numSheets
>
d
.
m_numSheets
)
if
(
m_numSheets
>
aSheetPathToTest
.
m_numSheets
)
return
1
;
return
1
;
if
(
m_numSheets
<
d
.
m_numSheets
)
if
(
m_numSheets
<
aSheetPathToTest
.
m_numSheets
)
return
-
1
;
return
-
1
;
//otherwise, same number of sheets.
//otherwise, same number of sheets.
for
(
int
i
=
0
;
i
<
m_numSheets
;
i
++
)
for
(
int
i
=
0
;
i
<
m_numSheets
;
i
++
)
{
{
if
(
m_sheets
[
i
]
->
m_TimeStamp
>
d
.
m_sheets
[
i
]
->
m_TimeStamp
)
if
(
m_sheets
[
i
]
->
m_TimeStamp
>
aSheetPathToTest
.
m_sheets
[
i
]
->
m_TimeStamp
)
return
1
;
return
1
;
if
(
m_sheets
[
i
]
->
m_TimeStamp
<
d
.
m_sheets
[
i
]
->
m_TimeStamp
)
if
(
m_sheets
[
i
]
->
m_TimeStamp
<
aSheetPathToTest
.
m_sheets
[
i
]
->
m_TimeStamp
)
return
-
1
;
return
-
1
;
}
}
...
@@ -87,18 +95,31 @@ EDA_BaseStruct* DrawSheetPath::LastDrawList()
...
@@ -87,18 +95,31 @@ EDA_BaseStruct* DrawSheetPath::LastDrawList()
}
}
void
DrawSheetPath
::
Push
(
DrawSheetStruct
*
sheet
)
/**************************************************/
void
DrawSheetPath
::
Push
(
DrawSheetStruct
*
aSheet
)
/**************************************************/
/** Function Push
* store (push) aSheet in list
* @param aSheet = pointer to the DrawSheetStruct to store in list
*/
{
{
wxASSERT
(
m_numSheets
<=
DSLSZ
);
if
(
m_numSheets
>
DSLSZ
)
wxMessageBox
(
wxT
(
"DrawSheetPath::Push() error: no room in buffer to store sheet"
)
);
if
(
m_numSheets
<
DSLSZ
)
if
(
m_numSheets
<
DSLSZ
)
{
{
m_sheets
[
m_numSheets
]
=
s
heet
;
m_sheets
[
m_numSheets
]
=
aS
heet
;
m_numSheets
++
;
m_numSheets
++
;
}
}
}
}
DrawSheetStruct
*
DrawSheetPath
::
Pop
()
DrawSheetStruct
*
DrawSheetPath
::
Pop
()
/** Function Pop
* retrieves (pop) the last entered sheet and remove it from list
* @return a DrawSheetStruct* pointer to the removed sheet in list
*/
{
{
if
(
m_numSheets
>
0
)
if
(
m_numSheets
>
0
)
{
{
...
@@ -110,10 +131,15 @@ DrawSheetStruct* DrawSheetPath::Pop()
...
@@ -110,10 +131,15 @@ DrawSheetStruct* DrawSheetPath::Pop()
wxString
DrawSheetPath
::
Path
()
wxString
DrawSheetPath
::
Path
()
/** Function Path
* the path uses the time stamps which do not changes even when editing sheet parameters
* a path is something like / (root) or /34005677 or /34005677/00AE4523
*/
{
{
wxString
s
,
t
;
wxString
s
,
t
;
s
=
wxT
(
"/"
);
s
=
wxT
(
"/"
);
// This is the root path
//start at 1 to avoid the root sheet,
//start at 1 to avoid the root sheet,
//which does not need to be added to the path
//which does not need to be added to the path
...
@@ -128,7 +154,15 @@ wxString DrawSheetPath::Path()
...
@@ -128,7 +154,15 @@ wxString DrawSheetPath::Path()
}
}
/******************************************/
wxString
DrawSheetPath
::
PathHumanReadable
()
wxString
DrawSheetPath
::
PathHumanReadable
()
/******************************************/
/** Function PathHumanReadable
* Return the sheet path in a readable form, i.e.
* as a path made from sheet names.
* (the "normal" path uses the time stamps which do not changes even when editing sheet parameters)
*/
{
{
wxString
s
,
t
;
wxString
s
,
t
;
...
@@ -155,7 +189,7 @@ void DrawSheetPath::UpdateAllScreenReferences()
...
@@ -155,7 +189,7 @@ void DrawSheetPath::UpdateAllScreenReferences()
if
(
t
->
Type
()
==
TYPE_SCH_COMPONENT
)
if
(
t
->
Type
()
==
TYPE_SCH_COMPONENT
)
{
{
SCH_COMPONENT
*
component
=
(
SCH_COMPONENT
*
)
t
;
SCH_COMPONENT
*
component
=
(
SCH_COMPONENT
*
)
t
;
component
->
GetField
(
REFERENCE
)
->
m_Text
=
component
->
GetRef
(
this
);
component
->
GetField
(
REFERENCE
)
->
m_Text
=
component
->
GetRef
(
this
);
component
->
m_Multi
=
component
->
GetUnitSelection
(
this
);
component
->
m_Multi
=
component
->
GetUnitSelection
(
this
);
}
}
t
=
t
->
Next
();
t
=
t
->
Next
();
...
@@ -209,17 +243,39 @@ bool DrawSheetPath::operator!=( const DrawSheetPath& d1 )
...
@@ -209,17 +243,39 @@ bool DrawSheetPath::operator!=( const DrawSheetPath& d1 )
}
}
/*********************************************************************/
/*********************************************************************/
/* Class EDA_SheetList to handle the list of Sheets in a hierarchy */
/* Class EDA_SheetList to handle the list of Sheets in a hierarchy */
/*********************************************************************/
/*********************************************************************/
/*******************************************************/
EDA_SheetList
::
EDA_SheetList
(
DrawSheetStruct
*
aSheet
)
/*******************************************************/
/* The constructor: build the list of sheets from aSheet.
* If aSheet == NULL (default) build the whole list of sheets in hierarchy
* So usually call it with no param.
*/
{
m_index
=
0
;
m_count
=
0
;
m_List
=
NULL
;
if
(
aSheet
==
NULL
)
aSheet
=
g_RootSheet
;
BuildSheetList
(
aSheet
);
}
/*****************************************/
/*****************************************/
DrawSheetPath
*
EDA_SheetList
::
GetFirst
()
DrawSheetPath
*
EDA_SheetList
::
GetFirst
()
/*****************************************/
/*****************************************/
/** Function GetFirst
* @return the first item (sheet) in m_List and prepare calls to GetNext()
*/
{
{
m_index
=
0
;
m_index
=
0
;
if
(
m_count
>
0
)
if
(
GetCount
()
>
0
)
return
&
(
m_List
[
0
]
);
return
&
(
m_List
[
0
]
);
return
NULL
;
return
NULL
;
}
}
...
@@ -228,51 +284,63 @@ DrawSheetPath* EDA_SheetList::GetFirst()
...
@@ -228,51 +284,63 @@ DrawSheetPath* EDA_SheetList::GetFirst()
/*****************************************/
/*****************************************/
DrawSheetPath
*
EDA_SheetList
::
GetNext
()
DrawSheetPath
*
EDA_SheetList
::
GetNext
()
/*****************************************/
/*****************************************/
/** Function GetNext
* @return the next item (sheet) in m_List or NULL if no more item in sheet list
*/
{
{
if
(
m_index
<
m_count
)
if
(
m_index
<
GetCount
()
)
m_index
++
;
m_index
++
;
return
GetSheet
(
m_index
);
return
GetSheet
(
m_index
);
}
}
/************************************************/
/************************************************/
DrawSheetPath
*
EDA_SheetList
::
GetSheet
(
int
i
ndex
)
DrawSheetPath
*
EDA_SheetList
::
GetSheet
(
int
aI
ndex
)
/************************************************/
/************************************************/
/* return the m_List[index] item
/** Function GetSheet
* @return the item (sheet) in aIndex position in m_List or NULL if less than index items
* @param aIndex = index in sheet list to get the sheet
*/
*/
{
{
if
(
index
<
m_count
)
if
(
aIndex
<
GetCount
()
)
return
&
(
m_List
[
i
ndex
]);
return
&
(
m_List
[
aI
ndex
]);
return
NULL
;
return
NULL
;
}
}
/************************************************************************/
/************************************************************************/
void
EDA_SheetList
::
BuildSheetList
(
DrawSheetStruct
*
s
heet
)
void
EDA_SheetList
::
BuildSheetList
(
DrawSheetStruct
*
aS
heet
)
/************************************************************************/
/************************************************************************/
/** Function BuildSheetList
* Build the list of sheets and their sheet path from the aSheet sheet
* if aSheet = g_RootSheet, the full sheet path list (and full sheet list) is built
* @param aSheet = the starting sheet to build list
*/
{
{
if
(
m_List
==
NULL
)
if
(
m_List
==
NULL
)
{
{
int
count
=
s
heet
->
CountSheets
();
int
count
=
aS
heet
->
CountSheets
();
m_count
=
count
;
m_count
=
count
;
m_index
=
0
;
m_index
=
0
;
count
*=
sizeof
(
DrawSheetPath
);
count
*=
sizeof
(
DrawSheetPath
);
m_List
=
(
DrawSheetPath
*
)
MyZMalloc
(
count
);
m_List
=
(
DrawSheetPath
*
)
MyZMalloc
(
count
);
m_currList
.
Clear
();
m_currList
.
Clear
();
}
}
m_currList
.
Push
(
s
heet
);
m_currList
.
Push
(
aS
heet
);
m_List
[
m_index
]
=
m_currList
;
m_List
[
m_index
]
=
m_currList
;
m_index
++
;
m_index
++
;
if
(
s
heet
->
m_AssociatedScreen
!=
NULL
)
if
(
aS
heet
->
m_AssociatedScreen
!=
NULL
)
{
{
EDA_BaseStruct
*
strct
=
m_currList
.
LastDrawList
();
EDA_BaseStruct
*
strct
=
m_currList
.
LastDrawList
();
while
(
strct
)
while
(
strct
)
{
{
if
(
strct
->
Type
()
==
DRAW_SHEET_STRUCT_TYPE
)
if
(
strct
->
Type
()
==
DRAW_SHEET_STRUCT_TYPE
)
{
{
DrawSheetStruct
*
sht
=
(
DrawSheetStruct
*
)
strct
;
DrawSheetStruct
*
sh
ee
t
=
(
DrawSheetStruct
*
)
strct
;
BuildSheetList
(
sht
);
BuildSheetList
(
sh
ee
t
);
}
}
strct
=
strct
->
Next
();
strct
=
strct
->
Next
();
}
}
...
...
eeschema/class_drawsheetpath.h
View file @
2be24e1f
...
@@ -11,11 +11,46 @@
...
@@ -11,11 +11,46 @@
#include "base_struct.h"
#include "base_struct.h"
/** Info about complex hierarchies handling:
/**********************************************/
* A hierarchical schematic uses sheets (hierachical sheets) included in a given sheet.
/* class to handle a series of sheets *********/
* each sheet corresponds to a schematic drawing handled by a SCH_SCREEN structure
/* a 'path' so to speak.. *********************/
* a SCH_SCREEN structure contains drawings, and have a filename to write to its data.
/**********************************************/
* Also a SCH_SCREEN display a sheet number and the name of the sheet
* In simple (and flat) hierarchies a sheet is linked to a SCH_SCREEN,
* and a SCH_SCREEN is used by only one hierarchical sheet.
*
* In complex hierachies the same SCH_SCREEN (and its data) is shared between more than one sheet.
* Therefore subsheets (like subsheets in a SCH_SCREEN shared by many sheets) can be also shared
* So the same SCH_SCREEN must handle differents components references and parts selection
* depending on which sheet is currently selected, and how a given subsheet is selected.
* 2 sheets share the same SCH_SCREEN (the same drawings) if they have the same filename.
*
* In kicad each component and sheet receives (when created) an unique identification called Time Stamp.
* So each sheet have 2 id : its time stamp (that cannot change) and its name
* ( that can be edited and therefore is not reliable for strong identification)
* Kicad uses therefore Time Stamp ( an unique 32 bit id), to identify sheets in hierarchies.
* A given sheet in a hierarchy is fully labelled by its path (or sheet path)
* that is the list of timestamp found to access it through the hierarchy
* the root sheet is /
* others have a path like /1234ABCD ou /4567FEDC/AA2233DD/
* of course this path can be displayed as human readable sheet name like :
* / or /sheet1/include_sheet/ or /sheet2/include_sheet/
*
* So to know for a given SCH_SCREEN (a given schematic drawings) we must:
* Handle all references possibilities.
* When acceded by a given selected sheet, display (update) the corresponding references and sheet path
*
* the class DrawSheetPath handles paths used to access a sheet
* the class EDA_SheetList allows to handle the full (or partial) list of sheets and their paths in a complex hierarchy.
* the class EDA_ScreenList allow to handle the list of SCH_SCREEN. It is useful to clear or save data,
* but is not suitable to handle the full complex hierarchy possibilities (useable in flat and simple hierarchies).
*/
/***************************************************/
/* class to handle a and acces to series of sheets */
/* a 'path' so to speak.. **************************/
/***************************************************/
class
DrawSheetPath
class
DrawSheetPath
{
{
public
:
public
:
...
@@ -27,11 +62,27 @@ public:
...
@@ -27,11 +62,27 @@ public:
DrawSheetPath
();
DrawSheetPath
();
~
DrawSheetPath
()
{
};
~
DrawSheetPath
()
{
};
void
Clear
()
{
m_numSheets
=
0
;
}
void
Clear
()
{
m_numSheets
=
0
;
}
int
Cmp
(
const
DrawSheetPath
&
d
)
const
;
/** Function Cmp
* Compare if this is the same sheet path as aSheetPathToTest
* @param aSheetPathToTest = sheet path to compare
* @return -1 if differents, 0 if same
*/
int
Cmp
(
const
DrawSheetPath
&
aSheetPathToTest
)
const
;
DrawSheetStruct
*
Last
();
DrawSheetStruct
*
Last
();
SCH_SCREEN
*
LastScreen
();
SCH_SCREEN
*
LastScreen
();
EDA_BaseStruct
*
LastDrawList
();
EDA_BaseStruct
*
LastDrawList
();
void
Push
(
DrawSheetStruct
*
sheet
);
/** Function Push
* store (push) aSheet in list
* @param aSheet = pointer to the DrawSheetStruct to store in list
*/
void
Push
(
DrawSheetStruct
*
aSheet
);
/** Function Pop
* retrieves (pop) the last entered sheet and remove it from list
* @return a DrawSheetStruct* pointer to the removed sheet in list
*/
DrawSheetStruct
*
Pop
();
DrawSheetStruct
*
Pop
();
/** Function Path
/** Function Path
...
@@ -69,11 +120,11 @@ public:
...
@@ -69,11 +120,11 @@ public:
/*******************************************************/
/*******************************************************/
/* sheets are not unique - can have many sheets with the same
/* sheets are not unique - can have many sheets with the same
* filename and the same SCH_SCREEN reference.
* filename and the same SCH_SCREEN reference.
* the schematic (SCH_SCREEN) is shared between these sheets,
* the schematic (SCH_SCREEN) is shared between these sheets,
* and component references are specific to a sheet path.
* and component references are specific to a sheet path.
* When a sheet is entered, component references and sheet number are updated
* When a sheet is entered, component references and sheet number are updated
*/
*/
class
EDA_SheetList
class
EDA_SheetList
{
{
private
:
private
:
...
@@ -81,37 +132,56 @@ private:
...
@@ -81,37 +132,56 @@ private:
int
m_count
;
/* Number of sheets included in hierarchy,
int
m_count
;
/* Number of sheets included in hierarchy,
* starting at the given sheet in constructor . the given sheet is counted
* starting at the given sheet in constructor . the given sheet is counted
*/
*/
int
m_index
;
int
m_index
;
/* internal variable to handle GetNext(): cleared by GetFirst()
* and incremented by GetNext() after returning the next item in m_List
* Also used for internal calculations in BuildSheetList()
*/
DrawSheetPath
m_currList
;
DrawSheetPath
m_currList
;
public
:
public
:
EDA_SheetList
(
DrawSheetStruct
*
sheet
)
{
m_index
=
0
;
m_count
=
0
;
m_List
=
NULL
;
if
(
sheet
==
NULL
)
sheet
=
g_RootSheet
;
BuildSheetList
(
sheet
);
}
/* The constructor: build the list of sheets from aSheet.
* If aSheet == NULL (default) build the whole list of sheets in hierarchy
* So usually call it with no param.
*/
EDA_SheetList
(
DrawSheetStruct
*
aSheet
=
NULL
);
~
EDA_SheetList
()
~
EDA_SheetList
()
{
{
if
(
m_List
)
if
(
m_List
)
{
free
(
m_List
);
free
(
m_List
);
}
m_List
=
NULL
;
m_List
=
NULL
;
}
}
/** Function GetCount()
* @return the number of sheets in list:
* usually the number of sheets found in the whole hierarchy
*/
int
GetCount
()
{
return
m_count
;
}
int
GetCount
()
{
return
m_count
;
}
/** Function GetFirst
* @return the first item (sheet) in m_List and prepare calls to GetNext()
*/
DrawSheetPath
*
GetFirst
();
DrawSheetPath
*
GetFirst
();
/** Function GetNext
* @return the next item (sheet) in m_List or NULL if no more item in sheet list
*/
DrawSheetPath
*
GetNext
();
DrawSheetPath
*
GetNext
();
DrawSheetPath
*
GetSheet
(
int
index
);
/** Function GetSheet
* @return the item (sheet) in aIndex position in m_List or NULL if less than index items
* @param aIndex = index in sheet list to get the sheet
*/
DrawSheetPath
*
GetSheet
(
int
aIndex
);
private
:
private
:
/** Function BuildSheetList
* Build the list of sheets and their sheet path from the aSheet sheet
* if aSheet = g_RootSheet, the full sheet path and sheet list is built
* @param aSheet = the starting sheet from the built is made
*/
void
BuildSheetList
(
DrawSheetStruct
*
sheet
);
void
BuildSheetList
(
DrawSheetStruct
*
sheet
);
};
};
...
...
eeschema/delsheet.cpp
View file @
2be24e1f
...
@@ -71,32 +71,6 @@ void DeleteSubHierarchy( DrawSheetStruct* FirstSheet, bool confirm_deletion )
...
@@ -71,32 +71,6 @@ void DeleteSubHierarchy( DrawSheetStruct* FirstSheet, bool confirm_deletion )
}
}
/*********************************************************************/
//void ClearDrawList(EDA_BaseStruct *DrawList, bool confirm_deletion)
/********************************************************************/
/* free the draw list DrawList and the subhierarchies */
//this is redundant -- use FreeDrawList, a member of SCH_SCREEN
/*
* {
* EDA_BaseStruct *DrawStruct;
*
* while (DrawList != NULL)
* {
* DrawStruct = DrawList;
* DrawList = DrawList->Pnext;
*
* if( DrawStruct->Type() == DRAW_SHEET_STRUCT_TYPE)
* {
* DeleteSubHierarchy((DrawSheetStruct*) DrawStruct, confirm_deletion);
* }
*
* delete DrawStruct;
* }
* }
*/
/********************************************************************/
/********************************************************************/
bool
ClearProjectDrawList
(
SCH_SCREEN
*
screen
,
bool
confirm_deletion
)
bool
ClearProjectDrawList
(
SCH_SCREEN
*
screen
,
bool
confirm_deletion
)
/********************************************************************/
/********************************************************************/
...
...
eeschema/erc.cpp
View file @
2be24e1f
...
@@ -724,7 +724,7 @@ static bool WriteDiagnosticERC( const wxString& FullFileName )
...
@@ -724,7 +724,7 @@ static bool WriteDiagnosticERC( const wxString& FullFileName )
fprintf
(
OutErc
,
"%s (%s)
\n
"
,
CONV_TO_UTF8
(
msg
),
Line
);
fprintf
(
OutErc
,
"%s (%s)
\n
"
,
CONV_TO_UTF8
(
msg
),
Line
);
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
for
(
Sheet
=
SheetList
.
GetFirst
();
Sheet
!=
NULL
;
Sheet
=
SheetList
.
GetNext
()
)
for
(
Sheet
=
SheetList
.
GetFirst
();
Sheet
!=
NULL
;
Sheet
=
SheetList
.
GetNext
()
)
{
{
...
...
eeschema/find.cpp
View file @
2be24e1f
...
@@ -78,7 +78,7 @@ SCH_ITEM * WinEDA_SchematicFrame::FindComponentAndItem(
...
@@ -78,7 +78,7 @@ SCH_ITEM * WinEDA_SchematicFrame::FindComponentAndItem(
wxString
msg
;
wxString
msg
;
LibDrawPin
*
pin
;
LibDrawPin
*
pin
;
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
sheet
=
SheetList
.
GetFirst
();
sheet
=
SheetList
.
GetFirst
();
if
(
!
Find_in_hierarchy
)
if
(
!
Find_in_hierarchy
)
...
@@ -276,7 +276,7 @@ SCH_ITEM * WinEDA_SchematicFrame::FindMarker( int SearchType )
...
@@ -276,7 +276,7 @@ SCH_ITEM * WinEDA_SchematicFrame::FindMarker( int SearchType )
if
(
SearchType
==
0
)
if
(
SearchType
==
0
)
s_MarkerCount
=
0
;
s_MarkerCount
=
0
;
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
NotFound
=
TRUE
;
StartCount
=
0
;
NotFound
=
TRUE
;
StartCount
=
0
;
/* Search for s_MarkerCount markers */
/* Search for s_MarkerCount markers */
...
@@ -446,7 +446,7 @@ SCH_ITEM* WinEDA_SchematicFrame::FindSchematicItem(
...
@@ -446,7 +446,7 @@ SCH_ITEM* WinEDA_SchematicFrame::FindSchematicItem(
NotFound
=
TRUE
;
NotFound
=
TRUE
;
StartCount
=
0
;
StartCount
=
0
;
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
Sheet
=
SheetList
.
GetFirst
();
Sheet
=
SheetList
.
GetFirst
();
if
(
!
Find_in_hierarchy
)
if
(
!
Find_in_hierarchy
)
...
...
eeschema/hierarch.cpp
View file @
2be24e1f
...
@@ -251,7 +251,7 @@ void WinEDA_HierFrame::OnSelect( wxTreeEvent& event )
...
@@ -251,7 +251,7 @@ void WinEDA_HierFrame::OnSelect( wxTreeEvent& event )
wxTreeItemId
ItemSel
=
m_Tree
->
GetSelection
();
wxTreeItemId
ItemSel
=
m_Tree
->
GetSelection
();
*
(
m_Parent
->
m_CurrentSheet
)
=
*
(
m_Parent
->
m_CurrentSheet
)
=
(
(
TreeItemData
*
)
(
m_Tree
->
GetItemData
(
ItemSel
)
)
)
->
m_SheetList
;
(
(
TreeItemData
*
)
m_Tree
->
GetItemData
(
ItemSel
)
)
->
m_SheetList
;
UpdateScreenFromSheet
(
m_Parent
);
UpdateScreenFromSheet
(
m_Parent
);
Close
(
TRUE
);
Close
(
TRUE
);
}
}
...
...
eeschema/netform.cpp
View file @
2be24e1f
...
@@ -285,7 +285,7 @@ void Write_GENERIC_NetList( WinEDA_SchematicFrame* frame,
...
@@ -285,7 +285,7 @@ void Write_GENERIC_NetList( WinEDA_SchematicFrame* frame,
/* Create netlist module section */
/* Create netlist module section */
fprintf
(
tmpfile
,
"$BeginComponentList
\n
"
);
fprintf
(
tmpfile
,
"$BeginComponentList
\n
"
);
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
{
{
...
@@ -409,7 +409,7 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f,
...
@@ -409,7 +409,7 @@ static void WriteNetListPspice( WinEDA_SchematicFrame* frame, FILE* f,
/* Create text list starting by [.-]pspice , or [.-]gnucap (simulator commands) */
/* Create text list starting by [.-]pspice , or [.-]gnucap (simulator commands) */
/* and create text list starting by [+]pspice , or [+]gnucap (simulator commands) */
/* and create text list starting by [+]pspice , or [+]gnucap (simulator commands) */
bufnum
[
BUFYPOS_LEN
]
=
0
;
bufnum
[
BUFYPOS_LEN
]
=
0
;
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
{
{
...
@@ -552,7 +552,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
...
@@ -552,7 +552,7 @@ static void WriteNetListPCBNEW( WinEDA_SchematicFrame* frame, FILE* f, bool with
/* Create netlist module section */
/* Create netlist module section */
ClearUsedFlags
(
);
/* Reset the flags FlagControlMulti in all schematic files*/
ClearUsedFlags
(
);
/* Reset the flags FlagControlMulti in all schematic files*/
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
{
{
...
@@ -767,7 +767,7 @@ static void FindAllsInstancesOfComponent( SCH_COMPONENT* Component_in,
...
@@ -767,7 +767,7 @@ static void FindAllsInstancesOfComponent( SCH_COMPONENT* Component_in,
DrawSheetPath
*
sheet
;
DrawSheetPath
*
sheet
;
wxString
str
,
Reference
=
Component_in
->
GetRef
(
Sheet_in
);
wxString
str
,
Reference
=
Component_in
->
GetRef
(
Sheet_in
);
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
{
{
...
@@ -956,7 +956,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
...
@@ -956,7 +956,7 @@ static void WriteNetListCADSTAR( WinEDA_SchematicFrame* frame, FILE* f )
/* Create netlist module section */
/* Create netlist module section */
ClearUsedFlags
(
);
/* Reset the flags FlagControlMulti in all schematic files*/
ClearUsedFlags
(
);
/* Reset the flags FlagControlMulti in all schematic files*/
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
{
{
...
...
eeschema/netlist.cpp
View file @
2be24e1f
...
@@ -198,7 +198,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
...
@@ -198,7 +198,7 @@ void* WinEDA_SchematicFrame::BuildNetListBase()
SetStatusText
(
activity
);
SetStatusText
(
activity
);
/* Build the sheet (not screen) list (flattened)*/
/* Build the sheet (not screen) list (flattened)*/
EDA_SheetList
SheetListList
(
NULL
)
;
EDA_SheetList
SheetListList
;
i
=
0
;
i
=
0
;
/* first pass : count objects used in connectivty calculation */
/* first pass : count objects used in connectivty calculation */
g_NbrObjNet
=
0
;
g_NbrObjNet
=
0
;
...
...
eeschema/schedit.cpp
View file @
2be24e1f
...
@@ -171,6 +171,7 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
...
@@ -171,6 +171,7 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
break
;
break
;
HandleBlockEndByPopUp
(
BLOCK_DELETE
,
&
dc
);
HandleBlockEndByPopUp
(
BLOCK_DELETE
,
&
dc
);
g_ItemToRepeat
=
NULL
;
g_ItemToRepeat
=
NULL
;
SetSheetNumberAndCount
();
break
;
break
;
case
wxID_PASTE
:
case
wxID_PASTE
:
...
@@ -358,6 +359,7 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
...
@@ -358,6 +359,7 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
screen
->
SetCurItem
(
NULL
);
screen
->
SetCurItem
(
NULL
);
g_ItemToRepeat
=
NULL
;
g_ItemToRepeat
=
NULL
;
TestDanglingEnds
(
screen
->
EEDrawList
,
&
dc
);
TestDanglingEnds
(
screen
->
EEDrawList
,
&
dc
);
SetSheetNumberAndCount
();
screen
->
SetModify
();
screen
->
SetModify
();
}
}
break
;
break
;
...
@@ -655,6 +657,7 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
...
@@ -655,6 +657,7 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
case
ID_POPUP_DELETE_BLOCK
:
case
ID_POPUP_DELETE_BLOCK
:
DrawPanel
->
MouseToCursorSchema
();
DrawPanel
->
MouseToCursorSchema
();
HandleBlockEndByPopUp
(
BLOCK_DELETE
,
&
dc
);
HandleBlockEndByPopUp
(
BLOCK_DELETE
,
&
dc
);
SetSheetNumberAndCount
();
break
;
break
;
case
ID_POPUP_ROTATE_BLOCK
:
case
ID_POPUP_ROTATE_BLOCK
:
...
...
eeschema/schematic_undo_redo.cpp
View file @
2be24e1f
...
@@ -300,7 +300,7 @@ bool WinEDA_SchematicFrame::GetSchematicFromRedoList()
...
@@ -300,7 +300,7 @@ bool WinEDA_SchematicFrame::GetSchematicFromRedoList()
/* Redo the last edition:
/* Redo the last edition:
* - Save the current schematic in undo list
* - Save the current schematic in undo list
* - Get the old version
* - Get the old version
* @return FALSE if nothing done, else
TRUE
* @return FALSE if nothing done, else
true
*/
*/
{
{
if
(
GetScreen
()
->
m_RedoList
==
NULL
)
if
(
GetScreen
()
->
m_RedoList
==
NULL
)
...
@@ -314,10 +314,11 @@ bool WinEDA_SchematicFrame::GetSchematicFromRedoList()
...
@@ -314,10 +314,11 @@ bool WinEDA_SchematicFrame::GetSchematicFromRedoList()
CurrentDrawItem
=
NULL
;
CurrentDrawItem
=
NULL
;
GetScreen
()
->
SetModify
();
GetScreen
()
->
SetModify
();
SetSheetNumberAndCount
();
ReCreateHToolbar
();
ReCreateHToolbar
();
SetToolbars
();
SetToolbars
();
return
TRUE
;
return
true
;
}
}
...
@@ -408,7 +409,7 @@ void WinEDA_SchematicFrame::PutDataInPreviousState( DrawPickedStruct* List )
...
@@ -408,7 +409,7 @@ void WinEDA_SchematicFrame::PutDataInPreviousState( DrawPickedStruct* List )
break
;
break
;
case
IS_WIRE_IMAGE
:
case
IS_WIRE_IMAGE
:
/* Exchange the current wires and the o
i
ld wires */
/* Exchange the current wires and the old wires */
List
->
SetSon
(
(
(
SCH_SCREEN
*
)
GetScreen
()
)
->
ExtractWires
(
FALSE
)
);
List
->
SetSon
(
(
(
SCH_SCREEN
*
)
GetScreen
()
)
->
ExtractWires
(
FALSE
)
);
while
(
FirstItem
)
while
(
FirstItem
)
{
{
...
@@ -472,10 +473,11 @@ void WinEDA_SchematicFrame::PutDataInPreviousState( DrawPickedStruct* List )
...
@@ -472,10 +473,11 @@ void WinEDA_SchematicFrame::PutDataInPreviousState( DrawPickedStruct* List )
bool
WinEDA_SchematicFrame
::
GetSchematicFromUndoList
()
bool
WinEDA_SchematicFrame
::
GetSchematicFromUndoList
()
/**********************************************************/
/**********************************************************/
/* Undo the last edition:
/** Function GetSchematicFromUndoList
* Undo the last edition:
* - Save the current schematic in Redo list
* - Save the current schematic in Redo list
* - Get an old version of the schematic
* - Get an old version of the schematic
* @return FALSE if nothing done, else
TRUE
* @return FALSE if nothing done, else
true
*/
*/
{
{
if
(
GetScreen
()
->
m_UndoList
==
NULL
)
if
(
GetScreen
()
->
m_UndoList
==
NULL
)
...
@@ -489,10 +491,11 @@ bool WinEDA_SchematicFrame::GetSchematicFromUndoList()
...
@@ -489,10 +491,11 @@ bool WinEDA_SchematicFrame::GetSchematicFromUndoList()
CurrentDrawItem
=
NULL
;
CurrentDrawItem
=
NULL
;
GetScreen
()
->
SetModify
();
GetScreen
()
->
SetModify
();
SetSheetNumberAndCount
();
ReCreateHToolbar
();
ReCreateHToolbar
();
SetToolbars
();
SetToolbars
();
return
TRUE
;
return
true
;
}
}
...
...
eeschema/schframe.cpp
View file @
2be24e1f
...
@@ -227,7 +227,7 @@ void WinEDA_SchematicFrame::SetSheetNumberAndCount()
...
@@ -227,7 +227,7 @@ void WinEDA_SchematicFrame::SetSheetNumberAndCount()
int
sheet_count
=
g_RootSheet
->
CountSheets
();
int
sheet_count
=
g_RootSheet
->
CountSheets
();
int
SheetNumber
=
1
;
int
SheetNumber
=
1
;
wxString
current_sheetpath
=
m_CurrentSheet
->
Path
();
wxString
current_sheetpath
=
m_CurrentSheet
->
Path
();
EDA_SheetList
SheetList
(
NULL
)
;
EDA_SheetList
SheetList
;
// Examine all sheets path to find the current sheets path,
// Examine all sheets path to find the current sheets path,
// and count them from root to the current scheet path:
// and count them from root to the current scheet path:
...
@@ -317,9 +317,9 @@ void WinEDA_SchematicFrame::OnCloseWindow( wxCloseEvent& Event )
...
@@ -317,9 +317,9 @@ void WinEDA_SchematicFrame::OnCloseWindow( wxCloseEvent& Event )
return
;
return
;
}
}
EDA_SheetList
sheets
(
g_RootSheet
)
;
EDA_SheetList
SheetList
;
for
(
sheet
=
sheets
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
sheets
.
GetNext
()
)
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
{
{
if
(
sheet
->
LastScreen
()
&&
sheet
->
LastScreen
()
->
IsModify
()
)
if
(
sheet
->
LastScreen
()
&&
sheet
->
LastScreen
()
->
IsModify
()
)
break
;
break
;
...
@@ -350,7 +350,7 @@ void WinEDA_SchematicFrame::OnCloseWindow( wxCloseEvent& Event )
...
@@ -350,7 +350,7 @@ void WinEDA_SchematicFrame::OnCloseWindow( wxCloseEvent& Event )
}
}
}
}
for
(
sheet
=
sheets
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
sheets
.
GetNext
()
)
for
(
sheet
=
SheetList
.
GetFirst
();
sheet
!=
NULL
;
sheet
=
SheetList
.
GetNext
()
)
{
{
if
(
sheet
->
LastScreen
()
)
if
(
sheet
->
LastScreen
()
)
{
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment