Logo Search packages:      
Sourcecode: ktechlab version File versions

itemlibrary.cpp

/***************************************************************************
 *   Copyright (C) 2003-2005 by David Saxton                               *
 *   david@bluehaze.org                                                    *
 *                                                                         *
 *   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.                                   *
 ***************************************************************************/

#include "config.h"

#include "cnitem.h"
#include "canvasitemparts.h"
#include "circuitdocument.h"
#include "component.h"
#include "ecsubcircuit.h"
#include "ecnode.h"
#include "itemlibrary.h"
#include "node.h"
#include "subcircuits.h"

#ifdef MECHANICS
#include "chassiscircular2.h"
#endif

#include "dptext.h"
#include "dpline.h"
#include "solidshape.h"

#include "callsub.h"
#include "count.h"
#include "delay.h"
#include "embed.h"
#include "end.h"
#include "inputbutton.h"
#include "interrupt.h"
#include "forloop.h"
#include "keypad.h"
#include "pulse.h"
#include "readport.h"
#include "repeat.h"
#include "setpin.h"
#include "sevenseg.h"
#include "start.h"
#include "sub.h"
#include "testpin.h"
#include "unary.h"
#include "varassignment.h"
#include "varcomparison.h"
#include "while.h"
#include "writeport.h"

#include "addac.h"
#include "bidirled.h"
#include "binarycounter.h"
#include "bussplitter.h"
#include "demultiplexer.h"
#include "dependentsource.h"
#include "discretelogic.h"
#include "externalconnection.h"
#include "flipflop.h"
#include "fulladder.h"
#include "inductor.h"
#include "magnitudecomparator.h"
#include "matrixdisplay.h"
#include "matrixdisplaydriver.h"
#include "meter.h"
#include "multiinputgate.h"
#include "multiplexer.h"
#include "parallelportcomponent.h"
#include "piccomponent.h"
#include "pushswitch.h"
#include "probe.h"
#include "ram.h"
#include "resistordip.h"
#include "rotoswitch.h"
#include "serialportcomponent.h"
#include "toggleswitch.h"

#include "ec555.h"
#include "ecbcdto7segment.h"
#include "eccapacitor.h"
#include "ecclockinput.h"
#include "eccurrentsignal.h"
#include "eccurrentsource.h"
#include "ecdiode.h"
#include "ecfixedvoltage.h"
#include "ecground.h"
#include "eckeypad.h"
#include "ecled.h"
#include "ecbjt.h"
#include "ecopamp.h"
#include "ecpotentiometer.h"
#include "ecresistor.h"
#include "ecsevensegment.h"
#include "ecsignallamp.h"
#include "ecvoltagesignal.h"
#include "ecvoltagesource.h"

#include "pinmapping.h"

#include "libraryitem.h"

#include "kdebug.h"
#include <kiconloader.h>
#include <qbitmap.h>
#include <qimage.h>
#include <qpainter.h>
#include <qpixmap.h>
#include <qpushbutton.h>
#include <qregexp.h>

#include <cassert>

ItemLibrary::ItemLibrary()
{
      addFlowParts();
      addComponents();
      addMechanics();
      addDrawParts();
}


ItemLibrary::~ItemLibrary()
{
      const LibraryItemList::iterator end = m_items.end();
      for ( LibraryItemList::iterator it = m_items.begin(); it != end; ++it )
      {
            delete *it;
      }
      m_items.clear();
}


