2011-10-12 14:03:43 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
2015-02-21 08:11:58 +00:00
|
|
|
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
|
|
|
* Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
|
|
|
|
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
|
2011-10-12 14:03:43 +00:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
2011-10-07 14:41:30 +00:00
|
|
|
/**
|
|
|
|
* @file sch_text.cpp
|
|
|
|
* @brief Code for handling schematic sheet labels.
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <fctsys.h>
|
|
|
|
#include <gr_basic.h>
|
|
|
|
#include <macros.h>
|
|
|
|
#include <trigo.h>
|
|
|
|
#include <eeschema_id.h>
|
|
|
|
#include <class_drawpanel.h>
|
|
|
|
#include <drawtxt.h>
|
2015-02-21 09:46:44 +00:00
|
|
|
#include <schframe.h>
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <plot_common.h>
|
2012-11-20 11:35:09 +00:00
|
|
|
#include <base_units.h>
|
2013-01-12 17:32:24 +00:00
|
|
|
#include <msgpanel.h>
|
2009-02-04 15:25:03 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <general.h>
|
|
|
|
#include <protos.h>
|
|
|
|
#include <sch_text.h>
|
|
|
|
#include <class_netlist_object.h>
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2011-07-03 18:51:07 +00:00
|
|
|
|
2011-10-12 14:03:43 +00:00
|
|
|
extern void IncrementLabelMember( wxString& name );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
/* Names of sheet label types. */
|
2009-04-05 20:49:15 +00:00
|
|
|
const char* SheetLabelType[] =
|
|
|
|
{
|
|
|
|
"Input",
|
|
|
|
"Output",
|
|
|
|
"BiDi",
|
|
|
|
"3State",
|
|
|
|
"UnSpc",
|
2013-04-07 11:55:18 +00:00
|
|
|
"???"
|
2009-04-05 20:49:15 +00:00
|
|
|
};
|
|
|
|
|
2009-05-05 17:32:07 +00:00
|
|
|
/* Coding polygons for global symbol graphic shapes.
|
|
|
|
* the first parml is the number of corners
|
|
|
|
* others are the corners coordinates in reduced units
|
|
|
|
* the real coordinate is the reduced coordinate * text half size
|
|
|
|
*/
|
2009-05-12 12:12:34 +00:00
|
|
|
static int TemplateIN_HN[] = { 6, 0, 0, -1, -1, -2, -1, -2, 1, -1, 1, 0, 0 };
|
|
|
|
static int TemplateIN_HI[] = { 6, 0, 0, 1, 1, 2, 1, 2, -1, 1, -1, 0, 0 };
|
|
|
|
static int TemplateIN_UP[] = { 6, 0, 0, 1, -1, 1, -2, -1, -2, -1, -1, 0, 0 };
|
|
|
|
static int TemplateIN_BOTTOM[] = { 6, 0, 0, 1, 1, 1, 2, -1, 2, -1, 1, 0, 0 };
|
|
|
|
|
|
|
|
static int TemplateOUT_HN[] = { 6, -2, 0, -1, 1, 0, 1, 0, -1, -1, -1, -2, 0 };
|
|
|
|
static int TemplateOUT_HI[] = { 6, 2, 0, 1, -1, 0, -1, 0, 1, 1, 1, 2, 0 };
|
|
|
|
static int TemplateOUT_UP[] = { 6, 0, -2, 1, -1, 1, 0, -1, 0, -1, -1, 0, -2 };
|
|
|
|
static int TemplateOUT_BOTTOM[] = { 6, 0, 2, 1, 1, 1, 0, -1, 0, -1, 1, 0, 2 };
|
|
|
|
|
|
|
|
static int TemplateUNSPC_HN[] = { 5, 0, -1, -2, -1, -2, 1, 0, 1, 0, -1 };
|
|
|
|
static int TemplateUNSPC_HI[] = { 5, 0, -1, 2, -1, 2, 1, 0, 1, 0, -1 };
|
|
|
|
static int TemplateUNSPC_UP[] = { 5, 1, 0, 1, -2, -1, -2, -1, 0, 1, 0 };
|
|
|
|
static int TemplateUNSPC_BOTTOM[] = { 5, 1, 0, 1, 2, -1, 2, -1, 0, 1, 0 };
|
|
|
|
|
|
|
|
static int TemplateBIDI_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
|
|
|
|
static int TemplateBIDI_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
|
|
|
|
static int TemplateBIDI_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
|
|
|
|
static int TemplateBIDI_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
|
|
|
|
|
|
|
|
static int Template3STATE_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
|
|
|
|
static int Template3STATE_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
|
|
|
|
static int Template3STATE_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
|
|
|
|
static int Template3STATE_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
|
|
|
|
|
|
|
|
static int* TemplateShape[5][4] =
|
2009-04-05 20:49:15 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
{ TemplateIN_HN, TemplateIN_UP, TemplateIN_HI, TemplateIN_BOTTOM },
|
|
|
|
{ TemplateOUT_HN, TemplateOUT_UP, TemplateOUT_HI, TemplateOUT_BOTTOM },
|
|
|
|
{ TemplateBIDI_HN, TemplateBIDI_UP, TemplateBIDI_HI, TemplateBIDI_BOTTOM },
|
|
|
|
{ Template3STATE_HN, Template3STATE_UP, Template3STATE_HI, Template3STATE_BOTTOM },
|
|
|
|
{ TemplateUNSPC_HN, TemplateUNSPC_UP, TemplateUNSPC_HI, TemplateUNSPC_BOTTOM }
|
2009-04-05 20:49:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
SCH_TEXT::SCH_TEXT( const wxPoint& pos, const wxString& text, KICAD_T aType ) :
|
2010-12-21 15:13:09 +00:00
|
|
|
SCH_ITEM( NULL, aType ),
|
2011-03-29 19:33:07 +00:00
|
|
|
EDA_TEXT( text )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2009-05-05 17:32:07 +00:00
|
|
|
m_Layer = LAYER_NOTES;
|
2010-12-21 15:13:09 +00:00
|
|
|
m_Pos = pos;
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = 0;
|
|
|
|
m_isDangling = false;
|
2010-12-21 15:13:09 +00:00
|
|
|
m_MultilineAllowed = true;
|
2011-12-08 15:45:01 +00:00
|
|
|
m_schematicOrientation = 0;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2009-05-05 17:32:07 +00:00
|
|
|
|
2010-12-21 15:13:09 +00:00
|
|
|
SCH_TEXT::SCH_TEXT( const SCH_TEXT& aText ) :
|
|
|
|
SCH_ITEM( aText ),
|
2011-03-29 19:33:07 +00:00
|
|
|
EDA_TEXT( aText )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2010-12-21 15:13:09 +00:00
|
|
|
m_Pos = aText.m_Pos;
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = aText.m_shape;
|
2010-12-21 15:13:09 +00:00
|
|
|
m_MultilineAllowed = aText.m_MultilineAllowed;
|
2011-12-08 15:45:01 +00:00
|
|
|
m_schematicOrientation = aText.m_schematicOrientation;
|
|
|
|
m_isDangling = false;
|
2010-12-21 15:13:09 +00:00
|
|
|
}
|
2008-01-21 16:21:41 +00:00
|
|
|
|
2008-02-12 21:12:46 +00:00
|
|
|
|
2012-03-17 14:39:27 +00:00
|
|
|
EDA_ITEM* SCH_TEXT::Clone() const
|
2010-12-21 15:13:09 +00:00
|
|
|
{
|
|
|
|
return new SCH_TEXT( *this );
|
|
|
|
}
|
2007-09-01 12:00:30 +00:00
|
|
|
|
|
|
|
|
2010-12-21 15:13:09 +00:00
|
|
|
void SCH_TEXT::IncrementLabel()
|
|
|
|
{
|
|
|
|
IncrementLabelMember( m_Text );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-17 13:24:22 +00:00
|
|
|
wxPoint SCH_TEXT::GetSchematicTextOffset() const
|
2009-05-12 12:12:34 +00:00
|
|
|
{
|
|
|
|
wxPoint text_offset;
|
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
// add a small offset (TXTMARGE) to x ( or y) position to allow a text to
|
|
|
|
// be on a wire or a line and be readable
|
2011-12-08 15:45:01 +00:00
|
|
|
switch( m_schematicOrientation )
|
2009-05-12 12:12:34 +00:00
|
|
|
{
|
|
|
|
default:
|
|
|
|
case 0: /* Horiz Normal Orientation (left justified) */
|
|
|
|
text_offset.y = -TXTMARGE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: /* Vert Orientation UP */
|
|
|
|
text_offset.x = -TXTMARGE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2: /* Horiz Orientation - Right justified */
|
|
|
|
text_offset.y = -TXTMARGE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: /* Vert Orientation BOTTOM */
|
|
|
|
text_offset.x = -TXTMARGE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return text_offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-10-20 19:43:58 +00:00
|
|
|
bool SCH_TEXT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint * aFindLocation )
|
2010-03-16 18:22:59 +00:00
|
|
|
{
|
2011-12-13 15:37:33 +00:00
|
|
|
wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText() );
|
2011-12-01 16:49:28 +00:00
|
|
|
|
2010-10-20 19:43:58 +00:00
|
|
|
if( SCH_ITEM::Matches( m_Text, aSearchData ) )
|
|
|
|
{
|
2011-03-29 19:33:07 +00:00
|
|
|
EDA_RECT BoundaryBox = GetBoundingBox();
|
2011-10-12 14:03:43 +00:00
|
|
|
|
2010-10-20 19:43:58 +00:00
|
|
|
if( aFindLocation )
|
|
|
|
*aFindLocation = BoundaryBox.Centre();
|
2011-10-12 14:03:43 +00:00
|
|
|
|
2010-10-20 19:43:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
2010-03-16 18:22:59 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
return false;
|
2009-05-12 12:12:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
void SCH_TEXT::MirrorY( int aYaxis_position )
|
2009-07-27 14:32:40 +00:00
|
|
|
{
|
2013-03-01 19:59:29 +00:00
|
|
|
// Text is NOT really mirrored; it is moved to a suitable horizontal position
|
2011-03-03 01:58:12 +00:00
|
|
|
switch( GetOrientation() )
|
2010-07-11 16:24:44 +00:00
|
|
|
{
|
2013-03-01 19:59:29 +00:00
|
|
|
case 0: // horizontal text
|
|
|
|
SetOrientation( 2 );
|
2010-07-11 16:24:44 +00:00
|
|
|
break;
|
|
|
|
|
2013-03-01 19:59:29 +00:00
|
|
|
case 2: // invert horizontal text
|
|
|
|
SetOrientation( 0 );
|
2010-09-05 17:01:48 +00:00
|
|
|
break;
|
|
|
|
|
2013-03-01 19:59:29 +00:00
|
|
|
case 1: // Vert Orientation UP
|
|
|
|
case 3: // Vert Orientation BOTTOM
|
2010-07-11 16:24:44 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-03-01 19:59:29 +00:00
|
|
|
m_Pos.x -= aYaxis_position;
|
|
|
|
NEGATE( m_Pos.x );
|
|
|
|
m_Pos.x += aYaxis_position;
|
2009-07-27 14:32:40 +00:00
|
|
|
}
|
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
void SCH_TEXT::MirrorX( int aXaxis_position )
|
2010-09-05 17:01:48 +00:00
|
|
|
{
|
2013-03-01 19:59:29 +00:00
|
|
|
// Text is NOT really mirrored; it is moved to a suitable vertical position
|
2011-03-03 01:58:12 +00:00
|
|
|
switch( GetOrientation() )
|
2010-09-05 17:01:48 +00:00
|
|
|
{
|
2013-03-01 19:59:29 +00:00
|
|
|
case 1: // Vert Orientation UP
|
|
|
|
SetOrientation( 3 );
|
2010-09-05 17:01:48 +00:00
|
|
|
break;
|
|
|
|
|
2013-03-01 19:59:29 +00:00
|
|
|
case 3: // Vert Orientation BOTTOM
|
|
|
|
SetOrientation( 1 );
|
2010-09-05 17:01:48 +00:00
|
|
|
break;
|
|
|
|
|
2013-03-01 19:59:29 +00:00
|
|
|
case 0: // horizontal text
|
|
|
|
case 2: // invert horizontal text
|
2010-09-05 17:01:48 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2013-03-01 19:59:29 +00:00
|
|
|
m_Pos.y -= aXaxis_position;
|
|
|
|
NEGATE( m_Pos.y );
|
|
|
|
m_Pos.y += aXaxis_position;
|
2010-09-05 17:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
void SCH_TEXT::Rotate( wxPoint aPosition )
|
2010-09-05 17:01:48 +00:00
|
|
|
{
|
|
|
|
int dy;
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
RotatePoint( &m_Pos, aPosition, 900 );
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( (GetOrientation() + 1) % 4 );
|
|
|
|
|
|
|
|
switch( GetOrientation() )
|
2010-09-05 17:01:48 +00:00
|
|
|
{
|
2012-09-07 19:29:44 +00:00
|
|
|
case 0: // horizontal text
|
2010-09-05 17:01:48 +00:00
|
|
|
dy = m_Size.y;
|
|
|
|
break;
|
|
|
|
|
2012-09-07 19:29:44 +00:00
|
|
|
case 1: // Vert Orientation UP
|
2010-09-05 17:01:48 +00:00
|
|
|
dy = 0;
|
|
|
|
break;
|
|
|
|
|
2012-09-07 19:29:44 +00:00
|
|
|
case 2: // invert horizontal text
|
2010-09-05 17:01:48 +00:00
|
|
|
dy = m_Size.y;
|
|
|
|
break;
|
|
|
|
|
2012-09-07 19:29:44 +00:00
|
|
|
case 3: // Vert Orientation BOTTOM
|
2010-09-05 17:01:48 +00:00
|
|
|
dy = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
dy = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_Pos.y += dy;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-03 01:58:12 +00:00
|
|
|
void SCH_TEXT::SetOrientation( int aOrientation )
|
2009-05-12 12:12:34 +00:00
|
|
|
{
|
2011-12-08 15:45:01 +00:00
|
|
|
m_schematicOrientation = aOrientation;
|
2009-05-12 12:12:34 +00:00
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
switch( m_schematicOrientation )
|
2009-05-12 12:12:34 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
default:
|
|
|
|
case 0: /* Horiz Normal Orientation (left justified) */
|
|
|
|
m_Orient = TEXT_ORIENT_HORIZ;
|
|
|
|
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
|
|
|
|
m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
|
2009-05-12 12:12:34 +00:00
|
|
|
break;
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
case 1: /* Vert Orientation UP */
|
|
|
|
m_Orient = TEXT_ORIENT_VERT;
|
|
|
|
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
|
|
|
|
m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
|
2009-05-12 12:12:34 +00:00
|
|
|
break;
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
case 2: /* Horiz Orientation - Right justified */
|
|
|
|
m_Orient = TEXT_ORIENT_HORIZ;
|
|
|
|
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
|
|
|
|
m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
|
2009-05-12 12:12:34 +00:00
|
|
|
break;
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
case 3: /* Vert Orientation BOTTOM */
|
|
|
|
m_Orient = TEXT_ORIENT_VERT;
|
|
|
|
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
|
|
|
|
m_VJustify = GR_TEXT_VJUSTIFY_BOTTOM;
|
2009-05-12 12:12:34 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
|
2011-10-19 20:32:21 +00:00
|
|
|
void SCH_TEXT::SwapData( SCH_ITEM* aItem )
|
2009-07-27 14:32:40 +00:00
|
|
|
{
|
2011-10-19 20:32:21 +00:00
|
|
|
SCH_TEXT* item = (SCH_TEXT*) aItem;
|
|
|
|
|
|
|
|
EXCHG( m_Text, item->m_Text );
|
|
|
|
EXCHG( m_Pos, item->m_Pos );
|
|
|
|
EXCHG( m_Size, item->m_Size );
|
|
|
|
EXCHG( m_Thickness, item->m_Thickness );
|
2011-12-08 15:45:01 +00:00
|
|
|
EXCHG( m_shape, item->m_shape );
|
2011-10-19 20:32:21 +00:00
|
|
|
EXCHG( m_Orient, item->m_Orient );
|
|
|
|
|
|
|
|
EXCHG( m_Layer, item->m_Layer );
|
|
|
|
EXCHG( m_HJustify, item->m_HJustify );
|
|
|
|
EXCHG( m_VJustify, item->m_VJustify );
|
2011-12-08 15:45:01 +00:00
|
|
|
EXCHG( m_isDangling, item->m_isDangling );
|
|
|
|
EXCHG( m_schematicOrientation, item->m_schematicOrientation );
|
2009-07-27 14:32:40 +00:00
|
|
|
}
|
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
|
2010-12-10 19:47:44 +00:00
|
|
|
int SCH_TEXT::GetPenSize() const
|
2010-09-05 17:01:48 +00:00
|
|
|
{
|
2010-11-27 13:09:18 +00:00
|
|
|
int pensize = m_Thickness;
|
2010-09-05 17:01:48 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
if( pensize == 0 ) // Use default values for pen size
|
|
|
|
{
|
|
|
|
if( m_Bold )
|
|
|
|
pensize = GetPenSizeForBold( m_Size.x );
|
|
|
|
else
|
2012-09-28 17:47:41 +00:00
|
|
|
pensize = GetDefaultLineThickness();
|
2010-09-05 17:01:48 +00:00
|
|
|
}
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
// Clip pen size for small texts:
|
|
|
|
pensize = Clamp_Text_PenSize( pensize, m_Size, m_Bold );
|
|
|
|
return pensize;
|
2010-09-05 17:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-21 19:30:59 +00:00
|
|
|
void SCH_TEXT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& aOffset,
|
2012-09-02 12:06:47 +00:00
|
|
|
GR_DRAWMODE DrawMode, EDA_COLOR_T Color )
|
2010-09-05 17:01:48 +00:00
|
|
|
{
|
2012-03-26 23:47:08 +00:00
|
|
|
EDA_COLOR_T color;
|
2012-09-28 17:47:41 +00:00
|
|
|
int linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness;
|
2013-06-29 09:52:22 +00:00
|
|
|
EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL;
|
2010-11-03 14:13:15 +00:00
|
|
|
|
|
|
|
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
|
|
|
|
|
|
|
|
if( Color >= 0 )
|
2012-09-02 12:06:47 +00:00
|
|
|
color = Color;
|
2010-11-03 14:13:15 +00:00
|
|
|
else
|
2013-04-04 21:35:01 +00:00
|
|
|
color = GetLayerColor( m_Layer );
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
GRSetDrawMode( DC, DrawMode );
|
|
|
|
|
|
|
|
wxPoint text_offset = aOffset + GetSchematicTextOffset();
|
2010-11-27 13:09:18 +00:00
|
|
|
EXCHG( linewidth, m_Thickness ); // Set the minimum width
|
2013-06-29 09:52:22 +00:00
|
|
|
EDA_TEXT::Draw( clipbox, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR );
|
2010-11-27 13:09:18 +00:00
|
|
|
EXCHG( linewidth, m_Thickness ); // set initial value
|
2011-10-12 14:03:43 +00:00
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
if( m_isDangling )
|
2010-11-03 14:13:15 +00:00
|
|
|
DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color );
|
|
|
|
|
|
|
|
// Enable these line to draw the bounding box (debug tests purposes only)
|
2013-11-06 19:36:46 +00:00
|
|
|
#if 0
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
2011-03-29 19:33:07 +00:00
|
|
|
EDA_RECT BoundaryBox = GetBoundingBox();
|
2013-06-29 09:52:22 +00:00
|
|
|
GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
|
2010-11-03 14:13:15 +00:00
|
|
|
}
|
|
|
|
#endif
|
2010-09-05 17:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
bool SCH_TEXT::Save( FILE* aFile ) const
|
2009-07-27 14:32:40 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
bool success = true;
|
|
|
|
const char* shape = "~";
|
|
|
|
|
|
|
|
if( m_Italic )
|
|
|
|
shape = "Italic";
|
|
|
|
|
2011-10-05 12:36:32 +00:00
|
|
|
// For compatibility reason, the text must be saved in only one text line
|
|
|
|
// so we replace all E.O.L. by \\n
|
2010-11-03 14:13:15 +00:00
|
|
|
wxString text = m_Text;
|
|
|
|
|
2011-10-05 12:36:32 +00:00
|
|
|
text.Replace( wxT("\n"), wxT( "\\n" ) );
|
2010-07-11 16:24:44 +00:00
|
|
|
|
2011-10-05 12:36:32 +00:00
|
|
|
// Here we should have no CR or LF character in line
|
|
|
|
// This is not always the case if a multiline text was copied (using a copy/paste function)
|
|
|
|
// from a text that uses E.O.L characters that differs from the current EOL format
|
|
|
|
// This is mainly the case under Linux using LF symbol when copying a text from
|
|
|
|
// Windows (using CRLF symbol)
|
|
|
|
// So we must just remove the extra CR left (or LF left under MacOSX)
|
|
|
|
for( unsigned ii = 0; ii < text.Len(); )
|
|
|
|
{
|
|
|
|
if( text[ii] == 0x0A || text[ii] == 0x0D )
|
|
|
|
text.erase( ii, 1 );
|
|
|
|
else
|
|
|
|
ii++;
|
2010-07-11 16:24:44 +00:00
|
|
|
}
|
|
|
|
|
2011-10-05 12:36:32 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
if( fprintf( aFile, "Text Notes %-4d %-4d %-4d %-4d %s %d\n%s\n",
|
2011-12-08 15:45:01 +00:00
|
|
|
m_Pos.x, m_Pos.y, m_schematicOrientation, m_Size.x,
|
2011-02-28 18:36:19 +00:00
|
|
|
shape, m_Thickness, TO_UTF8( text ) ) == EOF )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
success = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
2009-07-27 14:32:40 +00:00
|
|
|
}
|
2009-05-12 12:12:34 +00:00
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
bool SCH_TEXT::Load( LINE_READER& aLine, wxString& aErrorMsg )
|
|
|
|
{
|
|
|
|
char Name1[256];
|
|
|
|
char Name2[256];
|
|
|
|
char Name3[256];
|
|
|
|
int thickness = 0, size = 0, orient = 0;
|
|
|
|
|
|
|
|
Name1[0] = 0; Name2[0] = 0; Name3[0] = 0;
|
|
|
|
|
|
|
|
char* sline = (char*) aLine;
|
|
|
|
|
|
|
|
while( ( *sline != ' ' ) && *sline )
|
|
|
|
sline++;
|
|
|
|
|
|
|
|
// sline points the start of parameters
|
|
|
|
int ii = sscanf( sline, "%s %d %d %d %d %s %s %d", Name1, &m_Pos.x, &m_Pos.y,
|
|
|
|
&orient, &size, Name2, Name3, &thickness );
|
|
|
|
|
|
|
|
if( ii < 4 )
|
|
|
|
{
|
2011-09-30 18:15:37 +00:00
|
|
|
aErrorMsg.Printf( wxT( "Eeschema file text load error at line %d" ),
|
2010-11-10 15:30:12 +00:00
|
|
|
aLine.LineNumber() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !aLine.ReadLine() )
|
|
|
|
{
|
2011-09-30 18:15:37 +00:00
|
|
|
aErrorMsg.Printf( wxT( "Eeschema file text load error at line %d" ),
|
2010-11-10 15:30:12 +00:00
|
|
|
aLine.LineNumber() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( size == 0 )
|
2014-05-16 13:57:53 +00:00
|
|
|
size = GetDefaultTextSize();
|
2010-11-10 15:30:12 +00:00
|
|
|
|
|
|
|
char* text = strtok( (char*) aLine, "\n\r" );
|
|
|
|
|
|
|
|
if( text == NULL )
|
|
|
|
{
|
2011-09-30 18:15:37 +00:00
|
|
|
aErrorMsg.Printf( wxT( "Eeschema file text load error at line %d" ),
|
2010-11-10 15:30:12 +00:00
|
|
|
aLine.LineNumber() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-02-28 18:36:19 +00:00
|
|
|
wxString val = FROM_UTF8( text );
|
2011-12-08 15:45:01 +00:00
|
|
|
|
2011-03-03 19:08:13 +00:00
|
|
|
for( ; ; )
|
2010-11-10 15:30:12 +00:00
|
|
|
{
|
|
|
|
int i = val.find( wxT( "\\n" ) );
|
|
|
|
|
|
|
|
if( i == wxNOT_FOUND )
|
|
|
|
break;
|
2010-12-10 19:47:44 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
val.erase( i, 2 );
|
|
|
|
val.insert( i, wxT( "\n" ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
m_Text = val;
|
|
|
|
m_Size.x = m_Size.y = size;
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( orient );
|
2010-11-10 15:30:12 +00:00
|
|
|
|
|
|
|
if( isdigit( Name3[0] ) )
|
|
|
|
{
|
|
|
|
thickness = atol( Name3 );
|
|
|
|
m_Bold = ( thickness != 0 );
|
2010-11-27 13:09:18 +00:00
|
|
|
m_Thickness = m_Bold ? GetPenSizeForBold( size ) : 0;
|
2010-11-10 15:30:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if( strnicmp( Name2, "Italic", 6 ) == 0 )
|
|
|
|
m_Italic = 1;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
void SCH_TEXT::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
|
2010-09-05 17:01:48 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
// Normal text labels cannot be tested for dangling ends.
|
2010-12-10 19:47:44 +00:00
|
|
|
if( Type() == SCH_TEXT_T )
|
2010-11-03 14:13:15 +00:00
|
|
|
return;
|
|
|
|
|
2011-12-06 21:02:21 +00:00
|
|
|
DANGLING_END_ITEM item( LABEL_END, this, m_Pos );
|
2010-11-03 14:13:15 +00:00
|
|
|
aItemList.push_back( item );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SCH_TEXT::IsDanglingStateChanged( std::vector< DANGLING_END_ITEM >& aItemList )
|
|
|
|
{
|
|
|
|
// Normal text labels cannot be tested for dangling ends.
|
2010-12-10 19:47:44 +00:00
|
|
|
if( Type() == SCH_TEXT_T )
|
2010-11-03 14:13:15 +00:00
|
|
|
return false;
|
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
bool previousState = m_isDangling;
|
|
|
|
m_isDangling = true;
|
2010-11-03 14:13:15 +00:00
|
|
|
|
|
|
|
for( unsigned ii = 0; ii < aItemList.size(); ii++ )
|
2010-09-05 17:01:48 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
DANGLING_END_ITEM& item = aItemList[ii];
|
|
|
|
|
2011-12-06 21:02:21 +00:00
|
|
|
if( item.GetItem() == this )
|
2010-11-03 14:13:15 +00:00
|
|
|
continue;
|
|
|
|
|
2011-12-06 21:02:21 +00:00
|
|
|
switch( item.GetType() )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
case PIN_END:
|
|
|
|
case LABEL_END:
|
|
|
|
case SHEET_LABEL_END:
|
2011-12-06 21:02:21 +00:00
|
|
|
if( m_Pos == item.GetPosition() )
|
2011-12-08 15:45:01 +00:00
|
|
|
m_isDangling = false;
|
2011-12-06 21:02:21 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
break;
|
2010-09-05 17:01:48 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
case WIRE_START_END:
|
|
|
|
case BUS_START_END:
|
|
|
|
{
|
|
|
|
// These schematic items have created 2 DANGLING_END_ITEM one per end. But being
|
|
|
|
// a paranoid programmer, I'll check just in case.
|
|
|
|
ii++;
|
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
wxCHECK_MSG( ii < aItemList.size(), previousState != m_isDangling,
|
2010-11-03 14:13:15 +00:00
|
|
|
wxT( "Dangling end type list overflow. Bad programmer!" ) );
|
|
|
|
|
|
|
|
DANGLING_END_ITEM & nextItem = aItemList[ii];
|
2013-09-27 12:30:35 +00:00
|
|
|
m_isDangling = !IsPointOnSegment( item.GetPosition(), nextItem.GetPosition(), m_Pos );
|
2010-11-03 14:13:15 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-03-30 19:55:26 +00:00
|
|
|
if( !m_isDangling )
|
2010-11-03 14:13:15 +00:00
|
|
|
break;
|
2010-09-05 17:01:48 +00:00
|
|
|
}
|
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
return previousState != m_isDangling;
|
2010-09-05 17:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
bool SCH_TEXT::IsSelectStateChanged( const wxRect& aRect )
|
2010-09-05 17:01:48 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
bool previousState = IsSelected();
|
|
|
|
|
|
|
|
if( aRect.Contains( m_Pos ) )
|
2013-03-30 19:55:26 +00:00
|
|
|
SetFlags( SELECTED );
|
2010-11-03 14:13:15 +00:00
|
|
|
else
|
2015-02-21 08:11:58 +00:00
|
|
|
ClearFlags( SELECTED );
|
2010-11-03 14:13:15 +00:00
|
|
|
|
|
|
|
return previousState != IsSelected();
|
2010-09-05 17:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-13 16:27:30 +00:00
|
|
|
void SCH_TEXT::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const
|
2009-05-12 12:12:34 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
// Normal text labels do not have connection points. All others do.
|
2010-12-10 19:47:44 +00:00
|
|
|
if( Type() == SCH_TEXT_T )
|
2010-11-03 14:13:15 +00:00
|
|
|
return;
|
2009-05-12 12:12:34 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
aPoints.push_back( m_Pos );
|
2009-05-12 12:12:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-11-24 17:48:14 +00:00
|
|
|
const EDA_RECT SCH_TEXT::GetBoundingBox() const
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
// We must pass the effective text thickness to GetTextBox
|
|
|
|
// when calculating the bounding box
|
2012-09-28 17:47:41 +00:00
|
|
|
int linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness;
|
2009-05-12 12:12:34 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
|
2010-12-10 19:47:44 +00:00
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
EDA_RECT rect = GetTextBox( -1, linewidth );
|
2010-11-03 14:13:15 +00:00
|
|
|
|
|
|
|
if( m_Orient ) // Rotate rect
|
2008-04-15 19:38:19 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
wxPoint pos = rect.GetOrigin();
|
|
|
|
wxPoint end = rect.GetEnd();
|
|
|
|
RotatePoint( &pos, m_Pos, m_Orient );
|
|
|
|
RotatePoint( &end, m_Pos, m_Orient );
|
|
|
|
rect.SetOrigin( pos );
|
|
|
|
rect.SetEnd( end );
|
2008-04-15 19:38:19 +00:00
|
|
|
}
|
2009-05-12 12:12:34 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
rect.Normalize();
|
|
|
|
return rect;
|
2008-04-15 19:38:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-25 19:16:05 +00:00
|
|
|
wxString SCH_TEXT::GetSelectMenuText() const
|
2010-12-10 19:47:44 +00:00
|
|
|
{
|
2011-03-26 10:08:50 +00:00
|
|
|
wxString msg;
|
2014-09-13 18:15:45 +00:00
|
|
|
msg.Printf( _( "Graphic Text %s" ), GetChars( ShortenedShownText() ) );
|
2011-03-26 10:08:50 +00:00
|
|
|
return msg;
|
2011-03-25 19:16:05 +00:00
|
|
|
}
|
2010-12-13 15:59:00 +00:00
|
|
|
|
2011-03-25 19:16:05 +00:00
|
|
|
|
2013-09-25 19:09:57 +00:00
|
|
|
void SCH_TEXT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
|
|
|
|
SCH_SHEET_PATH* aSheetPath )
|
2011-10-12 14:03:43 +00:00
|
|
|
{
|
|
|
|
if( GetLayer() == LAYER_NOTES || GetLayer() == LAYER_SHEETLABEL )
|
|
|
|
return;
|
|
|
|
|
|
|
|
NETLIST_OBJECT* item = new NETLIST_OBJECT();
|
2013-09-29 18:24:38 +00:00
|
|
|
item->m_SheetPath = *aSheetPath;
|
|
|
|
item->m_SheetPathInclude = *aSheetPath;
|
2011-10-12 14:03:43 +00:00
|
|
|
item->m_Comp = (SCH_ITEM*) this;
|
|
|
|
item->m_Type = NET_LABEL;
|
|
|
|
|
|
|
|
if( GetLayer() == LAYER_GLOBLABEL )
|
|
|
|
item->m_Type = NET_GLOBLABEL;
|
|
|
|
else if( GetLayer() == LAYER_HIERLABEL )
|
|
|
|
item->m_Type = NET_HIERLABEL;
|
|
|
|
|
|
|
|
item->m_Label = m_Text;
|
|
|
|
item->m_Start = item->m_End = m_Pos;
|
|
|
|
|
|
|
|
aNetListItems.push_back( item );
|
|
|
|
|
|
|
|
/* If a bus connects to label */
|
|
|
|
if( IsBusLabel( m_Text ) )
|
2011-10-12 15:34:52 +00:00
|
|
|
item->ConvertBusToNetListItems( aNetListItems );
|
2011-10-12 14:03:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
bool SCH_TEXT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
|
2011-03-25 19:16:05 +00:00
|
|
|
{
|
2013-04-07 18:49:13 +00:00
|
|
|
EDA_RECT bBox = GetBoundingBox();
|
|
|
|
bBox.Inflate( aAccuracy );
|
|
|
|
return bBox.Contains( aPosition );
|
2010-12-10 19:47:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
bool SCH_TEXT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
|
2010-12-10 19:47:44 +00:00
|
|
|
{
|
2013-04-07 18:49:13 +00:00
|
|
|
EDA_RECT bBox = GetBoundingBox();
|
|
|
|
bBox.Inflate( aAccuracy );
|
|
|
|
|
|
|
|
if( aContained )
|
|
|
|
return aRect.Contains( bBox );
|
|
|
|
|
|
|
|
return aRect.Intersects( bBox );
|
2010-12-10 19:47:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
void SCH_TEXT::Plot( PLOTTER* aPlotter )
|
2011-06-17 13:24:22 +00:00
|
|
|
{
|
|
|
|
static std::vector <wxPoint> Poly;
|
|
|
|
|
2013-04-04 21:35:01 +00:00
|
|
|
EDA_COLOR_T color = GetLayerColor( GetLayer() );
|
2012-03-26 23:47:08 +00:00
|
|
|
wxPoint textpos = m_Pos + GetSchematicTextOffset();
|
|
|
|
int thickness = GetPenSize();
|
2011-06-17 13:24:22 +00:00
|
|
|
|
2012-05-03 18:37:56 +00:00
|
|
|
aPlotter->SetCurrentLineWidth( thickness );
|
2011-06-17 13:24:22 +00:00
|
|
|
|
|
|
|
if( m_MultilineAllowed )
|
|
|
|
{
|
2013-11-29 08:13:43 +00:00
|
|
|
std::vector<wxPoint> positions;
|
2015-01-15 20:01:53 +00:00
|
|
|
wxArrayString strings_list;
|
|
|
|
wxStringSplit( GetShownText(), strings_list, '\n' );
|
|
|
|
positions.reserve( strings_list.Count() );
|
2011-06-17 13:24:22 +00:00
|
|
|
|
2015-01-15 20:01:53 +00:00
|
|
|
GetPositionsOfLinesOfMultilineText(positions, strings_list.Count() );
|
2011-06-17 13:24:22 +00:00
|
|
|
|
2015-01-15 20:01:53 +00:00
|
|
|
for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
|
2011-06-17 13:24:22 +00:00
|
|
|
{
|
2015-01-15 20:01:53 +00:00
|
|
|
wxString& txt = strings_list.Item( ii );
|
2013-11-29 08:13:43 +00:00
|
|
|
aPlotter->Text( positions[ii], color, txt, m_Orient, m_Size, m_HJustify,
|
2011-06-17 13:24:22 +00:00
|
|
|
m_VJustify, thickness, m_Italic, m_Bold );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-09-13 18:15:45 +00:00
|
|
|
aPlotter->Text( textpos, color, GetShownText(), m_Orient, m_Size, m_HJustify,
|
2011-06-17 13:24:22 +00:00
|
|
|
m_VJustify, thickness, m_Italic, m_Bold );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Draw graphic symbol for global or hierarchical labels */
|
|
|
|
CreateGraphicShape( Poly, m_Pos );
|
|
|
|
|
2012-05-03 18:37:56 +00:00
|
|
|
aPlotter->SetCurrentLineWidth( GetPenSize() );
|
2011-06-17 13:24:22 +00:00
|
|
|
|
|
|
|
if( Poly.size() )
|
|
|
|
aPlotter->PlotPoly( Poly, NO_FILL );
|
|
|
|
}
|
|
|
|
|
2013-01-12 17:32:24 +00:00
|
|
|
|
2012-11-20 11:35:09 +00:00
|
|
|
/*
|
|
|
|
* Display the type, shape, size and some other props to the Message panel
|
|
|
|
*/
|
2013-01-12 17:32:24 +00:00
|
|
|
void SCH_TEXT::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
|
2012-11-20 11:35:09 +00:00
|
|
|
{
|
|
|
|
wxString msg;
|
|
|
|
|
|
|
|
switch( Type() )
|
|
|
|
{
|
2013-01-12 17:32:24 +00:00
|
|
|
case SCH_TEXT_T:
|
2014-11-15 19:06:05 +00:00
|
|
|
msg = _( "Graphic Text" );
|
2013-01-12 17:32:24 +00:00
|
|
|
break;
|
2012-11-20 11:35:09 +00:00
|
|
|
|
2013-01-12 17:32:24 +00:00
|
|
|
case SCH_LABEL_T:
|
|
|
|
msg = _( "Label" );
|
|
|
|
break;
|
2012-11-20 11:35:09 +00:00
|
|
|
|
2013-01-12 17:32:24 +00:00
|
|
|
case SCH_GLOBAL_LABEL_T:
|
2014-11-15 19:06:05 +00:00
|
|
|
msg = _( "Global Label" );
|
2013-01-12 17:32:24 +00:00
|
|
|
break;
|
2012-11-20 11:35:09 +00:00
|
|
|
|
2013-01-12 17:32:24 +00:00
|
|
|
case SCH_HIERARCHICAL_LABEL_T:
|
2014-11-15 19:06:05 +00:00
|
|
|
msg = _( "Hierarchical Label" );
|
2013-01-12 17:32:24 +00:00
|
|
|
break;
|
2012-11-20 11:35:09 +00:00
|
|
|
|
|
|
|
case SCH_SHEET_PIN_T:
|
|
|
|
msg = _( "Hierarchical Sheet Pin" );
|
|
|
|
break;
|
|
|
|
|
2013-01-12 17:32:24 +00:00
|
|
|
default:
|
|
|
|
return;
|
2012-11-20 11:35:09 +00:00
|
|
|
}
|
|
|
|
|
2014-09-13 18:15:45 +00:00
|
|
|
aList.push_back( MSG_PANEL_ITEM( msg, GetShownText(), DARKCYAN ) );
|
2012-11-20 11:35:09 +00:00
|
|
|
|
|
|
|
switch( GetOrientation() )
|
|
|
|
{
|
2013-01-12 17:32:24 +00:00
|
|
|
case 0: // horizontal text
|
|
|
|
msg = _( "Horizontal" );
|
|
|
|
break;
|
2012-11-20 11:35:09 +00:00
|
|
|
|
2013-01-12 17:32:24 +00:00
|
|
|
case 1: // Vert Orientation UP
|
|
|
|
msg = _( "Vertical up" );
|
|
|
|
break;
|
2012-11-20 11:35:09 +00:00
|
|
|
|
2013-01-12 17:32:24 +00:00
|
|
|
case 2: // invert horizontal text
|
|
|
|
msg = _( "Horizontal invert" );
|
|
|
|
break;
|
2012-11-20 11:35:09 +00:00
|
|
|
|
2013-01-12 17:32:24 +00:00
|
|
|
case 3: // Vert Orientation Down
|
|
|
|
msg = _( "Vertical down" );
|
|
|
|
break;
|
2012-11-20 11:35:09 +00:00
|
|
|
|
2013-01-12 17:32:24 +00:00
|
|
|
default:
|
|
|
|
msg = wxT( "???" );
|
|
|
|
break;
|
2012-11-20 11:35:09 +00:00
|
|
|
}
|
|
|
|
|
2013-01-12 17:32:24 +00:00
|
|
|
aList.push_back( MSG_PANEL_ITEM( _( "Orientation" ), msg, BROWN ) );
|
2012-11-20 11:35:09 +00:00
|
|
|
|
2013-01-12 17:32:24 +00:00
|
|
|
wxString textStyle[] = { _( "Normal" ), _( "Italic" ), _( "Bold" ), _( "Bold Italic" ) };
|
2012-11-20 11:35:09 +00:00
|
|
|
int style = 0;
|
|
|
|
|
|
|
|
if( m_Italic )
|
|
|
|
style = 1;
|
|
|
|
|
|
|
|
if( m_Bold )
|
|
|
|
style += 2;
|
|
|
|
|
2014-11-15 19:06:05 +00:00
|
|
|
aList.push_back( MSG_PANEL_ITEM( _( "Style" ), textStyle[style], BROWN ) );
|
2012-11-20 11:35:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Display electricat type if it is relevant
|
|
|
|
if( (Type() == SCH_GLOBAL_LABEL_T) ||
|
|
|
|
(Type() == SCH_HIERARCHICAL_LABEL_T ) ||
|
|
|
|
(Type() == SCH_SHEET_PIN_T ) )
|
|
|
|
{
|
|
|
|
switch( GetShape() )
|
|
|
|
{
|
2013-01-12 17:32:24 +00:00
|
|
|
case NET_INPUT: msg = _( "Input" ); break;
|
|
|
|
case NET_OUTPUT: msg = _( "Output" ); break;
|
|
|
|
case NET_BIDI: msg = _( "Bidirectional" ); break;
|
|
|
|
case NET_TRISTATE: msg = _( "Tri-State" ); break;
|
|
|
|
case NET_UNSPECIFIED: msg = _( "Passive" ); break;
|
|
|
|
default: msg = wxT( "???" ); break;
|
2012-11-20 11:35:09 +00:00
|
|
|
}
|
2013-01-12 17:32:24 +00:00
|
|
|
|
|
|
|
aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, BLUE ) );
|
2012-11-20 11:35:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Display text size (X or Y value, with are the same value in Eeschema)
|
* KIWAY Milestone A): Make major modules into DLL/DSOs.
! The initial testing of this commit should be done using a Debug build so that
all the wxASSERT()s are enabled. Also, be sure and keep enabled the
USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it
off is senseless anyways. If you want stable code, go back to a prior version,
the one tagged with "stable".
* Relocate all functionality out of the wxApp derivative into more finely
targeted purposes:
a) DLL/DSO specific
b) PROJECT specific
c) EXE or process specific
d) configuration file specific data
e) configuration file manipulations functions.
All of this functionality was blended into an extremely large wxApp derivative
and that was incompatible with the desire to support multiple concurrently
loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects.
An amazing amount of organization come from simply sorting each bit of
functionality into the proper box.
* Switch to wxConfigBase from wxConfig everywhere except instantiation.
* Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD,
PGM_SINGLE_TOP,
* Remove "Return" prefix on many function names.
* Remove obvious comments from CMakeLists.txt files, and from else() and endif()s.
* Fix building boost for use in a DSO on linux.
* Remove some of the assumptions in the CMakeLists.txt files that windows had
to be the host platform when building windows binaries.
* Reduce the number of wxStrings being constructed at program load time via
static construction.
* Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that
these functions are useful even when the wxConfigBase comes from another
source, as is the case in the KICAD_MANAGER_FRAME.
* Move the setting of the KIPRJMOD environment variable into class PROJECT,
so that it can be moved into a project variable soon, and out of FP_LIB_TABLE.
* Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all
its child wxFrames and wxDialogs now have a Kiway() member function which
returns a KIWAY& that that window tree branch is in support of. This is like
wxWindows DNA in that child windows get this member with proper value at time
of construction.
* Anticipate some of the needs for milestones B) and C) and make code
adjustments now in an effort to reduce work in those milestones.
* No testing has been done for python scripting, since milestone C) has that
being largely reworked and re-thought-out.
2014-03-20 00:42:08 +00:00
|
|
|
msg = StringFromValue( g_UserUnit, m_Size.x, true );
|
2013-01-12 17:32:24 +00:00
|
|
|
aList.push_back( MSG_PANEL_ITEM( _( "Size" ), msg, RED ) );
|
2012-11-20 11:35:09 +00:00
|
|
|
}
|
2011-06-17 13:24:22 +00:00
|
|
|
|
2008-04-22 16:38:23 +00:00
|
|
|
#if defined(DEBUG)
|
|
|
|
|
2011-12-14 17:25:42 +00:00
|
|
|
void SCH_TEXT::Show( int nestLevel, std::ostream& os ) const
|
2008-04-22 16:38:23 +00:00
|
|
|
{
|
|
|
|
// XML output:
|
|
|
|
wxString s = GetClass();
|
|
|
|
|
|
|
|
NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str()
|
2009-05-05 17:32:07 +00:00
|
|
|
<< " layer=\"" << m_Layer << '"'
|
2011-12-08 15:45:01 +00:00
|
|
|
<< " shape=\"" << m_shape << '"'
|
|
|
|
<< " dangling=\"" << m_isDangling << '"'
|
2009-05-05 17:32:07 +00:00
|
|
|
<< '>'
|
2011-02-28 18:36:19 +00:00
|
|
|
<< TO_UTF8( m_Text )
|
2009-05-05 17:32:07 +00:00
|
|
|
<< "</" << s.Lower().mb_str() << ">\n";
|
2008-04-22 16:38:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
|
2010-12-21 15:13:09 +00:00
|
|
|
SCH_LABEL::SCH_LABEL( const wxPoint& pos, const wxString& text ) :
|
|
|
|
SCH_TEXT( pos, text, SCH_LABEL_T )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
2010-12-21 15:13:09 +00:00
|
|
|
m_Layer = LAYER_LOCLABEL;
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_INPUT;
|
|
|
|
m_isDangling = true;
|
2010-12-21 15:13:09 +00:00
|
|
|
m_MultilineAllowed = false;
|
2010-11-03 14:13:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-17 14:39:27 +00:00
|
|
|
EDA_ITEM* SCH_LABEL::Clone() const
|
2008-04-15 19:38:19 +00:00
|
|
|
{
|
2010-12-21 15:13:09 +00:00
|
|
|
return new SCH_LABEL( *this );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-17 13:24:22 +00:00
|
|
|
wxPoint SCH_LABEL::GetSchematicTextOffset() const
|
2010-12-21 15:13:09 +00:00
|
|
|
{
|
|
|
|
return SCH_TEXT::GetSchematicTextOffset();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-03 01:58:12 +00:00
|
|
|
void SCH_LABEL::SetOrientation( int aOrientation )
|
2010-12-21 15:13:09 +00:00
|
|
|
{
|
2011-03-03 01:58:12 +00:00
|
|
|
SCH_TEXT::SetOrientation( aOrientation );
|
2008-04-15 19:38:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
void SCH_LABEL::MirrorX( int aXaxis_position )
|
2010-09-05 17:01:48 +00:00
|
|
|
{
|
|
|
|
// Text is NOT really mirrored; it is moved to a suitable position
|
2013-03-01 19:59:29 +00:00
|
|
|
switch( GetOrientation() )
|
|
|
|
{
|
|
|
|
case 1: // Vert Orientation UP
|
|
|
|
SetOrientation( 3 );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: // Vert Orientation BOTTOM
|
|
|
|
SetOrientation( 1 );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0: // horizontal text
|
|
|
|
case 2: // invert horizontal text
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_Pos.y -= aXaxis_position;
|
|
|
|
NEGATE( m_Pos.y );
|
|
|
|
m_Pos.y += aXaxis_position;
|
2010-09-05 17:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
void SCH_LABEL::Rotate( wxPoint aPosition )
|
2010-09-05 17:01:48 +00:00
|
|
|
{
|
2012-03-15 14:31:16 +00:00
|
|
|
RotatePoint( &m_Pos, aPosition, 900 );
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( (GetOrientation() + 1) % 4 );
|
2010-09-05 17:01:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-04-15 19:38:19 +00:00
|
|
|
bool SCH_LABEL::Save( FILE* aFile ) const
|
|
|
|
{
|
2009-05-05 17:32:07 +00:00
|
|
|
bool success = true;
|
|
|
|
const char* shape = "~";
|
|
|
|
|
|
|
|
if( m_Italic )
|
2008-12-19 20:40:08 +00:00
|
|
|
shape = "Italic";
|
|
|
|
|
|
|
|
if( fprintf( aFile, "Text Label %-4d %-4d %-4d %-4d %s %d\n%s\n",
|
2011-12-08 15:45:01 +00:00
|
|
|
m_Pos.x, m_Pos.y, m_schematicOrientation, m_Size.x, shape,
|
2011-02-28 18:36:19 +00:00
|
|
|
m_Thickness, TO_UTF8( m_Text ) ) == EOF )
|
2008-04-15 19:38:19 +00:00
|
|
|
{
|
|
|
|
success = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
bool SCH_LABEL::Load( LINE_READER& aLine, wxString& aErrorMsg )
|
|
|
|
{
|
|
|
|
char Name1[256];
|
|
|
|
char Name2[256];
|
|
|
|
char Name3[256];
|
|
|
|
int thickness = 0, size = 0, orient = 0;
|
|
|
|
|
|
|
|
Name1[0] = 0; Name2[0] = 0; Name3[0] = 0;
|
|
|
|
|
|
|
|
char* sline = (char*) aLine;
|
|
|
|
|
|
|
|
while( ( *sline != ' ' ) && *sline )
|
|
|
|
sline++;
|
|
|
|
|
|
|
|
// sline points the start of parameters
|
|
|
|
int ii = sscanf( sline, "%s %d %d %d %d %s %s %d", Name1, &m_Pos.x, &m_Pos.y,
|
|
|
|
&orient, &size, Name2, Name3, &thickness );
|
|
|
|
|
|
|
|
if( ii < 4 )
|
|
|
|
{
|
2011-09-30 18:15:37 +00:00
|
|
|
aErrorMsg.Printf( wxT( "Eeschema file label load error at line %d" ),
|
2010-11-10 15:30:12 +00:00
|
|
|
aLine.LineNumber() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !aLine.ReadLine() )
|
|
|
|
{
|
2011-09-30 18:15:37 +00:00
|
|
|
aErrorMsg.Printf( wxT( "Eeschema file label load error atline %d" ),
|
2010-11-10 15:30:12 +00:00
|
|
|
aLine.LineNumber() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( size == 0 )
|
2014-05-16 13:57:53 +00:00
|
|
|
size = GetDefaultTextSize();
|
2010-11-10 15:30:12 +00:00
|
|
|
|
|
|
|
char* text = strtok( (char*) aLine, "\n\r" );
|
|
|
|
|
|
|
|
if( text == NULL )
|
|
|
|
{
|
2011-09-30 18:15:37 +00:00
|
|
|
aErrorMsg.Printf( wxT( "Eeschema file label load error at line %d" ),
|
2010-11-10 15:30:12 +00:00
|
|
|
aLine.LineNumber() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-02-28 18:36:19 +00:00
|
|
|
m_Text = FROM_UTF8( text );
|
2010-11-10 15:30:12 +00:00
|
|
|
m_Size.x = m_Size.y = size;
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( orient );
|
2010-11-10 15:30:12 +00:00
|
|
|
|
|
|
|
if( isdigit( Name3[0] ) )
|
|
|
|
{
|
|
|
|
thickness = atol( Name3 );
|
|
|
|
m_Bold = ( thickness != 0 );
|
2010-11-27 13:09:18 +00:00
|
|
|
m_Thickness = m_Bold ? GetPenSizeForBold( size ) : 0;
|
2010-11-10 15:30:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if( stricmp( Name2, "Italic" ) == 0 )
|
|
|
|
m_Italic = 1;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-21 19:30:59 +00:00
|
|
|
void SCH_LABEL::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
|
2012-09-02 12:06:47 +00:00
|
|
|
GR_DRAWMODE DrawMode, EDA_COLOR_T Color )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
SCH_TEXT::Draw( panel, DC, offset, DrawMode, Color );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-11-24 17:48:14 +00:00
|
|
|
const EDA_RECT SCH_LABEL::GetBoundingBox() const
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
int x, y, dx, dy, length, height;
|
|
|
|
|
|
|
|
x = m_Pos.x;
|
|
|
|
y = m_Pos.y;
|
2012-09-28 17:47:41 +00:00
|
|
|
int width = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
|
2014-09-13 18:15:45 +00:00
|
|
|
length = LenSize( GetShownText() );
|
2010-11-03 14:13:15 +00:00
|
|
|
height = m_Size.y + width;
|
|
|
|
dx = dy = 0;
|
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
switch( m_schematicOrientation )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
case 0: /* Horiz Normal Orientation (left justified) */
|
|
|
|
dx = 2 * DANGLING_SYMBOL_SIZE + length;
|
|
|
|
dy = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
|
|
|
|
x -= DANGLING_SYMBOL_SIZE;
|
|
|
|
y += DANGLING_SYMBOL_SIZE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: /* Vert Orientation UP */
|
|
|
|
dx = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
|
|
|
|
dy = -2 * DANGLING_SYMBOL_SIZE - length;
|
|
|
|
x += DANGLING_SYMBOL_SIZE;
|
|
|
|
y += DANGLING_SYMBOL_SIZE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2: /* Horiz Orientation - Right justified */
|
|
|
|
dx = -2 * DANGLING_SYMBOL_SIZE - length;
|
|
|
|
dy = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
|
|
|
|
x += DANGLING_SYMBOL_SIZE;
|
|
|
|
y += DANGLING_SYMBOL_SIZE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: /* Vert Orientation BOTTOM */
|
|
|
|
dx = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
|
|
|
|
dy = 2 * DANGLING_SYMBOL_SIZE + length;
|
|
|
|
x += DANGLING_SYMBOL_SIZE;
|
|
|
|
y -= DANGLING_SYMBOL_SIZE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
EDA_RECT box( wxPoint( x, y ), wxSize( dx, dy ) );
|
2010-11-03 14:13:15 +00:00
|
|
|
box.Normalize();
|
|
|
|
return box;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-25 19:16:05 +00:00
|
|
|
wxString SCH_LABEL::GetSelectMenuText() const
|
2010-12-13 15:59:00 +00:00
|
|
|
{
|
2011-03-26 10:08:50 +00:00
|
|
|
wxString msg;
|
2014-09-13 18:15:45 +00:00
|
|
|
msg.Printf( _( "Label %s" ), GetChars( ShortenedShownText() ) );
|
2011-03-26 10:08:50 +00:00
|
|
|
return msg;
|
2011-03-25 19:16:05 +00:00
|
|
|
}
|
2010-12-13 15:59:00 +00:00
|
|
|
|
2011-03-25 19:16:05 +00:00
|
|
|
|
2010-12-13 15:59:00 +00:00
|
|
|
|
2008-04-15 19:38:19 +00:00
|
|
|
SCH_GLOBALLABEL::SCH_GLOBALLABEL( const wxPoint& pos, const wxString& text ) :
|
2010-12-10 19:47:44 +00:00
|
|
|
SCH_TEXT( pos, text, SCH_GLOBAL_LABEL_T )
|
2008-04-15 19:38:19 +00:00
|
|
|
{
|
2009-05-05 17:32:07 +00:00
|
|
|
m_Layer = LAYER_GLOBLABEL;
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_BIDI;
|
|
|
|
m_isDangling = true;
|
2009-05-12 12:12:34 +00:00
|
|
|
m_MultilineAllowed = false;
|
2008-04-15 19:38:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-17 14:39:27 +00:00
|
|
|
EDA_ITEM* SCH_GLOBALLABEL::Clone() const
|
2010-12-21 15:13:09 +00:00
|
|
|
{
|
|
|
|
return new SCH_GLOBALLABEL( *this );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-04-15 19:38:19 +00:00
|
|
|
bool SCH_GLOBALLABEL::Save( FILE* aFile ) const
|
|
|
|
{
|
2009-05-05 17:32:07 +00:00
|
|
|
bool success = true;
|
|
|
|
const char* shape = "~";
|
|
|
|
|
|
|
|
if( m_Italic )
|
2008-12-19 20:40:08 +00:00
|
|
|
shape = "Italic";
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2008-12-19 20:40:08 +00:00
|
|
|
if( fprintf( aFile, "Text GLabel %-4d %-4d %-4d %-4d %s %s %d\n%s\n",
|
2011-12-08 15:45:01 +00:00
|
|
|
m_Pos.x, m_Pos.y, m_schematicOrientation, m_Size.x,
|
|
|
|
SheetLabelType[m_shape], shape, m_Thickness, TO_UTF8( m_Text ) ) == EOF )
|
2008-04-15 19:38:19 +00:00
|
|
|
{
|
|
|
|
success = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
2009-05-05 17:32:07 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
bool SCH_GLOBALLABEL::Load( LINE_READER& aLine, wxString& aErrorMsg )
|
|
|
|
{
|
|
|
|
char Name1[256];
|
|
|
|
char Name2[256];
|
|
|
|
char Name3[256];
|
|
|
|
int thickness = 0, size = 0, orient = 0;
|
|
|
|
|
|
|
|
Name1[0] = 0; Name2[0] = 0; Name3[0] = 0;
|
|
|
|
|
|
|
|
char* sline = (char*) aLine;
|
2011-12-08 15:45:01 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
while( (*sline != ' ' ) && *sline )
|
|
|
|
sline++;
|
|
|
|
|
|
|
|
// sline points the start of parameters
|
|
|
|
int ii = sscanf( sline, "%s %d %d %d %d %s %s %d", Name1, &m_Pos.x, &m_Pos.y,
|
|
|
|
&orient, &size, Name2, Name3, &thickness );
|
|
|
|
|
|
|
|
if( ii < 4 )
|
|
|
|
{
|
2011-09-30 18:15:37 +00:00
|
|
|
aErrorMsg.Printf( wxT( "Eeschema file global label load error at line %d" ),
|
2010-11-10 15:30:12 +00:00
|
|
|
aLine.LineNumber() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !aLine.ReadLine() )
|
|
|
|
{
|
2011-09-30 18:15:37 +00:00
|
|
|
aErrorMsg.Printf( wxT( "Eeschema file global label load error at line %d" ),
|
2010-11-10 15:30:12 +00:00
|
|
|
aLine.LineNumber() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( size == 0 )
|
2014-05-16 13:57:53 +00:00
|
|
|
size = GetDefaultTextSize();
|
2010-11-10 15:30:12 +00:00
|
|
|
|
|
|
|
char* text = strtok( (char*) aLine, "\n\r" );
|
|
|
|
|
|
|
|
if( text == NULL )
|
|
|
|
{
|
2011-09-30 18:15:37 +00:00
|
|
|
aErrorMsg.Printf( wxT( "Eeschema file global label load error at line %d" ),
|
2010-11-10 15:30:12 +00:00
|
|
|
aLine.LineNumber() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-02-28 18:36:19 +00:00
|
|
|
m_Text = FROM_UTF8( text );
|
2010-11-10 15:30:12 +00:00
|
|
|
m_Size.x = m_Size.y = size;
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( orient );
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_INPUT;
|
2010-11-10 15:30:12 +00:00
|
|
|
m_Bold = ( thickness != 0 );
|
2010-11-27 13:09:18 +00:00
|
|
|
m_Thickness = m_Bold ? GetPenSizeForBold( size ) : 0;
|
2010-11-10 15:30:12 +00:00
|
|
|
|
|
|
|
if( stricmp( Name2, SheetLabelType[NET_OUTPUT] ) == 0 )
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_OUTPUT;
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
if( stricmp( Name2, SheetLabelType[NET_BIDI] ) == 0 )
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_BIDI;
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
if( stricmp( Name2, SheetLabelType[NET_TRISTATE] ) == 0 )
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_TRISTATE;
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
if( stricmp( Name2, SheetLabelType[NET_UNSPECIFIED] ) == 0 )
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_UNSPECIFIED;
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
if( stricmp( Name3, "Italic" ) == 0 )
|
|
|
|
m_Italic = 1;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
void SCH_GLOBALLABEL::MirrorY( int aYaxis_position )
|
2008-04-15 19:38:19 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
/* The global label is NOT really mirrored.
|
|
|
|
* for an horizontal label, the schematic orientation is changed.
|
2010-11-11 17:54:24 +00:00
|
|
|
* for a vertical label, the schematic orientation is not changed.
|
2010-11-03 14:13:15 +00:00
|
|
|
* and the label is moved to a suitable position
|
|
|
|
*/
|
2011-03-03 01:58:12 +00:00
|
|
|
switch( GetOrientation() )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
case 0: /* horizontal text */
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( 2 );
|
2010-11-03 14:13:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 2: /* invert horizontal text*/
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( 0 );
|
2010-11-03 14:13:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_Pos.x -= aYaxis_position;
|
|
|
|
NEGATE( m_Pos.x );
|
|
|
|
m_Pos.x += aYaxis_position;
|
2008-04-15 19:38:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
void SCH_GLOBALLABEL::MirrorX( int aXaxis_position )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
2011-03-03 01:58:12 +00:00
|
|
|
switch( GetOrientation() )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
case 1: /* vertical text */
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( 3 );
|
2010-11-03 14:13:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: /* invert vertical text*/
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( 1 );
|
2010-11-03 14:13:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_Pos.y -= aXaxis_position;
|
|
|
|
NEGATE( m_Pos.y );
|
|
|
|
m_Pos.y += aXaxis_position;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
void SCH_GLOBALLABEL::Rotate( wxPoint aPosition )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
2012-03-15 14:31:16 +00:00
|
|
|
RotatePoint( &m_Pos, aPosition, 900 );
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( (GetOrientation() + 3) % 4 );
|
2010-11-03 14:13:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-17 13:24:22 +00:00
|
|
|
wxPoint SCH_GLOBALLABEL::GetSchematicTextOffset() const
|
2008-04-15 19:38:19 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
wxPoint text_offset;
|
2012-09-28 17:47:41 +00:00
|
|
|
int width = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
|
2009-05-05 17:32:07 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
width = Clamp_Text_PenSize( width, m_Size, m_Bold );
|
|
|
|
int HalfSize = m_Size.x / 2;
|
|
|
|
int offset = width;
|
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
switch( m_shape )
|
2008-04-15 19:38:19 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
case NET_INPUT:
|
|
|
|
case NET_BIDI:
|
|
|
|
case NET_TRISTATE:
|
|
|
|
offset += HalfSize;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NET_OUTPUT:
|
|
|
|
case NET_UNSPECIFIED:
|
|
|
|
offset += TXTMARGE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2008-04-15 19:38:19 +00:00
|
|
|
}
|
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
switch( m_schematicOrientation )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
case 0: /* Orientation horiz normal */
|
|
|
|
text_offset.x -= offset;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: /* Orientation vert UP */
|
|
|
|
text_offset.y -= offset;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2: /* Orientation horiz inverse */
|
|
|
|
text_offset.x += offset;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: /* Orientation vert BOTTOM */
|
|
|
|
text_offset.y += offset;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return text_offset;
|
2008-04-15 19:38:19 +00:00
|
|
|
}
|
|
|
|
|
2009-05-05 17:32:07 +00:00
|
|
|
|
2011-03-03 01:58:12 +00:00
|
|
|
void SCH_GLOBALLABEL::SetOrientation( int aOrientation )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
2011-12-08 15:45:01 +00:00
|
|
|
m_schematicOrientation = aOrientation;
|
2010-11-03 14:13:15 +00:00
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
switch( m_schematicOrientation )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
default:
|
|
|
|
case 0: /* Horiz Normal Orientation */
|
|
|
|
m_Orient = TEXT_ORIENT_HORIZ;
|
|
|
|
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
|
|
|
|
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: /* Vert Orientation UP */
|
|
|
|
m_Orient = TEXT_ORIENT_VERT;
|
|
|
|
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
|
|
|
|
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
|
|
|
|
break;
|
2010-07-11 16:24:44 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
case 2: /* Horiz Orientation */
|
|
|
|
m_Orient = TEXT_ORIENT_HORIZ;
|
|
|
|
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
|
|
|
|
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
|
|
|
|
break;
|
2009-05-05 17:32:07 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
case 3: /* Vert Orientation BOTTOM */
|
|
|
|
m_Orient = TEXT_ORIENT_VERT;
|
|
|
|
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
|
|
|
|
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
|
|
|
|
break;
|
|
|
|
}
|
2009-01-31 18:08:47 +00:00
|
|
|
}
|
|
|
|
|
2008-04-15 19:38:19 +00:00
|
|
|
|
2011-01-21 19:30:59 +00:00
|
|
|
void SCH_GLOBALLABEL::Draw( EDA_DRAW_PANEL* panel,
|
|
|
|
wxDC* DC,
|
|
|
|
const wxPoint& aOffset,
|
2012-09-01 13:38:27 +00:00
|
|
|
GR_DRAWMODE DrawMode,
|
2012-09-02 12:06:47 +00:00
|
|
|
EDA_COLOR_T Color )
|
2007-05-06 16:03:28 +00:00
|
|
|
{
|
2009-05-05 17:32:07 +00:00
|
|
|
static std::vector <wxPoint> Poly;
|
2012-03-26 23:47:08 +00:00
|
|
|
EDA_COLOR_T color;
|
|
|
|
wxPoint text_offset = aOffset + GetSchematicTextOffset();
|
2009-11-03 13:26:31 +00:00
|
|
|
|
2008-02-20 19:37:17 +00:00
|
|
|
if( Color >= 0 )
|
2012-09-02 12:06:47 +00:00
|
|
|
color = Color;
|
2008-02-20 19:37:17 +00:00
|
|
|
else
|
2013-04-04 21:35:01 +00:00
|
|
|
color = GetLayerColor( m_Layer );
|
2008-02-20 19:37:17 +00:00
|
|
|
|
|
|
|
GRSetDrawMode( DC, DrawMode );
|
|
|
|
|
2012-09-28 17:47:41 +00:00
|
|
|
int linewidth = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
|
2010-11-03 14:13:15 +00:00
|
|
|
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
|
2010-11-27 13:09:18 +00:00
|
|
|
EXCHG( linewidth, m_Thickness ); // Set the minimum width
|
2013-06-29 09:52:22 +00:00
|
|
|
EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL;
|
|
|
|
EDA_TEXT::Draw( clipbox, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR );
|
2010-11-27 13:09:18 +00:00
|
|
|
EXCHG( linewidth, m_Thickness ); // set initial value
|
2007-05-06 16:03:28 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
CreateGraphicShape( Poly, m_Pos + aOffset );
|
2013-06-29 09:52:22 +00:00
|
|
|
GRPoly( clipbox, DC, Poly.size(), &Poly[0], 0, linewidth, color, color );
|
2007-05-06 16:03:28 +00:00
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
if( m_isDangling )
|
2010-11-03 14:13:15 +00:00
|
|
|
DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color );
|
2009-11-28 09:24:37 +00:00
|
|
|
|
|
|
|
// Enable these line to draw the bounding box (debug tests purposes only)
|
|
|
|
#if 0
|
|
|
|
{
|
2011-03-29 19:33:07 +00:00
|
|
|
EDA_RECT BoundaryBox = GetBoundingBox();
|
2013-06-29 09:52:22 +00:00
|
|
|
GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
|
2009-11-28 09:24:37 +00:00
|
|
|
}
|
|
|
|
#endif
|
2007-05-06 16:03:28 +00:00
|
|
|
}
|
2008-02-20 19:37:17 +00:00
|
|
|
|
|
|
|
|
2011-06-17 13:24:22 +00:00
|
|
|
void SCH_GLOBALLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& Pos )
|
2008-02-20 19:37:17 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
int HalfSize = m_Size.y / 2;
|
2012-09-28 17:47:41 +00:00
|
|
|
int linewidth = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
|
2008-02-20 19:37:17 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
|
2008-02-20 19:37:17 +00:00
|
|
|
|
2011-06-17 13:24:22 +00:00
|
|
|
aPoints.clear();
|
2008-12-29 18:02:54 +00:00
|
|
|
|
2014-09-13 18:15:45 +00:00
|
|
|
int symb_len = LenSize( GetShownText() ) + ( TXTMARGE * 2 );
|
2009-05-05 17:32:07 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
// Create outline shape : 6 points
|
|
|
|
int x = symb_len + linewidth + 3;
|
|
|
|
|
2012-09-07 19:29:44 +00:00
|
|
|
// Use negation bar Y position to calculate full vertical size
|
2013-04-10 19:09:59 +00:00
|
|
|
#define Y_CORRECTION 1.3
|
2012-09-07 19:29:44 +00:00
|
|
|
// Note: this factor is due to the fact the negation bar Y position
|
|
|
|
// does not give exactly the full Y size of text
|
|
|
|
// and is experimentally set to this value
|
2013-04-10 19:09:59 +00:00
|
|
|
int y = KiROUND( OverbarPositionY( HalfSize ) * Y_CORRECTION );
|
2012-09-07 19:29:44 +00:00
|
|
|
// add room for line thickness and space between top of text and graphic shape
|
|
|
|
y += linewidth;
|
2010-11-03 14:13:15 +00:00
|
|
|
|
|
|
|
// Starting point(anchor)
|
2011-06-17 13:24:22 +00:00
|
|
|
aPoints.push_back( wxPoint( 0, 0 ) );
|
|
|
|
aPoints.push_back( wxPoint( 0, -y ) ); // Up
|
|
|
|
aPoints.push_back( wxPoint( -x, -y ) ); // left
|
|
|
|
aPoints.push_back( wxPoint( -x, 0 ) ); // Up left
|
|
|
|
aPoints.push_back( wxPoint( -x, y ) ); // left down
|
|
|
|
aPoints.push_back( wxPoint( 0, y ) ); // down
|
2010-11-03 14:13:15 +00:00
|
|
|
|
|
|
|
int x_offset = 0;
|
2008-02-20 19:37:17 +00:00
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
switch( m_shape )
|
2010-09-11 16:33:43 +00:00
|
|
|
{
|
|
|
|
case NET_INPUT:
|
2010-11-03 14:13:15 +00:00
|
|
|
x_offset = -HalfSize;
|
2011-06-17 13:24:22 +00:00
|
|
|
aPoints[0].x += HalfSize;
|
2010-09-11 16:33:43 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NET_OUTPUT:
|
2011-06-17 13:24:22 +00:00
|
|
|
aPoints[3].x -= HalfSize;
|
2010-11-03 14:13:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NET_BIDI:
|
|
|
|
case NET_TRISTATE:
|
|
|
|
x_offset = -HalfSize;
|
2011-06-17 13:24:22 +00:00
|
|
|
aPoints[0].x += HalfSize;
|
|
|
|
aPoints[3].x -= HalfSize;
|
2010-09-11 16:33:43 +00:00
|
|
|
break;
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
case NET_UNSPECIFIED:
|
2010-09-11 16:33:43 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2010-11-03 14:13:15 +00:00
|
|
|
|
|
|
|
int angle = 0;
|
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
switch( m_schematicOrientation )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
case 0: /* Orientation horiz normal */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: /* Orientation vert UP */
|
|
|
|
angle = -900;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2: /* Orientation horiz inverse */
|
|
|
|
angle = 1800;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: /* Orientation vert BOTTOM */
|
|
|
|
angle = 900;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Rotate outlines and move corners in real position
|
2011-06-17 13:24:22 +00:00
|
|
|
for( unsigned ii = 0; ii < aPoints.size(); ii++ )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
2011-06-17 13:24:22 +00:00
|
|
|
aPoints[ii].x += x_offset;
|
2011-12-08 15:45:01 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
if( angle )
|
2011-06-17 13:24:22 +00:00
|
|
|
RotatePoint( &aPoints[ii], angle );
|
2011-12-08 15:45:01 +00:00
|
|
|
|
2011-06-17 13:24:22 +00:00
|
|
|
aPoints[ii] += Pos;
|
2010-11-03 14:13:15 +00:00
|
|
|
}
|
|
|
|
|
2011-06-17 13:24:22 +00:00
|
|
|
aPoints.push_back( aPoints[0] ); // closing
|
2010-09-11 16:33:43 +00:00
|
|
|
}
|
2009-05-05 17:32:07 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
|
2013-11-24 17:48:14 +00:00
|
|
|
const EDA_RECT SCH_GLOBALLABEL::GetBoundingBox() const
|
2008-03-30 09:27:53 +00:00
|
|
|
{
|
2008-03-30 10:47:03 +00:00
|
|
|
int x, y, dx, dy, length, height;
|
2008-03-30 09:27:53 +00:00
|
|
|
|
2009-05-05 17:32:07 +00:00
|
|
|
x = m_Pos.x;
|
|
|
|
y = m_Pos.y;
|
2008-03-30 11:48:18 +00:00
|
|
|
dx = dy = 0;
|
2008-03-30 09:27:53 +00:00
|
|
|
|
2012-09-28 17:47:41 +00:00
|
|
|
int width = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
|
2010-11-03 14:13:15 +00:00
|
|
|
height = ( (m_Size.y * 15) / 10 ) + width + 2 * TXTMARGE;
|
|
|
|
|
|
|
|
// text X size add height for triangular shapes(bidirectional)
|
2014-09-13 18:15:45 +00:00
|
|
|
length = LenSize( GetShownText() ) + height + DANGLING_SYMBOL_SIZE;
|
2008-03-30 09:27:53 +00:00
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
switch( m_schematicOrientation ) // respect orientation
|
2008-03-30 09:27:53 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
case 0: /* Horiz Normal Orientation (left justified) */
|
2009-05-05 17:32:07 +00:00
|
|
|
dx = -length;
|
|
|
|
dy = height;
|
|
|
|
x += DANGLING_SYMBOL_SIZE;
|
|
|
|
y -= height / 2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: /* Vert Orientation UP */
|
|
|
|
dx = height;
|
2009-05-12 12:12:34 +00:00
|
|
|
dy = -length;
|
2009-05-05 17:32:07 +00:00
|
|
|
x -= height / 2;
|
2009-05-12 12:12:34 +00:00
|
|
|
y += DANGLING_SYMBOL_SIZE;
|
2009-05-05 17:32:07 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 2: /* Horiz Orientation - Right justified */
|
|
|
|
dx = length;
|
|
|
|
dy = height;
|
|
|
|
x -= DANGLING_SYMBOL_SIZE;
|
|
|
|
y -= height / 2;
|
|
|
|
break;
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
case 3: /* Vert Orientation BOTTOM */
|
|
|
|
dx = height;
|
|
|
|
dy = length;
|
|
|
|
x -= height / 2;
|
|
|
|
y -= DANGLING_SYMBOL_SIZE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
EDA_RECT box( wxPoint( x, y ), wxSize( dx, dy ) );
|
2010-11-03 14:13:15 +00:00
|
|
|
box.Normalize();
|
|
|
|
return box;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-25 19:16:05 +00:00
|
|
|
wxString SCH_GLOBALLABEL::GetSelectMenuText() const
|
2010-12-13 15:59:00 +00:00
|
|
|
{
|
2011-03-26 10:08:50 +00:00
|
|
|
wxString msg;
|
2014-09-13 18:15:45 +00:00
|
|
|
msg.Printf( _( "Global Label %s" ), GetChars( ShortenedShownText() ) );
|
2011-03-26 10:08:50 +00:00
|
|
|
return msg;
|
2011-03-25 19:16:05 +00:00
|
|
|
}
|
2010-12-13 15:59:00 +00:00
|
|
|
|
2011-03-25 19:16:05 +00:00
|
|
|
|
2010-12-13 15:59:00 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
SCH_HIERLABEL::SCH_HIERLABEL( const wxPoint& pos, const wxString& text, KICAD_T aType ) :
|
|
|
|
SCH_TEXT( pos, text, aType )
|
|
|
|
{
|
|
|
|
m_Layer = LAYER_HIERLABEL;
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_INPUT;
|
|
|
|
m_isDangling = true;
|
2010-11-03 14:13:15 +00:00
|
|
|
m_MultilineAllowed = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-17 14:39:27 +00:00
|
|
|
EDA_ITEM* SCH_HIERLABEL::Clone() const
|
2010-12-21 15:13:09 +00:00
|
|
|
{
|
|
|
|
return new SCH_HIERLABEL( *this );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
bool SCH_HIERLABEL::Save( FILE* aFile ) const
|
|
|
|
{
|
|
|
|
bool success = true;
|
|
|
|
const char* shape = "~";
|
|
|
|
|
|
|
|
if( m_Italic )
|
|
|
|
shape = "Italic";
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
if( fprintf( aFile, "Text HLabel %-4d %-4d %-4d %-4d %s %s %d\n%s\n",
|
2011-12-08 15:45:01 +00:00
|
|
|
m_Pos.x, m_Pos.y, m_schematicOrientation, m_Size.x,
|
|
|
|
SheetLabelType[m_shape], shape, m_Thickness, TO_UTF8( m_Text ) ) == EOF )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
success = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
bool SCH_HIERLABEL::Load( LINE_READER& aLine, wxString& aErrorMsg )
|
|
|
|
{
|
|
|
|
char Name1[256];
|
|
|
|
char Name2[256];
|
|
|
|
char Name3[256];
|
|
|
|
int thickness = 0, size = 0, orient = 0;
|
|
|
|
|
|
|
|
Name1[0] = 0; Name2[0] = 0; Name3[0] = 0;
|
|
|
|
|
|
|
|
char* sline = (char*) aLine;
|
2011-10-12 14:03:43 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
while( (*sline != ' ' ) && *sline )
|
|
|
|
sline++;
|
|
|
|
|
|
|
|
// sline points the start of parameters
|
|
|
|
int ii = sscanf( sline, "%s %d %d %d %d %s %s %d", Name1, &m_Pos.x, &m_Pos.y,
|
|
|
|
&orient, &size, Name2, Name3, &thickness );
|
|
|
|
|
|
|
|
if( ii < 4 )
|
|
|
|
{
|
2011-09-30 18:15:37 +00:00
|
|
|
aErrorMsg.Printf( wxT( "Eeschema file hierarchical label load error at line %d" ),
|
2010-11-10 15:30:12 +00:00
|
|
|
aLine.LineNumber() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !aLine.ReadLine() )
|
|
|
|
{
|
2011-09-30 18:15:37 +00:00
|
|
|
aErrorMsg.Printf( wxT( "Eeschema file hierarchical label load error at line %d" ),
|
2010-11-10 15:30:12 +00:00
|
|
|
aLine.LineNumber() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( size == 0 )
|
2014-05-16 13:57:53 +00:00
|
|
|
size = GetDefaultTextSize();
|
2010-11-10 15:30:12 +00:00
|
|
|
|
|
|
|
char* text = strtok( (char*) aLine, "\n\r" );
|
|
|
|
|
|
|
|
if( text == NULL )
|
|
|
|
{
|
2011-09-30 18:15:37 +00:00
|
|
|
aErrorMsg.Printf( wxT( "Eeschema file hierarchical label load error at line %d" ),
|
2010-11-10 15:30:12 +00:00
|
|
|
aLine.LineNumber() );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-02-28 18:36:19 +00:00
|
|
|
m_Text = FROM_UTF8( text );
|
2010-11-10 15:30:12 +00:00
|
|
|
m_Size.x = m_Size.y = size;
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( orient );
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_INPUT;
|
2010-11-10 15:30:12 +00:00
|
|
|
m_Bold = ( thickness != 0 );
|
2010-11-27 13:09:18 +00:00
|
|
|
m_Thickness = m_Bold ? GetPenSizeForBold( size ) : 0;
|
2010-11-10 15:30:12 +00:00
|
|
|
|
|
|
|
if( stricmp( Name2, SheetLabelType[NET_OUTPUT] ) == 0 )
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_OUTPUT;
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
if( stricmp( Name2, SheetLabelType[NET_BIDI] ) == 0 )
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_BIDI;
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
if( stricmp( Name2, SheetLabelType[NET_TRISTATE] ) == 0 )
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_TRISTATE;
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
if( stricmp( Name2, SheetLabelType[NET_UNSPECIFIED] ) == 0 )
|
2011-12-08 15:45:01 +00:00
|
|
|
m_shape = NET_UNSPECIFIED;
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2010-11-10 15:30:12 +00:00
|
|
|
if( stricmp( Name3, "Italic" ) == 0 )
|
|
|
|
m_Italic = 1;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
|
2011-03-03 01:58:12 +00:00
|
|
|
void SCH_HIERLABEL::SetOrientation( int aOrientation )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
2011-12-08 15:45:01 +00:00
|
|
|
m_schematicOrientation = aOrientation;
|
2010-11-03 14:13:15 +00:00
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
switch( m_schematicOrientation )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
default:
|
|
|
|
case 0: /* Horiz Normal Orientation */
|
|
|
|
m_Orient = TEXT_ORIENT_HORIZ;
|
|
|
|
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
|
|
|
|
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: /* Vert Orientation UP */
|
|
|
|
m_Orient = TEXT_ORIENT_VERT;
|
|
|
|
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
|
|
|
|
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2: /* Horiz Orientation */
|
|
|
|
m_Orient = TEXT_ORIENT_HORIZ;
|
|
|
|
m_HJustify = GR_TEXT_HJUSTIFY_LEFT;
|
|
|
|
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: /* Vert Orientation BOTTOM */
|
|
|
|
m_Orient = TEXT_ORIENT_VERT;
|
|
|
|
m_HJustify = GR_TEXT_HJUSTIFY_RIGHT;
|
|
|
|
m_VJustify = GR_TEXT_VJUSTIFY_CENTER;
|
2009-05-05 17:32:07 +00:00
|
|
|
break;
|
2008-03-30 09:27:53 +00:00
|
|
|
}
|
|
|
|
}
|
2008-02-20 19:37:17 +00:00
|
|
|
|
2009-05-05 17:32:07 +00:00
|
|
|
|
2011-01-21 19:30:59 +00:00
|
|
|
void SCH_HIERLABEL::Draw( EDA_DRAW_PANEL* panel,
|
|
|
|
wxDC* DC,
|
|
|
|
const wxPoint& offset,
|
2012-09-01 13:38:27 +00:00
|
|
|
GR_DRAWMODE DrawMode,
|
2012-09-02 12:06:47 +00:00
|
|
|
EDA_COLOR_T Color )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
2009-05-05 17:32:07 +00:00
|
|
|
static std::vector <wxPoint> Poly;
|
2012-03-26 23:47:08 +00:00
|
|
|
EDA_COLOR_T color;
|
2013-06-29 09:52:22 +00:00
|
|
|
int linewidth = m_Thickness == 0 ?
|
|
|
|
GetDefaultLineThickness() : m_Thickness;
|
|
|
|
EDA_RECT* clipbox = panel? panel->GetClipBox() : NULL;
|
2008-02-20 19:37:17 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
|
2008-02-20 19:37:17 +00:00
|
|
|
|
|
|
|
if( Color >= 0 )
|
2012-09-02 12:06:47 +00:00
|
|
|
color = Color;
|
2008-02-20 19:37:17 +00:00
|
|
|
else
|
2013-04-04 21:35:01 +00:00
|
|
|
color = GetLayerColor( m_Layer );
|
2008-02-20 19:37:17 +00:00
|
|
|
|
|
|
|
GRSetDrawMode( DC, DrawMode );
|
|
|
|
|
2010-11-27 13:09:18 +00:00
|
|
|
EXCHG( linewidth, m_Thickness ); // Set the minimum width
|
2010-11-03 14:13:15 +00:00
|
|
|
wxPoint text_offset = offset + GetSchematicTextOffset();
|
2013-06-29 09:52:22 +00:00
|
|
|
EDA_TEXT::Draw( clipbox, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR );
|
2010-11-27 13:09:18 +00:00
|
|
|
EXCHG( linewidth, m_Thickness ); // set initial value
|
2008-02-20 19:37:17 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
CreateGraphicShape( Poly, m_Pos + offset );
|
2013-06-29 09:52:22 +00:00
|
|
|
GRPoly( clipbox, DC, Poly.size(), &Poly[0], 0, linewidth, color, color );
|
2008-02-20 19:37:17 +00:00
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
if( m_isDangling )
|
2010-11-03 14:13:15 +00:00
|
|
|
DrawDanglingSymbol( panel, DC, m_Pos + offset, color );
|
2009-11-28 09:24:37 +00:00
|
|
|
|
|
|
|
// Enable these line to draw the bounding box (debug tests purposes only)
|
|
|
|
#if 0
|
|
|
|
{
|
2011-03-29 19:33:07 +00:00
|
|
|
EDA_RECT BoundaryBox = GetBoundingBox();
|
2013-06-29 09:52:22 +00:00
|
|
|
GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
|
2009-11-28 09:24:37 +00:00
|
|
|
}
|
|
|
|
#endif
|
2008-02-20 19:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-17 13:24:22 +00:00
|
|
|
void SCH_HIERLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& Pos )
|
2008-02-20 19:37:17 +00:00
|
|
|
{
|
2011-12-08 15:45:01 +00:00
|
|
|
int* Template = TemplateShape[m_shape][m_schematicOrientation];
|
2010-11-03 14:13:15 +00:00
|
|
|
int HalfSize = m_Size.x / 2;
|
2009-06-02 07:26:49 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
int imax = *Template; Template++;
|
2009-05-05 17:32:07 +00:00
|
|
|
|
2011-06-17 13:24:22 +00:00
|
|
|
aPoints.clear();
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
for( int ii = 0; ii < imax; ii++ )
|
2008-02-20 19:37:17 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
wxPoint corner;
|
|
|
|
corner.x = ( HalfSize * (*Template) ) + Pos.x;
|
|
|
|
Template++;
|
2008-02-20 19:37:17 +00:00
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
corner.y = ( HalfSize * (*Template) ) + Pos.y;
|
|
|
|
Template++;
|
2008-02-20 19:37:17 +00:00
|
|
|
|
2011-06-17 13:24:22 +00:00
|
|
|
aPoints.push_back( corner );
|
2008-02-20 19:37:17 +00:00
|
|
|
}
|
2008-02-12 21:12:46 +00:00
|
|
|
}
|
2008-03-27 21:24:50 +00:00
|
|
|
|
2010-12-21 15:13:09 +00:00
|
|
|
|
2013-11-24 17:48:14 +00:00
|
|
|
const EDA_RECT SCH_HIERLABEL::GetBoundingBox() const
|
2008-03-30 09:27:53 +00:00
|
|
|
{
|
2008-03-30 10:47:03 +00:00
|
|
|
int x, y, dx, dy, length, height;
|
2008-03-30 09:27:53 +00:00
|
|
|
|
2009-05-05 17:32:07 +00:00
|
|
|
x = m_Pos.x;
|
|
|
|
y = m_Pos.y;
|
2008-03-30 11:48:18 +00:00
|
|
|
dx = dy = 0;
|
2008-03-30 09:27:53 +00:00
|
|
|
|
2012-09-28 17:47:41 +00:00
|
|
|
int width = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
|
2010-11-03 14:13:15 +00:00
|
|
|
height = m_Size.y + width + 2 * TXTMARGE;
|
2014-09-13 18:15:45 +00:00
|
|
|
length = LenSize( GetShownText() )
|
2010-11-03 14:13:15 +00:00
|
|
|
+ height // add height for triangular shapes
|
|
|
|
+ 2 * DANGLING_SYMBOL_SIZE;
|
2008-03-30 09:27:53 +00:00
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
switch( m_schematicOrientation ) // respect orientation
|
2008-03-30 09:27:53 +00:00
|
|
|
{
|
2011-12-08 15:45:01 +00:00
|
|
|
case 0: /* Horiz Normal Orientation (left justified) */
|
2009-05-05 17:32:07 +00:00
|
|
|
dx = -length;
|
|
|
|
dy = height;
|
|
|
|
x += DANGLING_SYMBOL_SIZE;
|
|
|
|
y -= height / 2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: /* Vert Orientation UP */
|
|
|
|
dx = height;
|
2009-05-12 12:12:34 +00:00
|
|
|
dy = -length;
|
2009-05-05 17:32:07 +00:00
|
|
|
x -= height / 2;
|
2009-05-12 12:12:34 +00:00
|
|
|
y += DANGLING_SYMBOL_SIZE;
|
2009-05-05 17:32:07 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 2: /* Horiz Orientation - Right justified */
|
|
|
|
dx = length;
|
|
|
|
dy = height;
|
|
|
|
x -= DANGLING_SYMBOL_SIZE;
|
|
|
|
y -= height / 2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: /* Vert Orientation BOTTOM */
|
|
|
|
dx = height;
|
2009-05-12 12:12:34 +00:00
|
|
|
dy = length;
|
2009-05-05 17:32:07 +00:00
|
|
|
x -= height / 2;
|
2009-05-12 12:12:34 +00:00
|
|
|
y -= DANGLING_SYMBOL_SIZE;
|
2009-05-05 17:32:07 +00:00
|
|
|
break;
|
2008-03-30 09:27:53 +00:00
|
|
|
}
|
|
|
|
|
2011-03-29 19:33:07 +00:00
|
|
|
EDA_RECT box( wxPoint( x, y ), wxSize( dx, dy ) );
|
2008-03-30 09:27:53 +00:00
|
|
|
box.Normalize();
|
|
|
|
return box;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-17 13:24:22 +00:00
|
|
|
wxPoint SCH_HIERLABEL::GetSchematicTextOffset() const
|
2009-11-28 09:24:37 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
wxPoint text_offset;
|
2008-03-27 21:24:50 +00:00
|
|
|
|
2012-09-28 17:47:41 +00:00
|
|
|
int width = std::max( m_Thickness, GetDefaultLineThickness() );
|
2010-11-03 14:13:15 +00:00
|
|
|
|
|
|
|
int ii = m_Size.x + TXTMARGE + width;
|
2008-03-27 21:24:50 +00:00
|
|
|
|
2011-12-08 15:45:01 +00:00
|
|
|
switch( m_schematicOrientation )
|
2008-03-27 21:24:50 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
case 0: /* Orientation horiz normale */
|
|
|
|
text_offset.x = -ii;
|
2009-05-05 17:32:07 +00:00
|
|
|
break;
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
case 1: /* Orientation vert UP */
|
|
|
|
text_offset.y = -ii;
|
2009-05-05 17:32:07 +00:00
|
|
|
break;
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
case 2: /* Orientation horiz inverse */
|
|
|
|
text_offset.x = ii;
|
2009-05-05 17:32:07 +00:00
|
|
|
break;
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
case 3: /* Orientation vert BOTTOM */
|
|
|
|
text_offset.y = ii;
|
2009-05-05 17:32:07 +00:00
|
|
|
break;
|
2008-03-27 21:24:50 +00:00
|
|
|
}
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
return text_offset;
|
2008-03-27 21:24:50 +00:00
|
|
|
}
|
2009-11-28 09:24:37 +00:00
|
|
|
|
2010-07-11 16:24:44 +00:00
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
void SCH_HIERLABEL::MirrorY( int aYaxis_position )
|
2009-11-28 09:24:37 +00:00
|
|
|
{
|
2010-12-21 15:13:09 +00:00
|
|
|
/* The hierarchical label is NOT really mirrored for an horizontal label, the schematic
|
2011-06-07 15:29:01 +00:00
|
|
|
* orientation is changed. For a vertical label, the schematic orientation is not changed
|
2010-12-21 15:13:09 +00:00
|
|
|
* and the label is moved to a suitable position.
|
|
|
|
*/
|
2010-07-11 16:24:44 +00:00
|
|
|
|
2011-03-03 01:58:12 +00:00
|
|
|
switch( GetOrientation() )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
|
|
|
case 0: /* horizontal text */
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( 2 );
|
2010-11-03 14:13:15 +00:00
|
|
|
break;
|
2009-11-28 09:24:37 +00:00
|
|
|
|
2010-12-21 15:13:09 +00:00
|
|
|
case 2: /* invert horizontal text*/
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( 0 );
|
2010-11-03 14:13:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_Pos.x -= aYaxis_position;
|
|
|
|
NEGATE( m_Pos.x );
|
|
|
|
m_Pos.x += aYaxis_position;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
void SCH_HIERLABEL::MirrorX( int aXaxis_position )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
2011-03-03 01:58:12 +00:00
|
|
|
switch( GetOrientation() )
|
2009-11-28 09:24:37 +00:00
|
|
|
{
|
2010-11-03 14:13:15 +00:00
|
|
|
case 1: /* vertical text */
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( 3 );
|
2010-11-03 14:13:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: /* invert vertical text*/
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( 1 );
|
2010-11-03 14:13:15 +00:00
|
|
|
break;
|
2009-11-28 09:24:37 +00:00
|
|
|
}
|
|
|
|
|
2010-11-03 14:13:15 +00:00
|
|
|
m_Pos.y -= aXaxis_position;
|
|
|
|
NEGATE( m_Pos.y );
|
|
|
|
m_Pos.y += aXaxis_position;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-15 14:31:16 +00:00
|
|
|
void SCH_HIERLABEL::Rotate( wxPoint aPosition )
|
2010-11-03 14:13:15 +00:00
|
|
|
{
|
2012-03-15 14:31:16 +00:00
|
|
|
RotatePoint( &m_Pos, aPosition, 900 );
|
2011-03-03 01:58:12 +00:00
|
|
|
SetOrientation( (GetOrientation() + 3) % 4 );
|
2009-11-28 09:24:37 +00:00
|
|
|
}
|
2010-12-13 15:59:00 +00:00
|
|
|
|
|
|
|
|
2011-03-25 19:16:05 +00:00
|
|
|
wxString SCH_HIERLABEL::GetSelectMenuText() const
|
2010-12-13 15:59:00 +00:00
|
|
|
{
|
2011-03-26 10:08:50 +00:00
|
|
|
wxString msg;
|
2014-09-13 18:15:45 +00:00
|
|
|
msg.Printf( _( "Hierarchical Label %s" ), GetChars( ShortenedShownText() ) );
|
2011-03-26 10:08:50 +00:00
|
|
|
return msg;
|
2011-03-25 19:16:05 +00:00
|
|
|
}
|