2
* @file page_layout_reader.cpp
3
* @brief read an S expression of description of graphic items and texts
4
* to build a title block and page layout
8
* This program source code file is part of KiCad, a free EDA CAD application.
10
* Copyright (C) 1992-2013 Jean-Pierre Charras <jp.charras at wanadoo.fr>.
11
* Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
14
* This program is free software; you can redistribute it and/or
15
* modify it under the terms of the GNU General Public License
16
* as published by the Free Software Foundation; either version 2
17
* of the License, or (at your option) any later version.
19
* This program is distributed in the hope that it will be useful,
20
* but WITHOUT ANY WARRANTY; without even the implied warranty of
21
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
* GNU General Public License for more details.
24
* You should have received a copy of the GNU General Public License
25
* along with this program; if not, you may find one here:
26
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
27
* or you may search the http://www.gnu.org website for the version 2 license,
28
* or you may write to the Free Software Foundation, Inc.,
29
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
33
#include <base_struct.h>
34
#include <worksheet.h>
35
#include <worksheet_shape_builder.h>
36
#include <class_worksheet_dataitem.h>
37
#include <page_layout_reader_lexer.h>
40
using namespace TB_READER_T;
43
* Class PAGE_LAYOUT_READER_PARSER
44
* holds data and functions pertinent to parsing a S-expression file
45
* for a WORKSHEET_LAYOUT.
47
class PAGE_LAYOUT_READER_PARSER : public PAGE_LAYOUT_READER_LEXER
50
PAGE_LAYOUT_READER_PARSER( const char* aLine, const wxString& aSource );
51
void Parse( WORKSHEET_LAYOUT* aLayout )
52
throw( PARSE_ERROR, IO_ERROR );
58
* parses an integer and constrains it between two values.
59
* @param aMin is the smallest return value.
60
* @param aMax is the largest return value.
61
* @return int - the parsed integer.
63
int parseInt( int aMin, int aMax );
66
* Function parseDouble
68
* @return double - the parsed double.
72
void parseSetup( WORKSHEET_LAYOUT* aLayout ) throw( IO_ERROR, PARSE_ERROR );
73
void parseGraphic( WORKSHEET_DATAITEM * aItem ) throw( IO_ERROR, PARSE_ERROR );
74
void parseText( WORKSHEET_DATAITEM_TEXT * aItem ) throw( IO_ERROR, PARSE_ERROR );
75
void parsePolygon( WORKSHEET_DATAITEM_POLYPOLYGON * aItem )
76
throw( IO_ERROR, PARSE_ERROR );
77
void parsePolyOutline( WORKSHEET_DATAITEM_POLYPOLYGON * aItem )
78
throw( IO_ERROR, PARSE_ERROR );
79
void parseCoordinate( POINT_COORD& aCoord) throw( IO_ERROR, PARSE_ERROR );
80
void readOption( WORKSHEET_DATAITEM * aItem ) throw( IO_ERROR, PARSE_ERROR );
83
// PCB_PLOT_PARAMS_PARSER
85
PAGE_LAYOUT_READER_PARSER::PAGE_LAYOUT_READER_PARSER( const char* aLine, const wxString& aSource ) :
86
PAGE_LAYOUT_READER_LEXER( aLine, aSource )
91
void PAGE_LAYOUT_READER_PARSER::Parse( WORKSHEET_LAYOUT* aLayout )
92
throw( PARSE_ERROR, IO_ERROR )
95
WORKSHEET_DATAITEM * item;
99
while( ( token = NextTok() ) != T_RIGHT )
104
if( token == T_LEFT )
107
if( token == T_page_layout )
112
case T_setup: // Defines default values for graphic items
113
parseSetup( aLayout );
117
item = new WORKSHEET_DATAITEM( WORKSHEET_DATAITEM::WS_SEGMENT );
118
parseGraphic( item );
119
aLayout->Append( item );
123
item = new WORKSHEET_DATAITEM( WORKSHEET_DATAITEM::WS_RECT );
124
parseGraphic( item );
125
aLayout->Append( item );
129
item = new WORKSHEET_DATAITEM_POLYPOLYGON();
130
parsePolygon( (WORKSHEET_DATAITEM_POLYPOLYGON*) item );
131
aLayout->Append( item );
135
NeedSYMBOLorNUMBER();
136
item = new WORKSHEET_DATAITEM_TEXT( FromUTF8() );
137
parseText( (WORKSHEET_DATAITEM_TEXT*) item );
138
aLayout->Append( item );
142
Unexpected( CurText() );
148
void PAGE_LAYOUT_READER_PARSER::parseSetup( WORKSHEET_LAYOUT* aLayout )
149
throw( IO_ERROR, PARSE_ERROR )
152
while( ( token = NextTok() ) != T_RIGHT )
163
WORKSHEET_DATAITEM::m_DefaultLineWidth = parseDouble();
168
WORKSHEET_DATAITEM::m_DefaultTextSize.x = parseDouble();
169
WORKSHEET_DATAITEM::m_DefaultTextSize.y = parseDouble();
173
case T_textlinewidth:
174
WORKSHEET_DATAITEM::m_DefaultTextThickness = parseDouble();
179
aLayout->SetLeftMargin( parseDouble() );
184
aLayout->SetRightMargin( parseDouble() );
189
aLayout->SetTopMargin( parseDouble() );
193
case T_bottom_margin:
194
aLayout->SetBottomMargin( parseDouble() );
199
Unexpected( CurText() );
205
void PAGE_LAYOUT_READER_PARSER::parsePolygon( WORKSHEET_DATAITEM_POLYPOLYGON * aItem )
206
throw( IO_ERROR, PARSE_ERROR )
210
while( ( token = NextTok() ) != T_RIGHT )
215
if( token == T_LEFT )
221
NeedSYMBOLorNUMBER();
222
aItem->m_Info = FromUTF8();
227
parseCoordinate( aItem->m_Pos );
231
NeedSYMBOLorNUMBER();
232
aItem->m_Name = FromUTF8();
241
parsePolyOutline( aItem );
242
aItem->CloseContour();
246
aItem->m_Orient = parseDouble();
251
aItem->m_RepeatCount = parseInt( -1, 100 );
256
aItem->m_IncrementVector.x = parseDouble();
261
aItem->m_IncrementVector.y = parseDouble();
266
aItem->m_LineWidth = parseDouble();
271
Unexpected( CurText() );
276
aItem->SetBoundingBox();
279
void PAGE_LAYOUT_READER_PARSER::parsePolyOutline( WORKSHEET_DATAITEM_POLYPOLYGON * aItem )
280
throw( IO_ERROR, PARSE_ERROR )
285
while( ( token = NextTok() ) != T_RIGHT )
290
if( token == T_LEFT )
296
corner.x = parseDouble();
297
corner.y = parseDouble();
298
aItem->AppendCorner( corner );
303
Unexpected( CurText() );
309
void PAGE_LAYOUT_READER_PARSER::readOption( WORKSHEET_DATAITEM * aItem )
310
throw( IO_ERROR, PARSE_ERROR )
314
while( ( token = NextTok() ) != T_RIGHT )
322
aItem->SetPage1Option( 1 );
326
aItem->SetPage1Option( -1 );
330
Unexpected( CurText() );
337
void PAGE_LAYOUT_READER_PARSER::parseGraphic( WORKSHEET_DATAITEM * aItem )
338
throw( IO_ERROR, PARSE_ERROR )
342
while( ( token = NextTok() ) != T_RIGHT )
347
if( token == T_LEFT )
353
NeedSYMBOLorNUMBER();
354
aItem->m_Info = FromUTF8();
363
NeedSYMBOLorNUMBER();
364
aItem->m_Name = FromUTF8();
369
parseCoordinate( aItem->m_Pos );
373
parseCoordinate( aItem->m_End );
377
aItem->m_RepeatCount = parseInt( -1, 100 );
382
aItem->m_IncrementVector.x = parseDouble();
387
aItem->m_IncrementVector.y = parseDouble();
392
aItem->m_LineWidth = parseDouble();
397
Unexpected( CurText() );
404
void PAGE_LAYOUT_READER_PARSER::parseText( WORKSHEET_DATAITEM_TEXT* aItem )
405
throw( IO_ERROR, PARSE_ERROR )
409
while( ( token = NextTok() ) != T_RIGHT )
414
if( token == T_LEFT )
420
NeedSYMBOLorNUMBER();
421
aItem->m_Info = FromUTF8();
430
NeedSYMBOLorNUMBER();
431
aItem->m_Name = FromUTF8();
436
parseCoordinate( aItem->m_Pos );
440
aItem->m_RepeatCount = parseInt( -1, 100 );
445
aItem->m_IncrementVector.x = parseDouble();
450
aItem->m_IncrementVector.y = parseDouble();
455
aItem->m_IncrementLabel = parseInt(INT_MIN, INT_MAX);
460
aItem->m_BoundingBoxSize.x = parseDouble();
465
aItem->m_BoundingBoxSize.y = parseDouble();
470
while( ( token = NextTok() ) != T_RIGHT )
481
aItem->SetBold( true );
485
aItem->SetItalic( true );
489
aItem->m_TextSize.x = parseDouble();
490
aItem->m_TextSize.y = parseDouble();
495
aItem->m_LineWidth = parseDouble();
500
Unexpected( CurText() );
507
while( ( token = NextTok() ) != T_RIGHT )
515
aItem->m_Hjustify = GR_TEXT_HJUSTIFY_CENTER;
516
aItem->m_Vjustify = GR_TEXT_VJUSTIFY_CENTER;
520
aItem->m_Hjustify = GR_TEXT_HJUSTIFY_LEFT;
524
aItem->m_Hjustify = GR_TEXT_HJUSTIFY_RIGHT;
528
aItem->m_Vjustify = GR_TEXT_VJUSTIFY_TOP;
532
aItem->m_Vjustify = GR_TEXT_VJUSTIFY_BOTTOM;
536
Unexpected( CurText() );
543
aItem->m_Orient = parseDouble();
548
Unexpected( CurText() );
554
// parse an expression like " 25 1 ltcorner)"
555
void PAGE_LAYOUT_READER_PARSER::parseCoordinate( POINT_COORD& aCoord)
556
throw( IO_ERROR, PARSE_ERROR )
560
aCoord.m_Pos.x = parseDouble();
561
aCoord.m_Pos.y = parseDouble();
563
while( ( token = NextTok() ) != T_RIGHT )
568
aCoord.m_Anchor = LT_CORNER; // left top corner
572
aCoord.m_Anchor = LB_CORNER; // left bottom corner
576
aCoord.m_Anchor = RB_CORNER; // right bottom corner
580
aCoord.m_Anchor = RT_CORNER; // right top corner
584
Unexpected( CurText() );
590
int PAGE_LAYOUT_READER_PARSER::parseInt( int aMin, int aMax )
594
if( token != T_NUMBER )
595
Expecting( T_NUMBER );
597
int val = atoi( CurText() );
601
else if( val > aMax )
608
double PAGE_LAYOUT_READER_PARSER::parseDouble()
612
if( token != T_NUMBER )
613
Expecting( T_NUMBER );
615
double val = strtod( CurText(), NULL );
620
// defaultPageLayout is the default page layout description
622
// see page_layout_default_shape.cpp
623
extern const char defaultPageLayout[];
625
void WORKSHEET_LAYOUT::SetDefaultLayout()
628
PAGE_LAYOUT_READER_PARSER lp_parser( defaultPageLayout, wxT( "default page" ) );
632
lp_parser.Parse( this );
633
SetDefaultDescrFlag( true );
635
catch( IO_ERROR ioe )
637
wxLogMessage( ioe.errorText );
642
* Populates the list from a S expr description stored in a string
643
* @param aPageLayout = the S expr string
645
void WORKSHEET_LAYOUT::SetPageLayout( const char* aPageLayout, bool Append )
650
PAGE_LAYOUT_READER_PARSER lp_parser( aPageLayout, wxT( "Sexpr_string" ) );
654
lp_parser.Parse( this );
655
SetDefaultDescrFlag( true );
657
catch( IO_ERROR ioe )
659
wxLogMessage( ioe.errorText );
665
// SetLayout() try to load a custom layout file,
666
// currently defined by the environment variable KICAD_WKSFILE
667
// (a *.kicad_wks file).
668
// if does not exists, loads the default page layout.
669
void WORKSHEET_LAYOUT::SetPageLayout( const wxString& aFullFileName, bool Append )
671
wxString fullFileName = aFullFileName;
675
fullFileName = MakeFullFileName( aFullFileName );
677
if( fullFileName.IsEmpty() )
678
wxGetEnv( wxT( "KICAD_WKSFILE" ), &fullFileName );
680
if( fullFileName.IsEmpty() || !wxFileExists( fullFileName ) )
683
if( !fullFileName.IsEmpty() )
685
wxLogMessage( wxT("Page layout file <%s> not found"),
686
fullFileName.GetData() );
694
wxFile wksFile( fullFileName );
696
if( ! wksFile.IsOpened() )
703
int filelen = wksFile.Length();
704
char * buffer = new char[filelen+10];
706
if( wksFile.Read( buffer, filelen ) != filelen )
707
wxLogMessage( _("The file <%s> was not fully read"),
708
fullFileName.GetData() );
714
PAGE_LAYOUT_READER_PARSER lp_parser( buffer, fullFileName );
718
lp_parser.Parse( this );
719
SetDefaultDescrFlag( false );
721
catch( IO_ERROR ioe )
723
wxLogMessage( ioe.errorText );