/* -*- C++ -*- This file is part of ViPEC Copyright (C) 1991-2001 Johan Rossouw (jrossouw@alcatel.altech.co.za) This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library 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 Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include int Component::nodeSize_ = 3; //----------------------------------------------------------------- Component::Component( const QPoint& center ) : boundingRect_( QRect(0,0,0,0) ), centerPoint_( center ), textRect_( QRect(0,0,0,0) ), textOffset_( QPoint(0,0) ), rotation_( 0 ), schematic_(0) { attributeList_.setAutoDelete( TRUE ); } //----------------------------------------------------------------- Component::~Component() { CircuitNode* node = 0; for (node = nodeList_.first(); node != 0; node = nodeList_.next()) { delete node; } } //----------------------------------------------------------------- QPoint Component::getCenter() const { return centerPoint_; } //----------------------------------------------------------------- int Component::getRotation() const { return rotation_; } //----------------------------------------------------------------- void Component::setRotation( int rotation ) { for ( int i=0; i<(rotation/90); i++ ) { rotate(); } } //----------------------------------------------------------------- int Component::getNodeSize() { return nodeSize_; } //----------------------------------------------------------------- void Component::setSchematic( Schematic* schematic ) { schematic_ = schematic; } //----------------------------------------------------------------- void Component::writeToStream( QTextStream& stream ) { stream << "" << endl; stream << "" << endl; stream << ""; Attribute* it = 0; for( it = attributeList_.first(); it != 0; it = attributeList_.next() ) { stream << "symbol_ << "=\""; if ( (it->value_).isEmpty() ) { stream << "NULL"; } else { stream << it->value_; } stream << "\" />" << endl; } stream << "" << endl; } //----------------------------------------------------------------- bool Component::readFromDOM( QDomElement& element ) { QDomNode node = element.firstChild(); while( !node.isNull() ) { QDomElement childElement = node.toElement(); if( !childElement.isNull() ) { if ( childElement.tagName() == "LOCATION" ) { QString xStr = childElement.attribute( "X" ); QString yStr = childElement.attribute( "Y" ); QString rotStr = childElement.attribute( "ROTATION" ); int x = xStr.toInt(); int y = yStr.toInt(); int rotation = rotStr.toInt(); moveTo( QPoint(x,y) ); setRotation( rotation); } else if ( childElement.tagName() == "TEXTOFFSET" ) { QString xStr = childElement.attribute( "X" ); QString yStr = childElement.attribute( "Y" ); int x = xStr.toInt(); int y = yStr.toInt(); setTextOffset( QPoint( x, y ) ); } else if ( childElement.tagName() == "ATTRIBUTE" ) { QDomNamedNodeMap map = childElement.attributes(); for (uint l=0; lvalue_ = value; } } else { return FALSE; } } node = node.nextSibling(); } return TRUE; } //----------------------------------------------------------------- CircuitNode* Component::addNode(int x, int y, bool isPortNode, bool isGndNode, bool isFloatAllowed) { ASSERT( schematic_ ); QPoint point(x,y); point += centerPoint_; CircuitNode* node = new CircuitNode( point, TRUE, isPortNode, isGndNode, isFloatAllowed ); schematic_->addNode( node ); nodeList_.append( node ); return node; } //----------------------------------------------------------------- CircuitNode* Component::node(uint i) { ASSERT(i < nodeList_.count() ); return nodeList_.at(i); } //----------------------------------------------------------------- void Component::rotate() { rotation_ = (rotation_ + 90) % 360; int x = boundingRect_.x(); int y = boundingRect_.y(); int w = boundingRect_.width(); int h = boundingRect_.height(); boundingRect_ = QRect(y,x,h,w); CircuitNode* node = 0; for (node = nodeList_.first(); node != 0; node = nodeList_.next()) { node->pos() -= centerPoint_; Utils::rotatePoint90Degccw( node->pos() ); node->pos() += centerPoint_; } } //----------------------------------------------------------------- void Component::moveTo(QPoint point) { CircuitNode* node = 0; for (node = nodeList_.first(); node != 0; node = nodeList_.next()) { node->pos() -= centerPoint_; node->pos() += point; } centerPoint_ = point; } //----------------------------------------------------------------- void Component::moveRel(QPoint delta) { CircuitNode* node = 0; for (node = nodeList_.first(); node != 0; node = nodeList_.next()) { node->pos() += delta; } centerPoint_ += delta; } //----------------------------------------------------------------- QRect Component::getBoundingRect() const { QRect rect = boundingRect_; rect.moveBy(centerPoint_.x(), centerPoint_.y()); return rect; } //----------------------------------------------------------------- bool Component::isInsideBoundingRect(QPoint point) const { return getBoundingRect().contains(point); } //----------------------------------------------------------------- QRect Component::getTextRect() const { QRect rect = textRect_; rect.moveBy(centerPoint_.x(), centerPoint_.y()); return rect; } //----------------------------------------------------------------- bool Component::isInsideTextRect(QPoint point) const { return getTextRect().contains(point); } //----------------------------------------------------------------- void Component::setTextOffset( QPoint offset ) { textOffset_ += offset; } //----------------------------------------------------------------- void Component::draw(QPainter* painter) { painter->save(); if ( isSelected() ) { painter->setPen( Qt::red ); if ( Setup::instance()->isDebugMode() ) { painter->save(); painter->setPen( QPen( Qt::red, 1, Qt::DashLine ) ); QRect rect = getBoundingRect(); Utils::growRect( rect, 2 ); painter->drawRect( rect ); painter->restore(); } } else { painter->setPen( Qt::blue ); } painter->translate( centerPoint_.x(), centerPoint_.y() ); painter->rotate( rotation_ ); drawSymbol( painter ); painter->restore(); if ( (Setup::instance()->isComponentTextEnabled()) || isSelected() ) { drawAttributes( painter ); } } //----------------------------------------------------------------- void Component::drawAttributes(QPainter* painter) { painter->save(); painter->translate( centerPoint_.x(), centerPoint_.y() ); if ( isSelected() ) { painter->setPen( Qt::red ); } else { painter->setPen( Qt::black ); } QRect rect = getBoundingRect(); rect.moveBy(-centerPoint_.x(), -centerPoint_.y()); int nrAttr = (int) attributeList_.count(); bool horisonalOrientation = (rotation_ == 0) || (rotation_ == 180); int ypos = 0; if ( horisonalOrientation ) { ypos = rect.bottom() + 12; } else { ypos = -(nrAttr-1) * 5 + 4; } ypos += textOffset_.y(); bool firstRect = true; Attribute* it = 0; for( it = attributeList_.first(); it != 0; it = attributeList_.next() ) { QString text = it->symbol_ + "=" + it->value_; if ( (it->value_).isEmpty() ) { text = text + "?"; } int xpos = 0; if ( horisonalOrientation ) { xpos = - VectorFont::textWidth(text)/2; } else { xpos = rect.right() + 4; } xpos += textOffset_.x(); VectorFont::instance()->drawText(text, painter, QPoint( xpos, ypos ) ); QRect tempRect( xpos, ypos-8, VectorFont::textWidth(text), 8 ); if ( firstRect ) { textRect_ = tempRect; firstRect = false; } else { textRect_ = textRect_.unite( tempRect ); } ypos += 12; } if ( Setup::instance()->isDebugMode() ) { painter->setPen( Qt::red ); painter->drawRect( textRect_ ); } painter->restore(); } //----------------------------------------------------------------- void Component::addAttribute( const QString& name, const QString& symbol, double value ) { Attribute* attribute = new Attribute(); attribute->name_ = name; attribute->symbol_ = symbol; if ( value != 0 ) { attribute->value_.setNum( value ); } else { attribute->value_ = ""; } attributeList_.append( attribute ); } //----------------------------------------------------------------- Component::AttributeList& Component::getAttributeList() { return attributeList_; } //----------------------------------------------------------------- Component::Attribute* Component::findAttribute( const QString& symbol ) { Attribute* item = 0; for( item = attributeList_.first(); item != 0; item = attributeList_.next() ) { if ( (item->symbol_) == symbol ) { break; } } return item; } //----------------------------------------------------------------- const QString& Component::getAttributeStr( const QString& symbol ) { Attribute* attr = findAttribute( symbol ); ASSERT( attr ); const QString& valueStr = attr->value_; return valueStr; } //----------------------------------------------------------------- TReal Component::getAttributeValue( const QString& symbol ) { Attribute* attr = findAttribute( symbol ); ASSERT( attr ); const QString& valueStr = attr->value_; if ( valueStr.isEmpty() ) { throw Exception::AttributeHasNoValue(); } bool ok = FALSE; double value = valueStr.toDouble(&ok); if ( !ok ) { value = MainWindow::instance()->getVariableValue( valueStr ); } return value; } //----------------------------------------------------------------- TReal Component::getDimensionValue( const QString& name ) { return Setup::instance()->getDimensionValue( name ); } //----------------------------------------------------------------- void Component::copyData( Component& source ) { setRotation( source.getRotation() ); Attribute* attr = 0; for ( attr = attributeList_.first(); attr != 0; attr = attributeList_.next() ) { Attribute* sourceAttr = source.findAttribute( attr->symbol_ ); ASSERT( sourceAttr != 0 ); attr->value_ = sourceAttr->value_; } }