// Replace all of the symbols in our drawing with a different one...
void CTinyCadDoc::ReplaceSymbol( hSYMBOL old_symbol, hSYMBOL new_symbol, bool keep_old_fields )
{
  // Search for methods, and look at their pins
	drawingIterator it = GetDrawingBegin();
	while (it != GetDrawingEnd()) 
	{
		CDrawingObject *ObjPtr = *it;
		if (ObjPtr->GetType() == xMethodEx3)
		{
			CDrawMethod *pMethod = static_cast<CDrawMethod*>(ObjPtr);
			pMethod->ReplaceSymbol( old_symbol, new_symbol, keep_old_fields );
			pMethod->Display( TRUE );
		}

		++ it;
	}
}
// Called after a paste or import to enable the
// document to sort out the imported block when
// necessary
void CTinyCadDoc::UngroupSymbols()
{
	// Scan and convert any imported symbols
	// into their component parts
	drawingIterator it = GetDrawingBegin();
	while (it != GetDrawingEnd()) 
	{
		drawingIterator current = it;
		++ it;
		CDrawingObject *pObject = *current;

		// Is this a method object?
		if (   pObject->GetType() == xMethodEx3
			&& IsSelected(pObject))
		{
			// Convert to the actual type
			CDrawMethod *pMethod = static_cast<CDrawMethod*>(pObject);

			// Get the symbol data
			CDPoint tr;
			drawingCollection method;
			pMethod->ExtractSymbol( tr,method );
			
			// Remove the method from the linked list
			UnSelect(pMethod);
			Delete( pMethod );

			// Now re-insert using the offset of the main
			// method
			CDPoint offset = method.front()->m_point_a;
			drawingIterator it = method.begin();
			while (it != method.end())
			{
				CDrawingObject *pInsertObject = *it;
				CDrawingObject *pDup = pInsertObject->Store();
				
				pDup->m_point_a += offset;
				pDup->m_point_b += offset;

				Select( pDup );
				
				++ it;
			}
		}
	}
}
// Remove an item from the drawing...
void CTinyCadDoc::Delete( drawingIterator it)
{
	CDrawingObject *pointer = *it;

	pointer->Display();
	if (pointer == GetSelectable())
	{
		SetSelectable( NULL );
	}
	UnSelect(pointer);

	MarkDeleteForUndo( *it );
	delete *it;
	m_drawing.erase( it );

	SetModifiedFlag( TRUE );
}
// Set which part in the package to edit
void CTinyCadSymbolDoc::EditPartInPackage( int p )
{
	int OldPart = GetPart();
	
	// Get rid of any drawing tool
	SelectObject(new CDrawEditItem(this));

	m_part = p;

	// Are there any pins selected for this part
	int innew = FALSE,inold = FALSE;

	drawingIterator it = GetDrawingBegin();
	while (it != GetDrawingEnd()) 
	{
		CDrawingObject *pointer = *it;

		if (pointer->GetType()==xPinEx && ((CDrawPin *)pointer)->GetPart()==GetPart())
				innew = TRUE;
		if (pointer->GetType()==xPinEx && ((CDrawPin *)pointer)->GetPart()==OldPart)
				inold = TRUE;
		
		++ it;
	}

	// Do we need to copy over the pins?
	if (!innew && inold && Message(IDS_COPYPINS,MB_YESNO | MB_ICONQUESTION)==IDYES) 
	{
		CDrawPin *NewPin;
		drawingIterator it = GetDrawingBegin();
		while (it != GetDrawingEnd()) 
		{
			CDrawingObject *pointer = *it;
			if (pointer->GetType()==xPinEx && ((CDrawPin *)pointer)->GetPart()==OldPart) {
				NewPin = new CDrawPin(this);
				*NewPin = *((CDrawPin *)pointer);
				NewPin->SetPart(GetPart());
				Add(NewPin);
			}
			
			++ it;
		}
	}

	Invalidate();
}
int CTinyCadSymbolDoc::GetPartsPerPackage()
{
	// Find out how many parts in this package
	int max=0;
	drawingIterator it = GetDrawingBegin();
	while (it != GetDrawingEnd()) 
	{
		CDrawingObject *pointer = *it;

		if (pointer->GetType()==xPinEx && ((CDrawPin *)pointer)->GetPart()>max)
		{
			max = ((CDrawPin *)pointer)->GetPart();
		}

		++ it;
	}

	return max + 1;
}
// Remove all errors from this design
void CTinyCadDoc::DeleteErrors()
{
  // Get rid of any drawing tool
  SelectObject(new CDrawEditItem(this));

	drawingIterator it = GetDrawingBegin();
	while (it != GetDrawingEnd()) 
	{
		drawingIterator current = it;
		++ it;
		
		CDrawingObject *pointer = *current;
		if (pointer->GetType()==xError) 
		{
			m_drawing.erase(current);
			delete pointer;
		}
	}

	Invalidate();
}
// Delete the selected objects!
void CTinyCadDoc::SelectDelete()
{
  if (!IsSelected())
	return;

    CJunctionUtils j( this );

	drawingIterator it = GetDrawingBegin();
	while (it != GetDrawingEnd()) 
	{
		drawingIterator current = it;
		++ it;

		CDrawingObject *pointer = *current;
		if (IsSelected( pointer ))
		{
			if (pointer == GetSelectable())
			{
				SetSelectable( NULL );
			}

			j.AddObjectToTodo( pointer );
			MarkDeleteForUndo( pointer );
			m_drawing.erase( current );
			pointer->Display();
			delete pointer;
		}
	}

	m_selected.erase( m_selected.begin(), m_selected.end() );

  // ... and perform the junction requirements...
  j.CheckTodoList( true );

  SetModifiedFlag( TRUE );
}
// Auto anotate the design
void CTinyCadView::OnSpecialAnotate()
{
  CDlgAnotateBox theDialog(this,theASetup);

  // Get rid of any drawing tool
  GetCurrentDocument()->SelectObject(new CDrawEditItem(GetCurrentDocument()));

  // Do the dialog
  int action = theDialog.DoModal();
  
  if (action == IDC_REF_PAINTER)
  {
	  theASetup = theDialog.v;
	  GetCurrentDocument()->SelectObject(new CDrawRefPainter(GetCurrentDocument(), theASetup.startval ));
	  return;
  }
  else if (action !=IDOK)
  {
	return;
  }

  theASetup = theDialog.v;

  // Set the busy icon
  SetCursor( AfxGetApp()->LoadStandardCursor( IDC_WAIT ) );
  

  // Now add/remove references
  CDrawMethod *thisMethod;
  CSymbolRecord *thisSymbol;
  int value=0;
  int part=0;
  BOOL IsSet,IsMatch,MissingSymbols=FALSE;
  

	for (int i = 0; i < 2; i++)
	{
		int sheet = theASetup.all_sheets ? 0 : GetDocument()->GetActiveSheetIndex();

		do
		{
			drawingIterator it = GetDocument()->GetSheet(sheet)->GetDrawingBegin();
			while (it != GetDocument()->GetSheet(sheet)->GetDrawingEnd()) 
			{
				CDrawingObject *pointer = *it;
				// Look for method objects
				if (pointer->GetType() == xMethodEx3) 
				{
					thisMethod = (CDrawMethod *)pointer;
					thisSymbol = thisMethod->GetSymbolData();

					// If there is no symbol then cannot modify this symbol!
					if (thisMethod->IsNoSymbol()) 
					{
						MissingSymbols = TRUE;
						++ it;
						continue;
					}

					// Has this symbol got a reference?
					IsSet   = thisMethod->HasRef();

					switch (theASetup.reference)
					{
					case 0:		// All references
						IsMatch = TRUE;
						break;
					case 1:		// Un-numbered references
						IsMatch = !thisMethod->HasRef();
						break;
					case 2:		// References that match...
						IsMatch = theASetup.matchval == thisSymbol->reference;
						break;
					}

					if (IsMatch)
					{

						// First pass  - we remove references if necessary,
						// Second pass - we add refences back in...
						//
						if (i == 0)
						{
							// Remove any matching references (if necessary)
							if (IsSet && (theASetup.value!=1 || thisMethod->GetRefVal()>=theASetup.startval) ) 
							{
								thisMethod->RemoveReference();
							}
						}
						else
						{
							// Now add back any references
							if (theASetup.action == 0) 
							{
								if (theASetup.reference != 1)
								{
									value = (theASetup.value == 0) ? 1 : theASetup.startval;
								}
								thisMethod->AddReference( value, theASetup.all_sheets );
							}
						}
					}
				}

				++ it;
			}
			++ sheet;
		} while ( theASetup.all_sheets && sheet < GetDocument()->GetNumberOfSheets() );
	}

  // Where there any missing symbols?
  if (MissingSymbols)
	Message(IDS_MISSMETH,MB_ICONEXCLAMATION);


  // Restore the correct cursor
  SetCursor( AfxGetApp()->LoadStandardCursor( IDC_ARROW ) );


  // Ensure the window is re-drawn
  GetCurrentDocument()->SetModifiedFlag( TRUE );
  Invalidate();  
}
// The code below is from the wizard but it has been customized for this 
// application. There is a custom code to handle WM_SIZE, WM_GESTURENOTIFY
// and WM_GESTURE messages.
//
// Processes messages for the main window:
//      WM_COMMAND        - process the application menu
//      WM_SIZE           - process resizing of client window
//      WM_PAINT          - paint the main window
//      WM_DESTROY        - post a quit message and return
//      WM_GESTURENOTIFY  - process a gesture notification message 
//      WM_GESTURE        - process the gesture command
// in:
//      hWnd        window handle
//      message     message code
//      wParam      message parameter (message-specific)
//      lParam      message parameter (message-specific)
// returns:
//      the result of the message processing and depends on the message sent
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_GESTURENOTIFY:
        {
            // This is the right place to define the list of gestures that this
            // application will support. By populating GESTURECONFIG structure 
            // and calling SetGestureConfig function. We can choose gestures 
            // that we want to handle in our application. In this app we
            // decide to handle all gestures.
            GESTURECONFIG gc = {
                0,              // gesture ID
                GC_ALLGESTURES, // settings related to gesture ID that are to be 
                                // turned on
                0               // settings related to gesture ID that are to be 
                                // turned off
            };

            BOOL bResult = SetGestureConfig(
                hWnd,                 // window for which configuration is specified  
                0,                    // reserved, must be 0
                1,                    // count of GESTURECONFIG structures
                &gc,                  // array of GESTURECONFIG structures, dwIDs will be processed in the
                                      // order specified and repeated occurances will overwrite previous ones
                sizeof(GESTURECONFIG) // sizeof(GESTURECONFIG)
            );                        
            
            if (!bResult)
            {
                ASSERT(L"Error in execution of SetGestureConfig" && 0);
            }
        }
        break;

    case WM_GESTURE:
        // The gesture processing code is implemented in the CGestureEngine 
        // class.
        return g_cGestureEngine.WndProc(hWnd,wParam,lParam);
        break;

    case WM_SIZE:
        // resize rectangle and place it in the middle of the new client area
        g_cRect.ResetObject(LOWORD(lParam),HIWORD(lParam));
        break;

    case WM_COMMAND:
        wmId = LOWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;

    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);       

        // Full redraw: background + rectangle
        g_cRect.Paint(hdc);

        EndPaint(hWnd, &ps);
        break;

    case WM_DESTROY:

        PostQuitMessage(0);

        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