void ItemLibrary::addFlowParts()
{
      // Container loops
      addLibraryItem( Repeat::libraryItem() );
      addLibraryItem( While::libraryItem() );
      addLibraryItem( ForLoop::libraryItem() );
      
      // Variable operations
      addLibraryItem( Unary::libraryItem() );
      addLibraryItem( VarAssignment::libraryItem() );
      addLibraryItem( VarComparison::libraryItem() );
      
      // I/O
      addLibraryItem( SetPin::libraryItem() );
      addLibraryItem( TestPin::libraryItem() );
      addLibraryItem( WritePort::libraryItem() );
      addLibraryItem( ReadPort::libraryItem() );
      
      // Functions
      addLibraryItem( SevenSeg::libraryItem() );
//    addLibraryItem( Pulse::libraryItem() );
      addLibraryItem( Keypad::libraryItem() );
//    addLibraryItem( Count::libraryItem() );
//    addLibraryItem( InputButton::libraryItem() );
      addLibraryItem( Delay::libraryItem() );
      
      // Common
      addLibraryItem( Embed::libraryItem() );
      addLibraryItem( CallSub::libraryItem() );
//    addLibraryItem( Interrupt::libraryItem() );
      addLibraryItem( Sub::libraryItem() );
      addLibraryItem( End::libraryItem() );
      addLibraryItem( Start::libraryItem() );
}


void ItemLibrary::addComponents()
{
      // Integrated Circuits
      addLibraryItem( ECBCDTo7Segment::libraryItem() );
      addLibraryItem( MatrixDisplayDriver::libraryItem() );
      addLibraryItem( BinaryCounter::libraryItem() );
      addLibraryItem( DAC::libraryItem() );
      addLibraryItem( ADC::libraryItem() );
      addLibraryItem( ECOpAmp::libraryItem() );
      addLibraryItem( MagnitudeComparator::libraryItem() );
      addLibraryItem( Demultiplexer::libraryItem() );
      addLibraryItem( Multiplexer::libraryItem() );
      addLibraryItem( FullAdder::libraryItem() );
      addLibraryItem( RAM::libraryItem() );
      addLibraryItem( EC555::libraryItem() );
      addLibraryItem( ECDFlipFlop::libraryItem() );
      addLibraryItem( ECSRFlipFlop::libraryItem() );
      addLibraryItem( ECJKFlipFlop::libraryItem() );
#ifndef NO_GPSIM
      addLibraryItem( PICComponent::libraryItem() );
#endif
      
      // Connections
      addLibraryItem( ParallelPortComponent::libraryItem() );
      addLibraryItem( SerialPortComponent::libraryItem() );
      addLibraryItem( ExternalConnection::libraryItem() );
      addLibraryItem( BusSplitter::libraryItem() );
      
      // Logic
      addLibraryItem( ECXnor::libraryItem() );
      addLibraryItem( ECXor::libraryItem() );
      addLibraryItem( ECNor::libraryItem() );
      addLibraryItem( ECOr::libraryItem() );
      addLibraryItem( ECNand::libraryItem() );
      addLibraryItem( ECAnd::libraryItem() );
      addLibraryItem( Inverter::libraryItem() );
      addLibraryItem( Buffer::libraryItem() );
      addLibraryItem( ECClockInput::libraryItem() );
      addLibraryItem( ECLogicOutput::libraryItem() );
      addLibraryItem( ECLogicInput::libraryItem() );
      
      
      // Outputs
//    addLibraryItem( FrequencyMeter::libraryItem() );
      addLibraryItem( CurrentProbe::libraryItem() );
      addLibraryItem( VoltageProbe::libraryItem() );
      addLibraryItem( LogicProbe::libraryItem() );
      addLibraryItem( ECAmmeter::libraryItem() );
      addLibraryItem( ECVoltMeter::libraryItem() );
      addLibraryItem( MatrixDisplay::libraryItem() );
      addLibraryItem( ECSevenSegment::libraryItem() );
      addLibraryItem( BiDirLED::libraryItem() );
      addLibraryItem( ECSignalLamp::libraryItem() );
      addLibraryItem( ECLed::libraryItem() );
      
      // Switches
      addLibraryItem( ECRotoSwitch::libraryItem() );
      addLibraryItem( ECDPDT::libraryItem() );
      addLibraryItem( ECSPDT::libraryItem() );
      addLibraryItem( ECDPST::libraryItem() );
      addLibraryItem( ECSPST::libraryItem() );
      addLibraryItem( ECKeyPad::libraryItem() );
      addLibraryItem( ECPTBSwitch::libraryItem() );
      addLibraryItem( ECPTMSwitch::libraryItem() );
      
      
      // Discrete
      addLibraryItem( ECPotentiometer::libraryItem() );
      addLibraryItem( ResistorDIP::libraryItem() );
      addLibraryItem( ECBJT::libraryItemPNP() );
      addLibraryItem( ECBJT::libraryItemNPN() );
      addLibraryItem( Inductor::libraryItem() );
      addLibraryItem( ECDiode::libraryItem() );
      addLibraryItem( ECCapacitor::libraryItem() );
      addLibraryItem( ECResistor::libraryItem() );
      
      // Dependent Sources
      addLibraryItem( ECVCVS::libraryItem() );
      addLibraryItem( ECVCCS::libraryItem() );
      addLibraryItem( ECCCVS::libraryItem() );
      addLibraryItem( ECCCCS::libraryItem() );
      
      // Independent Sources
      addLibraryItem( ECCurrentSignal::libraryItem() );
      addLibraryItem( ECVoltageSignal::libraryItem() );
      addLibraryItem( ECCurrentSource::libraryItem() );
      addLibraryItem( ECGround::libraryItem() );
      addLibraryItem( ECFixedVoltage::libraryItem() );
      addLibraryItem( ECCell::libraryItem() );
      
      // Other
      addLibraryItem( ECSubcircuit::libraryItem() );
      addLibraryItem( PIC_IC::libraryItem() );
}