示例#10
0
void CTinyCadView::OnDraw(CDC* pDC)
{
	//CTinyCadDoc* pDoc = GetCurrentDocument();
	CDC BitmapDC;
	CBitmap *old_bitmap = NULL;

	int selected;

	CRect client;
	if (pDC->IsKindOf(RUNTIME_CLASS(CPaintDC)))
	{
		client = static_cast<CPaintDC*> (pDC)->m_ps.rcPaint;
	}
	else
	{
		GetClientRect(&client);
	}

	// Are we going to use off-screen drawing?
	BOOL osb = !pDC->IsPrinting() && m_use_offscreen_drawing && CreateBitmap(*pDC, client.Width(), client.Height());

	if (osb)
	{
		BitmapDC.CreateCompatibleDC(pDC);
		old_bitmap = BitmapDC.SelectObject(&m_bitmap);
	}

	{
		CContext dc(osb ? &BitmapDC : pDC, GetTransform(), this);

		CDPoint origin = GetTransform().GetOrigin();

		if (osb)
		{
			CPoint point = CPoint(-client.left, -client.top);
			dc.SetPixelOffset(point);
		}

		if (pDC->IsPrinting())
		{
			dc.SetBlack(CTinyCadRegistry::GetPrintBandW());
		}

		CDPoint Start, End;
		CRect rect;
		GetClientRect(&rect);
		TransformSnap snap;
		snap.SetGridSnap(FALSE);
		Start = GetTransform().DeScale(snap, CPoint(rect.left, rect.top));
		End = GetTransform().DeScale(snap, CPoint(rect.right, rect.bottom));

		// Is any of this region in the off-page area?
		if (!pDC->IsPrinting())
		{

			// Paint the region white
			if (pDC->IsPrinting())
			{
				dc.SelectBrush(cWHITE);
				dc.SelectPen(PS_SOLID, 1, cWHITE);
			}
			else
			{
				COLORREF col = GetCurrentDocument()->GetOptions()->GetUserColor().Get(CUserColor::BACKGROUND);
				dc.SelectBrush(col, 0);
				dc.SelectPen(PS_SOLID, 1, col);
			}
			dc.Rectangle(CDRect(Start.x - 2, Start.y - 2, End.x + 2, End.y + 2));

			dc.SelectBrush(cOFFPAGE);
			dc.SelectPen(PS_SOLID, 1, cOFFPAGE);

			if (End.x > GetCurrentDocument()->GetDetails().GetPageBoundsAsPoint().x)
			{
				CDPoint a = CDPoint(GetCurrentDocument()->GetDetails().GetPageBoundsAsPoint().x, 0);
				dc.Rectangle(CDRect(a.x, a.y, End.x, End.y));
			}
			if (End.y > GetCurrentDocument()->GetDetails().GetPageBoundsAsPoint().y)
			{
				CDPoint a = CDPoint(Start.x, GetCurrentDocument()->GetDetails().GetPageBoundsAsPoint().y);
				dc.Rectangle(CDRect(a.x, a.y, End.x, End.y));
			}
			if (Start.x < 0) dc.Rectangle(CDRect(0, Start.y, Start.x, End.y));
			if (Start.y < 0) dc.Rectangle(CDRect(Start.x, 0, End.x, Start.y));

			// Fill this region with a grid
			double grid = GetCurrentDocument()->m_snap.GetGrid();
			double SGrid = dc.GetTransform().doubleScale(grid);
			if (GetCurrentDocument()->GetOptions()->ShowGrid() && SGrid > 10)
			{
				double x = dc.GetTransform().GetOrigin().x;
				double y = dc.GetTransform().GetOrigin().y;

				TransformSnap s = GetCurrentDocument()->m_snap;
				s.SetGridSnap(TRUE);

				x = s.Snap(x);
				y = s.Snap(y);

				for (double xp = x >= 0 ? x : 0; xp < End.x && xp < GetCurrentDocument()->GetDetails().GetPageBoundsAsPoint().x; xp += grid)
				{
					for (double yp = y >= 0 ? y : 0; yp < End.y && yp < GetCurrentDocument()->GetDetails().GetPageBoundsAsPoint().y; yp += grid)
					{
						dc.SetPixel(CDPoint(xp, yp), 0);
					}
				}
			}
		}

		Start -= CDPoint(10, 10);
		End += CDPoint(10, 10);

		GetCurrentDocument()->GetSelectBegin();

		drawingIterator it = GetCurrentDocument()->GetDrawingBegin();
		while (it != GetCurrentDocument()->GetDrawingEnd())
		{
			CDrawingObject *obj = *it;

			selected = !pDC->IsPrinting() && GetCurrentDocument()->IsSelected(obj);
			paint_options options = selected ? draw_selected : draw_normal;

			if (!pDC->IsPrinting() || !obj->IsConstruction())
			{
				if (pDC->IsPrinting() || obj->IsInside(Start.x, End.x, Start.y, End.y))
				{
					obj->Paint(dc, options);
				}
			}

			++it;
		}

		// Now draw the selectable object, so it stands out...
		CDrawingObject *obj = GetCurrentDocument()->GetSelectable();
		if (obj != NULL && !GetCurrentDocument()->IsSelected(obj))
		{
			paint_options options = draw_selectable;
			GetCurrentDocument()->GetSelectable()->Paint(dc, options);
		}

		// If only one item is selected then just draw its handles now
		if (GetCurrentDocument()->IsSingleItemSelected())
		{
			GetCurrentDocument()->GetSingleSelectedItem()->PaintHandles(dc);
		}

		// if necessary turn back on the current object to be edited
		if (GetCurrentDocument()->GetEdit() != NULL) {
			//ATLTRACE2("TinyCadView::GetCurrentDocument->GetEdit->Paint(dc, draw_selected=%d)\n",draw_selected);
			GetCurrentDocument()->GetEdit()->Paint(dc, draw_selected);
		}

		// Draw the design details
		GetCurrentDocument()->Display(dc);
	}

	if (osb)
	{
		pDC->BitBlt(client.left, client.top, client.Width(), client.Height(), &BitmapDC, 0, 0, SRCCOPY);
		BitmapDC.SelectObject(old_bitmap);
	}
}
示例#11
0
//-------------------------------------------------------------------------
void CTinyCadDoc::SaveXML(CXMLWriter &xml, drawingCollection &drawing, BOOL Details, BOOL SaveSelect, BOOL SaveResources )
{
  // Write the objects to the file
  try
  {  
	xml.addTag(GetXMLTag());

	// If necessary write the header stamp
	if (Details) 
	{
		xml.addTag(_T("NAME"));
		xml.addChildData( m_sheet_name );
		xml.closeTag();

		xml.addTag(_T("DETAILS"));
		m_oDetails.WriteXML( xml );
		m_snap.SaveXML( xml );
		xml.closeTag();
	}

	if (SaveResources)
	{
		// Find out which resources are in use
		
		for( drawingIterator i = drawing.begin(); i != drawing.end(); i++ )
		{
			(*i)->TagResources();
		}

		// Save the resource details details
		theOptions.SaveFontsXML(xml);
		theOptions.SaveStylesXML(xml);
		theOptions.SaveFillStylesXML(xml);
		theOptions.SaveMetaFilesXML(xml);
	}

	// Only save the symbols if we are not saving
	// to a library or the header...
	if (Details)
	{
		theOptions.SaveSymbolsXML(xml);
	}

	if (Details)
	{
		theOptions.WriteXML( xml) ;
	}

	for( drawingIterator i = drawing.begin(); i != drawing.end(); i++ )
	{
		CDrawingObject* obj = *i;

		if (obj->GetType() != xError
			&& 	(Details || !obj->IsConstruction()) 
			&&  (!SaveSelect || IsSelected( obj )) )
		{

			// Now save the actual object data
			obj->SaveXML(xml);
		}
	}

	xml.closeTag();

  }
  catch ( CException *e) 
  {
	// Could not save the file properly
    e->ReportError();
    e->Delete();
  }
}
示例#12
0
////// Load a design from a file, loaded design will be selected //////
BOOL CTinyCadDoc::ReadFileXML(CXMLReader &xml, BOOL Details, drawingCollection &drawing, BOOL AlreadyStarted)
{
  try
  {
	// Read in the first item...
	CString name;
	bool sheets = false;

	if (!AlreadyStarted)
	{
		xml.nextTag( name );
		if (name == "TinyCADSheets")
		{
			xml.intoTag();
			sheets = true;
			// We must search for the first TinyCAD section
			while (xml.nextTag( name ) && name != GetXMLTag())
			{
			}
		}
		
		// Check we are at the right point
		if (name != GetXMLTag())
		{
			Message(IDS_ABORTVERSION,MB_ICONEXCLAMATION);
			return FALSE;
		}
	}

	BOOL ResetMerge = TRUE;

	xml.intoTag();

	while (	xml.nextTag( name ) )
	{
		// Save the old layer setting
		CDrawingObject *obj = NULL;

		if (name == "DETAILS" )
		{
			if (Details)
			{
				GetDetails().ReadXML( xml, m_snap );
			}
		}
		else if (name == "NAME")
		{
			if (Details)
			{
				xml.getChildData( m_sheet_name );
			}
		}
		else if (name == "GRID")
		{
			if (Details)
			{
				m_snap.LoadXML( xml );
			}
		}
		else if (name == "FONT")
		{
			if (ResetMerge)
			{
				theOptions.ResetMerge();
				ResetMerge = FALSE;
			}
			theOptions.LoadFontXML(xml);
		}
		else if (name == "STYLE")
		{
			if (ResetMerge)
			{
				theOptions.ResetMerge();
				ResetMerge = FALSE;
			}
			theOptions.LoadStyleXML(xml);
		}
		else if (name == "FILL")
		{
			if (ResetMerge)
			{
				theOptions.ResetMerge();
				ResetMerge = FALSE;
			}
			theOptions.LoadFillStyleXML(xml);
		}
		else if (name == "META" || name == "IMAGE")
		{
			if (ResetMerge)
			{
				theOptions.ResetMerge();
				ResetMerge = FALSE;
			}
			theOptions.LoadMetaFileXML(xml);
		}
		else if (name == "SYMBOLDEF")
		{
			if (ResetMerge)
			{
				theOptions.ResetMerge();
				ResetMerge = FALSE;
			}
			theOptions.LoadSymbolXML(xml);
		}
		else if (name == "OPTIONS")
		{
			theOptions.ReadXML( xml );
		}
		else if (name == CDrawBusSlash::GetXMLTag())
		{
			obj = new CDrawBusSlash(this);
		}
		else if (name == CDrawTag::GetXMLTag())
		{
			obj = new CDrawTag(this);
		}
		else if (name == CDrawJunction::GetXMLTag())
		{
			obj = new CDrawJunction(this);
		}
		else if (name == CDrawLine::GetXMLTag(xBus))
		{
			obj = new CDrawLine(this, xBus);
		}
		else if (name == CDrawLine::GetXMLTag(xWire))
		{
			obj = new CDrawLine(this, xWire);
		}
		else if (name == CDrawLine::GetXMLTag(xLineEx2))
		{
			obj = new CDrawLine(this, xLineEx2);
		}
		else if (name == CDrawMetaFile::GetXMLTag())
		{
			obj = new CDrawMetaFile(this);
		}
		else if (name == CDrawMethod::GetXMLTag())
		{
			obj = new CDrawMethod(this);
		}
		else if (name == CDrawHierarchicalSymbol::GetXMLTag())
		{
			obj = new CDrawHierarchicalSymbol(this);
		}
		else if (name == CDrawNoConnect::GetXMLTag())
		{
			obj = new CDrawNoConnect(this);
		}
		else if (name == CDrawPin::GetXMLTag())
		{
			obj = new CDrawPin(this);
		}
		else if (name == CDrawRuler::GetXMLTag())
		{
			obj = new CDrawRuler(this, FALSE);
		}
		else if (name == CDrawSquare::GetXMLTag( TRUE ))
		{
			obj = new CDrawSquare(this, xSquareEx3);
		}
		else if (name == CDrawSquare::GetXMLTag( FALSE ))
		{
			obj = new CDrawSquare(this, xCircleEx3);
		}
		else if (name == CDrawText::GetXMLTag(xTextEx2))
		{
			obj = new CDrawText(this, xTextEx2);
		}
		else if (name == CDrawText::GetXMLTag(xBusNameEx))
		{
			obj = new CDrawText(this, xBusNameEx);
		}
		else if (name == CDrawLabel::GetXMLTag())
		{
			obj = new CDrawLabel(this);
		}
		else if (name == CDrawPolygon::GetXMLTag())
		{
			obj = new CDrawPolygon(this);
		}
		else if (name == CDrawPower::GetXMLTag())
		{
			obj = new CDrawPower(this);
		}

		if (obj != NULL)
		{
			// Load this object...
			obj->LoadXML( xml );

			// Now add object to linked list
			drawing.insert( drawing.end(), obj );
		}
	}

	xml.outofTag();

	if (sheets)
	{
		xml.outofTag();
	}
  }
  catch( CException *e ) 
  {
	  e->ReportError();
	  e->Delete();
	  return FALSE;
  }


  return drawing.size() > 0;
}
示例#13
0
//-- Load a design from a file, loaded design will be selected
BOOL CTinyCadDoc::ReadFile(CStream &theArchive, BOOL Details, drawingCollection &drawing)
{
  try
  {
	// Save the old layer setting
	CDrawingObject*	obj		= NULL;
	BYTE			tp		= xNULL;
	CHeaderStamp	oHeader;

	LONG pos = theArchive.GetPos();

	oHeader.Read( theArchive );

	if( ! oHeader.IsChecked(false) )
	{
		// Perhaps this is XML?
		theArchive.Seek(pos);
		CXMLReader xml( &theArchive );
		return ReadFileXML( xml, Details, drawing, FALSE );
	}

	while (tp!=xEndFile) {
		theArchive >> tp;

		switch (tp) {
			case xDesignInformation:
				GetDetails().Read( theArchive );
				break;
			case xDesignInformation2:
				GetDetails().ReadEx( theArchive );
				m_snap.Load( theArchive, Details );
				break;
			case xOptions:
				if( Details )
				{
					theOptions.ReadNative( theArchive );
				}
				else
				{
					COption().ReadNative( theArchive );
				}
				obj = NULL;
				break;
			case xFont:
				theOptions.LoadFonts(theArchive);
				obj = NULL;
				break;
			case xLineStyle:
				theOptions.LoadStyles(theArchive);
				obj = NULL;
				break;
			case xFillStyle:
				theOptions.LoadFillStyles(theArchive);
				obj = NULL;
				break;
			case xMetaFiles:
				theOptions.LoadMetaFiles(theArchive);
				obj = NULL;
				break;
			case xSymbols:
				theOptions.LoadSymbols(theArchive);
				obj = NULL;
				break;
			case xLayerTable:
				{
					// Read in the number of Layers in this list
					CString theNewName;
					WORD NumberOfResources;
					theArchive >> NumberOfResources;

					hRESOURCE OldResourceNumber = 0;

					while (NumberOfResources > 0) {
						theArchive >> OldResourceNumber;
						theArchive >> theNewName;
						NumberOfResources--;
					}
					obj = NULL;
				}
				break;
			case xRuler:
				obj = new CDrawRuler(this,FALSE);
				break;
			case xBus:
				obj = new CDrawLine(this,xBus);
				break;
			case xWire:
				obj = new CDrawLine(this,xWire);
				break;
			case xBusName:
				obj = new CDrawText(this,xBusName);
				break;
			case xBusNameEx:
				obj = new CDrawText(this,xBusNameEx);
				break;
			case xLabel:  	
				obj = new CDrawLabel(this);
				break;
			case xLabelEx:
				obj = new CDrawLabel(this);
				break;
			case xLabelEx2:
				obj = new CDrawLabel(this);
				break;
			case xJunction:
				obj = new CDrawJunction(this);
				break;
			case xNoConnect:
				obj = new CDrawNoConnect(this);
				break;
			case xBusSlash:
				obj = new CDrawBusSlash(this);
				break;
			case xPower:
				obj = new CDrawPower(this);
				break;
			case xPin:
			case xPinEx:
				obj = new CDrawPin(this);
				break;
			case xLine:
				obj = new CDrawPolygon(this,xLine);
				break;
			case xLineEx:
				obj = new CDrawPolygon(this,xLineEx);
				break;
			case xLineEx2:
				obj = new CDrawPolygon(this,xLineEx2);
				break;
			case xPolygon:
				obj = new CDrawPolygon(this,xPolygon);
				break;
			case xDash:
				obj = new CDrawPolygon(this,xDash);
				break;
			case xText:		// The old text type
				obj = new CDrawText(this,xText);
				break;
			case xTextEx:
				obj = new CDrawText(this,xTextEx);
				break;
			case xTextEx2:
				obj = new CDrawText(this,xTextEx2);
				break;
			case xCircle:
			case xCircleEx:
			case xCircleEx2:
			case xCircleEx3:
				obj = new CDrawSquare(this,xCircleEx3);
				break;
			case xSquare:
			case xSquareEx:
			case xSquareEx2:
			case xSquareEx3:
				obj = new CDrawSquare(this,xSquareEx3);
				break;
			case xArc:
			case xArcEx:
			case xArcEx2:
				obj = new CDrawPolygon(this,static_cast<ObjType>(tp));
				break;
			case xMethod:		// The old method type
			case xMethodEx:
			case xMethodEx2:
			case xMethodEx3:
				obj = new CDrawMethod(this);
				break;
			case xTag:
				obj = new CDrawTag(this);
				break;
			case xMetaFile:
				obj = new CDrawMetaFile(this);
				break;
			default:
				obj = NULL;
				break;
		}
		
		if (obj!=NULL) 
		{
			// Provide special handling for old objects
			switch (tp) {
				case xSquare:
				case xSquareEx:
				case xCircle:
				case xCircleEx:
					((CDrawSquare *)obj)->OldLoad(theArchive,tp);
					break;
				case xCircleEx2:
				case xSquareEx2:
					((CDrawSquare *)obj)->OldLoad2(theArchive);
					break;
				case xMethod:
					((CDrawMethod *)obj)->OldLoad(theArchive);
					break;
				case xMethodEx:
					((CDrawMethod *)obj)->OldLoad2(theArchive);
					break;
				case xMethodEx2:
					((CDrawMethod *)obj)->OldLoad3(theArchive);
					break;
				case xPin:
					((CDrawPin *)obj)->OldLoad(theArchive);
					break;
				case xLabel:
				case xLabelEx:
				case xLabelEx2:
					((CDrawLabel *)obj)->Load(theArchive,(ObjType)tp);
					break;
				default:
					obj->Load(theArchive);
					break;
			}

			// Now add object to linked list
			drawing.insert( drawing.end(), obj );
		}
  	}

  }

  catch( CException *e) 
  {
		CString s;
		CString msg;
		e->GetErrorMessage( msg.GetBuffer(256), 256, NULL );
		msg.ReleaseBuffer();
		s.Format(_T("Cannot load file.\r\n%s"),
			msg );
		AfxMessageBox( s );
		e->Delete();
  }


  return drawing.size() > 0;
}
// Redo the last action
void CTinyCadDoc::Redo()
{
	SetSelectable( NULL );
	BOOL action_taken = FALSE;

	// Is this possible?
	while (CanRedo() && !action_taken)
	{


		m_undo_level ++;

		// Re-apply all of the changes we have done at this level
		CDocUndoSet &s = m_undo[ m_undo_level ];


		// Go through the list of action and redo each one 
		//
		CDocUndoSet::actionCollection::iterator act_it = s.m_actions.begin();

		while (act_it != s.m_actions.end())
		{
			CDocUndoSet::CDocUndoAction &act = *act_it;

			// Look up this item from the index...
			drawingCollection::iterator it = m_drawing.begin();
			int index = act.m_index;
			while (index > 0 && it != m_drawing.end())
			{
				++ it;
				-- index;
			}

			if (it != m_drawing.end())
			{
				(*it)->Display();
			}
			act.m_object->Display();

			switch (act.m_action)
			{
			case CDocUndoSet::Deletion:
				// We must re-delete the deleted objects
				delete *it;
				m_drawing.erase( it );
				action_taken = TRUE;
				break;
			case CDocUndoSet::Addition:
				// We must re-insert the additions
				m_drawing.insert( it, Dup(act.m_object) );
				action_taken = TRUE;
				break;
			case CDocUndoSet::Change:
				// We convert the old objects into the new objects...
				{
					// Keep a copy for the redo...
					CDrawingObject *copy = Dup(*it);
					delete *it;

					copy->Display();
					*it = act.m_object;
					act.m_object = copy;
				}
				action_taken = TRUE;
				break;
			}

			++ act_it;
		}
	}
}
示例#15
0
// Create netlist and output as a PCB file
void CNetList::WriteNetListFileTinyCAD( CTinyCadMultiDoc *pDesign, const TCHAR *filename )
{
  FILE *theFile;
  errno_t err;
  err = _tfopen_s(&theFile, filename,_T("w"));
  if ((theFile == NULL) || (err != 0))
  {
	Message(IDS_CANNOTOPEN);
	return;
  }

  // Set the Busy icon
  SetCursor( AfxGetApp()->LoadStandardCursor( IDC_WAIT ) );

  // Get the net list
  MakeNet( pDesign );

  _ftprintf(theFile,NetComment _T(" ====+  Net List for %s  +====\n\n"), pDesign->GetPathName() );


  _ftprintf(theFile,NetComment _T(" ======+ The component list\n\n"));

  // Keep track of the references we have outputted...
  std::set<CString>	referenced;

  	// Do this for all of the files in the imports list...
	fileCollection::iterator fi = m_imports.begin();
	for (;fi != m_imports.end(); ++ fi)
	{
		CTinyCadMultiDoc *dsn = pDesign;

		if ((*fi)->m_file_name_index != 0)
		{
			dsn = (*fi)->m_pDesign;
		}

		// Generate a component for every sheet in this design
		for (int i = 0; i < dsn->GetNumberOfSheets(); i++)
		{
			drawingIterator it = dsn->GetSheet(i)->GetDrawingBegin();
			while (it != dsn->GetSheet(i)->GetDrawingEnd()) 
			{
			CDrawingObject *pointer = *it;

			if (pointer->GetType() == xMethodEx3) 
			{
				CDrawMethod *pMethod = static_cast<CDrawMethod *>(pointer);
				CString Name = pMethod->GetField(CDrawMethod::Name);
				CString Ref  = pMethod->GetRefSheet(m_prefix_references,m_prefix_import,(*fi)->m_file_name_index,i+1);

				// Do we need to output this part?
				if (referenced.find( Ref ) == referenced.end())
				{
					referenced.insert( Ref );

					_ftprintf(theFile,_T("COMPONENT '%s' = %s\n"),Ref,Name);

					// Now write it it's "other" references
					for (int i = 2; i < pMethod->GetFieldCount(); i++)
					{
						_ftprintf(theFile,_T("\tOPTION '%s' = %s\n"),pMethod->GetFieldName(i), pMethod->GetField(i) );
					}
				}
			}
			
			++ it;
			}
		}
	}

  _ftprintf(theFile,_T("\n\n") NetComment _T(" ======+ The net list\n\n"));
  int Label = 0;

  netCollection::iterator nit = m_nets.begin();

	while (nit != m_nets.end()) 
	{
		nodeVector::iterator nv_it = (*nit).second.begin();

		CString theLine,theLabel;

		if (nv_it != (*nit).second.end()) 
		{
			theLine = "";
			BOOL first = TRUE,PrintLine=FALSE, Labeled = FALSE;

			while (nv_it != (*nit).second.end()) 
			{
				CNetListNode& theNode = *nv_it;
				++ nv_it;

				if (theNode.getLabel() != "" && !Labeled) 
				{
					theLabel = theNode.getLabel();
					Labeled = TRUE;
				}
				else
				{
					CString add;
					if (!theNode.getLabel().IsEmpty())
					{
						add = theNode.getLabel();
					}
					else if (!theNode.m_reference.IsEmpty())
					{
						add.Format(_T("(%s,%s)"), theNode.m_reference, theNode.m_pin );
					}

					if (!add.IsEmpty())
					{
						if (first)
						{
							first = FALSE;
						}
						else
						{
							theLine += _T(",");
						}

						theLine += add;
						PrintLine=TRUE;
					}
				}
			}
			if (PrintLine) {
				_ftprintf(theFile,_T("NET  "));
				if (Labeled)
					_ftprintf(theFile,_T("'%s'"),theLabel);
				else
					_ftprintf(theFile,_T("'N%06d'"),Label++);
				_ftprintf(theFile,_T(" =  %s\n"),theLine);
			}
		}

		++ nit;
	}


  SetCursor( AfxGetApp()->LoadStandardCursor( IDC_ARROW ) );
  fclose(theFile);
}
示例#16
0
// Create netlist and output as a SPICE file
void CNetList::WriteSpiceFile( CTinyCadMultiDoc *pDesign, const TCHAR *filename )
{
	// Open the filename for the spice file
	FILE *theFile;
	errno_t err;
	err = _tfopen_s(&theFile, filename,_T("w"));
	if ((theFile == NULL) || (err != 0))
	{
		Message(IDS_CANNOTOPEN);
		return;
	}

	// Output the standard header comment - expected on line 1 by some Spice engines
	_ftprintf(theFile,_T("* Schematics Netlist *\n"));

	createErrorFile( filename );

	_ftprintf(m_err_file,_T("Results of Spice file generation for %s\n\n"),
		pDesign->GetPathName() );


	// Set the Busy icon
	SetCursor( AfxGetApp()->LoadStandardCursor( IDC_WAIT ) );

	// Create the net list
	m_prefix_import = TRUE;
	m_prefix_references = TRUE;
	MakeNet( pDesign );

	
	// Now we have the net list we must convert it into a file suitable for
	// spice...
	//
	// The netlist represents a single vector per net, however, spice requires
	// a vector per symbol.  We have to rotate the array, so that we have one
	// entry in our vector for each of the symbols in our drawing....
	//
	
	typedef std::map<CString,CNetListSymbol>	symbolCollection;
	symbolCollection symbols;
	labelCollection labels;


	netCollection::iterator nit = m_nets.begin();

	while (nit != m_nets.end()) 
	{
		nodeVector::iterator nv_it = (*nit).second.begin();

		while (nv_it != (*nit).second.end()) 
		{
			CNetListNode& theNode = *nv_it;
			++ nv_it;

			// Is this node a symbol?
			if (!theNode.m_reference.IsEmpty() && theNode.m_pMethod->GetType() == xMethodEx3 )
			{
				// Yes, so update the pin allocations in the symbol map...
				CNetListSymbol &symbol = symbols[ theNode.m_reference ];

				symbol.m_pins[ theNode.m_pin ] = theNode.m_NetList;
				symbol.m_pMethod = theNode.m_pMethod;
			}

			// Is this node a label?
			if (!theNode.getLabel().IsEmpty())
			{
				// Yes, so update the label collection
				labels[ theNode.m_NetList ] = theNode.getLabel();
			}
		}

		++ nit;
	}


	//
	// We scan the symbols array and extract any file imports
	// That we need from the fields of the symbols...
	//
	symbolCollection::iterator sit = symbols.begin();

	typedef std::set<CString> strings;
	typedef std::vector<strings> string_collection;
	string_collection prolog_lines;
	string_collection epilog_lines;
	prolog_lines.resize( 10 );
	epilog_lines.resize( 10 );

	// Do this for all of the files in the imports list...
	fileCollection::iterator fi = m_imports.begin();
	for (;fi != m_imports.end(); ++ fi)
	{
		CTinyCadMultiDoc *dsn = pDesign;

		if ((*fi)->m_file_name_index != 0)
		{
			dsn = (*fi)->m_pDesign;
		}

		// Generate a component for every sheet in this design
		for (int sheet = 0; sheet < dsn->GetNumberOfSheets(); sheet++)
		{
			drawingIterator it = dsn->GetSheet(sheet)->GetDrawingBegin();
			while (it != dsn->GetSheet(sheet)->GetDrawingEnd()) 
			{
				CDrawingObject *pointer = *it;

				if (pointer->GetType() == xMethodEx3) 
				{
					CDrawMethod *pMethod = static_cast<CDrawMethod *>(pointer);

					// Search this symbols fields and extract the SPICE_IMPORT field...
					//

					CString spice_prolog;
					CString spice_epilog;
					int spice_pro_priority = 5;
					int spice_epi_priority = 5;

					for (int j = 0; j < pMethod->GetFieldCount(); j++)
					{
						CString field = pMethod->GetFieldName(j);
						if (field.CompareNoCase(AttrSpiceProlog) == 0)
						{
							CNetListSymbol symbol( (*fi)->m_file_name_index, sheet, pMethod );
							spice_prolog = expand_spice( (*fi)->m_file_name_index, sheet, symbol, labels, pMethod->GetField(j) );
						}
						else if (field.CompareNoCase(AttrSpiceEpilog) == 0)
						{
							CNetListSymbol symbol( (*fi)->m_file_name_index, sheet, pMethod );
							spice_epilog = expand_spice( (*fi)->m_file_name_index, sheet, symbol, labels, pMethod->GetField(j) );
						}
						else if (field.CompareNoCase(AttrSpicePrologPri) == 0)
						{
							spice_pro_priority = _tstoi( pMethod->GetField(j) );
							if (spice_pro_priority < 0 || spice_pro_priority > 9)
							{
								spice_pro_priority = 5;
							}
						}
						else if (field.CompareNoCase(AttrSpiceEpilogPri) == 0)
						{
							spice_epi_priority = _tstoi( pMethod->GetField(j) );
							if (spice_epi_priority < 0 || spice_epi_priority > 9)
							{
								spice_epi_priority = 5;
							}
						}
					}


					// Prologue...
					strings &prolog = prolog_lines[ spice_pro_priority ];
					if (prolog.find( spice_prolog ) == prolog.end())
					{
						// Not included yet...
						prolog.insert( spice_prolog );
					}

					// Epilog..
					strings &epilog = epilog_lines[ spice_pro_priority ];
					if (epilog.find( spice_epilog ) == epilog.end())
					{
						// Not included yet...
						epilog.insert( spice_epilog );
					}
				}
			
				++ it;
			}
		}
	}
 
	// We have extracted the prologue, so now output it in the
    // order of priority (0 being first...)
	int priority;
    for (priority = 0; priority < 10; priority ++)
	{
		strings &s = prolog_lines[ priority ];
		strings::iterator i = s.begin();
		while (i != s.end())
		{
			_ftprintf( theFile, _T("%s\n"), *i );
			++ i;
		}
	}


	// We now have the netlist in the form we require it, so
	// let us now output the symbols in the correct SPICE format...
	//
	sit = symbols.begin();
	while (sit != symbols.end())
	{
		CString reference = (*sit).first;
		CNetListSymbol &symbol = (*sit).second;
		CDrawMethod* pMethod = symbol.m_pMethod;
		int sheet = symbol.m_sheet;
		int file_name_index = symbol.m_file_name_index;

		// Here is the data we are going to extract from
		// the symbol's fields...
		CString spice = "";

		// Search this symbols fields and extract the SPICE field...
		//
		int i;
		for (i = 0; i < pMethod->GetFieldCount(); i++)
		{
			if (pMethod->GetFieldName(i).CompareNoCase(AttrSpice) == 0)
			{
				spice = pMethod->GetField(i);
			}
		}

		
		// Now output the SPICE model line
		if (!spice.IsEmpty())
		{
			_ftprintf(theFile,_T("%s\n"), expand_spice( file_name_index, sheet, symbol, labels, spice ) );
		}
		else
		{
			_ftprintf(theFile,_T("NO_MODEL\n") );
			writeError(_T("%s: %s on sheet %d has no model\n"),
				symbol.m_pMethod->GetRef(), symbol.m_pMethod->GetName(), sheet );
		}
		++ sit;
	}


	// Now write out the epilog
    for (priority = 9; priority >= 0; priority --)
	{
		strings &s = epilog_lines[ priority ];
		strings::iterator i = s.begin();
		while (i != s.end())
		{
			_ftprintf( theFile,_T("%s\n"), *i );
			++ i;
		}
	}



	SetCursor( AfxGetApp()->LoadStandardCursor( IDC_ARROW ) );
	fclose(theFile);

	reopenErrorFile( true );
}
示例#17
0
// Perform the work of making a netlist from a single sheet in this design...
void CNetList::MakeNetForSheet( fileCollection &imports, int file_index_id, int &file_name_index, int sheet, CTinyCadDoc *pDesign )
{
  // Get rid of any old data
  m_CurrentNet = 1;
  m_nodes.erase( m_nodes.begin(), m_nodes.end() );
  m_nets.erase( m_nets.begin(), m_nets.end() );

  // Here is some temporary data for this function
  typedef std::map<CString,int> stringCollection;
  stringCollection	Powers;
  stringCollection	Connected;

  // Search for nodes, and build the node tree
  drawingIterator it = pDesign->GetDrawingBegin();
  for (;it != pDesign->GetDrawingEnd(); ++ it ) 
  {
	CDrawingObject *ObjPtr = *it;
	stringCollection::iterator found;
	int hold;
	CDPoint tr;

	switch (ObjPtr->GetType()) 
	{
		case xHierarchicalSymbol:
			{
				CDrawHierarchicalSymbol *pSymbol = static_cast<CDrawHierarchicalSymbol*>(ObjPtr);

				// Try and stop recursion by limiting the number of imports
				if (imports.size() > 100)
				{
					AfxMessageBox( IDS_RECURSION );
					continue;
				}

				// Push back this filename into the list of extra imports
				CImportFile *f = new CImportFile;
				++ file_name_index;
				f->m_file_name_index = file_name_index;
				if (f->Load( pSymbol->GetFilename() ) )
				{
					imports.push_back( f );

					// Now search the symbol for pins to link the other symbols to
					drawingCollection method;
					pSymbol->ExtractSymbol(tr,method);

					drawingIterator it = method.begin();
					while ( it != method.end() ) 
					{
						CDrawingObject *pointer = *it;

						if (pointer->GetType()==xPinEx) 
						{
							CDrawPin *thePin = static_cast<CDrawPin*>(pointer);

							// This in effect labels the node with the new node name...
							CNetListNode n( file_name_index, sheet, thePin, thePin->GetActivePoint(pSymbol) );
							n.setLabel( thePin->GetPinName() );
							n.m_reference = pSymbol->GetRefSheet(m_prefix_references,m_prefix_import,file_index_id,sheet);
							n.m_pin = thePin->GetNumber();
							n.m_pMethod = pSymbol;
							Add(n);
						}

						++ it;
					}
				}
				else
				{
					delete f;
				}
			}
			break;
		case xMethodEx3:
			#define thePin ((CDrawPin*)pointer)
			#define theMethod ((CDrawMethod*)ObjPtr)
			{
				drawingCollection method;
				((CDrawMethod *)ObjPtr)->ExtractSymbol(tr,method);

				drawingIterator it = method.begin();
				while ( it != method.end() ) 
				{
					CDrawingObject *pointer = *it;

					if (pointer->GetType()==xPinEx && !(thePin->IsPower()) ) 
					{
						CNetListNode n( file_index_id, sheet, thePin,thePin->GetActivePoint(theMethod));
						n.m_reference = theMethod->GetRefSheet(m_prefix_references,m_prefix_import,file_index_id,sheet);
						n.m_pin = thePin->GetNumber();
						n.m_pMethod = theMethod;
						Add(n);
					}

					++ it;
				}

				// Has this symbol had it's power connected?
				if (Connected.find(theMethod->GetRefSheet(m_prefix_references,m_prefix_import,file_index_id,sheet)) == Connected.end()) 
				{
					Connected[ theMethod->GetRefSheet(m_prefix_references,m_prefix_import,file_index_id,sheet) ] = TRUE;

					drawingCollection method;
					((CDrawMethod *)ObjPtr)->ExtractSymbol(tr,method);
					drawingIterator it = method.begin();
					while (it!=method.end()) 
					{
						CDrawingObject *pointer = *it;

						if (pointer->GetType()==xPinEx && thePin->IsPower()) 
						{
							CNetListNode n(file_index_id, sheet, thePin,thePin->GetActivePoint(theMethod) );
							n.m_reference = theMethod->GetRefSheet(m_prefix_references,m_prefix_import,file_index_id,sheet);
							n.m_pin = thePin->GetNumber();
							n.m_pMethod = theMethod;


							// Look up the netlist this power belongs to
							found = Powers.find( thePin->GetPinName() );
							if (found != Powers.end())
								n.m_NetList = (*found).second;
							hold = Add(n);
							if (found == Powers.end())
								Powers[thePin->GetPinName()] = hold;
						}

						++ it;
					}
				}
			}			
			break;
		case xNoConnect:
			Add(CNetListNode(file_index_id, sheet, ObjPtr,ObjPtr->m_point_a));			
			break;
		case xJunction:
			Add(CNetListNode(file_index_id, sheet, ObjPtr,ObjPtr->m_point_a));
			break;			
		case xPower:
			{
			CNetListNode n(file_index_id, sheet, ObjPtr,ObjPtr->m_point_a);
			n.setLabel( ((CDrawPower *)ObjPtr)->GetValue() );

			// Does this power item exist?
			found = Powers.find(((CDrawPower *)ObjPtr)->GetValue());
			if (found != Powers.end())
				n.m_NetList = (*found).second;
			hold = Add(n);
			if (found == Powers.end())
				Powers[((CDrawPower *)ObjPtr)->GetValue()] = hold;
			}
			break;
		case xWire:
			{
				CNetListNode n(file_index_id, sheet, ObjPtr,ObjPtr->m_point_a);
				hold = Add(n);
			}
			{
				CNetListNode n(file_index_id, sheet, ObjPtr,ObjPtr->m_point_b);
				n.m_NetList = hold;
				Add(n);
			}
			break;
	}
  }

 

  // Search for junctions and connect together
  it = pDesign->GetDrawingBegin();
  while (it != pDesign->GetDrawingEnd()) 
  {
	CDrawingObject *ObjPtr = *it;

	// Search for junctions
	if (ObjPtr->GetType() == xJunction) 
	{
		// Find out which netlist was assigned to this point
		CDPoint a = ObjPtr->m_point_a;
		int NetNumber = m_nodes[ a ];

		// Look for wires which cross this junction
		drawingIterator search_it = pDesign->GetDrawingBegin();
		while (search_it != pDesign->GetDrawingEnd()) 
		{
			CDrawingObject *search = *search_it;

			// Find the wires
			// If the wire has an end at this junction then it is already connected
			if (search->GetType()==xWire 
			 && search->m_point_a!=a && search->m_point_b!=a)
			{
				// Is this point on this wire?
				CLineUtils l( search->m_point_a, search->m_point_b );
				double distance_along_a;

				if (l.IsPointOnLine( a, distance_along_a ))
				{
					CNetListNode n(file_index_id, sheet, NULL,search->m_point_a);
					n.m_NetList = NetNumber;
					NetNumber = Add(n);
				}
			}

			++ search_it;
		}
	}
	
	++ it;
  }

  // Search for labels and connect to their respective lines
  stringCollection labels;
  it = pDesign->GetDrawingBegin();
  while (it != pDesign->GetDrawingEnd()) 
  {
	CDrawingObject *ObjPtr = *it;

	// Search for junctions
	if (ObjPtr->GetType() == xLabelEx2) 
	{
		CDPoint a = static_cast<CDrawLabel*>(ObjPtr)->GetLabelPoint();

		// Search for a wire this label is connect to
		// Only atempt to connect to a single wire
		drawingIterator search_it = pDesign->GetDrawingBegin();
		while (search_it != pDesign->GetDrawingEnd()) 
		{
			CDrawingObject *search = *search_it;
			if (search->GetType()==xWire && search->IsInside(a.x,a.x,a.y,a.y)) 
			{
				a = search->m_point_a;
				break;
			}
			
			++ search_it;
		}

		// Look up this label
		CNetListNode n(file_index_id, sheet, ObjPtr,a);
		n.setLabel(  ((CDrawLabel *)ObjPtr)->GetValue() );

		// Has this label already been assigned a netlist?
		stringCollection::iterator found = labels.find(((CDrawLabel *)ObjPtr)->GetValue());
		if (found!=labels.end()) 
		{
			n.m_NetList = (*found).second;
			n.setLabel( _T("") );
		}

		int hold = Add(n);

		// If there was no netlist write it back...
		if (found == labels.end())
			labels[ ((CDrawLabel *)ObjPtr)->GetValue()] = hold;
	}
	
	++ it;
  }  

  // Our work with the nodes map is complete, so we can discard
  // it now...
  m_nodes.erase( m_nodes.begin(), m_nodes.end() );

}
CDPoint CTinyCadDoc::GetStickyPoint( CDPoint q, BOOL pins, BOOL wires, BOOL &is_stuck, BOOL &is_junction )
{
  CDPoint r(0,0);
  bool first = true;
  double min_distance = 0;
  int items = 0;

  int range = GetOption().GetAutoSnapRange();

  if (!GetOption().GetAutoSnap())
  {
  	  is_stuck = FALSE;
	  is_junction = FALSE;
	  return q;
  }


  // Search for methods, and look at their pins
	drawingIterator it = GetDrawingBegin();
	while (it != GetDrawingEnd()) 
	{
		CDrawingObject *ObjPtr = *it;

		switch (ObjPtr->GetType()) 
		{
			case xWire:
				#define theLine ((CDrawLine*)ObjPtr)
				if (wires)
				{
					CDPoint d;
					CLineUtils l( theLine->m_point_a, theLine->m_point_b );
					double distance = l.DistanceFromPoint( q, d );

					if (d == r)
					{
						items ++;
					}

					if (first || distance < min_distance)
					{
						if (r != d)
						{
							// have we split this wire?
							if (d != theLine->m_point_a && d != theLine->m_point_b)
							{
								items = 2;
							}
							else
							{
								items = 1;
							}
						}
						r = d;
						first = false;
						min_distance = distance;
					}
				}
				break;
			default:
				if (pins)
				{
					CDRect s( ObjPtr->m_point_a.x, ObjPtr->m_point_a.y, ObjPtr->m_point_b.x, ObjPtr->m_point_b.y );
					s.NormalizeRect();
					s.left -= range * 2;
					s.right += range * 2;
					s.bottom += range * 2;
					s.top -= range * 2;

					if (s.PtInRect(q))
					{
						CActiveNode a;
						ObjPtr->GetActiveListFirst( a );
						while (ObjPtr->GetActive(a)) 
						{
							// This is a valid pin...
							CDPoint d = a.m_a;
							double dx = d.x - q.x;
							double dy = d.y - q.y;
							double distance = sqrt(dx*dx + dy*dy);

							if (r == d)
							{
								items ++;
							}

							if (first || distance < min_distance)
							{
								if (r != d)
								{
									items = 1;
								}

								r = d;
								first = false;
								min_distance = distance;
							}
						}
					}
				}
				break;
			}

		++ it;
	}



  if (!first && min_distance < GetOption().GetAutoSnapRange())
  {
	  is_stuck = TRUE;
	  is_junction = GetOption().GetAutoJunc() ? items > 1 : FALSE;
	  return r;
  }
  else
  {
	  is_junction = FALSE;
	  is_stuck = FALSE;
  }

  return q;
}
示例#19
0
// Create netlist and output as a PCB file (PADS-PCB)
void CNetList::WriteNetListFilePADS( CTinyCadMultiDoc *pDesign, const TCHAR *filename )
{
  FILE *theFile;
  errno_t err;
  err = _tfopen_s(&theFile, filename,_T("w"));
  if ((theFile == NULL) || (err != 0))
  {
	Message(IDS_CANNOTOPEN);
	return;
  }

  // Set the Busy icon
  SetCursor( AfxGetApp()->LoadStandardCursor( IDC_WAIT ) );

  // Get the net list
  MakeNet( pDesign );

  _ftprintf(theFile,_T("*PADS-PCB*\n"));


  _ftprintf(theFile,_T("*PART*\n"));
  

  // Keep track of the references we have outputted...
  std::set<CString>	referenced;

	// Do this for all of the files in the imports list...
	fileCollection::iterator fi = m_imports.begin();
	for (;fi != m_imports.end(); ++ fi)
	{
		CTinyCadMultiDoc *dsn = pDesign;

		if ((*fi)->m_file_name_index != 0)
		{
			dsn = (*fi)->m_pDesign;
		}

		// Generate a component for every sheet in this design
		for (int i = 0; i < dsn->GetNumberOfSheets(); i++)
		{

			drawingIterator it = dsn->GetSheet(i)->GetDrawingBegin();
			while (it != dsn->GetSheet(i)->GetDrawingEnd()) 
			{
				CDrawingObject *pointer = *it;

				if (pointer->GetType() == xMethodEx3) 
				{
					CDrawMethod *pMethod = static_cast<CDrawMethod *>(pointer);
					CString Ref  = pMethod->GetRefSheet(m_prefix_references,m_prefix_import,(*fi)->m_file_name_index,i+1);

					// Do we need to output this part?
					if (referenced.find( Ref ) == referenced.end())
					{
						referenced.insert( Ref );

						CString Package = _T("This part has no 'Package' attribute");
						for (int i = 2; i < pMethod->GetFieldCount(); i++)
						{
							if (pMethod->GetFieldName(i).CompareNoCase(_T("package")) == 0)
							{
								Package = pMethod->GetField(i);
							}
						}


						// Pad to correct length...
						do
						{
							Ref = Ref + _T(" ");
						}
						while (Ref.GetLength() < 8);
						_ftprintf(theFile,_T("%s%s\n"), Ref, Package);
					}
				}
				
				++ it;
			}
	}
	}

  _ftprintf(theFile,_T("\n*NET*\n"));
  int Label = 0;

  netCollection::iterator nit = m_nets.begin();

	while (nit != m_nets.end()) 
	{
		nodeVector::iterator nv_it = (*nit).second.begin();

		CString theLine,theLabel;

		if (nv_it != (*nit).second.end()) 
		{
			theLine = _T("");
			BOOL first = TRUE, Labeled = FALSE;
			int len = 0;
			int count = 0;

			while (nv_it != (*nit).second.end()) 
			{
				CNetListNode& theNode = *nv_it;
				++ nv_it;

				if (theNode.getLabel() != _T("") && !Labeled) 
				{
					theLabel = theNode.getLabel();
					Labeled = TRUE;
				}
				else
				{
					CString add;
					if (!theNode.getLabel().IsEmpty())
					{
					// NOT FOR PADS:	add = theNode.getLabel();
					}
					else if (!theNode.m_reference.IsEmpty())
					{
						add.Format(_T("%s.%s"), theNode.m_reference, theNode.m_pin );
					}

					if (!add.IsEmpty())
					{
						len += add.GetLength();
						if (len > 127)
						{
							theLine += _T("\n");
							len = add.GetLength();
							first = TRUE;
						}

						if (first)
						{
							first = FALSE;
						}
						else
						{
							theLine += " ";
							len ++;
						}


						theLine += add;
						++ count;
						
					}
				}
			}

			if (count > 1) 
			{
				_ftprintf(theFile,_T("*SIGNAL*  "));
				if (Labeled)
					_ftprintf(theFile,_T("%s"), theLabel);
				else
					_ftprintf(theFile,_T("N%06d"),Label++);
				_ftprintf(theFile,_T("\n%s\n"), theLine);
			}
		}

		++ nit;
	}

	_ftprintf(theFile,_T("*END*\n"));


  SetCursor( AfxGetApp()->LoadStandardCursor( IDC_ARROW ) );
  fclose(theFile);
}
示例#20
0
void CTinyCadView::OnSpecialCheck()
{
	// Get rid of any drawing tool
	GetCurrentDocument()->SelectObject(new CDrawEditItem(GetCurrentDocument()));

	CDlgERCBox theDialog;

	static union { ErrorTest e; WORD i; } theErrorTest;

	theErrorTest.i = CTinyCadRegistry::GetInt("ERC", 0xffff);


	// Get the user's options
	theDialog.SetErrorTest(theErrorTest.e);
	if (theDialog.DoModal() != IDOK)
	{
		return;
	}

	theErrorTest.e = theDialog.GetErrorTest();  
	CTinyCadRegistry::Set("ERC",theErrorTest.i);

	// Set the Busy icon
	SetCursor( AfxGetApp()->LoadStandardCursor( IDC_WAIT ) );

	// Generate the netlist
	CNetList netlist;
	netlist.m_follow_imports = false;
	CTinyCadMultiDoc *pDoc = static_cast<CTinyCadMultiDoc*>(GetDocument());
	netlist.MakeNet( pDoc );
	netCollection *nets = &netlist.m_nets;

	// Delete all the errors which are currently in the design
	theERCListBox.Close();
	// GetCurrentDocument()->DeleteErrors();
	theERCListBox.Open( pDoc );
	int CurrentError = 0;

	// Scan the design for duplicated references
	if ((theErrorTest.e).DupRef)
	{
		std::set<CString>	refs;

		CString last = "";

		for (int i = 0; i < pDoc->GetNumberOfSheets(); i++)
		{
			drawingIterator it = pDoc->GetSheet(i)->GetDrawingBegin();
			while (it != pDoc->GetSheet(i)->GetDrawingEnd()) 
			{
				CDrawingObject *pointer = *it;

				if (pointer->GetType()==xMethodEx3) 
				{
					CString ref = static_cast<CDrawMethod *>(pointer)->GetField(CDrawMethod::Ref);

					if (refs.find( ref ) != refs.end())
					{
						// We have a duplicate...
						CString buffer;
						buffer.LoadString( ERR_DUPREF );
						pDoc->GetSheet(i)->Add(new CDrawError(pDoc->GetSheet(i),static_cast<CDrawMethod *>(pointer)->GetFieldPos(CDrawMethod::Ref),CurrentError++));
						theERCListBox.AddString(buffer);
					}
					else
					{
						refs.insert( ref );
					}
				}

				++ it;
			}
		}
	}


	// Scan netlist to determine the type of each net
	netCollection::iterator nit = nets->begin();

	while (nit != nets->end()) 
	{
		nodeVector::iterator nv_it = (*nit).second.begin();

		int theNetType = nUnknown;
		CString lastPower = "";
		int connections = 0;

		CDPoint pos;
		int sheet = 0;

		while (theNetType < ERR_BASE && nv_it != (*nit).second.end()) 
		{
			CNetListNode& theNode = *nv_it;

			CDrawingObject* pObject = theNode.m_parent;
			
			if (pObject != NULL) 
			{
				// Determine the type of this node
				int node_type = nUnknown;
				switch (pObject->GetType()) 
				{
				case xPower:
					node_type = nPower;
					if (lastPower=="")
					{
						lastPower = static_cast<CDrawPower *>(pObject)->GetValue();
					}
					else 
					{
						if ( lastPower != static_cast<CDrawPower *>(pObject)->GetValue() ) 
						{
							theNetType = ERR_POWER;
							node_type = nUnknown;
							break;
						}
					}
					connections ++;
					pos = pObject->m_point_a;
					sheet = theNode.m_sheet;
					break;
				case xNoConnect:
					node_type = 1;
					connections ++;
					pos = pObject->m_point_a;
					sheet = theNode.m_sheet;
					break;
				case xPin:
				case xPinEx:
					{
						CDrawPin *pPin = static_cast<CDrawPin*>( pObject );
						switch(pPin->GetElec()) 
						{
						case 0:		// Input
							node_type = nInput; 
							break;
						case 1:		// Output
							node_type = nOutput; 
							break;
						case 2:		// Tristate
							node_type = nBiDir; 
							break;
						case 3:		// Open Collector
							node_type = nBiDir; 
							break;
						case 4:		// Passive
							node_type = nPassive; 
							break;
						case 5:		// Input/Output
							node_type = nBiDir; 
							break;
						case 6:		// Not Connected
							node_type = nNoConnect;
							break;
						}
						
						if (pPin->IsPower()) 
						{
							node_type = nPower;
						}

						pos = pPin->GetActivePoint(theNode.m_pMethod);
						sheet = theNode.m_sheet;
						connections ++;
					}
					break;
				}
				
				theNetType = (node_type!=nUnknown) ? ErcTable[theNetType][node_type] : theNetType;
			}

			++ nv_it;
		}

		int ErrorNumber = 0;

		if (connections == 1)
		{
			theNetType = ERR_UNCONNECT;
		}
	

		switch (theNetType) 
		{
			case nUnknown:
				if (connections > 0)
				{
					ErrorNumber = ERR_UNCONNECTED;
				}
				break;
			case nInput:
				ErrorNumber = ERR_NOUTPUT;
				break;
			case nNoConnect:
				if (connections > 2)
				{
					theNetType = ERR_UNCONNECT;
				}
				break;
			default:
				ErrorNumber = theNetType;
				break;
		}

		// Is this error to be reported?
		switch (ErrorNumber) 
		{
		case ERR_UNCONNECT:
			if (!((theErrorTest.e).UnConnect))
				ErrorNumber = -1;
			break;
		case ERR_POWER:
			if (!((theErrorTest.e).Power))
				ErrorNumber = -1;
			break;
		case ERR_NOCONNECT:
			if (!((theErrorTest.e).NoConnect))
				ErrorNumber = -1;
			break;
		case ERR_NOUTPUT:
			if (!((theErrorTest.e).NoOutput))
				ErrorNumber = -1;
			break;
		case ERR_DUPREF:
			if (!((theErrorTest.e).DupRef))
				ErrorNumber = -1;
			break;
		case ERR_OUTPUT:
			if (!((theErrorTest.e).Output))
				ErrorNumber = -1;
			break;
		case ERR_OUTPUTTOPWR:
			if (!((theErrorTest.e).OutputPwr))
				ErrorNumber = -1;
			break;
		case ERR_UNCONNECTED:
			if (!((theErrorTest.e).UnConnected))
				ErrorNumber = -1;
			break;
		case ERR_OUTPUTBIDIR:
			if (!((theErrorTest.e).Output))
				ErrorNumber = -1;
			break;
		case ERR_POWERBIDIR:
			if (!((theErrorTest.e).OutputPwr))
				ErrorNumber = -1;
			break;
		}

		if (ErrorNumber >= ERR_BASE) 
		{
			CString buffer;
			buffer.LoadString( ErrorNumber );
			pDoc->GetSheet(sheet-1)->Add(new CDrawError(pDoc->GetSheet(sheet-1),pos,CurrentError++));
			theERCListBox.AddString(buffer);
		}

		++ nit;
	}


	// Were any errors detected?
	if (CurrentError == 0) 
	{
		CString buffer;
		buffer.LoadString( ERR_NOERROR );
		theERCListBox.AddString(buffer);
	}

	// Set the normal icon
	SetCursor( AfxGetApp()->LoadStandardCursor( IDC_ARROW ) );

	// Re-Draw the window
	Invalidate();

}