void ItemLibrary::addDrawParts()
{
      addLibraryItem( DPText::libraryItem() );
      addLibraryItem( DPLine::libraryItem() );
      addLibraryItem( DPArrow::libraryItem() );
      addLibraryItem( DPRectangle::libraryItem() );
      addLibraryItem( DPEllipse::libraryItem() );
}


void ItemLibrary::addMechanics()
{
#ifdef MECHANICS
      addLibraryItem( ChassisCircular2::libraryItem() );
#endif
}


00286 void ItemLibrary::addLibraryItem( LibraryItem *item )
{
      m_items.append(item);
}


00292 Item *ItemLibrary::createItem( const QString &id, ItemDocument *itemDocument, bool newItem, const char *newId, bool finishCreation  )
{
      Item * item = 0l;
      if ( id.startsWith("sc/") )
      {
            // Is a subcircuit...
            
            CircuitDocument * circuitDocument = dynamic_cast<CircuitDocument*>(itemDocument);
            if (!circuitDocument)
            {
                  kdWarning() << "Cannot create subcircuit without a circuit document" << endl;
                  return 0l;
            }
            
            QString temp = id;
            int numId = temp.remove("sc/").toInt();
            
            item = subcircuits()->createSubcircuit( numId, /*id,*/ circuitDocument, newItem, newId );
      }
      
      else
      {
            const LibraryItemList::iterator end = m_items.end();
            LibraryItemList::iterator it = m_items.begin();
            for ( ; it != end; ++it )
            {
                  if ( (*it)->allIDs().contains(id) )
                  {
                        item = (*it)->createItemFnPtr()( itemDocument, newItem, newId );
                        item->m_type = (*it)->activeID();
                        break;
                  }
            }
            
            if ( it == end )
                  kdWarning() << "Could not find the item constructor for id " << id << endl;
      }
      
      if ( finishCreation && item )
            item->finishedCreation();
      
      return item;
}


00337 QImage ItemLibrary::itemImage( Item *item, const uint maxSize )
{
      Component *component = dynamic_cast<Component*>(item);
      
    QRect bound = item->boundingRect().normalize();
      bound.setLeft( bound.left()-8 );
      bound.setRight( bound.right()+8 );
      bound.setTop( bound.top()-8 );
      bound.setBottom( bound.bottom()+8 );

      // We want a nice square bounding rect
      const int dy = bound.width() - bound.height();
      if ( dy > 0 )
      {
            bound.setTop( bound.top()-(dy/2) );
            bound.setBottom( bound.bottom()+(dy/2) );
      }
      else if ( dy < 0 )
      {
            bound.setLeft( bound.left()+(dy/2) );
            bound.setRight( bound.right()-(dy/2) );
      }
      
      const bool cache = ((bound.width()*bound.height()) > (int)maxSize);
      QString type;
      if ( cache && m_imageMap.contains(item->type()) )
            return m_imageMap[item->type()];
      
      // Create pixmap big enough to contain CNItem and surrounding nodes
      // and copy the button grab to it
      
      QPixmap pm( bound.size() );
      
      QBitmap mask( bound.size() );
      mask.fill( Qt::color0 );
      
      QPainter maskPainter(&mask);
      maskPainter.translate( -bound.x(), -bound.y() );
      maskPainter.setPen( Qt::color1 );
      maskPainter.setBrush( Qt::color1 );
      
      
      QPainter p(&pm);
      p.translate( -bound.x(), -bound.y() );
      p.setPen( item->pen() );
      p.setBrush( item->brush() );
      
      // Now draw the shape :-)
      const bool sel = item->isSelected();
      if (sel)
      {
            // We block the signals as we end up in an infinite loop with cnitem emitting a selected signal
            item->blockSignals(true);
            item->setSelected(false);
            item->blockSignals(false);
      }
      item->drawShape(p);
      item->drawShape(maskPainter);
      if (sel)
      {
            item->blockSignals(true);
            item->setSelected(sel);
            item->blockSignals(false);
      }
      
      maskPainter.setPen( Qt::color1 );
      maskPainter.setBrush( Qt::color1 );
      
      QWMatrix transMatrix; // Matrix to apply to the image
      
      CNItem *cnItem = dynamic_cast<CNItem*>(item);
      if (cnItem)
      {
            NodeMap nodes = cnItem->nodeMap();
            const NodeMap::iterator nodesEnd = nodes.end();
            for ( NodeMap::iterator it = nodes.begin(); it != nodesEnd; ++it )
            {
                  Node *node = it.data().node;
                  const bool sel = node->isSelected();
                  if (sel)
                        node->setSelected(false);
                  if ( ECNode *ecnode = dynamic_cast<ECNode*>(node)  )
                  {
                        const bool showVB = ecnode->showVoltageBars();
                        ecnode->setShowVoltageBars(false);
                        ecnode->drawShape(p);
                        ecnode->drawShape(maskPainter);
                        ecnode->setShowVoltageBars(showVB);
                  }
                  else
                  {
                        node->drawShape(p);
                        node->drawShape(maskPainter);
                  }
                  if (sel)
                        node->setSelected(sel);
            }
            
            p.setPen(Qt::black);
            TextMap text = cnItem->textMap();
            const TextMap::iterator textEnd = text.end();
            for ( TextMap::iterator it = text.begin(); it != textEnd; ++it )
            {
                  it.data()->drawShape(p);
                  it.data()->drawShape(maskPainter);
            }
            
//          maskPainter.setPen( Qt::color1 );
//          maskPainter.setBrush( Qt::color1 );
            cnItem->drawWidgets(p);
//          cnItem->drawWidgets(maskPainter);
            
            transMatrix = Component::transMatrix( component->angleDegrees(), component->flipped(), bound.width()/2, bound.height()/2, true );
      }
      
      pm.setMask(mask);
            
      // Now, rotate the image so that it's the right way up, and scale it to size
      QImage im = pm.convertToImage();
      im = im.xForm(transMatrix);
      im = im.smoothScale( 50, 50, QImage::ScaleMin );
      
      if (cache)
            m_imageMap[item->type()] = im;
      
      return im;
}

00465 QPixmap ItemLibrary::itemIconFull( const QString &id )
{
      LibraryItemList::iterator end = m_items.end();
      for ( LibraryItemList::iterator it = m_items.begin(); it != end; ++it )
      {
            if ( *it && (*it)->allIDs().contains(id) )
            {
                  return (*it)->iconFull();
            }
      }
      return QPixmap();
}

Generated by  Doxygen 1.6.0   Back to index