/***************************************************************************
 *   Copyright (C) 2004 by Juergen Thies                                   *
 *   layout@juergenthies.de                                                *
 *                                                                         *
 *   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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#define _USE_MATH_DEFINES
#include <math.h>
#include "drawingfield.h"
#include "elements/path.h"
#include <qcolor.h>
#include <qimage.h>
#include <QPixmap>
#include <QBitmap>
#include <QWheelEvent>
#include <QEvent>
#include <QResizeEvent>
#include <QMouseEvent>
#include <QImageIOPlugin>
#include <QImageWriter>
#include "elements/cell.h"
#include <qpainter.h>
#include <qcursor.h>
#include "layers.h"
#include <math.h>
#include <qfile.h>
#include <qdatetime.h>
#include "elements/cellref.h"
#include "elements/cellrefarray.h"
#include <qmessagebox.h>
#include <qinputdialog.h>
#include "fileformats/gds.h"
#include "layout.h"
#include "fileformats/filedialog.h"
#include "fileformats/dxf.h"
#include "fileformats/gerber.h"
#include "fileformats/cif.h"
#include "fileformats/ap.h"
#include "fileformats/tld.h"
#include "fileformats/svg.h"
#include "fileformats/electromask.h"
#include "fileformats/csv.h"
#include "fileformats/oasis.h"
#include "fileformats/pixel.h"
#include "widgets/mousewidget.h"
#include <QThread>
#include "paintpixmapthread.h"
#include <QtGlobal>
#include <QByteArray>
#include <QBuffer>
#include "dialog/helpwindow.h"
#include <QWhatsThis>
#include "basemode.h"
#include "dialog/pointentry.h"
#include "layout.h"
#include "general/setup.h"
#ifdef OPENACCESS
#include "oa/oalayout.h"
#endif
#ifdef backgroundutility
#include "background/backgroundmodule.h"
#endif
#include "ui_rotatedialog.h"
#include "general/userunitsvalidator.h"

drawingField::drawingField(QWidget *parent, const char *) : QWidget(parent){  //name   , name,Qt::WNoAutoErase
#ifdef LIBCHECK
#include "../liblayout/libcheck.cpp"
if (libCheckResult) return;
#endif
  setup::init();
  setAttribute(Qt::WA_OpaquePaintEvent);
  setAttribute(Qt::WA_NoSystemBackground);
  firstCell=new cellList();
  autorepaint=false;
  currentCell=firstCell->thisCell;
  pixmap= new paintPixmapThread(this);
  paintNode=-1;
#ifdef backgroundutility
  bgModule=NULL;
#endif
  //paintPixmap = new paintPixmapThread(this);
  connect(pixmap,SIGNAL(updateRequest()),this,SLOT(update()),Qt::QueuedConnection);
  resize(500,500);
  setMouseTracking(true);
  setCursor(QCursor(Qt::BlankCursor));
  // default setup on new layout
  userunits=0.001;
  databaseunits=0.000000001;
  libname="noname";
  // init drawingparameter
  activeLayer=1;
  gridauto=true;
  gridX=5000;
  gridY=5000;
  gridOffsetX=0;
  gridOffsetY=0;
  defaultMode=0;
  mode=0; //default mode
  modestep=0;
  mouseVisible=false;
  reset();
  pointarray.resize(1);
  pointarray.resize(10);
  modifyStatus=false;
  paintDetailLevel=1;
  for (int i=0;i<20;i++){
  	undo_[i]=NULL;
  	redo_[i]=NULL;
	}
  resetUndo();
  setFocusPolicy(Qt::StrongFocus);
  snapGrid=true;
  snapPoint=false;;
  snapLine=false;
  snapMiddle=false;
  snapCenter=false;
  snapIntersection=false;
  elementUsedLocked=false;
  //macrorecording
  record=false;
  macro="";
  autorepaint=true;
  mutexInit();
  installEventFilter(this);
  setAcceptDrops(true);
  dragTimer.setSingleShot (true);
  dragTimer.setInterval (QApplication::startDragTime ());
  dragDropRunning=false;
  connect(&dragTimer,SIGNAL(timeout()),this,SLOT(startDrag()));
  setWhatsThis("istmirdochegal");
  connect(this,SIGNAL(requestBlankCursor()),this,SLOT(setBlankCursor()),Qt::QueuedConnection);
  connect(this,SIGNAL(requestWaitCursor()),this,SLOT(setWaitCursor()),Qt::QueuedConnection);
}


drawingField::~drawingField(){
//QTime t;
//t.start();
//printf("end df 1\n");
  pixmap->endPaint();
//printf("end df 2\n");
  resetUndo();
//printf("end df 3\n");
  deleteAllCell();
//printf("end df 4\n");
  //paintPixmap->endPaint();
  //delete paintPixmap;
  delete pixmap;
//printf("end df 5\n");
}

void drawingField::paintEvent ( QPaintEvent * ){
//printf("start paintEvent\n");
  //printf("pe\n");
  //QBitmap bm=pixmap->getPixmap().createMaskFromColor(setup::backgroundColor);

  QPen pen(setup::mouseColor);
  QPainter paint(this); 
  paint.setPen(pen);
  QFont font;
  font.setPixelSize(setup::fontSize);
  paint.setFont(font);
#ifdef backgroundutility
  if (bgModule!=NULL) if (bgModule->backgroundPaint(&paint)) {  
	paint.end();
	setUpdatesEnabled(true);
	return;}
#endif

  if (mode!=591) paint.drawPixmap(-1,-1,pixmap->getPixmap());
#ifdef backgroundutility
  if (bgModule!=NULL) if (bgModule->backgroundPaint2(&paint)) {  
	paint.end();
	setUpdatesEnabled(true);
	return;}
#endif
  /*
  if (background.size()>0)
    paint.setCompositionMode(QPainter::CompositionMode_SourceOver);
  */
  pixmap->scaleMutex.lock();
  // allways paint
  	switch (mode) {
        case 1: //Command
		paint.setMatrix(QMatrix(1,0,0,1,0,0));
		for (int i=1;i<=modestep;i++){
			QPoint p=pixmap->trans.mapDraw(pointarray.point(i-1));
			paint.drawLine(p-QPoint(2,2),p+QPoint(2,2));
			paint.drawLine(p-QPoint(2,-2),p+QPoint(2,-2));
			}
		break;
		/*case 160: //netlist route
		{
			for (int i=0;i<placeConnections.size();i++)
				if (placeConnections[i].size()>1){
					paint.setMatrix(pixmap->trans.matrix);
					//printf("%d\n",placeConnections[i].size());
					paint.drawPolyline(placeConnections[i]);
				}
				else 
				{
					paint.setMatrix(QMatrix(1,0,0,1,0,0));
					QPoint p=pixmap->trans.mapDraw(placeConnections[i].point(0));
					paint.drawLine(p-QPoint(2,2),p+QPoint(2,2));
					paint.drawLine(p-QPoint(2,-2),p+QPoint(2,-2));
				}
		
		}
		break;*/
	default: 
		if (mode>600) modeHandler->paintAlways(&paint);
	}
  if (mouseVisible){
  	paint.setMatrix(pixmap->trans.matrix);
 	switch (mode) {
	case 0: //default
		if (modestep>=2) {
			paint.setPen(setup::gridColor);
			paint.drawRect(makeRectPaintEvent(pointarray.point(0),pointarray.point(1)));
			paint.setPen(setup::mouseColor);
			}
		if (modestep>=3){
			
			paint.drawLine(pointarray.point(2),pointarray.point(3));
			if (pointarray.point(2)==pointarray.point(18)){
				QPoint dif=pointarray.point(3)-pointarray.point(2);
				paint.drawRect(makeRectPaintEvent(pointarray.point(0)+dif,pointarray.point(1)+dif));
				}
			else if (pointarray.point(2)==pointarray.point(10))
			   paint.drawRect(makeRectPaintEvent(pointarray.point(3),pointarray.point(12)));
			else if (pointarray.point(2)==pointarray.point(11))
			   paint.drawRect(makeRectPaintEvent(pointarray.point(3),pointarray.point(13)));
			else if (pointarray.point(2)==pointarray.point(12))
			   paint.drawRect(makeRectPaintEvent(pointarray.point(3),pointarray.point(10)));
			else if (pointarray.point(2)==pointarray.point(13))
			   paint.drawRect(makeRectPaintEvent(pointarray.point(3),pointarray.point(11)));
			else if (pointarray.point(2)==pointarray.point(14))
			   paint.drawRect(makeRectPaintEvent(QPoint (pointarray.point(3).x(),pointarray.point(0).y()),pointarray.point(1)));
			else if (pointarray.point(2)==pointarray.point(15))
			   paint.drawRect(makeRectPaintEvent(QPoint (pointarray.point(1).x(),pointarray.point(3).y()),pointarray.point(0)));
			else if (pointarray.point(2)==pointarray.point(16))
			   paint.drawRect(makeRectPaintEvent(QPoint (pointarray.point(3).x(),pointarray.point(1).y()),pointarray.point(0)));
			else if (pointarray.point(2)==pointarray.point(17))
			   paint.drawRect(makeRectPaintEvent(QPoint (pointarray.point(0).x(),pointarray.point(3).y()),pointarray.point(1)));
		}
		break;
	case 100: //Box
	  	if ((mouseModifiers==(Qt::ShiftModifier+Qt::ControlModifier))|| (mouseModifiers==Qt::ControlModifier)){
		   if (modestep==1)
			  paint.drawRect(makeDotPaintEvent(mouseDrawingPos,pointarray.point(0)));
		}
		else {
		  if (modestep==1) {
			  paint.drawRect(makeRectPaintEvent(mouseDrawingPos,pointarray.point(0)));
		  }
		}
		break;
	case 110: //Polygon
		if(modestep>=1) paint.drawPolyline(pointarray);
		break;
	case 120: //cellref
		//paint.drawRect(makeRectPaintEvent(minPoint+mouseDrawingPos,maxPoint+mouseDrawingPos));
		break;
	/*case 121: //placeCell
		{
			for (int i=0;i<placeConnections.size();i++)
			   if (placeConnections[i].size()>1){
				double dis =1E99;
				int num=0;
				QPoint p=mouseDrawingPos+cellrefTrans.mapOut(placeConnections[i].point(0));
				for (int k=1;k<placeConnections[i].size();k++)
			{
				double d=element::distance(p,placeConnections[i].point(k));
				if (d<dis) {
					num=k;
					dis=d;
				}
			}
			paint.drawLine(p,placeConnections[i].point(num));
			}
		
		}
		break;*/
	case 130: //Cellrefarray
		/*if (modestep==0) { paint.drawRect(makeRectPaintEvent(minPoint+mouseDrawingPos,maxPoint+mouseDrawingPos));}
		if (modestep==1){	
			paint.drawRect(makeRectPaintEvent(minPoint+pointarray.point(0),maxPoint+pointarray.point(0)));
			paint.drawRect(makeRectPaintEvent(minPoint+mouseDrawingPos,maxPoint+mouseDrawingPos));
			}*/
		break;
	case 150: //path
		if(modestep>=1)paint.drawPolyline(pointarray);
		break;
	/*case 160: //netlist route
		{
			if ((mouseButton==Qt::LeftButton)&&(mouseDrawingPos!=routePressedPoint)){
				paint.drawRect(makeRectPaintEvent(mouseDrawingPos,routePressedPoint));
			}
			if(modestep>=1){
							class path p(pointarray,0);
							p.width=layers::num[activeLayer].getTypeParameter(1);
							pointArray pa2=p.toPolygon();
							paint.drawPolyline(pa2);
			}
		
		}
		break;*/
  	case 180: //ruler
		if (modestep>0){
			paint.drawLine(mouseDrawingPos,pointarray.point(0));
			double dx=mouseDrawingPos.x()-pointarray.point(0).x();
			double dy=mouseDrawingPos.y()-pointarray.point(0).y();
			double dist=sqrt(dx*dx+dy*dy);
			QString s;
			s=s.setNum(dist*userunits,'g',6);
			paint.setMatrix(QMatrix(1,0,0,1,0,0));
  			QPoint map=pixmap->trans.mapDraw(mouseDrawingPos);
			paint.drawText(map+QPoint(10,10),s);
			}
		break;
	case 181: //length measurement
		if (modestep==1){
			paint.setMatrix(QMatrix(1,0,0,1,0,0));
			QPoint p=pixmap->trans.mapDraw(pointarray.point(0));
			paint.drawLine(p-QPoint(2,2),p+QPoint(2,2));
			paint.drawLine(p-QPoint(2,-2),p+QPoint(2,-2));
			}
		else if(modestep>1){
			paint.drawPolyline(pointarray);
			QPoint p=pointarray.point(0);
			double l=0;
			for(int i=1;i<pointarray.size();i++){
				l+= element::length(p-pointarray.point(i));
				p=pointarray.point(i);
				}
			QString s;
			s=s.setNum(l*userunits,'g',6);
			paint.setMatrix(QMatrix(1,0,0,1,0,0));
  			QPoint map=pixmap->trans.mapDraw(mouseDrawingPos);
			paint.drawText(map+QPoint(10,10),s);
			}
		break;
  	case 185: //angle
		{
		int r=int(element::distance(mouseDrawingPos,pointarray.point(0))/2);
		if (modestep==1){
			paint.drawLine(mouseDrawingPos,pointarray.point(0));
			double angle=element::angle(QPoint(-100,0)+pointarray.point(0),pointarray.point(0),mouseDrawingPos);
			paint.drawArc ( pointarray.point(0).x()-r, pointarray.point(0).y()-r, 2*r, 2*r, 0, int(-angle*16) );
			QString s;
			s=s.setNum(angle,'f',2);
			paint.setMatrix(QMatrix(1,0,0,1,0,0));
  			QPoint map=pixmap->trans.mapDraw(mouseDrawingPos);
			paint.drawText(map+QPoint(10,10),s);
			}
		if (modestep==2){
			paint.drawLine(mouseDrawingPos,pointarray.point(0));
			paint.drawLine(pointarray.point(1),pointarray.point(0));
			double angle=element::angle(pointarray.point(0)+2*(pointarray.point(0)-pointarray.point(1)), pointarray.point(0),mouseDrawingPos);
			double anglestart=element::angle(QPoint(-100,0)+pointarray.point(0),pointarray.point(0),mouseDrawingPos);
			paint.drawArc ( pointarray.point(0).x()-r, pointarray.point(0).y()-r, 2*r, 2*r, int(-anglestart*16), int(angle*16) );
			QString s;
			s=s.setNum(angle,'f',2);
			paint.setMatrix(QMatrix(1,0,0,1,0,0));
  			QPoint map=pixmap->trans.mapDraw(mouseDrawingPos);
			paint.drawText(map+QPoint(10,10),s);
			}
		}
		break;
	case 189: //circle box (ellipse)
		if (modestep>0) {
			QPoint pc=(pointarray.point(0)+mouseDrawingPos)/2;
			QPoint pr=pointarray.point(0)-mouseDrawingPos;
			int r=abs(pr.x());
			if (abs(pr.y())<r) r=abs(pr.y());
			QPoint pr2=pc+QPoint(r/2,0);
			QPolygon a;
			if (mouseModifiers==Qt::ControlModifier+Qt::ShiftModifier) a=element::ellipse(pc,pr.x()/2,pr.y()/2,setup::circularDefault);
			else a=element::spirale(pc,pr2,pr2,setup::circularDefault);
			paint.drawPolyline(a);
			QPen pen(setup::mouseColor);
			pen.setStyle(Qt::DotLine);
			paint.setPen(pen);
			paint.drawRect(makeRectPaintEvent(mouseDrawingPos,pointarray.point(0)));
			pen.setStyle(Qt::SolidLine);
			paint.setPen(pen);
			}
		break;
  	case 190: //spiral
		if (modestep>1) {
			QPolygon a=element::spirale(pointarray.point(0),pointarray.point(1),mouseDrawingPos,5);
			paint.drawPolyline(a);
			}
		break;
  	case 191: //circle
		if (modestep>0) {
			QPolygon a=element::spirale(pointarray.point(0),mouseDrawingPos,mouseDrawingPos,5);
			paint.drawPolyline(a);
			}
		break;
  	case 192: //sector
		if (modestep>1) {
			pointarray.setPoint(2,(mouseDrawingPos-pointarray.point(0))*(element::distance(pointarray.point(0),pointarray.point(1))/element::distance(pointarray.point(0),mouseDrawingPos))+pointarray.point(0));
			QPoint p=pointarray.point(0);
			QPolygon a=element::spirale(pointarray.point(0),pointarray.point(1),pointarray.point(2),setup::circularDefault);
			int i=a.size();
			a.resize(i+2);
			a.setPoint(i,p);
			a.setPoint(i+1,a.point(0));
			paint.drawPolyline(a);
			}
			break;
  	case 193: //arc
		if (modestep>1) {
			pointarray.setPoint(2,(mouseDrawingPos-pointarray.point(0))*(element::distance(pointarray.point(0),pointarray.point(1))/element::distance(pointarray.point(0),mouseDrawingPos))+pointarray.point(0));
			QPolygon a=element::spirale(pointarray.point(0),pointarray.point(1),pointarray.point(2),setup::circularDefault);
			paint.drawPolyline(a);
			}
		break;
  	case 194: //polygon arc
		if (modestep>1) {
			pointarray.setPoint(2,(mouseDrawingPos-pointarray.point(0))*(element::distance(pointarray.point(0),pointarray.point(1))/element::distance(pointarray.point(0),mouseDrawingPos))+pointarray.point(0));
			QPolygon a=element::spirale(pointarray.point(0),pointarray.point(1),pointarray.point(2),setup::circularDefault);
			paint.drawPolyline(a);
			QPolygon b=pointarray;
			b.setPoint(2,mouseDrawingPos);
			b.setPoint(1,(pointarray.point(1)-pointarray.point(0))*(element::distance(pointarray.point(0),mouseDrawingPos)/element::distance(pointarray.point(0),pointarray.point(1)))+pointarray.point(0));
			b=element::spirale(pointarray.point(0),b.point(1),b.point(2),setup::circularDefault);
			paint.drawPolyline(b);
			paint.drawLine(a.point(0),b.point(0));
			paint.drawLine(a.point(a.size()-1),b.point(b.size()-1));
			}
		break;
  	case 195: //bezier2
  		if (modestep==1)
			paint.drawLine(mouseDrawingPos,pointarray.point(0));	
		else if (modestep>1) {
			QPolygon a=element::bezier2(pointarray.point(0),pointarray.point(1),mouseDrawingPos);
			paint.drawPolyline(a);
		}
  		break;
  	case 196: //bezier3
  		if (modestep==1)
			paint.drawLine(mouseDrawingPos,pointarray.point(0));
		else if (modestep==2) {
			QPolygon a=element::bezier3(pointarray.point(0),pointarray.point(1),mouseDrawingPos,mouseDrawingPos);
			paint.drawPolyline(a);
			}
		else if (modestep==3) {
			QPolygon a=element::bezier3(pointarray.point(0),pointarray.point(1),pointarray.point(2),mouseDrawingPos);
			paint.drawPolyline(a);
			}
  		break;
  	case 200: //zoom
  	
  		break;
  	case 300: //mirror
		if(modestep>=1)
			paint.drawLine(mouseDrawingPos,pointarray.point(0));
		break;
  	case 308: //move x
		if(modestep>=1) {
			paint.drawLine(QPoint(mouseDrawingPos.x(),pointarray.point(0).y()),pointarray.point(0));
			QPen pen(setup::mouseColor);
			pen.setStyle(Qt::DotLine);
			paint.setPen(pen);
			paint.drawLine(QPoint(mouseDrawingPos.x(),pointarray.point(0).y()),mouseDrawingPos);
			pen.setStyle(Qt::SolidLine);
			paint.setPen(pen);}
		break;
  	case 309: //move y
		if(modestep>=1) {
			paint.drawLine(QPoint(pointarray.point(0).x(),mouseDrawingPos.y()),pointarray.point(0));
			QPen pen(setup::mouseColor);
			pen.setStyle(Qt::DotLine);
			paint.setPen(pen);
			paint.drawLine(QPoint(pointarray.point(0).x(),mouseDrawingPos.y()),mouseDrawingPos);
			pen.setStyle(Qt::SolidLine);
			paint.setPen(pen);
			}
		break;
  	case 310: //move
		if(modestep>=1)
			paint.drawLine(mouseDrawingPos,pointarray.point(0));
		break;
 	case 312: //move single point
		if(modestep>=1)
			paint.drawLine(mouseDrawingPos,pointarray.point(0));
		break;
 	case 313: //insert point
		if(modestep>=1) {
			paint.drawLine(mouseDrawingPos,pointarray.point(0));
			if (pointarray.size()>1)paint.drawLine(mouseDrawingPos,pointarray.point(1));}
		break;
  	case 315: //set cell origin
		break;
  	case 320: //rotate
		if (modestep>0){
		int r=int(element::distance(mouseDrawingPos,pointarray.point(0))/2);
		if (modestep==1){
			paint.drawLine(mouseDrawingPos,pointarray.point(0));
			double angle=element::angle(QPoint(-100,0)+pointarray.point(0),pointarray.point(0),mouseDrawingPos);
			paint.drawArc ( pointarray.point(0).x()-r, pointarray.point(0).y()-r, 2*r, 2*r, 0, int(-angle*16) );
			QString s;
			s=s.setNum(angle,'f',2);
			paint.setMatrix(QMatrix(1,0,0,1,0,0));
  			QPoint map=pixmap->trans.mapDraw(mouseDrawingPos);
			paint.drawText(map+QPoint(10,10),s);
			}
		if (modestep==2){
			paint.drawLine(mouseDrawingPos,pointarray.point(0));
			paint.drawLine(pointarray.point(1),pointarray.point(0));
			double angle=element::angle(pointarray.point(0)+2*(pointarray.point(0)-pointarray.point(1)), pointarray.point(0),mouseDrawingPos);
			double anglestart=element::angle(QPoint(-100,0)+pointarray.point(0),pointarray.point(0),mouseDrawingPos);
			paint.drawArc ( pointarray.point(0).x()-r, pointarray.point(0).y()-r, 2*r, 2*r, int(-anglestart*16), int(angle*16) );
			QString s;
			s=s.setNum(angle,'f',2);
			paint.setMatrix(QMatrix(1,0,0,1,0,0));
  			QPoint map=pixmap->trans.mapDraw(mouseDrawingPos);
			paint.drawText(map+QPoint(10,10),s);
			}
		}
		break;
  	case 330: //copy
		if(modestep>=1)
			paint.drawLine(mouseDrawingPos,pointarray.point(0));
		break;
  	case 340: //cut
		if(modestep>=1)
			paint.drawLine(mouseDrawingPos,pointarray.point(0));
		break;
  	case 350: //scale
		if (modestep>1)
			paint.drawLine(mouseDrawingPos,pointarray.point(1));
  		break;
	default	:
		if (mode>600) modeHandler->paintImage(&paint);
  	}
  	if (mouseButton&Qt::LeftButton)
  	{
	switch (mode) {
	case 0: //default
		if (modestep<2)paint.drawRect(makeRectPaintEvent(mouseDrawingPos,pointarray.point(0)));
		break;
	case 10: //fselect
	case 15: //fdeselect
	case 20: //pselect	
	case 25: //pdeselect	
	case 30: //cselect	
	case 35: //cdeselect	
	case 200: //zoom
		paint.drawRect(makeRectPaintEvent(mouseDrawingPos,pointarray.point(0)));
		break;
	}
	}
  	paint.setMatrix(QMatrix(1,0,0,1,0,0));
  	switch (mode) {
	case 0: //default
		if (modestep<2){
			if (!(mouseButton&Qt::LeftButton))
			if (!elementUsedLocked) {
			if (mutexReadTryLock()){
				if (elementUsed!=NULL)
					if (elementUsed->thisElement!=NULL){
						elementUsed->thisElement->paintHighlighted(&paint,pixmap->trans);
						elementUsed->thisElement->paintHighlightedBackground(&paint,pixmap->trans);
					}
			mutexReadUnlock();
			}
			}
		}
		else {
		if (modestep==2){
			paint.setMatrix(QMatrix(1,0,0,1,0,0));
			paint.setPen(setup::gridColor);
			paint.setBrush(setup::gridColor);
			for (int i=10;i<19;i++){
				paint.drawEllipse(pixmap->trans.mapDraw(pointarray.point(i)),3,3);
			}
			paint.setPen(setup::mouseColor);
			QPoint p=pixmap->trans.mapDraw(pointarray.point(2));
			paint.drawLine(p-QPoint(3,3),p+QPoint(3,3));
			paint.drawLine(p-QPoint(3,-3),p+QPoint(3,-3));

		}
		}
		paint.setPen(pen);
		break;
	case 10: //fselect
	case 15: //fdeselect
		if (!(mouseButton&Qt::LeftButton))
			{
			if (mutexReadTryLock()){
			  if (elementUsed!=NULL)
			    if (elementUsed->thisElement!=NULL){
				elementUsed->thisElement->paintHighlighted(&paint,pixmap->trans);
				elementUsed->thisElement->paintHighlightedBackground(&paint,pixmap->trans);
				}
			  mutexReadUnlock();
			  }
			}
		paint.setPen(pen);
		break; 
	case 20: //pselect
	case 25: //pdeselect
		if (!(mouseButton&Qt::LeftButton))
			{
			if (mutexReadTryLock()){
			  if (elementUsed!=NULL)
			    if (elementUsed->thisElement!=NULL){
				elementUsed->thisElement->paintHighlighted(&paint,pixmap->trans,pointarray.point(0));
				elementUsed->thisElement->paintHighlightedBackground(&paint,pixmap->trans);
				}
			   mutexReadUnlock();
			   }
			}
		paint.setPen(pen);
		break;
	case 120: //cellref
		if (cell_ref!=NULL) if (mutexReadTryLock()){
			cellrefPaint=cellref::cellref(cell_ref,mouseDrawingPos);
			cellrefPaint.map(cellrefTrans);
			cellrefPaint.setPos(mouseDrawingPos);
			cellrefPaint.paintHighlighted(&paint,pixmap->trans);
			cellrefPaint.paintHighlightedBackground(&paint,pixmap->trans);
			mutexReadUnlock();
		}
		paint.setPen(pen);
		break;
/*	case 121: //placeCell
		if (cell_ref!=NULL) if (mutexReadTryLock()){
		cellrefPaint=cellref::cellref(cell_ref,mouseDrawingPos);
		cellrefPaint.map(cellrefTrans);
		cellrefPaint.setPos(mouseDrawingPos);
		cellrefPaint.paintHighlighted(&paint,pixmap->trans);
		mutexReadUnlock();
		}
		paint.setPen(pen);
		break;*/
	case 130: //cellrefarray
		if (cell_ref!=NULL) if (mutexReadTryLock()){
			cellrefPaint=cellref::cellref(cell_ref,mouseDrawingPos);
			cellrefPaint.map(cellrefTrans);
			cellrefPaint.setPos(mouseDrawingPos);
			if (modestep==0) cellrefPaint.paintHighlighted(&paint,pixmap->trans);
			else if (modestep==1){
				cellrefPaint.paintHighlighted(&paint,pixmap->trans);
				cellrefPaint.setPos(pointarray.point(0));
				cellrefPaint.paintHighlighted(&paint,pixmap->trans);
				//cellrefPaint.paintHighlightedBackground(&paint,pixmap->trans);
				int nx=pointarray.point(2).x()-1;
				int ny=pointarray.point(2).y()-1;
				if (ny*nx>30){
				  if (ny>8) ny=8;
				  if (nx>8) nx=8;
				  if (ny*nx>30) {ny=3;nx=3;}
				}
				QPoint space= pointarray.point(0)-mouseDrawingPos;
				for (int x=0;x<=nx;x++)
				  for (int y=0;y<=ny;y++){
				    cellrefPaint.setPos(-QPoint(x*space.x(),y*space.y())+pointarray.point(0));
				    cellrefPaint.paintHighlightedBackground(&paint,pixmap->trans);
				  }

			}
			mutexReadUnlock();
		}
		paint.setPen(pen);

		/*if (modestep==0) { paint.drawRect(makeRectPaintEvent(minPoint+mouseDrawingPos,maxPoint+mouseDrawingPos));}
		if (modestep==1){	
			paint.drawRect(makeRectPaintEvent(minPoint+pointarray.point(0),maxPoint+pointarray.point(0)));
			paint.drawRect(makeRectPaintEvent(minPoint+mouseDrawingPos,maxPoint+mouseDrawingPos));
			}*/
		break;
	case 170: //nodemode
			{
			if (mutexReadTryLock()){
			  if (elementUsed!=NULL)
			    if (elementUsed->thisElement!=NULL){
				elementUsed->thisElement->paintHighlighted(&paint,pixmap->trans);
				elementUsed->thisElement->paintHighlightedBackground(&paint,pixmap->trans);
				}
			  mutexReadUnlock();
			  }
			}
		paint.setPen(pen);
		break; 
	case 30: //cselect
	case 35: //cdeselect
	//case 122: //netlist link
	case 600: //select cell to view
		if (!(mouseButton&Qt::LeftButton))
			{
			if (mutexReadTryLock()){
			  if (elementUsed!=NULL)
			    if (elementUsed->thisElement!=NULL){
				elementUsed->thisElement->paintHighlighted(&paint,pixmap->trans);
				elementUsed->thisElement->paintHighlightedBackground(&paint,pixmap->trans);
				}
			   mutexReadUnlock();
			   }
			}
		paint.setPen(pen);
		break;
	case 188: //circle Fit
		{ for (int i=0; i<modestep;i++){
			QPoint p=pixmap->trans.mapDraw(pointarray.point(i));
			paint.drawLine(p-QPoint(2,2),p+QPoint(2,2));
			paint.drawLine(p-QPoint(2,-2),p+QPoint(2,-2));
			}
		}
		break;
	case 190://spiral
	case 191://circle
	case 192://sector
	case 193://arc
	case 194://polygon arc
		if (modestep>=1){
			QPoint p=pixmap->trans.mapDraw(pointarray.point(0));
			paint.drawLine(p-QPoint(2,2),p+QPoint(2,2));
			paint.drawLine(p-QPoint(2,-2),p+QPoint(2,-2));
			}
		break;
	case 200: //zoom
		if (mouseButton&Qt::LeftButton){
		if (mouseDrawingPos.x()>=pointarray.point(0).x()){
			QPoint p=pixmap->trans.mapDraw(mouseDrawingPos)+QPoint(5,-5);
			paint.drawLine(p+QPoint(2,0),p+QPoint(-2,0));
			paint.drawLine(p+QPoint(0,-2),p+QPoint(0,2));
		}
		else {
			QPoint p=pixmap->trans.mapDraw(mouseDrawingPos)+QPoint(5,-5);
			paint.drawLine(p+QPoint(2,0),p+QPoint(-2,0));
		}}
		break;
	case 312: //move single point
		if (!elementUsedLocked) {
		     if (mutexReadTryLock()){
		        if (elementUsed!=NULL)
		    		if (elementUsed->thisElement!=NULL){
					elementUsed->thisElement->paintHighlighted(&paint,pixmap->trans);
					elementUsed->thisElement->paintHighlighted(&paint,pixmap->trans,pointarray.point(0));
					elementUsed->thisElement->paintHighlightedBackground(&paint,pixmap->trans);
					}
		     mutexReadUnlock();
		     }
		paint.setPen(pen);
		}
		break;
	case 313: //insert point
		if (!elementUsedLocked) {
		     if (mutexReadTryLock()){
		        if (elementUsed!=NULL)
		    		if (elementUsed->thisElement!=NULL){
					elementUsed->thisElement->paintHighlighted(&paint,pixmap->trans);
					elementUsed->thisElement->paintHighlighted(&paint,pixmap->trans,pointarray.point(0));
					elementUsed->thisElement->paintHighlightedBackground(&paint,pixmap->trans);
					if (pointarray.size()>1) elementUsed->thisElement->paintHighlighted(&paint,pixmap->trans,pointarray.point(1));
					}
		     mutexReadUnlock();
		     }
		paint.setPen(pen);
		}
		break;
	case 350://scale
		if (modestep>=1){
			QPoint p=pixmap->trans.mapDraw(pointarray.point(0));
			paint.drawLine(p-QPoint(2,2),p+QPoint(2,2));
			paint.drawLine(p-QPoint(2,-2),p+QPoint(2,-2));
			}
		break;
	case 400://properties
		if (!elementUsedLocked) {
		   if (mutexReadTryLock()){
			if (elementUsed!=NULL)
		    		if (elementUsed->thisElement!=NULL){
					elementUsed->thisElement->paintHighlighted(&paint,pixmap->trans);
					elementUsed->thisElement->paintHighlightedBackground(&paint,pixmap->trans);
				}
		   mutexReadUnlock();
		   }
		paint.setPen(pen);
		}
		break;
	default	:
		if (mode>600) {
			modeHandler->paintCell(&paint);
			paint.setPen(pen);
			}
	}
  //paint mouse pointer
  QPoint mouse=pixmap->trans.mapDraw(mouseDrawingPos);
  QPoint pos=pixmap->trans.mapDraw(getDUnits(mousePos));
  switch (setup::mouseView){
  case 0: paint.drawPoint(mouse.x(),mouse.y());
  	break;
  case 1:
  	paint.drawLine(mouse.x()-5,mouse.y(),mouse.x()+5,mouse.y());
  	paint.drawLine(mouse.x(),mouse.y()-5,mouse.x(),mouse.y()+5);
	break;
  case 2:
  	paint.drawLine(0,mouse.y(),width(),mouse.y());
  	paint.drawLine(mouse.x(),0,mouse.x(),height());
	break;
  case 3:
  	paint.drawLine(mouse.x()-1,mouse.y(),mouse.x()+1,mouse.y());
  	paint.drawLine(mouse.x(),mouse.y()-1,mouse.x(),mouse.y()+1);
	paint.drawLine(pos.x()-5,pos.y(),pos.x()+5,pos.y());
  	paint.drawLine(pos.x(),pos.y()-5,pos.x(),pos.y()+5);
  	break;
	}
  }
  paint.end();
  pixmap->scaleMutex.unlock();
  setUpdatesEnabled(true);
//  printf("pe ende\n");
// printf("end paintEvent\n");
}

void drawingField::resizeEvent(QResizeEvent *){
// printf("start resize\n");

 pixmap->abortPaint();
 bool alt=autorepaint;
 autorepaint=false;
 
 pixmap->resize(this->width(),this->height());
//printf("resize 1\n");
 autorepaint=alt;
 paint();

// printf("resize end\n");
}


void drawingField::enterEvent(QEvent *){
//  printf("start enter\n");
  mouseVisible=true;
  setMouseHelp();
  setCursor(QCursor(Qt::BlankCursor));
  repaint();
//  printf("end enter\n");
}

void drawingField::prepareOutput(){
//  printf("prepareOutut\n");
// mousemouse and ctl/shift pressed
mouseDrawingPos=getDUnits(mousePos);
switch (mode){
  case 0: //default
	//if (mouseModifiers==Qt::NoModifier) {
	if (modestep<2){
		if (mouseButton==Qt::LeftButton){
			if (pointarray.size()>=1) emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
		} else {
			if (elementUsed==NULL) emit mousePosChange(mouseDrawingPos);
			if (mutexReadTryLock()){
			if (!elementUsedLocked) {
				//elementUsed=currentCell->nearestElement(mouseDrawingPos);
			if (elementUsed!=NULL)
			if (elementUsed->thisElement!=NULL){
				if (elementUsed->thisElement->isBox()) emit message(tr("Box"));
				else if (elementUsed->thisElement->isPolygon()) emit message(tr("Polygon"));
				else if (elementUsed->thisElement->isPath()) emit message(tr("Path"));
				else if (elementUsed->thisElement->isText()) emit message(tr("Text"));
				else if (elementUsed->thisElement->isCellref()) emit message(tr("Cellref: ")+elementUsed->thisElement->depend()->cellName);
				else if (elementUsed->thisElement->isCellrefArray()) emit message(tr("CellrefArray: ")+elementUsed->thisElement->depend()->cellName);
				}}
			mutexReadUnlock();
			}
		}
	}
	else { //move/scale in default mode
		pointArray pa;
		pa<<pointarray.point(0);
		pa<<QPoint(pointarray.point(0).x(),pointarray.point(1).y());
		pa<<pointarray.point(1);
		pa<<QPoint(pointarray.point(1).x(),pointarray.point(0).y());
		pa<<(pa.point(0)+pa.point(1))/2;
		pa<<(pa.point(2)+pa.point(1))/2;
		pa<<(pa.point(2)+pa.point(3))/2;
		pa<<(pa.point(0)+pa.point(3))/2;
		pa<<(pa.point(0)+pa.point(2))/2;
		if (modestep==3){
			mouseDrawingPos=snap(mouseDrawingPos);
			if (pointarray.point(2)==pa.point(4)){
				mouseDrawingPos.setY(pa.point(4).y());
			}
			else if (pointarray.point(2)==pa.point(5)){
				mouseDrawingPos.setX(pa.point(5).x());
			}
			else if (pointarray.point(2)==pa.point(6)){
				mouseDrawingPos.setY(pa.point(4).y());
			}
			else if (pointarray.point(2)==pa.point(7)){
				mouseDrawingPos.setX(pa.point(5).x());
			}
			pointarray.setPoint(3,mouseDrawingPos);
			emit mousePosDifChange(mouseDrawingPos,pointarray.point(2));
		}
		if (modestep==2){
			
			double d=1000000000;
			int f=-1;
			for (int i=0;i<pa.size();i++){
				double d1=element::distance(mouseDrawingPos,pa.point(i));
				if (d1<d){
					d=d1;
					f=i;
				}
			}
			pointarray.setPoint(2,pa.point(f));
			emit mousePosChange(mouseDrawingPos);
		}
	}
	//}
	break;
  case 1: //Command
	if (mouseModifiers==Qt::NoModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);}
	else if (mouseModifiers==Qt::ShiftModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
 		if(modestep>=1){
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(modestep-1));
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(modestep-1));
		}
		else 	emit mousePosChange(mouseDrawingPos);
		
		}
	break;
  case 10: //fselect
  case 15: //fdeselect
	if ((mouseModifiers==Qt::NoModifier)||(mouseModifiers==Qt::ControlModifier)) {
	  	elementUsed=NULL;
	  	if (mutexReadTryLock()){
  	  	   	if (!(mouseButton&Qt::LeftButton))
	  			elementUsed=currentCell->nearestForm(mouseDrawingPos);
			emit mousePosChange(mouseDrawingPos);
			mutexReadUnlock();
	     	}
	}
	if (mouseButton==Qt::LeftButton){
		if (pointarray.size()==1) emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	}
	break;
  case 20: //pselect
  case 25: //pdeselect
	if ((mouseModifiers==Qt::NoModifier)||(mouseModifiers==Qt::ControlModifier)) {
	  	if (mutexReadTryLock()){
  	  	  	if (!(mouseButton&Qt::LeftButton)) {
				QPoint p=pointarray.point(0);
	 	  		elementUsed=currentCell->nearestPoint(mouseDrawingPos,&p);
				emit mousePosChange(p);
				pointarray.setPoint(0,p);
				}
         	   	mutexReadUnlock();
	 	 }
	}
	if (mouseButton==Qt::LeftButton){
		if (pointarray.size()==1) emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	}
	  break;
  case 30: //cselect
  case 35: //cdeselect
  //case 122: //netlist link
	if ((mouseModifiers==Qt::NoModifier)||(mouseModifiers==Qt::ControlModifier)) {
	  	if (mutexReadTryLock()){
			if ((!(mouseButton&Qt::LeftButton))&&(mouseStatus!=5)) {
				elementExcluded.clear();
	 	  		elementUsed=currentCell->nearestCell(mouseDrawingPos);
				if (elementUsed!=NULL) {
				   cell *c=elementUsed->thisElement->depend();
				   if (c!=NULL) {emit message(c->cellName);}
			           else 
				    { emit mousePosChange(mouseDrawingPos);}
				}
				else 
				   {emit mousePosChange(mouseDrawingPos);}
				}
         	 	mutexReadUnlock();
	 	 }	
	}
	if (mouseButton==Qt::LeftButton){
		if (pointarray.size()==1) emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	}
	  break;
  case 100: //Box
 	mouseDrawingPos=snap(mouseDrawingPos);
	if (mouseModifiers==Qt::NoModifier) {
	     if (modestep==1){
		emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));}
	     else emit mousePosChange(mouseDrawingPos);}
	else if (mouseModifiers==Qt::ShiftModifier) {
	    if (modestep==1){
		mouseDrawingPos=square(mouseDrawingPos,pointarray.point(0));
		emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));}
	     else emit mousePosChange(mouseDrawingPos);}
	else if (mouseModifiers==(Qt::ShiftModifier+Qt::ControlModifier)){
	     if (modestep==1){
		mouseDrawingPos=square(mouseDrawingPos,pointarray.point(0));
		emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));}
	     else emit mousePosChange(mouseDrawingPos);}
	else if (mouseModifiers==Qt::ControlModifier) {
	     if (modestep==1){
		 emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));}
	     else emit mousePosChange(mouseDrawingPos);}
	break;
  case 110: //polygon
	if (mouseModifiers==Qt::ControlModifier) {
		if(modestep>2){
			pointarray.setPoint(modestep,pointarray.point(0));
			emit mousePosDifChange(pointarray.point(0),pointarray.point(0)-pointarray.point(modestep-1));
		}
		}
	else if (mouseModifiers==Qt::NoModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
 		if(modestep>=1){
			pointarray.setPoint(modestep,mouseDrawingPos);
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(modestep-1));
		}
		else 	emit mousePosChange(mouseDrawingPos);
		}
	else if (mouseModifiers==Qt::ShiftModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
 		if(modestep>=1){
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(modestep-1));
			pointarray.setPoint(modestep,mouseDrawingPos);
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(modestep-1));
		}
		else 	emit mousePosChange(mouseDrawingPos);
		
		}
	else if (mouseModifiers==(Qt::ShiftModifier+Qt::ControlModifier)) {
		//printf("clt+shift\n");
		mouseDrawingPos=snap(mouseDrawingPos);
 		if(modestep>=1){
			pointarray.setPoint(modestep,pointarray.point(modestep-1));
			emit mousePosChange(pointarray.point(modestep-1));
		}
		else 	emit mousePosChange(mouseDrawingPos);
		}
	break;
  case 120: //cellref
	mouseDrawingPos=snap(mouseDrawingPos);
	emit mousePosChange(mouseDrawingPos);
	break;
/*  case 121: //placeCell
	mouseDrawingPos=snap(mouseDrawingPos);
	emit mousePosChange(mouseDrawingPos);
	break;*/
  case 130: //Cellrefarray
	mouseDrawingPos=snap(mouseDrawingPos);
	if (modestep==1)emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	     else emit mousePosChange(mouseDrawingPos);
	break;
  case 140: //Text
 	mouseDrawingPos=snap(mouseDrawingPos);
	emit mousePosChange(mouseDrawingPos);
	break;

  case 150: //path
	if (mouseModifiers==Qt::ControlModifier) {
		if(modestep>1){
			pointarray.setPoint(modestep,pointarray.point(modestep-1));
			emit mousePosChange(pointarray.point(modestep-1));
		}
		}
	else if (mouseModifiers==Qt::NoModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
 		if(modestep>=1){
			pointarray.setPoint(modestep,mouseDrawingPos);
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(modestep-1));
			}
		else emit mousePosChange(mouseDrawingPos);
		}
	else if (mouseModifiers==Qt::ShiftModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if(modestep>=1){
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(modestep-1));
			pointarray.setPoint(modestep,mouseDrawingPos);
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(modestep-1));
			}
		else emit mousePosChange(mouseDrawingPos);
		}
	else if (mouseModifiers==(Qt::ShiftModifier+Qt::ControlModifier)) {
		//printf("clt+shift\n");
		mouseDrawingPos=snap(mouseDrawingPos);
 		if(modestep>=1){
			pointarray.setPoint(modestep,pointarray.point(modestep-1));
			emit mousePosChange(pointarray.point(modestep-1));
		}
		else 	emit mousePosChange(mouseDrawingPos);
		}
	break;
/*  case 160: //netlist route
	  mouseDrawingPos=snap(mouseDrawingPos);
	  if(modestep>=1){
		  QPoint p=mouseDrawingPos;
		  if (route90) p=perpendicular(mouseDrawingPos,pointarray.point(modestep-1));
		  if (route45) p=angle45(mouseDrawingPos,pointarray.point(modestep-1));
		  pointarray.setPoint(modestep,p);
			emit mousePosDifChange(p,p-pointarray.point(modestep-1));
			}
	  else
	  emit mousePosChange(mouseDrawingPos);
	  break;*/
  case 180: //ruler
		if ((mouseModifiers==Qt::ShiftModifier)||
		  (mouseModifiers==Qt::ShiftModifier+Qt::ControlModifier)) {
			mouseDrawingPos=snap(mouseDrawingPos);
			if(modestep>=1){
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
			}
		}
		else {
			mouseDrawingPos=snap(mouseDrawingPos);
		}
		if (modestep>0)
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
		else emit mousePosChange(mouseDrawingPos);
	break;
  case 181: //length measurement  
	if ((mouseModifiers==Qt::NoModifier)||(mouseModifiers==Qt::ControlModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
 		emit mousePosChange(mouseDrawingPos);
		}
	else if (mouseModifiers==Qt::ShiftModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if(modestep>=1){
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(modestep-1));
			}
		emit mousePosChange(mouseDrawingPos);
		}
	else if (mouseModifiers==(Qt::ShiftModifier+Qt::ControlModifier)) {
		//printf("clt+shift\n");
		mouseDrawingPos=snap(mouseDrawingPos);
 		emit mousePosChange(mouseDrawingPos);
		}
	break;  
  case 185: //angle
  		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep>0)
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
		else emit mousePosChange(mouseDrawingPos);
	break;
case 189: //circle box
	if ((mouseModifiers==Qt::NoModifier)||(mouseModifiers==Qt::ControlModifier+Qt::ShiftModifier)) {
  		mouseDrawingPos=snap(mouseDrawingPos);
  		if (modestep==0) emit mousePosChange(mouseDrawingPos);
		if (modestep>0) emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	}
	else if (mouseModifiers==Qt::ShiftModifier) {
  		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep>0) mouseDrawingPos=square(mouseDrawingPos,pointarray.point(0));
  		if (modestep==0) emit mousePosChange(mouseDrawingPos);
		if (modestep>0) emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	}
	break;
case 190: //spiral
	if (mouseModifiers==Qt::NoModifier) {
  		mouseDrawingPos=snap(mouseDrawingPos);
  		if (modestep==0)
			emit mousePosChange(mouseDrawingPos);
  		else if (modestep>=1)
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
		if (modestep>1) 
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	}
	break;
case 191: //circle
	if (mouseModifiers==Qt::NoModifier) {
  		mouseDrawingPos=snap(mouseDrawingPos);
  		if (modestep==0) emit mousePosChange(mouseDrawingPos);
		if (modestep>0) emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	}
	break;
case 192: //sector
	if (mouseModifiers==Qt::NoModifier) {
  		mouseDrawingPos=snap(mouseDrawingPos);
  		if (modestep==0)
			emit mousePosChange(mouseDrawingPos);
  		else if (modestep>=1)
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
		if (modestep>1) 
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	}
	break;
case 193: //arc
	if (mouseModifiers==Qt::NoModifier) {
  		mouseDrawingPos=snap(mouseDrawingPos);
  		if (modestep==0)emit mousePosChange(mouseDrawingPos);
  		else if (modestep>=1)
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
		if (modestep>1) 
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	}
	break;
case 194: //polygon arc
	if (mouseModifiers==Qt::NoModifier) {
  		mouseDrawingPos=snap(mouseDrawingPos);
  		if (modestep==0)
			emit mousePosChange(mouseDrawingPos);
  		else if (modestep>=1)
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
		if (modestep>1) 
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	}
	break;
case 195: //bezier2
	if (mouseModifiers==Qt::NoModifier) {
  		mouseDrawingPos=snap(mouseDrawingPos);
  		if (modestep==0)
			emit mousePosChange(mouseDrawingPos);
  		else if (modestep==1)
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
		else if (modestep>1)
			emit mousePosChange(mouseDrawingPos);
	}
  	break;
case 196: //bezier3
	if (mouseModifiers==Qt::NoModifier) {
  		mouseDrawingPos=snap(mouseDrawingPos);
  		if (modestep==0)
			emit mousePosChange(mouseDrawingPos);
  		else if (modestep==1)
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
		else if (modestep==2) 
			emit mousePosChange(mouseDrawingPos);
		else if (modestep==3) 
			emit mousePosChange(mouseDrawingPos);
	}
  	break;
case 200: //zoom
  	if (!(mouseButton&Qt::LeftButton))
		emit mousePosChange(mouseDrawingPos);
	else {
		if (pointarray.size()==1) emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	}
  	break;
case 300: //mirror
	if (mouseModifiers==Qt::NoModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if(modestep>=1)
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
		else emit mousePosChange(mouseDrawingPos);
	}
	else if (mouseModifiers==Qt::ShiftModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if(modestep>=1) {
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
			}
		else emit mousePosChange(mouseDrawingPos);
	}
	break;
case 308: //move x
	if (mouseModifiers==Qt::NoModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if(modestep>=1)
			emit mousePosDifChange(mouseDrawingPos,QPoint((mouseDrawingPos-pointarray.point(0)).x(),0));
		else emit mousePosChange(mouseDrawingPos);
	}
	break;
case 309: //move y
	if (mouseModifiers==Qt::NoModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if(modestep>=1)
			emit mousePosDifChange(mouseDrawingPos,QPoint(0,(mouseDrawingPos-pointarray.point(0)).y()));
		else emit mousePosChange(mouseDrawingPos);
	}
	break;
case 310: //move
	if (mouseModifiers==Qt::NoModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if(modestep>=1)
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
		else emit mousePosChange(mouseDrawingPos);
	}
	else if (mouseModifiers==Qt::ShiftModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if(modestep>=1) {
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
			}
		else emit mousePosChange(mouseDrawingPos);
	}
	break;
case 312: //move single point
	if (mouseModifiers==Qt::NoModifier) {
		if(modestep>=1){
			mouseDrawingPos=snap(mouseDrawingPos);
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));}
		else emit mousePosChange(mouseDrawingPos);
	}
	else if (mouseModifiers==Qt::ShiftModifier) {
			if(modestep>=1){
			mouseDrawingPos=snap(mouseDrawingPos);
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));}
		else emit mousePosChange(mouseDrawingPos);

	}
	break;
case 313: //insert point
	if (mouseModifiers==Qt::NoModifier) {
		if(modestep>=1){
			mouseDrawingPos=snap(mouseDrawingPos);
			 emit mousePosChange(mouseDrawingPos);}
		else emit mousePosChange(mouseDrawingPos);
	}
	else if (mouseModifiers==Qt::ShiftModifier) {
			if(modestep>=1){
			mouseDrawingPos=snap(mouseDrawingPos);
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
			 emit mousePosChange(mouseDrawingPos);}
		else emit mousePosChange(mouseDrawingPos);

	}
	break;
  case 315: //set cell origin
	if (mouseModifiers==Qt::NoModifier) {
  		mouseDrawingPos=snap(mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
	}
	break;
  case 320: //rotate
	if ((modestep==2)&&(mouseModifiers==Qt::ShiftModifier)) mouseDrawingPos= perpendicular(mouseDrawingPos,pointarray.point(0));
	else mouseDrawingPos=snap(mouseDrawingPos);
	if (modestep==0) {
		emit mousePosChange(mouseDrawingPos);
	}else if (modestep>0)
  		emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
	break;
  case 330: //copy
	if (mouseModifiers==Qt::NoModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if(modestep>=1)
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
		else emit mousePosChange(mouseDrawingPos);
	}
	else if (mouseModifiers==Qt::ShiftModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if(modestep>=1){
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
			}
		else emit mousePosChange(mouseDrawingPos);
	}
	break;
  case 340: //cut
	if (mouseModifiers==Qt::NoModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if(modestep>=1) {
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
			}
		else emit mousePosChange(mouseDrawingPos);
	}
	else if (mouseModifiers==Qt::ShiftModifier) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if(modestep>=1){
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(0));
			}
		else emit mousePosChange(mouseDrawingPos);
	}
	break;
  case 350: //scale
	if (mouseModifiers==Qt::NoModifier) {
  		mouseDrawingPos=snap(mouseDrawingPos);
  		if (modestep==0)
			emit mousePosChange(mouseDrawingPos);
  		else if (modestep>=1)
			emit mousePosDifChange(mouseDrawingPos,mouseDrawingPos-pointarray.point(modestep-1));
	}
  	break;
case 400: //properties
	//if (mouseModifiers==Qt::NoModifier) {
	  if (mutexReadTryLock()){
  	  if (!elementUsedLocked) {
		  //elementUsed=currentCell->nearestElement(mouseDrawingPos);
	  if (elementUsed!=NULL)
	    if (elementUsed->thisElement!=NULL){
		if (elementUsed->thisElement->isBox()) emit message(tr("Box"));
		else if (elementUsed->thisElement->isPolygon()) emit message(tr("Polygon"));
		else if (elementUsed->thisElement->isPath()) emit message(tr("Path"));
		else if (elementUsed->thisElement->isText()) emit message(tr("Text"));
		else if (elementUsed->thisElement->isCellref()) emit message(tr("Cellref: ")+elementUsed->thisElement->depend()->cellName);
		else if (elementUsed->thisElement->isCellrefArray()) emit message(tr("CellrefArray: ")+elementUsed->thisElement->depend()->cellName);
		}}
	  mutexReadUnlock();
	  }
	//}
	break;
  case 600: //select cell to view
	if (mouseModifiers==Qt::NoModifier) {
	  	if (mutexReadTryLock()){
			if (!(mouseButton&Qt::LeftButton)){
	 	  		elementUsed=currentCell->nearestCell(mouseDrawingPos);
				if (elementUsed!=NULL) {
				   cell *c=elementUsed->thisElement->depend();
				   if (c!=NULL) {emit message(c->cellName);}
			           else 
				    { emit mousePosChange(mouseDrawingPos);}
				}
				else 
				   {emit mousePosChange(mouseDrawingPos);}
				}
         	 	mutexReadUnlock();
	 	 }	
	}
	  break;
	default	:
		if (mode>600) modeHandler->prepareOutput();

 }
setMouseHelp();
}

void drawingField::mouseMoveEvent(QMouseEvent *e){
//  printf("mousemoved start\n");
  if (mousePos==e->pos()) return;
  mouseVisible=true;
  mousePos=e->pos();
  mouseButton=e->buttons();
  mouseModifiers=e->modifiers();
  mousemove=true;
  if ((paintMode==170)&&(paintMode!=mode))paint();
  if (((mousePos - dragPoint).manhattanLength()
          >  (QApplication::startDragDistance()*64))&&(mouseButton==Qt::LeftButton)) startDrag();
if (mode==0){
  		if (modestep<2)
		   if (!(mouseButton&Qt::LeftButton))
		   {
		   	if (mutexReadTryLock()){
				QPoint p=pointarray.point(0);
				pointarray.resize(1);
		   		if (!elementUsedLocked) elementUsed=currentCell->nearestElement(mouseDrawingPos,&p);
		   		pointarray.setPoint(0,p);
				mutexReadUnlock();
	  		}
		}

}
else if (mode==400){
 //properties mode 
  		if (modestep==0)
		   {
		   	if (mutexReadTryLock()){
				QPoint p=pointarray.point(0);
				pointarray.resize(1);
		   		if (!elementUsedLocked) elementUsed=currentCell->nearestElement(mouseDrawingPos,&p);
		   		pointarray.setPoint(0,p);
				mutexReadUnlock();
	  	}
	   }
	}
else if (((mode==30)||(mode==35))&&(mouseStatus==5)){  //cellselect deselect after switch through
    	mouseStatus=0;
	pointarray.resize(1);
	pointarray.setPoint(0,getDUnits(e->pos()));
	}

prepareOutput();

if (e->buttons()&Qt::RightButton) if (!(mouseMoveFunction()&&(e->buttons()&Qt::LeftButton))){  //scroll
	pixmap->scaleMutex.lock();
	pixmap->move((e->x()-mousepress.x()),(e->y()-mousepress.y()));
	pixmap->scaleMutex.unlock();
	emit mousePosDifChange(mouseDrawingPos,QPoint(e->x()-mousepress.x(),e->y()-mousepress.y()));
	mousepress=mousePos;
	paint();
	}
if (mode==312){
 //move single point 
  		if (modestep==0)
		   {
		   	if (mutexReadTryLock()){
				QPoint p=pointarray.point(0);
		   		elementUsed=currentCell->nearestPoint(mouseDrawingPos,&p);
		   		pointarray.setPoint(0,p);
				mutexReadUnlock();
	  	}
	   }
}
else if (mode==313){
 //insert point 
  		if (modestep==0)
		   {
		   	if (mutexReadTryLock()){
				QPoint p=pointarray.point(0);
		   		elementUsed=currentCell->nearestPoint(mouseDrawingPos,&p);
				if (elementUsed!=NULL)
				if (elementUsed->thisElement!=NULL)
					if ((elementUsed->thisElement->isPolygon())|| (elementUsed->thisElement->isPath())) {
					pointArray pa=elementUsed->thisElement->getPoints();
					pointarray.setPoint(0,p);
					pointarray.resize(1);
					double dis=1e99;
					for (int i=0;i<pa.size();i++){
						if (pa.point(i)==p){
							if (i>0) {
								double d=element::distance(mouseDrawingPos,pa.point(i-1));
								if ((mouseDrawingPos.x()>=p.x())&& (mouseDrawingPos.x()<=pa.point(i-1).x())) d=d/8;
								if ((mouseDrawingPos.x()<=p.x())&& (mouseDrawingPos.x()>=pa.point(i-1).x())) d=d/8;
								if ((mouseDrawingPos.y()>=p.y())&& (mouseDrawingPos.y()<=pa.point(i-1).y())) d=d/8;
								if ((mouseDrawingPos.y()<=p.y())&& (mouseDrawingPos.y()>=pa.point(i-1).y())) d=d/8;
								if (d<dis) {
									dis=d;
									pointarray.resize(2);
									pointarray.setPoint(1,pa.point(i-1));
								}
							}
							if (i<pa.size()-1) {
								double d=element::distance(mouseDrawingPos,pa.point(i+1));
								if ((mouseDrawingPos.x()>=p.x())&& (mouseDrawingPos.x()<=pa.point(i+1).x())) d=d/8;
								if ((mouseDrawingPos.x()<=p.x())&& (mouseDrawingPos.x()>=pa.point(i+1).x())) d=d/8;
								if ((mouseDrawingPos.y()>=p.y())&& (mouseDrawingPos.y()<=pa.point(i+1).y())) d=d/8;
								if ((mouseDrawingPos.y()<=p.y())&& (mouseDrawingPos.y()>=pa.point(i+1).y())) d=d/8;
								if (d<dis) {
									dis=d;
									pointarray.resize(2);
									pointarray.setPoint(1,pa.point(i+1));
								}
							}
						}
					}
					if ((elementUsed->thisElement->isPath())&& (element::distance(mouseDrawingPos,p)<dis)&&(pa.point(0)==p||(pa.point(pa.size()-1)==p))) pointarray.resize(1);
					}
					else elementUsed=NULL;
				mutexReadUnlock();
	  	}
	   }
}
//  printf("mm ende\n");

  repaint();
}

void drawingField::mousePressEvent(QMouseEvent *e){
 // printf("mousepressed start\n");
  mousemove=false;
  mousePos=e->pos();
  mouseButton=e->buttons();
  mouseModifiers=e->modifiers();
  mouseDrawingPos=getDUnits(e->pos());
  double d;
  bool b;
  QRect rect(mouseDrawingPos,mouseDrawingPos);
  element *f;
  QString s;
  if (e->button()==Qt::RightButton)
	
	{ //scroll
 	mousepress=e->pos();
 	}
  if ((e->button()==Qt::LeftButton)&&(!mouseMoveFunction())) { //drag
        dragPoint=mousePos;
	dragTimer.start();
	}
  switch (mode){
  case 0: //default
	mouseStatus=-1;
	if ((e->button()==Qt::MidButton)||((e->modifiers()==Qt::ShiftModifier)&&(e->button()==Qt::LeftButton))){ //add to selection
		mouseStatus=2;
	}
	else if (((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier))) {// replace selection
		mouseStatus=0;
	}
	else if (((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {// free to use
		mouseStatus=1;
	}
	else if (((e->button()==Qt::LeftButton)&&(e->modifiers()==(Qt::ControlModifier|Qt::ShiftModifier)))) {// free to use
		mouseStatus=3;
	}
	if (e->button()==Qt::LeftButton)
	if (modestep<2){
		pointarray.resize(1);
		pointarray.setPoint(0,mouseDrawingPos);
	} else if (modestep==2){
		modestep=3;
		pointarray.resize(4);
		pointarray.setPoint(3,mouseDrawingPos);
		}
	else if (modestep==3){//perform move scale
		//printf("perform\n");
		if (mutexChangeGuiTryLock()){
			prepareUndo();
			modestep=1;
			setModifyChanged();
			QPoint p1,p2;
			pointArray pa;
			pa<<pointarray.point(0);
			pa<<QPoint(pointarray.point(0).x(),pointarray.point(1).y());
			pa<<pointarray.point(1);
			pa<<QPoint(pointarray.point(1).x(),pointarray.point(0).y());
			pa<<(pa.point(0)+pa.point(1))/2;
			pa<<(pa.point(2)+pa.point(1))/2;
			pa<<(pa.point(2)+pa.point(3))/2;
			pa<<(pa.point(0)+pa.point(3))/2;
			pa<<(pa.point(0)+pa.point(2))/2;
			if (pointarray.point(2)==pa.point(0)){
				p1=pa.point(2);
				p2=pa.point(0);
				}
			else if (pointarray.point(2)==pa.point(1)){
				p1=pa.point(3);
				p2=pa.point(1);
				}
			else if (pointarray.point(2)==pa.point(2)){
				p1=pa.point(0);
				p2=pa.point(2);
				}
			else if (pointarray.point(2)==pa.point(3)){
				p1=pa.point(1);
				p2=pa.point(3);
				}
			else if (pointarray.point(2)==pa.point(4)){
				p1=pa.point(6);
				p2=pa.point(4);
				}
			else if (pointarray.point(2)==pa.point(5)){
				p1=pa.point(7);
				p2=pa.point(5);
				}
			else if (pointarray.point(2)==pa.point(6)){
				p1=pa.point(4);
				p2=pa.point(6);
				}
			else if (pointarray.point(2)==pa.point(7)){
				p1=pa.point(5);
				p2=pa.point(7);
				}
			if (pointarray.point(2)==pa.point(8)){
				currentCell->moveSelect(mouseDrawingPos-pointarray.point(2));
				macroAdd("layout->drawing->point("+str(pointarray.point(2))+");");
				macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
				macroAdd("layout->drawing->move();");
				}
			else {
				currentCell->scaleSelect(p1,p2,mouseDrawingPos);
				macroAdd("layout->drawing->point("+str(p1)+");");
				macroAdd("layout->drawing->point("+str(p2)+");");
				macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
				macroAdd("layout->drawing->scale();");
			}
			mutexChangeUnlock();
			}
		pointarray.resize(2);
		pointarray.setPoint(0,mouseDrawingPos);
		paint();
	}
	break;
  case 1: //Command
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
		emit mousePosChange(mouseDrawingPos);
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		modestep=0;
		macroAdd("layout->drawing->clearPoints();");
		repaint();
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep>1) mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(modestep-2));
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
		emit mousePosChange(mouseDrawingPos);
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier)) {
		if (modestep>=1) {
			modestep--;
			mouseDrawingPos=snap(mouseDrawingPos);
			pointarray.resize(modestep+1);
			pointarray.setPoint(modestep,mouseDrawingPos);
			macroAdd("layout->drawing->delPoint();");
			repaint();
			}
		}
		break;
case 15: // fdeselect 
case 10: // fselect 
	mouseStatus=-1;
	pointarray.resize(1);
	pointarray.setPoint(0,mouseDrawingPos);
	mouseStatus=1;
	if ((e->button()==Qt::MidButton)||((e->modifiers()==Qt::ShiftModifier)&&(e->button()==Qt::LeftButton))){ //for all point in rect
		mouseStatus=2;
	}
	else if (((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier))) {// one point in window
		mouseStatus=0;
	}
	else if (((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {// one point in window /replace selection
		mouseStatus=1;
	}
	else if (((e->button()==Qt::LeftButton)&&(e->modifiers()==(Qt::ControlModifier|Qt::ShiftModifier)))) {// for all points in rect /replace selection
		mouseStatus=3;
	}
	break;
/*
	if ((e->button()==Qt::MidButton)||((e->modifiers()==Qt::ShiftModifier)&&(e->button()==Qt::LeftButton))){ // for all point in rect
		pointarray.resize(1);
		pointarray.setPoint(0,mouseDrawingPos);
		mouseStatus=1;
	}
	else if (((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) || ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {// one point in window
		pointarray.resize(1);
		pointarray.setPoint(0,mouseDrawingPos);
		mouseStatus=0;
		if (e->modifiers()==Qt::ControlModifier) mouseStatus=2;
	}
	break;*/

case 20: // pselect
case 25: // pdeselect
	mouseStatus=-1;
	if (((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier))|| ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		pointarray.resize(1);
		pointarray.setPoint(0,mouseDrawingPos);
		mouseStatus=0;
		if (e->modifiers()==Qt::ControlModifier) mouseStatus=1;
	}
	break;
case 30: // cselect
case 35: // cdeselect
	mouseStatus=-1;
	if (((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier))|| ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		pointarray.resize(1);
		pointarray.setPoint(0,mouseDrawingPos);
		mouseStatus=0;
		if (e->modifiers()==Qt::ControlModifier) mouseStatus=1;
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		mouseStatus=5;
		}
	break;
case 100: //Box
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		if (modestep==1)
			{
			mouseDrawingPos=snap(mouseDrawingPos);
			if (mutexAddGuiTryLock()){
			prepareUndo();
			rect=makeRect(mouseDrawingPos,pointarray.point(0));
 			f=currentCell->addBox(rect,activeLayer);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->box();");
			setModifyAdded();
			mutexAddUnlock();
			}}
		else 	{
			pointarray.resize(1);
			pointarray.setPoint(0,snap(mouseDrawingPos));
			modestep=1;	
			}}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		if (modestep==1)
			{
			mouseDrawingPos=snap(mouseDrawingPos);
			mouseDrawingPos=square(mouseDrawingPos,pointarray.point(0));
			if (mutexAddGuiTryLock()){
			prepareUndo();
			rect=makeRect(mouseDrawingPos,pointarray.point(0));
 			f=currentCell->addBox(rect,activeLayer);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->box();");
			setModifyAdded();
			mutexAddUnlock();
			}}
		else 	{
			pointarray.resize(1);
			pointarray.setPoint(0,snap(mouseDrawingPos));
			modestep=1;	
			}
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier)) {
		if (modestep==1)
			{
			mouseDrawingPos=snap(mouseDrawingPos);
			if (mutexAddGuiTryLock()){
			prepareUndo();
			rect=makeDot(mouseDrawingPos,pointarray.point(0));
 			f=currentCell->addBox(rect,activeLayer);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->dot();");
			setModifyAdded();
			mutexAddUnlock();
			}}
		else 	{
			pointarray.resize(1);
			pointarray.setPoint(0,snap(mouseDrawingPos));
			modestep=1;	
			}}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier)) {
		if (modestep==1)
			{
			mouseDrawingPos=snap(mouseDrawingPos);
			mouseDrawingPos=square(mouseDrawingPos,pointarray.point(0));
			if (mutexAddGuiTryLock()){
			prepareUndo();
			rect=makeDot(mouseDrawingPos,pointarray.point(0));
 			f=currentCell->addBox(rect,activeLayer);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->dot();");
			setModifyAdded();
			mutexAddUnlock();
			}}
		else 	{
			pointarray.resize(1);
			pointarray.setPoint(0,snap(mouseDrawingPos));
			modestep=1;	
			}
		}
	else if ((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier)){
	  modestep=0;	
	  pointarray.resize(0);
	  repaint();
	}
		break;
  case 110: //polygon
	{
	if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		if (modestep==0) setMovePointMode();
		else {
			if (modestep>2)
				if (mutexAddGuiTryLock()){
				prepareUndo();
				pointarray.setPoint(modestep,pointarray.point(0));
				f=currentCell->addPolygon(pointarray,activeLayer);
				if (autorepaint) drawElement(f);//f->paint(pixmap);
				for (int i=0; i<modestep;i++){
					macroAdd("layout->drawing->point("+str(pointarray.point(i))+");");
					}
				macroAdd("layout->drawing->polygon();");
				mutexAddUnlock();
				}
			modestep=0;
			setModifyAdded();
			repaint();
		}
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		if (modestep==0) setInsertPointMode();
		else {
			modestep++;
			mouseDrawingPos=snap(mouseDrawingPos);
			if (modestep>1) mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(modestep-2));
			pointarray.resize(modestep+1);
			pointarray.setPoint(modestep-1,mouseDrawingPos);
			emit mousePosChange(mouseDrawingPos);
		}
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier)) {
		if (modestep>=1) {
			modestep--;
			mouseDrawingPos=snap(mouseDrawingPos);
			pointarray.resize(modestep+1);
			pointarray.setPoint(modestep,mouseDrawingPos);
			}
		}
	}
	break;
case 120: // Cellref
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		prepareUndo();
		mouseDrawingPos=snap(mouseDrawingPos);
		if (cell_ref!=NULL) 
                   if (mutexAddGuiTryLock()) { 
			f=currentCell->addCellref(cell_ref,mouseDrawingPos);
			f->map(cellrefTrans);
			f->setPos(mouseDrawingPos);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			mutexAddUnlock();
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->cellref(\""+cell_ref->cellName+"\");");
			}
		update();
		setModifyAdded();
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		cellrefTrans.rotate(90);
		update();
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier)) {
		cellrefTrans.rotate(-90);
		update();
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier)) {
		cellrefTrans.toggleMirror_x();
		update();
	}
	break;
/*case 121: // placeCell
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		prepareUndo();
		mouseDrawingPos=snap(mouseDrawingPos);
		if (cell_ref!=NULL) 
                   if (mutexAddGuiTryLock()) { 
			f=currentCell->addCellref(cell_ref,mouseDrawingPos);
			f->map(cellrefTrans);
			f->setPos(mouseDrawingPos);
			f->setDeviceName(placeDevicename);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			mutexAddUnlock();
			setCommandMode();
			emit cellPlaced(placeDevicename);
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->cellref(\""+cell_ref->cellName+"\");");
			}
		update();
		setModifyAdded();
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		cellrefTrans.rotate(90);
		update();
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier)) {
		cellrefTrans.rotate(-90);
		update();
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier)) {
		cellrefTrans.toggleMirror_x();
		update();
	}
	break;*/
/*case 122: //netlist link
		if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) 
		  if (mutexReadTryLock()){
			elementList *el=currentCell->nearestCell(mouseDrawingPos);
	   		if (el!=NULL)
	   		if (el->thisElement!=NULL){
				el->thisElement->setDeviceName(placeDevicename);
				emit linked(el->thisElement);
				setCommandMode();
				}
			mutexReadUnlock();
			}
		break;*/
case 130: // CellrefArray
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		if (modestep==1) {
			mouseDrawingPos=snap(mouseDrawingPos);
			int anz_y=pointarray.point(2).y();
			int anz_x=pointarray.point(2).x();
			//QInputDialog::getInteger(this,"Add Cellreference Array","Enter number of Cells in x-Direction:",1,1,32767,1,&b);
			//if (b) anz_y=QInputDialog::getInteger(this,"Add Cellreference Array","Enter number of Cells in y-Direction:",1,1,32767,1,&b);
			//if (b) 
		 	   if (mutexAddGuiTryLock()){
				prepareUndo();
				if (cell_ref!=NULL) { 
					f=currentCell->addCellrefArray(cell_ref,pointarray.point(0),mouseDrawingPos,anz_x,anz_y,cellrefTrans);
					if (autorepaint)drawElement(f);//f->paint(pixmap);
					}
				update();
				setModifyAdded();
				if (cell_ref!=NULL) macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
				if (cell_ref!=NULL) macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
				if (cell_ref!=NULL) macroAdd("layout->drawing->cellrefarray(\""+cell_ref->cellName+"\","+str(anz_x)+","+str(anz_y)+");");
			   	mutexAddUnlock();
			   }
			modestep=0;
			}
			
		else {
			pointarray.resize(3);
			pointarray.setPoint(0,snap(mouseDrawingPos));
			modestep=1;}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))) {
		modestep=0;
		repaint();
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		cellrefTrans.rotate(90);
		update();
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier)) {
		cellrefTrans.rotate(-90);
		update();
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier)) {
		cellrefTrans.toggleMirror_x();
		update();
	}
	break;
case 140: // Text
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		s=QInputDialog::getText(this,"Add Text","Enter Text:",QLineEdit::Normal,QString::null,&b);
		if (b&&(s!=QString::null)) {
		    if (mutexAddGuiTryLock()){
			prepareUndo();
			f=currentCell->addText(activeLayer,mouseDrawingPos,s);
			f->setWidth(setup::defaultTextWidth);
			f->setPresentation(setup::defaultTextPresentation);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			update();
			setModifyAdded();
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->text(\""+s+"\");");
		 	mutexAddUnlock();
			}
		    }
		modestep=0;
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier)))
		if (modestep==0) setMovePointMode();
	break;
case 150: //path
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		if (modestep==0) setMovePointMode();
		else {
			if (modestep>1) if (mutexAddGuiTryLock()){
				prepareUndo();
				pointarray.resize(modestep);
				f=currentCell->addPath(pointarray,activeLayer);
				f->setCap(setup::defaultPathCap);
				f->setWidth(setup::defaultPathWidth);
				if (autorepaint)drawElement(f);//f->paint(pixmap);
				for (int i=0; i<modestep;i++){
					macroAdd("layout->drawing->point("+str(pointarray.point(i))+");");}
				macroAdd("layout->drawing->path();");
				mutexAddUnlock();
				}
			modestep=0;
			setModifyAdded();
			repaint();
			}
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		if (modestep==0) setInsertPointMode();
		else {
			modestep++;
			mouseDrawingPos=snap(mouseDrawingPos);
			if (modestep>1) mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(modestep-2));
			pointarray.resize(modestep+1);
			pointarray.setPoint(modestep-1,mouseDrawingPos);
			emit mousePosChange(mouseDrawingPos);
		}
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier)) {
		if (modestep>=1) {
			modestep--;
			mouseDrawingPos=snap(mouseDrawingPos);
			pointarray.resize(modestep+1);
			pointarray.setPoint(modestep,mouseDrawingPos);
			}
		}
	break;
/*case 160: // netlist route
		routePressedPoint=snap(mouseDrawingPos);
		mouseDrawingPos=routePressedPoint;
	break;*/
case 170: //node mode
	   if (e->button()==Qt::LeftButton)
		if (mutexReadTryLock()){
			elementList *el=currentCell->nearestForm(mouseDrawingPos);
	   		if (el!=NULL)
	   		if (el->thisElement!=NULL){
				paintNode=el->thisElement->getNode();
				modestep=1;
				//printf("-> paint Node %d\n",paintNode);
				paint();
				}
			mutexReadUnlock();
		}
	break;
case 180: //ruler
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		pointarray.resize(1);
		pointarray.setPoint(0,snap(mouseDrawingPos));
		modestep=1;
	}
	else if ((e->button()==Qt::LeftButton)&&((e->modifiers()==Qt::ControlModifier)||
	   (e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier))){
		prepareUndo();
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(2);
		if (e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier) 
		  mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
		pointarray.setPoint(1,mouseDrawingPos);
		f=currentCell->addPath(pointarray,activeLayer);
		f->setCap(0);
		f->setWidth(0);
		if (autorepaint)drawElement(f);
		double dx=pointarray.point(1).x()-pointarray.point(0).x();
		double dy=pointarray.point(1).y()-pointarray.point(0).y();
		double dist=sqrt(dx*dx+dy*dy);
		QPoint
		p=QPoint((pointarray.point(1).x()+pointarray.point(0).x())/2,(pointarray.point(1).y()+pointarray.point(0).y())/2);
		QString s;
		s=s.setNum(dist*userunits,'g',6);
		f=currentCell->addText(activeLayer,p,s);
		f->setWidth(-setup::fontSize);
		f->setPresentation(1);
		double
		ang=element::angle(pointarray.point(1),pointarray.point(0));
		if (ang<0) {ang+=360;}
		if ((ang>90)&&(ang<270)) {ang-=180;};
		f->rotate(ang);
		if (autorepaint)drawElement(f);
		modestep=0;
		repaint();
		}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 181: //length measurement
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		repaint();
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		modestep=0;
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep>1) mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(modestep-2));
		pointarray.resize(modestep);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		repaint();
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier)) {
		if (modestep>=1) {
			modestep--;
			pointarray.resize(modestep);
			repaint();
			}
		}
	break;
case 183: //element size
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		elementExcluded.clear();
		if (elementUsed!=NULL) 
			if (elementUsed->thisElement!=NULL){
				elementExcluded<<(elementUsed->thisElement);
				modestep=1;
				}
			else modestep=0;
		else modestep=0;
	}
	break;
case 185: //angle
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		if (modestep==0) {
			pointarray.resize(1);
			pointarray.setPoint(0,snap(mouseDrawingPos));
			modestep=1;}
		else if (modestep==1){
			pointarray.resize(2);
			pointarray.setPoint(1,snap(mouseDrawingPos));
			modestep=2;}
		else if (modestep>1){
			pointarray.resize(1);
			pointarray.setPoint(0,snap(mouseDrawingPos));
			modestep=1;}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 188: //circleFit
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		repaint();
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		if (modestep>1)
			if (mutexAddGuiTryLock()){
			prepareUndo();
			f=currentCell->addPolygon(element::fitToCircle(pointarray),activeLayer);
			if (autorepaint) drawElement(f);//f->paint(pixmap);
			for (int i=0; i<modestep;i++){
				macroAdd("layout->drawing->point("+str(pointarray.point(i))+");");}
			macroAdd("layout->drawing->circleFit();");
			mutexAddUnlock();
			}
		modestep=0;
		setModifyAdded();
		repaint();
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier)) {
		if (modestep>=1) {
			modestep--;
			mouseDrawingPos=snap(mouseDrawingPos);
			pointarray.resize(modestep);
			repaint();
			}
		}
	break;
case 189: //circle box
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		if (modestep==2){
		     if (mutexAddGuiTryLock()){
			QPoint pc=(pointarray.point(0)+pointarray.point(1))/2;
			QPoint pr=pointarray.point(0)-pointarray.point(1);
			int r=abs(pr.x());
			if (abs(pr.y())<r) r=abs(pr.y());
			pr=pc+QPoint(r/2,0);
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(1))+");");
			macroAdd("layout->drawing->circleBox();");
			prepareUndo();
			pointarray=element::spirale(pc,pr,pr,setup::circularDefault);
			f=currentCell->addPolygon(pointarray,activeLayer);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			setModifyAdded();
			mutexAddUnlock();
			}
		}
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep==2) mouseDrawingPos=square(mouseDrawingPos,pointarray.point(0));
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		if (modestep==2){
		     if (mutexAddGuiTryLock()){
			QPoint pc=(pointarray.point(0)+pointarray.point(1))/2;
			QPoint pr=pointarray.point(0)-pointarray.point(1);
			int r=abs(pr.x());
			if (abs(pr.y())<r) r=abs(pr.y());
			pr=pc+QPoint(r/2,0);
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(1))+");");
			macroAdd("layout->drawing->circleBox();");
			prepareUndo();
			pointarray=element::spirale(pc,pr,pr,setup::circularDefault);
			f=currentCell->addPolygon(pointarray,activeLayer);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			setModifyAdded();
			mutexAddUnlock();
			}
		}
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier+Qt::ShiftModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		if (modestep==2){
		     if (mutexAddGuiTryLock()){
			QPoint pc=(pointarray.point(0)+pointarray.point(1))/2;
			QPoint pr=pointarray.point(0)-pointarray.point(1);
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(1))+");");
			macroAdd("layout->drawing->ellipse();");
			prepareUndo();
			pointarray=element::ellipse(pc,pr.x()/2,pr.y()/2,setup::circularDefault);
			f=currentCell->addPolygon(pointarray,activeLayer);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			setModifyAdded();
			mutexAddUnlock();
			}
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 190: //spiral
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		if (modestep==3)
			if (mutexAddGuiTryLock()){
				macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
				macroAdd("layout->drawing->point("+str(pointarray.point(1))+");");
				macroAdd("layout->drawing->point("+str(pointarray.point(2))+");");
				macroAdd("layout->drawing->spiral();");
				prepareUndo();
				pointarray=element::spirale(pointarray.point(0),pointarray.point(1),pointarray.point(2),setup::circularDefault);
				f=currentCell->addPath(pointarray,activeLayer);
				if (autorepaint)drawElement(f);// f->paint(pixmap);
				modestep=0;
				update();
				setModifyAdded();
				mutexAddUnlock();
			}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 191: //circle
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		if (modestep==2){
		     if (mutexAddGuiTryLock()){
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(1))+");");
			macroAdd("layout->drawing->circle();");
			prepareUndo();
			pointarray=element::spirale(pointarray.point(0),pointarray.point(1),pointarray.point(1),setup::circularDefault);
			f=currentCell->addPolygon(pointarray,activeLayer);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			setModifyAdded();
			mutexAddUnlock();
			}
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 192: //sector
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		if (modestep==3){
		    if (mutexAddGuiTryLock()){
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(1))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(2))+");");
			macroAdd("layout->drawing->sector();");
			prepareUndo();
			pointarray.setPoint(2,(pointarray.point(2)-pointarray.point(0))*(element::distance(pointarray.point(0),pointarray.point(1))/element::distance(pointarray.point(0),pointarray.point(2)))+pointarray.point(0));
			QPoint p=pointarray.point(0);
			pointarray=element::spirale(pointarray.point(0),pointarray.point(1),pointarray.point(2),setup::circularDefault);
			int i=pointarray.size();
			pointarray.resize(i+2);
			pointarray.setPoint(i,p);
			pointarray.setPoint(i+1,pointarray.point(0));
			f=currentCell->addPolygon(pointarray,activeLayer);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			setModifyAdded();
			mutexAddUnlock();
			}
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 193: //arc
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		if (modestep==3){
		    if (mutexAddGuiTryLock()){
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(1))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(2))+");");
			macroAdd("layout->drawing->arc();");
			prepareUndo();
			pointarray.setPoint(2,(pointarray.point(2)-pointarray.point(0))*(element::distance(pointarray.point(0),pointarray.point(1))/element::distance(pointarray.point(0),pointarray.point(2)))+pointarray.point(0));
			QPoint p=pointarray.point(0);
			pointarray=element::spirale(pointarray.point(0),pointarray.point(1),pointarray.point(2),setup::circularDefault);
			f=currentCell->addPath(pointarray,activeLayer);
			if (autorepaint) drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			setModifyAdded();
			mutexAddUnlock();
			}
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		modestep=0;
		repaint();
	}
	break;	
case 194: //polygon arc
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		if (modestep==3){
		   if (mutexAddGuiTryLock()){
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(1))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(2))+");");
			macroAdd("layout->drawing->polygonArc();");
			prepareUndo();
			pointArray a=pointarray;
			pointArray b=pointarray;
			a.setPoint(2,(pointarray.point(2)-pointarray.point(0))*(element::distance(pointarray.point(0),pointarray.point(1))/element::distance(pointarray.point(0),pointarray.point(2)))+pointarray.point(0));
			a=element::spirale(a.point(0),a.point(1),a.point(2),setup::circularDefault);
			b.setPoint(1,(pointarray.point(1)-pointarray.point(0))*(element::distance(pointarray.point(0),pointarray.point(2))/element::distance(pointarray.point(0),pointarray.point(1)))+pointarray.point(0));
			b=element::spirale(b.point(0),b.point(1),b.point(2),setup::circularDefault);
			for (int i=0;i<b.size();i++){
				a.resize(a.size()+1);
				a.setPoint(a.size()-1,b.point(b.size()-1-i));
				}
			a.resize(a.size()+1);
			a.setPoint(a.size()-1,a.point(0));
			f=currentCell->addPolygon(a,activeLayer);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			setModifyAdded();
			mutexAddUnlock();
			}
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 195: //bezier2
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		if (modestep==3){
		    if (mutexAddGuiTryLock()){
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(1))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(2))+");");
			macroAdd("layout->drawing->bezier2();");
			prepareUndo();
			pointarray=element::bezier2(pointarray.point(0),pointarray.point(1),pointarray.point(2));
			f=currentCell->addPath(pointarray,activeLayer);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			setModifyAdded();
			mutexAddUnlock();
			}
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 196: //bezier3
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		if (modestep==4){
		    if (mutexAddGuiTryLock()){
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(1))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(2))+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(3))+");");
			macroAdd("layout->drawing->bezier3();");
			prepareUndo();
			pointarray=element::bezier3(pointarray.point(0),pointarray.point(1),pointarray.point(2),pointarray.point(3));
			f=currentCell->addPath(pointarray,activeLayer);
			if (autorepaint)drawElement(f);//f->paint(pixmap);
			modestep=0;
			update();
			setModifyAdded();
			mutexAddUnlock();
			}
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 200: // zoom
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		pointarray.resize(1);
		pointarray.setPoint(0,mouseDrawingPos);
		
	}
	break;
case 300: //mirror
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep==0){
			pointarray.resize(1);
			pointarray.setPoint(0,mouseDrawingPos);
			modestep=1;}
		else {  if (mutexChangeGuiTryLock()){
				prepareUndo();
				modestep=0;
				setModifyChanged();
				currentCell->mirrorSelect(mouseDrawingPos,pointarray.point(0));
				macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
				macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
				macroAdd("layout->drawing->mirror();");
				mutexChangeUnlock();
				paint();
				}
		}
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep==0){
			pointarray.resize(1);
			pointarray.setPoint(0,mouseDrawingPos);
			modestep=1;}
		else {
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
		  	if (mutexChangeGuiTryLock()){
				prepareUndo();
				modestep=0;
				setModifyChanged();
				currentCell->mirrorSelect(mouseDrawingPos,pointarray.point(0));
				macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
				macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
				macroAdd("layout->drawing->mirror();");
				mutexChangeUnlock();
				paint();
				}
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 308: //move x
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep==0){
		        modestep=1;
			pointarray.resize(1);
			pointarray.setPoint(0,mouseDrawingPos);
			}
		else if (mutexChangeGuiTryLock()){
			prepareUndo();
			modestep=0;
			setModifyChanged();
			currentCell->moveSelect(QPoint((mouseDrawingPos-pointarray.point(0)).x(),0));
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->moveX();");
			mutexChangeUnlock();
			paint();
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 309: //move y
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep==0){
		        modestep=1;
			pointarray.resize(1);
			pointarray.setPoint(0,mouseDrawingPos);
			}
		else if (mutexChangeGuiTryLock()){
			prepareUndo();
			modestep=0;
			setModifyChanged();
			currentCell->moveSelect(QPoint(0,(mouseDrawingPos-pointarray.point(0)).y()));
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->moveY();");
			mutexChangeUnlock();
			paint();
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 310: //move
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep==0){
		        modestep=1;
			pointarray.resize(1);
			pointarray.setPoint(0,mouseDrawingPos);
			}
		else if (mutexChangeGuiTryLock()){
			prepareUndo();
			modestep=0;
			setModifyChanged();
			currentCell->moveSelect(mouseDrawingPos-pointarray.point(0));
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->move();");
			mutexChangeUnlock();
			paint();
		}
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep==0){
			emit moveByRequest();
			}
		else if (mutexChangeGuiTryLock()){
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
			prepareUndo();
			modestep=0;
			setModifyChanged();
			currentCell->moveSelect(mouseDrawingPos-pointarray.point(0));
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->move();");
			mutexChangeUnlock();
			paint();
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		if (modestep==0) setMovePointMode();
	}
	break;
case 312: //move single point
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		if (modestep==0) {
			modestep=1;
			}
		else if (elementUsed!=NULL) {
			mouseDrawingPos=snap(mouseDrawingPos);
				if (mutexChangeGuiTryLock()){ 
				setModifyChanged();
				prepareUndo();
				elementUsed->thisElement->deselectAll();
				elementUsed->thisElement->pSelect(makeRect(pointarray.point(0),pointarray.point(0)));
				elementUsed->thisElement->moveSelect(mouseDrawingPos-pointarray.point(0));
				elementUsed->thisElement->deselectAll();
				currentCell->paintInfoClear();
				modestep=0;
				elementUsed=NULL;
				currentCell->paintInfoClear();
				mutexChangeUnlock();
				paint();
			}
		}
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		if (modestep==0) {
			if (elementUsed!=NULL) {
			QPoint p=pointarray.point(0);
			bool b=pointEntry::editPoint(this,&p);
			if (b)
				if (mutexChangeGuiTryLock()){ 
				setModifyChanged();
				prepareUndo();
				elementUsed->thisElement->deselectAll();
				elementUsed->thisElement->pSelect(makeRect(pointarray.point(0),pointarray.point(0)));
				elementUsed->thisElement->moveSelect(p-pointarray.point(0));
				elementUsed->thisElement->deselectAll();
				modestep=0;
				elementUsed=NULL;
				currentCell->paintInfoClear();
				mutexChangeUnlock();
				paint();
			}
		}}
		else if (elementUsed!=NULL) {
			mouseDrawingPos=snap(mouseDrawingPos);
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
				if (mutexChangeGuiTryLock()){ 
				setModifyChanged();
				prepareUndo();
				elementUsed->thisElement->deselectAll();
				elementUsed->thisElement->pSelect(makeRect(pointarray.point(0),pointarray.point(0)));
				elementUsed->thisElement->moveSelect(mouseDrawingPos-pointarray.point(0));
				elementUsed->thisElement->deselectAll();
				modestep=0;
				elementUsed=NULL;
				currentCell->paintInfoClear();
				mutexChangeUnlock();
				paint();
			}
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		if (modestep==0) {if (elementUsed!=NULL) {
			if (mutexReadTryLock()){
		        	elementUsed=currentCell->identicalPoint( elementUsed, pointarray.point(0));
				repaint();
				mutexReadUnlock();
				}
			}
			}
		else {
			modestep=0;
			elementUsed=NULL;
			repaint();
			}
	}
	break;
case 313: //insert point
	{
	bool add=false;
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		if (modestep==0) {
			modestep=1;
			}
		else if (elementUsed!=NULL){
			mouseDrawingPos=snap(mouseDrawingPos);
			add=true;
			}
		}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		if (modestep==0) {
			if (elementUsed!=NULL) {
			mouseDrawingPos=snap(mouseDrawingPos);
			add=pointEntry::editPoint(this,&mouseDrawingPos);
			
			}}
		else if (elementUsed!=NULL) {
			mouseDrawingPos=snap(mouseDrawingPos);
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
			add=true;
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		if (modestep==0) {
			}
		else {
			modestep=0;
			elementUsed=NULL;
			repaint();
			}
	}
	if ((add)&&(elementUsed!=NULL)) 
            if ((elementUsed->thisElement->isPath())|| (elementUsed->thisElement->isPolygon())){
		if (mutexChangeGuiTryLock()){ 
				setModifyChanged();
				prepareUndo();
				pointArray pa=elementUsed->thisElement->getPoints();
				if (pointarray.size()==2){
					for (int i=0;i<pa.size();i++){
						if (pa.point(i)==pointarray.point(0)){
							if (i>0) if (pa.point(i-1)==pointarray.point(1)){
								pa.insert(i,mouseDrawingPos);
								++i;
								}
							if (i<pa.size()-1) if (pa.point(i+1)==pointarray.point(1)){
								pa.insert(i+1,mouseDrawingPos);
								++i;
								}
						}
					}
				}
				else if ((pointarray.size()==1)&& (elementUsed->thisElement->isPath())){
					if (pa.point(0)==pointarray.point(0)) {
						pa.insert(0,mouseDrawingPos);
					}else pa<<mouseDrawingPos;
				}
				elementUsed->thisElement->setPoints(pa);
				modestep=0;
				elementUsed->thisElement->deselectAll();
				elementUsed=NULL;
				currentCell->paintInfoClear();
				mutexChangeUnlock();
				paint();
			}
	}
	}
	break;
case 315: //set Cell Origin
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if (mutexChangeGuiTryLock()) {
			resetUndo();
			modestep=1;
			pointarray.resize(1);
			pointarray.setPoint(0,mouseDrawingPos);
			moveOrigin();
			setModifyChanged();
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->moveOrigin();");
			mutexChangeUnlock();
			paint();}
	}
	break;
case 320: //Rotate
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		if (modestep==0){
			mouseDrawingPos=snap(mouseDrawingPos);
			QPoint mypos=mouseDrawingPos;
			//d=QInputDialog::getDouble(this,tr("Rotate"),tr("Enter Angle:"),0,-360,360,3,&b);
			QDialog di;
			QString s;
			userunitsValidator v(userunits,this);
			int decimals=v.decimals();
			Ui::rotateDialog dia;
			dia.setupUi(&di);
			dia.center->hide();
			dia.orginX->setValidator(new userunitsValidator(userunits,dia.orginX));
			dia.orginY->setValidator(new userunitsValidator(userunits,dia.orginY));
			s.setNum((double)(mypos.x())*userunits,'f',decimals);
			dia.orginX->setText(s);
			s.setNum((double)(mypos.y())*userunits,'f',decimals);
			dia.orginY->setText(s);
			di.show();
			int i=di.exec();
			d=dia.angle->value();
			if (dia.center->isHidden()==false){
				  mypos=QPoint(element::round(dia.orginX->text().toDouble()/userunits),element::round(dia.orginY->text().toDouble()/userunits));
			//printf("-(%f %f)-\n",dia.orginX->text().toDouble(),dia.orginY->text().toDouble());
			}
			di.hide();
			//printf("(%d %d)\n",mypos.x(),mypos.y());
			if (i==QDialog::Accepted) b=true;
			else b=false;
			if (b) if (mutexChangeGuiTryLock()) {
				prepareUndo();
				currentCell->rotateSelect(d,mypos);
				setModifyChanged();
				macroAdd("layout->drawing->point("+str(mypos)+");");
				macroAdd("layout->drawing->rotate("+str(d)+");");
				mutexChangeUnlock();
				modestep=0;
				paint();
			}
		}
		else if (modestep==1){
			mouseDrawingPos=snap(mouseDrawingPos);
			double angle=element::angle(QPoint(-100,0)+pointarray.point(0), pointarray.point(0),mouseDrawingPos);
			if (mutexChangeGuiTryLock()) {
				prepareUndo();
				currentCell->rotateSelect(angle,pointarray.point(0));
				setModifyChanged();
				macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
				macroAdd("layout->drawing->rotate("+str(angle)+");");
				mutexChangeUnlock();
				modestep=0;
				paint();
			}
		}
		else if (modestep==2){
			mouseDrawingPos=snap(mouseDrawingPos);
			double angle= element::angle(pointarray.point(0)+2*(pointarray.point(0)-pointarray.point(1)), pointarray.point(0), mouseDrawingPos);
			if (mutexChangeGuiTryLock()) {
				prepareUndo();
				currentCell->rotateSelect(angle,pointarray.point(0));
				setModifyChanged();
				macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
				macroAdd("layout->drawing->rotate("+str(angle)+");");
				mutexChangeUnlock();
				modestep=0;
				paint();
			}
		}

	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		bool add=true;
		if (modestep>0) if (mouseDrawingPos==pointarray.point(0)) add=false;
		if (modestep==2) {
			mouseDrawingPos= perpendicular(mouseDrawingPos,pointarray.point(0));
			double angle= element::angle(pointarray.point(0)+2*(pointarray.point(0)-pointarray.point(1)), pointarray.point(0), mouseDrawingPos);
			if (mutexChangeGuiTryLock()) {
				prepareUndo();
				currentCell->rotateSelect(angle,pointarray.point(0));
				setModifyChanged();
				macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
				macroAdd("layout->drawing->rotate("+str(angle)+");");
				mutexChangeUnlock();
				modestep=0;
				paint();
			}
			add=false;
			}
		if (add) {
			pointarray.resize(modestep+1);
			pointarray.setPoint(pointarray.size()-1,mouseDrawingPos);
			modestep++;
			}
	}
	break;
case 330: //copy
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep==0){
			pointarray.resize(1);
			pointarray.setPoint(0,snap(mouseDrawingPos));
			modestep=1;}
		else if (mutexChangeGuiTryLock()){	
			prepareUndo();
			modestep=0;
			setModifyAdded();
			currentCell->copySelect(mouseDrawingPos-pointarray.point(0));
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->copy();");
			recountSelect();
			mutexChangeUnlock();
			paint();
		}
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep==0){
			pointarray.resize(1);
			pointarray.setPoint(0,snap(mouseDrawingPos));
			modestep=1;}
		else if (mutexChangeGuiTryLock()){	
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
			prepareUndo();
			modestep=0;
			setModifyAdded();
			currentCell->copySelect(mouseDrawingPos-pointarray.point(0));
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->copy();");
			recountSelect();
			mutexChangeUnlock();
			paint();
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 340: //cut
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep==0){
			pointarray.resize(1);
			pointarray.setPoint(0,mouseDrawingPos);
			modestep=1;}
		else if (mutexChangeGuiTryLock()){	
			prepareUndo();
			modestep=0;
			setModifyChanged();
			currentCell->cutSelect(mouseDrawingPos,pointarray.point(0));
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->cut();");
			recountSelect();
			mutexChangeUnlock();
			paint();
		}
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)) {
		mouseDrawingPos=snap(mouseDrawingPos);
		if (modestep==0){
			pointarray.resize(1);
			pointarray.setPoint(0,mouseDrawingPos);
			modestep=1;}
		else if (mutexChangeGuiTryLock()){	
			mouseDrawingPos=perpendicular(mouseDrawingPos,pointarray.point(0));
			prepareUndo();
			modestep=0;
			setModifyChanged();
			currentCell->cutSelect(mouseDrawingPos,pointarray.point(0));
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->point("+str(mouseDrawingPos)+");");
			macroAdd("layout->drawing->cut();");
			recountSelect();
			mutexChangeUnlock();
			paint();
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 350: //scale
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		modestep++;
		mouseDrawingPos=snap(mouseDrawingPos);
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,mouseDrawingPos);
		emit mousePosChange(mouseDrawingPos);
		if (modestep==2){
			if (pointarray.point(0)==pointarray.point(1)) modestep--;
			}
		if (modestep==3)if (mutexChangeGuiTryLock()){
				prepareUndo();
				modestep=0;
				setModifyChanged();
				currentCell->scaleSelect(pointarray.point(0),pointarray.point(1),pointarray.point(2));
				macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
				macroAdd("layout->drawing->point("+str(pointarray.point(1))+");");
				macroAdd("layout->drawing->point("+str(pointarray.point(2))+");");
				macroAdd("layout->drawing->scale();");
				mutexChangeUnlock();
				paint();
		}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))) {
		modestep=0;
		repaint();
	}
	break;
case 400: //properties
	if (((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier))||	((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier))) {
		bool basic=false;
		if (e->modifiers()==Qt::ShiftModifier+Qt::ControlModifier) basic=true;
		if (mutexChangeGuiTryLock()){
		setCursor(QCursor(Qt::ForbiddenCursor));
		prepareUndo();
		if (elementUsed!=NULL) 
		  if (elementUsed->thisElement!=NULL) {
		   elementUsedLocked=true;
		   setModifyChanged();
		   if (elementUsed->thisElement->showProperties(elementUsed,this,basic)){
			delete elementUsed->thisElement;
			elementUsed->thisElement=NULL;
			currentCell->clean();
			};
		    currentCell->paintInfoClear();
		   }
		setCursor(QCursor(Qt::BlankCursor));
		deselectAll();
		recountSelect();
		mutexChangeUnlock();
		setFocus();
		paint();
		elementUsedLocked=false;
		elementUsed=NULL;}
	}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
		((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) 
		{if (elementUsed!=NULL) {
			if (mutexReadTryLock()){
		        	if (!elementUsedLocked)
					{
					//printf("search %d %d\n",pointarray.point(0).x(),pointarray.point(0).y());
					elementUsed=currentCell->identicalElementPoint( elementUsed, pointarray.point(0));
					}
				//else printf("locked\n");
				repaint();
				mutexReadUnlock();
				}
			prepareOutput();
			}
			
		else {
			modestep=0;
			repaint();
		}
		}
	else if((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier))
	  setInsertPointMode();
	break;
case 590: //adjust background picture
#ifdef backgroundutility
	if (bgModule==NULL)break;
        if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)){
	  if ((bgModule->currentImage>=0)&&(bgModule->currentImage<bgModule->background.size())) {
	        modestep=1;
		pointarray.resize(2);
		pointarray.setPoint(0,mouseDrawingPos);
		pointarray.setPoint(1,QPoint((int)bgModule->background.at(bgModule->currentImage).x,(int)bgModule->background.at(bgModule->currentImage).y));
	  }}
	else if (((e->button()==Qt::MidButton)&&(e->modifiers()==Qt::NoModifier))||
	    ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ControlModifier))) {
		modestep=2;
		pointarray.resize(2);
		pointarray.setPoint(0,mouseDrawingPos);
		// scale
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier)){
	        modestep=3;
		pointarray.resize(2);
		pointarray.setPoint(0,mouseDrawingPos);
		//rotate
	}
	else if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::ShiftModifier|Qt::ControlModifier)){
	        modestep=4;
		pointarray.resize(2);
		pointarray.setPoint(0,mouseDrawingPos);
		//shear
	}
	break;
case 591: //choose color for background
	if (bgModule==NULL)break;
        if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)){
	  bgModule->colorChoosen(mouseDrawingPos);
	}
#endif
        break;
case 600://select cell to view
	if ((e->button()==Qt::LeftButton)&&(e->modifiers()==Qt::NoModifier)) {
		QString cn="";
		if (mutexReadTryLock()){
			  if (elementUsed!=NULL)
			    if (elementUsed->thisElement!=NULL){
				cn=elementUsed->thisElement->depend()->cellName;
				}
			   mutexReadUnlock();
			}
		setCellGui(cn);
	}
	break;
default:
	if (mode>600) modeHandler->mousePressed();
}

setMouseHelp();
 // printf("mousepressed end\n");
}

void drawingField::contextMainMenu(){
emit rightclick();
}

void drawingField::contextProperties(){
	if (mutexChangeGuiTryLock()){
		setCursor(QCursor(Qt::ForbiddenCursor));
		prepareUndo();
		if (elementUsed!=NULL) 
		  if (elementUsed->thisElement!=NULL) {
		   elementUsedLocked=true;
		   setModifyChanged();
		   if (elementUsed->thisElement->showProperties(elementUsed,this,false)){
			delete elementUsed->thisElement;
			elementUsed->thisElement=NULL;
			currentCell->clean();
			};
		    currentCell->paintInfoClear();
		   }
		setCursor(QCursor(Qt::BlankCursor));
		recountSelect();
		mutexChangeUnlock();
		paint();
		elementUsedLocked=false;
		elementUsed=NULL;
	}
}
void drawingField::contextMoveScale(){
mode=0;
modestep=2;
if (mutexReadGuiTryLock()){
	contextAddElementUsed();
	prepareUndo();
	pointarray.resize(10);
	QPoint max=QPoint(INT_MIN,INT_MIN);
  	QPoint min=QPoint(INT_MAX,INT_MAX);
  	currentCell->minimumSelect(&min);
  	currentCell->maximumSelect(&max);
	pointarray.setPoint(0,min);
	pointarray.setPoint(1,max);
	pointarray.setPoint(2,mouseDrawingPos);
	pointArray pa;
	pa<<pointarray.point(0);
	pa<<QPoint(pointarray.point(0).x(),pointarray.point(1).y());
	pa<<pointarray.point(1);
	pa<<QPoint(pointarray.point(1).x(),pointarray.point(0).y());
	pa<<(pa.point(0)+pa.point(1))/2;
	pa<<(pa.point(2)+pa.point(1))/2;
	pa<<(pa.point(2)+pa.point(3))/2;
	pa<<(pa.point(0)+pa.point(3))/2;
	pa<<(pa.point(0)+pa.point(2))/2;
	pointarray<<pa;
	mutexReadUnlock();
}
}

void drawingField::contextCopyMove(){
mode=0;
modestep=2;
if (mutexReadGuiTryLock()){
	contextAddElementUsed();
	prepareUndo();
	currentCell->copySelect();
	setModifyChanged();
	pointarray.resize(10);
	QPoint max=QPoint(INT_MIN,INT_MIN);
  	QPoint min=QPoint(INT_MAX,INT_MAX);
  	currentCell->minimumSelect(&min);
  	currentCell->maximumSelect(&max);
	pointarray.setPoint(0,min);
	pointarray.setPoint(1,max);
	pointarray.setPoint(2,mouseDrawingPos);
	pointArray pa;
	pa<<pointarray.point(0);
	pa<<QPoint(pointarray.point(0).x(),pointarray.point(1).y());
	pa<<pointarray.point(1);
	pa<<QPoint(pointarray.point(1).x(),pointarray.point(0).y());
	pa<<(pa.point(0)+pa.point(1))/2;
	pa<<(pa.point(2)+pa.point(1))/2;
	pa<<(pa.point(2)+pa.point(3))/2;
	pa<<(pa.point(0)+pa.point(3))/2;
	pa<<(pa.point(0)+pa.point(2))/2;
	pointarray<<pa;
	modestep=3;
	pointarray.resize(4);
	pointarray.setPoint(2,pa.point(8));
	pointarray.setPoint(3,mouseDrawingPos);
	mutexReadUnlock();
}
}

void drawingField::contextGroup(){
if (mutexChangeGuiTryLock()){
   contextAddElementUsed();
   prepareUndo();
   group();
   recountSelect();
   emit cellsChange();
   mutexChangeUnlock();
   paint();
}
}

void drawingField::contextRotate(){
bool b;
double d=QInputDialog::getDouble(this,"Rotate","Enter Angle:",0,-360,360,3,&b);
if (b)
if (mutexChangeGuiTryLock()){
   contextAddElementUsed();
   QPoint max=QPoint(INT_MIN,INT_MIN);
   QPoint min=QPoint(INT_MAX,INT_MAX);
   currentCell->minimumSelect(&min);
   currentCell->maximumSelect(&max);
   prepareUndo();
   max=(min+max)/2;
   currentCell->rotateSelect(d,max);
   setModifyChanged();
   macroAdd("layout->drawing->point("+str(max)+");");
   macroAdd("layout->drawing->rotate("+str(d)+");");
   mutexChangeUnlock();
   paint();
}
}

void drawingField::contextMirror(){
if (mutexChangeGuiTryLock()){
   contextAddElementUsed();
   QPoint max=QPoint(INT_MIN,INT_MIN);
   QPoint min=QPoint(INT_MAX,INT_MAX);
   currentCell->minimumSelect(&min);
   currentCell->maximumSelect(&max);
   prepareUndo();
   max=(min+max)/2;
   min=max+QPoint(0,10);
   setModifyChanged();
   currentCell->mirrorSelect(max,min);
   macroAdd("layout->drawing->point("+str(max)+");");
   macroAdd("layout->drawing->point("+str(min)+");");
   macroAdd("layout->drawing->mirror();");
   mutexChangeUnlock();
   paint();
}
}

void drawingField::contextDelete(){
if (mutexChangeGuiTryLock()){
   contextAddElementUsed();
   prepareUndo();
   setModifyChanged();
   currentCell->deleteSelect();
   recountSelect();
   macroAdd("layout->drawing->currentCell->deleteSelect();");
   mutexChangeUnlock();
   paint();
}
}

void drawingField::contextToPolygon(){
if (mutexChangeGuiTryLock()){
   contextAddElementUsed();
   prepareUndo();
   setModifyChanged();
   currentCell->toPolygonSelect();
   recountSelect();
   macroAdd("layout->drawing->currentCell->toPolygonSelect();");
   mutexChangeUnlock();
   paint();
}
}

void drawingField::contextMoveLayer(){
if (mutexChangeGuiTryLock()){
   contextAddElementUsed();
   prepareUndo();
   setModifyChanged();
   currentCell->moveToLayerSelect(activeLayer);
   macroAdd("layout->drawing->currentCell->moveToLayerSelect(layout->drawing->activeLayer);");
   mutexChangeUnlock();
   paint();
}
}

void drawingField::contextAddElementUsed(){
elementCount ec1=currentCell->countSelect();
int i=ec1.box+ec1.cellref+ec1.cellrefarray+ec1.path+ec1.polygon+ec1.text;
if (i==0){
	elementList *el=elementUsed;
	if (el!=NULL)
	if (el->thisElement!=NULL){
		el->thisElement->selectAll();
		}
	recountSelect();	
	}
}

void drawingField::mouseReleaseEvent(QMouseEvent *e){
 //     printf("mousereleased\n");
  mousePos=e->pos();
  mouseButton=e->buttons();
  mouseModifiers=e->modifiers();
  //printf("%d\n",mouseModifiers/(1<<16));
  QPoint pos=getDUnits(e->pos());
    if (e->button()&Qt::RightButton){
  	if (!mousemove) {
		if ((mode!=0)&&(mode!=10)&&(mode!=15)&&(mode!=20)&&(mode!=25)&&(mode!=30)&&(mode!=35))
			emit rightclick();
		else if (modestep<2){
			elementCount ec1=currentCell->countSelect();
			int sum=ec1.box+ec1.cellref+ec1.cellrefarray+ec1.path+ec1.polygon+ec1.text;
			bool b=false;
			if (elementUsed!=NULL) if (elementUsed->thisElement!=NULL) b=true;
			bool c=b;
			if (sum>0) c=true;
			QMenu menu;
			if (c) menu.addAction(helpWindow::getIcon(setMoveModeHelp),tr("Move/Scale"),this,SLOT(contextMoveScale()));
			if (c) menu.addAction(helpWindow::getIcon(setCopyModeHelp),tr("Copy/Move"),this,SLOT(contextCopyMove()));
			if (c) menu.addAction(helpWindow::getIcon(groupHelp),tr("Group"),this,SLOT(contextGroup()));
			if (c) menu.addAction(helpWindow::getIcon(setRotateModeHelp),tr("Rotate"),this,SLOT(contextRotate()));
			if (c) menu.addAction(helpWindow::getIcon(setMirrorModeHelp),tr("Mirror"),this,SLOT(contextMirror()));
			if (c) menu.addAction(helpWindow::getIcon(deleteHelp),tr("Delete"),this,SLOT(contextDelete()));
			if (c) menu.addAction(helpWindow::getIcon(moveToLayerHelp),tr("Move to active Layer"),this,SLOT(contextMoveLayer()));
			//menu.addAction(tr("Main Menu"),this,SLOT(contentsMainMenu()));
			//menu.exec(QCursor::pos());
			emit rightclick(&menu);
			menu.exec(QCursor::pos());
		}
			else emit rightclick();
	}
  }
  if (dragTimer.isActive () ) { //drag
	dragTimer.stop();
	}
  if (e->button()==Qt::LeftButton) {
	if (pointarray.size()==1)
 	switch (mode) {
	case 0: //default
		if (modestep<2){
		    modestep=1;
		    if (mutexReadTryLock()){
		    	if (pointarray.point(0)!=pos) { // select in window
				if (mouseStatus==0){ // one point in rect
					deselectAll();
					currentCell->fSelect(makeRect(pos,pointarray.point(0)));
					currentCell->cSelect(makeRect(pos,pointarray.point(0)));
					macroAdd("layout->drawing->deselectAll();");
					macroAdd("layout->drawing->point("+str(pos)+");");
					macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
					macroAdd("layout->drawing->fSelect();");
					macroAdd("layout->drawing->point("+str(pos)+");");
					macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
					macroAdd("layout->drawing->cSelect();");
					recountSelect();
					}
				else if (mouseStatus==2){ //window add to selection
					currentCell->fSelect(makeRect(pos,pointarray.point(0)));
					currentCell->cSelect(makeRect(pos,pointarray.point(0)));
					macroAdd("layout->drawing->point("+str(pos)+");");
					macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
					macroAdd("layout->drawing->fSelect();");
					macroAdd("layout->drawing->point("+str(pos)+");");
					macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
					macroAdd("layout->drawing->cSelect();");
					recountSelect();
					}
				elementUsed=NULL;
				}
			else { 
				if (mouseStatus==0){
					deselectAll();
					elementList *el=elementUsed;
					if (el!=NULL)
					if (el->thisElement!=NULL){
						el->thisElement->selectAll();
						}
					macroAdd("layout->drawing->deselectAll();");
					macroAdd("layout->drawing->point("+str(pos)+");");
					macroAdd("layout->drawing->fSelect();");
					macroAdd("layout->drawing->point("+str(pos)+");");
					macroAdd("layout->drawing->cSelect();");
					recountSelect();	
				} 
				else if (mouseStatus==2){
					elementList *el=elementUsed;
					if (el!=NULL)
					if (el->thisElement!=NULL){
						el->thisElement->selectAll();
						}
					macroAdd("layout->drawing->point("+str(pos)+");");
					macroAdd("layout->drawing->fSelect();");
					macroAdd("layout->drawing->point("+str(pos)+");");
					macroAdd("layout->drawing->cSelect();");
					recountSelect();	
				} 
			}
		        mutexReadUnlock();
			}
		    paint();
		} else {
			//move/scale
		}
		break;
	case 10: //fselect
		if (mouseStatus>=0)
		if (mutexReadTryLock()){
			if (mouseStatus%2==1) {
				currentCell->deselectAll();
				mouseStatus--;
				macroAdd("layout->drawing->deselectAll();");
				}
		if (pointarray.point(0)!=pos) {
			if (mouseStatus==0){ // one point in rect
				currentCell->fSelect(makeRect(pos,pointarray.point(0)));
				macroAdd("layout->drawing->point("+str(pos)+");");
				macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
				macroAdd("layout->drawing->fSelect();");
				recountSelect();
			}
			else if (mouseStatus==2){  // all points in rect
				currentCell->fAllSelect(makeRect(pos,pointarray.point(0)));
				macroAdd("layout->drawing->point("+str(pos)+");");
				macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
				macroAdd("layout->drawing->fAllSelect();");
				recountSelect();
				}
			}
                else  {
			elementList *el=currentCell->nearestForm(pos);
	   		if (el!=NULL)
	   		if (el->thisElement!=NULL){
				el->thisElement->selectAll();
				}
			macroAdd("layout->drawing->point("+str(pos)+");");
			macroAdd("layout->drawing->fSelect();");
			recountSelect();
			
			}
		mutexReadUnlock();}
		paint();
		break;
	case 15: //fdeselect
		if (mouseStatus>=0)
		if (mutexReadTryLock()){
			if (mouseStatus%2==1) {
				currentCell->selectAll();
				mouseStatus--;
				macroAdd("layout->drawing->selectAll();");
				}
			if (pointarray.point(0)!=pos) {
				if (mouseStatus==0){ // one point in rect
					currentCell->fDeselect(makeRect(pos,pointarray.point(0)));
					macroAdd("layout->drawing->point("+str(pos)+");");
					macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
					macroAdd("layout->drawing->fDeselect();");
					recountSelect();
				}
				else if (mouseStatus==2){  // all points in rect
					currentCell->fAllDeselect(makeRect(pos,pointarray.point(0)));
					macroAdd("layout->drawing->point("+str(pos)+");");
					macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
					macroAdd("layout->drawing->fAllDeselect();");
					recountSelect();
					}
				}
                	else {
				elementList *el=currentCell->nearestForm(pos);
				if (el!=NULL)
				if (el->thisElement!=NULL){
					el->thisElement->deselectAll();
					}
				macroAdd("layout->drawing->point("+str(pos)+");");
				macroAdd("layout->drawing->fDeselect();");
				recountSelect();}
			mutexReadUnlock();
			}
                paint();
		break;
	case 20: //pselect
		if (mouseStatus>=0)
		if (pointarray.point(0)!=pos) {
		    if (mutexReadTryLock()){
			if (mouseStatus>0) {
				currentCell->deselectAll();
				macroAdd("layout->drawing->deselectAll();");
				}
			currentCell->pSelect(makeRect(pos,pointarray.point(0)));
			macroAdd("layout->drawing->point("+str(pos)+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->pSelect();");
			recountSelect();
			mutexReadUnlock();
			}}
                else if (mutexReadTryLock()){
			if (mouseStatus>0) {
				currentCell->deselectAll();
				macroAdd("layout->drawing->deselectAll();");
				}
			QPoint p_;
			elementList *el;
			el=currentCell->nearestPoint(pos,&p_);
			currentCell->pSelect(makeRect(p_,p_));
			macroAdd("layout->drawing->point("+str(pos)+");");
			macroAdd("layout->drawing->pSelect();");
			recountSelect();
			mutexReadUnlock();
	   		/*if (el!=NULL)
	   		if (el->this_element!=NULL){
				el->this_element->pSelect(makeRect(p_,p_));
				}*/
			}
                paint();
		break;
	case 25: //pdeselect
		if (mouseStatus>=0)
 		if (pointarray.point(0)!=pos) {
		   if (mutexReadTryLock()){
			if (mouseStatus>0) {
				currentCell->selectAll();
				macroAdd("layout->drawing->selectAll();");
				}
			currentCell->pDeselect(makeRect(pos,pointarray.point(0)));
			macroAdd("layout->drawing->point("+str(pos)+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->pDeselect();");
			recountSelect();
			mutexReadUnlock();
			}}
                else if (mutexReadTryLock()){
			if (mouseStatus>0) {
				currentCell->selectAll();
				macroAdd("layout->drawing->selectAll();");
				}
			QPoint p_;
			elementList *el;
			el=currentCell->nearestPoint(pos,&p_);
			currentCell->pDeselect(makeRect(p_,p_));
			macroAdd("layout->drawing->point("+str(pos)+");");
			macroAdd("layout->drawing->pDeselect();");
			recountSelect();
			mutexReadUnlock();
	   		/*if (el!=NULL)
	   		if (el->this_element!=NULL){
				el->this_element->pDeselect(makeRect(p_,p_));
				}*/
			}
                paint();
		break;
	case 30: //cselect
		if (mouseStatus==5){
			if (mutexReadTryLock()){
				//printf("pressed %d \n",mouseStatus);
					//printf("po shift %d %d\n",mouseButton,Qt::LeftButton);
				if (elementUsed!=NULL) elementExcluded<<elementUsed->thisElement;
				elementUsed=currentCell->nearestCell(mouseDrawingPos,elementExcluded);
				if (elementUsed!=NULL) {
					cell *c=elementUsed->thisElement->depend();
					if (c!=NULL) {emit message(c->cellName);}
					}	
				mutexReadUnlock();
				repaint();
				}}
		else {
		if (mouseStatus>=0)
		if (pointarray.point(0)!=pos) {
		   if (mutexReadTryLock()){
			if (mouseStatus>0) {
				currentCell->deselectAll();
				macroAdd("layout->drawing->deselectAll();");
				}
			currentCell->cSelect(makeRect(pos,pointarray.point(0)));
			macroAdd("layout->drawing->point("+str(pos)+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->cSelect();");
			recountSelect();
			mutexReadUnlock();
			}
			}
                else if (mutexReadTryLock()){
			if (mouseStatus>0) {
				currentCell->deselectAll();
				macroAdd("layout->drawing->deselectAll();");
				}
			mouseStatus=0;
			elementList *el=elementUsed;
			if (elementUsed==NULL) el=currentCell->nearestCell(pos);
			elementExcluded.clear();
			if (el!=NULL)
			if (el->thisElement!=NULL){
				el->thisElement->selectAll();
				}
			elementUsed=NULL;
			macroAdd("layout->drawing->point("+str(pos)+");");
			macroAdd("layout->drawing->cSelect();");
			recountSelect();
			mutexReadUnlock();
			}
                paint();}
		break;
	case 35: //cdeselect
		if (mouseStatus==5){
			if (mutexReadTryLock()){
				//printf("pressed %d \n",mouseStatus);
					//printf("po shift %d %d\n",mouseButton,Qt::LeftButton);
				if (elementUsed!=NULL) elementExcluded<<elementUsed->thisElement;
				elementUsed=currentCell->nearestCell(mouseDrawingPos,elementExcluded);
				if (elementUsed!=NULL) {
					cell *c=elementUsed->thisElement->depend();
					if (c!=NULL) {emit message(c->cellName);}
					}	
				mutexReadUnlock();
				repaint();
				}}
		else {
		if (mouseStatus>=0)
		if (pointarray.point(0)!=pos) {
		   if (mutexReadTryLock()){
			if (mouseStatus>0) {
				currentCell->selectAll();
				macroAdd("layout->drawing->selectAll();");
				}
			currentCell->cDeselect(makeRect(pos,pointarray.point(0)));
			macroAdd("layout->drawing->point("+str(pos)+");");
			macroAdd("layout->drawing->point("+str(pointarray.point(0))+");");
			macroAdd("layout->drawing->cDeselect();");
			recountSelect();
			mutexReadUnlock();
			}}
                else if (mutexReadTryLock()){
			if (mouseStatus>0) {
				currentCell->selectAll();
				macroAdd("layout->drawing->selectAll();");
				}
			elementList *el=elementUsed;
			if (elementUsed==NULL) el=currentCell->nearestCell(pos);
			elementExcluded.clear();
	   		if (el!=NULL)
	   		if (el->thisElement!=NULL){
				el->thisElement->deselectAll();
				}
			elementUsed=NULL;
			macroAdd("layout->drawing->point("+str(pos)+");");
			macroAdd("layout->drawing->cDeselect();");
			recountSelect();
			mutexReadUnlock();
			}
                paint();
		}
		break;
	case 200: //zoom
		if (pos!=pointarray.point(0)){
		     if ((pos.x()>=pointarray.point(0).x())){
			QPoint max,min;
			if (pos.x()>pointarray.point(0).x()){min.setX(pointarray.point(0).x());max.setX(pos.x());}
			else {max.setX(pointarray.point(0).x());min.setX(pos.x());}
			if (pos.y()>pointarray.point(0).y()){min.setY(pointarray.point(0).y());max.setY(pos.y());}
			else {max.setY(pointarray.point(0).y());min.setY(pos.y());}
			pixmap->scaleMutex.lock();
			double scale1=(this->height()-10)/((double)max.y()-(double)min.y());
 			double scale2=(this->width()-10)/((double)max.x()-(double)min.x());
 			if (scale1>scale2){scale1=scale2;}
 			if (scale1>12) {scale1=12;}
 			if (scale1<=0){scale1=1;}
 			pixmap->setScale(scale1,(int)(-(max.x()+min.x())/2+width()/2/scale1),(int)((max.y()+min.y())/2+height()/2/scale1));
			pixmap->scaleMutex.unlock();
			setAutoGrid();
 			paint();}
		     else {  //zoomout
			QPoint max,min;
			if (pos.x()>pointarray.point(0).x()){ min.setX(pointarray.point(0).x());max.setX(pos.x());}
			else {max.setX(pointarray.point(0).x());min.setX(pos.x());}
			if (pos.y()>pointarray.point(0).y()){min.setY(pointarray.point(0).y());max.setY(pos.y());}
			else {max.setY(pointarray.point(0).y());min.setY(pos.y());}
			QPoint min_=pixmap->trans.mapDraw(min);
			QPoint max_=pixmap->trans.mapDraw(max);
			double dif=(((double)max_.x()-(double)min_.x())-((double)max_.y()-(double)min_.y()));
			pixmap->scaleMutex.lock();
			double scale;
			int xh_,yh_;
			pixmap->getScale(&scale,&xh_,&yh_);
			double scale1=scale/((double)(width())+(double)(height()))*dif;
			if (scale1>5) {scale1=5;}
 			if (scale1<=0){scale1=1;}
			//printf("%f %f %f %d\n",scale,scale1,dif,width()+height());
 			pixmap->setScale(scale1,(int)(-(max.x()+min.x())/2+width()/2/scale1),(int)((max.y()+min.y())/2+height()/2/scale1));
			pixmap->scaleMutex.unlock();
			setAutoGrid();
 			paint();
			}
		}
		else scalePlus();
		break;
	}
	switch (mode){
	  case 590: //adjust background picture
#ifdef backgroundutility
	    if (bgModule==NULL) break;
	    if ((bgModule->currentImage>=0)&&(bgModule->currentImage<bgModule->background.size())){
		QPoint p=pointarray.point(1);
		p+=mouseDrawingPos-pointarray.point(0);
		int i=bgModule->currentImage;
		if (modestep==1)
		    bgModule->backgroundOffset(bgModule->currentImage,p.x(),p.y());
		p=mouseDrawingPos-pointarray.point(0);;
		if (modestep==2) bgModule->backgroundScale(bgModule->currentImage,bgModule->background.at(i).sx+(double)p.x()/1000.0,bgModule->background.at(i).sy-(double)p.y()/1000.0);
	        if (modestep==4) bgModule->backgroundShear(bgModule->currentImage,bgModule->background.at(i).shx+(double)p.x()/1000000.0,bgModule->background.at(i).shy+(double)p.y()/1000000.0);
		if (modestep==3) bgModule->backgroundRotate(bgModule->currentImage,bgModule->background.at(i).angle-(double)(p.x()+p.y())/10000.0);
		modestep=0;
		bgModule->updateRequest=true;
		update();
	    }
#endif
	    break;
	}
	}
	if (mode>600) {
		mouseButton=e->button();
		modeHandler->mouseReleased();	
		mouseButton=e->buttons();
		}
  //    printf("mousereleased end\n");
}
/*
bool drawingField::routeModeAddPathpoint(QPoint p){
	//printf("add\n");
	if (modestep==0)return false;
	if (p==pointarray.point(modestep-1)) return false;
	bool add2Point=false;
	bool correctLastPoint=false;
	QPoint addPoint, correctPoint;
	if (routeAdjust){
		int space=layers::num[activeLayer].getTypeParameter(2);
		int width=layers::num[activeLayer].getTypeParameter(1)/2;
		QPoint p1=pointarray.point(modestep-1);
		QPoint p2=p;
		if (p1.x()<p.x()){
			p2.setX(p1.x());
			p1.setX(p.x());
		}
	    if (p1.y()<p.y()){
			p2.setY(p1.y());
			p1.setY(p.y());
		}
		if (p1.x()==p2.x()){
			int left,right;
			if (mutexAddGuiTryLock()) {
				left=currentCell->findEdge(p1+QPoint(-width-1,width), p2+QPoint(-width-2*space,-width),activeLayer,0)-p.x();
				right=currentCell->findEdge(p1+QPoint(+width+1,width), p2+QPoint(+width+2*space,-width),activeLayer,2)-p.x();
				mutexAddUnlock();
				}
			else return false;
			if (abs(left-right)<2*width+2*space)return false;
			if ((abs(left)<width+2*space)||(abs(right)<width+2*space)){
				//do adjust
				int newX=p.x();
				if (abs(left)<abs(right)){
					newX=left+p.x()+width+space;
				}else{
					newX=right+p.x()-width-space;
				}
				correctLastPoint=true;
				correctPoint=pointarray[modestep-1];
				correctPoint.setX(newX);
				p.setX(newX);
				if (modestep>1) 
					if (pointarray.point(modestep-1).x() == pointarray.point(modestep-2).x()) {
						add2Point=true;
						addPoint=pointarray[modestep-1];
						addPoint.setX(newX);
						correctLastPoint=false;
					}
			}
		}
		if (p1.y()==p2.y()){
			int top,bottom;
			if (mutexAddGuiTryLock()) {
				top=currentCell->findEdge(p1+QPoint(width,width+2*space),p2+QPoint(-width,+width+1),activeLayer,3)-p.y();
				bottom=currentCell->findEdge(p1+QPoint(width,-width-1),p2+QPoint(-width,-width-2*space),activeLayer,1)-p.y();
				mutexAddUnlock();
				}
			else return false;
			if (abs(top-bottom)<2*width+2*space)return false;
			if ((abs(top)<width+2*space)||(abs(bottom)<width+2*space)){
				//do adjust
				int newY=p.y();
				if (abs(top)<abs(bottom)){
					newY=top+p.y()-width-space;
				}else{
					newY=bottom+p.y()+width+space;
				}
				correctLastPoint=true;
				correctPoint=pointarray[modestep-1];
				correctPoint.setY(newY);
				p.setY(newY);
				if (modestep>1) 
					if (pointarray.point(modestep-1).y()== pointarray.point(modestep-2).y()) {
						add2Point=true;
						addPoint=pointarray[modestep-1];
						addPoint.setY(newY);
						correctLastPoint=false;
					}
			}
		}
	}
	if (add2Point){
		modestep++;
		pointarray.resize(modestep+1);
		pointarray.setPoint(modestep-1,addPoint);
	}
	if (correctLastPoint) {
		pointarray.setPoint(modestep-1,correctPoint);
	}
	modestep++;
	pointarray.resize(modestep+1);
	pointarray.setPoint(modestep-1,p);
	pointarray.setPoint(modestep,p);
	emit mousePosChange(p);
	return true;
}
void drawingField::routeModeStartPath(QPoint p){
	//printf("start\n");
	modestep=1;
	pointarray.resize(modestep+1);
	pointarray.setPoint(modestep-1,p);
	pointarray.setPoint(modestep,p);
	emit mousePosChange(p);
}
void drawingField::routeModeEndPath(){
	//printf("end\n");
	prepareUndo();
	setModifyAdded();
	if (modestep>1)
	if (mutexAddGuiTryLock()) {
		pointarray.resize(modestep);
		element *f=currentCell->addPath(pointarray,activeLayer);
		f->setWidth(layers::num[activeLayer].getTypeParameter(1));
		if (autorepaint)drawElement(f);
		modestep=0;
		mutexAddUnlock();
	}else
		modestep=0;
}

bool drawingField::routeModeAddVia(QPoint p1, QPoint p2,bool dir,QPoint *pCenter){
	prepareUndo();
	setModifyAdded();
	int dirMulti=1;
	int difX=abs(p1.x()-p2.x());
	int difY=abs(p1.y()-p2.y());
	int centerX=(p1.x()+p2.x())/2;
	int centerY=(p1.y()+p2.y())/2;
	if (!dir) dirMulti=-1;
	int curLevel=layers::num[activeLayer].getTypeParameter(0);
	int viaLayer=layers::findLevel(curLevel+dirMulti);
	int newLayer=layers::findLevel(curLevel+dirMulti*2);
	//check setup errors
	if (viaLayer<0) return false;
	if (newLayer<0) return false;
	if (layers::num[viaLayer].layerType!=layerTypeVia)return false;
	if (layers::num[newLayer].layerType!=layerTypeConductor)return false;
	int viaType=layers::num[viaLayer].getTypeParameter(5);
	if (viaType<0) viaType=0;
	if (viaType>2) viaType=0;
	//check minimum size
	int minSizeCur=layers::num[viaLayer].getTypeParameter(1);
	if (dir) minSizeCur+=layers::num[viaLayer].getTypeParameter(3)*2;
	else minSizeCur+=layers::num[viaLayer].getTypeParameter(2)*2;
	int minSizeNew=layers::num[viaLayer].getTypeParameter(1);
	if (dir) minSizeNew+=layers::num[viaLayer].getTypeParameter(2)*2;
	else minSizeNew+=layers::num[viaLayer].getTypeParameter(3)*2;
	int sizeXCur=difX;
	if (difX<minSizeCur) sizeXCur=minSizeCur;
	int sizeYCur=difY;
	if (difY<minSizeCur) sizeYCur=minSizeCur;
	if (mutexAddGuiTryLock()) { 
		bool place=true;
		if (routeAdjust){
			int spaceCur=layers::num[activeLayer].getTypeParameter(2);
			int spaceNew=layers::num[newLayer].getTypeParameter(2);
			int widthCur=layers::num[activeLayer].getTypeParameter(1);
			int difCurNew=minSizeNew-minSizeCur;
			bool adjustLeft=false;
			bool adjustRight=false;
			bool adjustTop=false;
			bool adjustBottom=false;
			int leftGet=p1.x();
			if (p2.x()<leftGet) leftGet=p2.x();
			if (difX==0) leftGet-=widthCur/2;
			leftGet-=spaceCur/2;
			int rightGet=p1.x();
			if (p2.x()>rightGet) rightGet=p2.x();
			if (difX==0) rightGet+=widthCur/2;
			rightGet+=spaceCur/2;
			int bottomGet=p1.y();
			if (p2.y()<bottomGet) bottomGet=p2.y();
			if (difY==0) bottomGet-=widthCur/2;
			bottomGet-=spaceCur/2;
			int topGet=p1.y();
			if (p2.y()>topGet) topGet=p2.y();
			if (difY==0) topGet+=widthCur/2;
			topGet+=spaceCur/2;
			int helpPos;
			int left=currentCell->findEdge(QPoint(leftGet-1,topGet),
					QPoint(centerX-sizeXCur/2-2*spaceCur,bottomGet),activeLayer,0);
			if (left>centerX-sizeXCur/2-2*spaceCur) {
					adjustLeft=true;
					left+=spaceCur;
					}
			helpPos=currentCell->findEdge(QPoint(leftGet-1,topGet+difCurNew/2),
					QPoint(centerX-(sizeXCur+difCurNew)/2-2*spaceNew,bottomGet-difCurNew/2),newLayer,0);
			if (helpPos>centerX-(sizeXCur+difCurNew)/2-2*spaceNew){
					helpPos+=spaceNew+difCurNew/2;
					if (helpPos>left) left=helpPos;
					adjustLeft=true;
					}
			int right=currentCell->findEdge(QPoint(centerX+sizeXCur/2+2*spaceCur,topGet),
					QPoint(rightGet+1,bottomGet),activeLayer,2);
			if (right<centerX+sizeXCur/2+2*spaceCur) {
					adjustRight=true;
					right-=spaceCur;
					}
			helpPos=currentCell->findEdge(QPoint(centerX+(sizeXCur+difCurNew)/2+2*spaceNew,topGet+difCurNew/2),
					QPoint(rightGet+1,bottomGet-difCurNew/2),newLayer,2);
			if (helpPos<centerX+(sizeXCur+difCurNew)/2+2*spaceNew){
					helpPos-=spaceNew+difCurNew/2;
					if (helpPos<right) right=helpPos;
					adjustRight=true;
					}
			int top=currentCell->findEdge(QPoint(rightGet,centerY+sizeYCur/2+2*spaceCur),
					QPoint(leftGet,topGet+1),activeLayer,3);
			if (top<centerY+sizeYCur/2+2*spaceCur) {
					adjustTop=true;
					top-=spaceCur;
					}
			helpPos=currentCell->findEdge(QPoint(rightGet+difCurNew/2,centerY+(sizeYCur+difCurNew)/2+2*spaceNew),QPoint(leftGet-difCurNew/2,topGet+1),newLayer,3);
			if (helpPos<centerY+(sizeYCur+difCurNew)/2+2*spaceNew){
					helpPos-=spaceNew+difCurNew/2;
					if (helpPos<top) top=helpPos;
					adjustTop=true;
					}
			int bottom=currentCell->findEdge(QPoint(rightGet,bottomGet-1),
					QPoint(leftGet,centerY-sizeYCur/2-2*spaceCur),activeLayer,1);
			if (bottom>centerY-sizeYCur/2-2*spaceCur) {
					adjustBottom=true;
					bottom+=spaceCur;
					}
			helpPos=currentCell->findEdge(QPoint(rightGet+difCurNew/2,bottomGet-1),
					QPoint(leftGet-difCurNew/2,centerY-(sizeYCur+difCurNew)/2-2*spaceNew),newLayer,1);
			if (helpPos>centerY-(sizeYCur+difCurNew)/2-2*spaceNew){
					helpPos+=spaceNew+difCurNew/2;
					if (helpPos>bottom) bottom=helpPos;
					adjustBottom=true;
					}
			if (adjustLeft&&adjustRight){
				centerX=(left+right)/2;
				sizeXCur=right-left;
				if (sizeXCur<<minSizeCur) place=false;
				}
			else if (adjustLeft) {
				if (centerX+sizeXCur/2-left<minSizeCur){
					centerX=left+sizeXCur/2;
					sizeXCur=minSizeCur;
					}
				else {
					centerX=(left+centerX+sizeXCur/2)/2;
					sizeXCur=centerX+sizeXCur/2-left;
					}
				}
			else if (adjustRight) {
				if (right-centerX+sizeXCur/2<minSizeCur){
					centerX=right-sizeXCur/2;
					sizeXCur=minSizeCur;
					}
				else {
					centerX=(right+centerX-sizeXCur/2)/2;
					sizeXCur=right-centerX+sizeXCur/2;
					}
				}
			if (adjustTop&&adjustBottom){
				centerY=(bottom+top)/2;
				sizeYCur=top-bottom;
				if (sizeYCur<<minSizeCur) place=false;
				}
			else if (adjustBottom) {
				if (centerY+sizeYCur/2-bottom<minSizeCur){
					centerY=bottom+sizeYCur/2;
					sizeYCur=minSizeCur;
					}
				else {
					centerY=(bottom+centerY+sizeYCur/2)/2;
					sizeYCur=centerY+sizeYCur/2-bottom;
					}
				}
			else if (adjustTop) {
				if (top-centerY+sizeYCur/2<minSizeCur){
					centerY=top-sizeYCur/2;
					sizeYCur=minSizeCur;
					}
				else {
					centerY=(top+centerY-sizeYCur/2)/2;
					sizeYCur=top-centerY+sizeYCur/2;
					}
				}
			
			}
		if (place){
			if (viaType==2){
				//round via
				if (sizeYCur>sizeXCur) sizeYCur=sizeXCur;
				if (sizeXCur>sizeYCur) sizeXCur=sizeYCur;
			}
			element *f;
			if ((viaType==0)||(viaType==1)) // box conductor
				f=currentCell->addBox(centerX-sizeXCur/2,centerY-sizeYCur/2,
							sizeXCur,sizeYCur,activeLayer);	
			else //round conductor
				f=currentCell->addCircleBox(QPoint(centerX-sizeXCur/2,centerY-sizeYCur/2),
							QPoint(centerX+sizeXCur/2,centerY+sizeYCur/2),
							activeLayer);	
			if (autorepaint)drawElement(f);
			int borderCur=minSizeCur-layers::num[viaLayer].getTypeParameter(1);
			int sizeXVia=sizeXCur-borderCur;
			int sizeYVia=sizeYCur-borderCur;
			int minSizeVia=layers::num[viaLayer].getTypeParameter(1);
			int sr=minSizeVia+layers::num[viaLayer].getTypeParameter(4);
			// add possible vias in size
			if (viaType!=2){
				int nx=(sizeXVia-minSizeVia)/sr+1;
				int ny=(sizeYVia-minSizeVia)/sr+1;
				sizeXVia=(nx-1)*sr+minSizeVia;
				sizeYVia=(ny-1)*sr+minSizeVia;
				for (int ix=0;ix<nx;ix++)
					for(int iy=0;iy<ny;iy++){
						if (viaType==0) // box via
							f=currentCell->addBox(
								centerX-sizeXVia/2+ix*sr,
								centerY-sizeYVia/2+iy*sr,
								minSizeVia,minSizeVia,viaLayer);
						else //round via
							f=currentCell->addCircleBox(
								QPoint(centerX-sizeXVia/2+ix*sr,
								centerY-sizeYVia/2+iy*sr),
								QPoint(centerX-sizeXVia/2+ix*sr+minSizeVia,
								centerY-sizeYVia/2+iy*sr+minSizeVia),
								viaLayer);
						if (autorepaint)drawElement(f);
					}}
			else {
				// single round via;
				f=currentCell->addCircleBox(QPoint(centerX-minSizeVia/2,centerY-minSizeVia/2),
							QPoint(centerX+minSizeVia/2,centerY+minSizeVia/2),
							viaLayer);
				if (autorepaint)drawElement(f);	
			}
			int sizeXNew=sizeXVia;
			int sizeYNew=sizeYVia;
			if (dir) {
				sizeXNew+=layers::num[viaLayer].getTypeParameter(2)*2;
				sizeYNew+=layers::num[viaLayer].getTypeParameter(2)*2;
				}
			else {
				sizeXNew+=layers::num[viaLayer].getTypeParameter(3)*2;
				sizeYNew+=layers::num[viaLayer].getTypeParameter(3)*2;
			}
			if ((viaType==0)||(viaType==1))// box conductor
				f=currentCell->addBox(centerX-sizeXNew/2,centerY-sizeYNew/2,
								sizeXNew,sizeYNew,newLayer);
			else //round conductor
				f=currentCell->addCircleBox(QPoint(centerX-sizeXNew/2,centerY-sizeYNew/2),
							QPoint(centerX-sizeXNew/2,centerY-sizeYNew/2),
							newLayer);	
			if (autorepaint)drawElement(f);
			activeLayer=newLayer;
			emit activeLayerChanged();
			if (pCenter!=NULL) *pCenter=QPoint(centerX,centerY);
		}
		mutexAddUnlock();
		if (place) return true;
		
	}
	return false;
}
*/


// reset internal pointer
void drawingField::reset(){
  cell_ref=NULL;
  elementUsed=NULL;
  elementExcluded.clear();
  maxPoint=QPoint(0,0);
  minPoint=QPoint(0,0);
  mouseStatus=0;
  if (mode>600) modeHandler->init();
}

QPoint drawingField::getDUnits(QPoint pos){
  QMatrix invers=pixmap->trans.matrix.inverted();
  return invers.map(pos);
}

void drawingField::wheelEvent(QWheelEvent *e){
    //      printf("wheelEvent\n");
  pixmap->scaleMutex.lock();
  double scale=pixmap->trans.mag;
  double f=1.5;
  if (QApplication::keyboardModifiers ()==Qt::ShiftModifier) f=1.1;
  else if (QApplication::keyboardModifiers ()==Qt::ControlModifier) f=1.01;
  scale=scale*(pow(f,double(e->delta())/120));
  if (scale>12){scale=12;}
  if (scale<=0) {scale=1;}
  pixmap->changeScale(scale,e->x(),e->y());
  pixmap->scaleMutex.unlock();
  setAutoGrid();
  if (mouseVisible) prepareOutput();
  paint();
     //       printf("wheelEvent end\n");
}

void drawingField::scalePlus(){
  pixmap->scaleMutex.lock();
  double scale=pixmap->trans.mag;
  scale=scale*(1.5);
  if (scale>12){scale=12;}
  if (scale<=0) {scale=1;}
  pixmap->changeScale(scale,this->width()/2,this->height()/2);
  pixmap->scaleMutex.unlock();
  setAutoGrid();
  if (mouseVisible) prepareOutput();
  paint();
}
 
void drawingField::scaleMinus(){
  pixmap->scaleMutex.lock();
  double scale=pixmap->trans.mag;
  scale=scale*((double)(1/1.5));
  if (scale>12){scale=12;}
  if (scale<=0) {scale=1;}
  pixmap->changeScale(scale,this->width()/2,this->height()/2);
  pixmap->scaleMutex.unlock();
  setAutoGrid();
  if (mouseVisible) prepareOutput();
  paint();
}
 
void drawingField::scaleEins(){
  pixmap->scaleMutex.lock();
  double scale=1*userunits;
  pixmap->changeScale(scale,this->width()/2,this->height()/2);
  pixmap->scaleMutex.unlock();
  setAutoGrid();
  if (mouseVisible) prepareOutput();
  paint();
}
 
void drawingField::scaleFullGui(){
  if (!mutexReadGuiTryLock()) return;
  scaleFull();
  mutexReadUnlock();
}
void drawingField::scaleSelectGui(){
  if (!mutexReadGuiTryLock()) return;
  scaleSelect();
  mutexReadUnlock();
}
 
void drawingField::scaleFull(){
  pixmap->scaleMutex.lock();
/*
  QPoint max=QPoint(-(1<<30),-(1<<30));
  QPoint min=QPoint((1<<30),(1<<30));
  currentCell->minimum(&min);
  currentCell->maximum(&max);
 */
  /*  cellList *e=firstCell;
    while (e!=NULL){
		e->thisCell->paintInfoClear();
		e=e->nextCell;
	}*/
  QPoint max;
  QPoint min;
  uint gh;
  currentCell->paintInfoGet(&min,&max,&gh);
  double scale1=(this->height()-10)/((double)max.y()-(double)min.y());
  double scale2=(this->width()-10)/((double)max.x()-(double)min.x());
  if (scale1>scale2){scale1=scale2;}
  if (scale1>5) {scale1=5;}
  if (scale1<=0){scale1=1;}
  pixmap->setScale(scale1,(int)(-(max.x()+min.x())/2+width()/2/scale1),(int)((max.y()+min.y())/2+height()/2/scale1));
  pixmap->scaleMutex.unlock();
  //printf("end scale full\n");
  setAutoGrid();
  if (mouseVisible) prepareOutput();
  calcDetails();
  paint();
}

void drawingField::scale(QPoint p1, QPoint p2){
      QPoint max,min;
      if (p1.x()>p2.x()){min.setX(p2.x());max.setX(p1.x());}
      else {max.setX(p2.x());min.setX(p1.x());}
      if (p1.y()>p2.y()){min.setY(p2.y());max.setY(p1.y());}
      else {max.setY(p2.y());min.setY(p1.y());}
      pixmap->scaleMutex.lock();
      double scale1=(this->height()-10)/((double)max.y()-(double)min.y());
      double scale2=(this->width()-10)/((double)max.x()-(double)min.x());
      if (scale1>scale2){scale1=scale2;}
      if (scale1>12) {scale1=12;}
      if (scale1<=0){scale1=1;}
      pixmap->setScale(scale1,(int)(-(max.x()+min.x())/2+width()/2/scale1),(int)((max.y()+min.y())/2+height()/2/scale1));
      pixmap->scaleMutex.unlock();
      setAutoGrid();
      if (mouseVisible) prepareOutput();
      calcDetails();
}

void drawingField::scaleSelect(){
  //printf("begin scale full\n");
  pixmap->scaleMutex.lock();
  QPoint max=QPoint(INT_MIN,INT_MIN);
  QPoint min=QPoint(INT_MAX,INT_MAX);
  currentCell->minimumSelect(&min);
  currentCell->maximumSelect(&max);
  double scale1=(this->height()-10)/((double)max.y()-(double)min.y());
  double scale2=(this->width()-10)/((double)max.x()-(double)min.x());
  if (scale1>scale2){scale1=scale2;}
  if (scale1>5) {scale1=5;}
  if (scale1<=0){scale1=1;}
  pixmap->setScale(scale1,(int)(-(max.x()+min.x())/2+width()/2/scale1),(int)((max.y()+min.y())/2+height()/2/scale1));
  pixmap->scaleMutex.unlock();
  //printf("end scale full\n");
  setAutoGrid();
  if (mouseVisible) prepareOutput();
  paint();
}

void drawingField::scrollLeft(){
  pixmap->scaleMutex.lock();
  if (setup::scrollDirection) pixmap->move(-this->width()/3,0);
  else pixmap->move(this->width()/3,0);
  pixmap->scaleMutex.unlock();
  if (mouseVisible) prepareOutput();
  paint();
}

void drawingField::scrollUp(){
  pixmap->scaleMutex.lock();
  if (setup::scrollDirection) pixmap->move(0,-this->height()/3);
  else pixmap->move(0,this->height()/3);
  pixmap->scaleMutex.unlock();
  if (mouseVisible) prepareOutput();
  paint();
}

void drawingField::scrollRight(){
  pixmap->scaleMutex.lock();
  if (setup::scrollDirection) pixmap->move(this->width()/3,0);
  else pixmap->move(-this->width()/3,0);
  pixmap->scaleMutex.unlock();
  if (mouseVisible) prepareOutput();
  paint();
}

void drawingField::scrollDown(){
  pixmap->scaleMutex.lock();
  //printf("scale look scroll down\n");
  if (setup::scrollDirection) pixmap->move(0,this->height()/3);
  else pixmap->move(0,-this->height()/3);
  //printf("scale unlook scroll down\n");
  pixmap->scaleMutex.unlock();
  if (mouseVisible) prepareOutput();
  paint();
}
void drawingField::setView(double scale,int x,int y){
 //printf("start set scale df\n");
 pixmap->setScale(scale,x,y);
 setAutoGrid();
 //printf("end set scale df\n");
 paint();
}

void drawingField::getView(double *scale,int *x,int *y){
 pixmap->getScale(scale,x,y);
}

void drawingField::paint(){
//  printf("start paint\n");
 if (autorepaint){


// for multi thread use
	pixmap->abortPaint();
	paintMode=mode;
    pixmap->startPaint();
	pixmap->wait(150);
	update();

        emit painted();
  }
//  printf("end paint\n");
}

void drawingField::forcePaint(){
  if (autorepaint){
	pixmap->wait();
	update();
  }
  else {
	firstCell->paintInfoClear();
   	pixmap->drawPrepare();
	pixmap->reset();
   	if (setup::showGrid) pixmap->imagePainter->drawGrid(gridX,gridY,gridOffsetX,gridOffsetY); 
	
	currentCell->paint(pixmap->imagePainter);
   	currentCell->paintSelect(pixmap->imagePainter);
	update();
  }
}



	
void drawingField::print(QPrinter *printer){
  int printerWidth=printer->width();
  int printerHeight=printer->height();
  //printf("printerresolution width %d height %d\n",printerWidth,printerHeight);
  double scaleX=(double)pixmap->width()/(double)printerWidth;
  double scaleY=(double)pixmap->height()/(double)printerHeight;
  if (scaleX<scaleY){scaleX=scaleY;}
  int yStep=10000000/printerWidth+3;
  int numSteps=printerHeight/yStep;
  if (yStep>printerHeight) yStep=printerHeight;
#ifndef NO_PRINTER
  QPainter p1(printer);
#endif
  QPrinter pr1(QPrinter::HighResolution);
  pr1.setPaperSize(printer->paperSize());
  pr1.setOutputFileName("print.pdf");
  QPainter p2(&pr1);
#ifndef NO_PRINTER
  QPrinter pr2(QPrinter::HighResolution);
  pr2.setPaperSize(printer->paperSize());
  pr2.setOutputFileName("print.ps");
  QPainter p3(&pr2);
#endif
  layoutImage im(printerWidth,yStep);
  int count =0;
	for (int i=0;i<printerHeight;i+=yStep){
		strans trans;
		strans s=pixmap->trans;
		trans.setMirror_x();
		trans.translate((int)(s.matrix.dx()/scaleX), (int)(-s.matrix.dy()/scaleX)+i);
  		trans.scale(s.mag);
  		trans.scale(1.0/scaleX);
  		im.setDrawTrans(trans);

		if ((setup::paintEngine==1)&&(!setup::transparentWhiteEngine())) im.fill(QColor(0, 0, 0).rgb());
		else im.fill(QColor(255, 255, 255).rgb());
		currentCell->paint(im.imagePainter);
		QImage *ih=im.getImage();
		QRect target(1,i-count,printerWidth-2,yStep);
		QRect source(1,1,printerWidth-2,yStep);
#ifndef NO_PRINTER
		p1.drawImage(target,*ih,source);
#endif
		p2.drawImage(target,*ih,source);
#ifndef NO_PRINTER
		p3.drawImage(target,*ih,source);
#endif
		count++;
		int p=(int)((double)(count)/numSteps*100.0);
		if (p>100) p=100;
		showMessage(tr("Printing %1 %").arg(p));
		//printf("count %d\n",count);
	}
#ifndef NO_PRINTER
  p1.end();
#endif
  p2.end();
#ifndef NO_PRINTER
  p3.end();
#endif

 /* layoutImage im(printerWidth,printerHeight);
printf("%d %d\n",printerWidth,printerHeight);
  {
	QImage *i=im.getImage();
	if (i->isNull()){
		showMessage(tr("Not enough memory to print in this resolution!"));
		return;
		}
  }
	return;
  strans s=pixmap->trans;
  strans trans;
  trans.setMirror_x();
  trans.translate((int)(s.matrix.dx()/scaleX), (int)(-s.matrix.dy()/scaleX));
  trans.scale(s.mag);
  trans.scale(1.0/scaleX);
  im.setDrawTrans(trans);

  if (setup::paintEngine==1) im.fill(QColor(0, 0, 0).rgb());
  else im.fill(QColor(255, 255, 255).rgb());
  currentCell->paint(im.imagePainter);
  QImage *i=im.getImage();
  i->save("print.png");
  QPainter p(printer);
  p.drawImage(-1,-1,*i);
  p.end();
  QPrinter pr(QPrinter::HighResolution);
  pr.setOutputFileName("print.pdf");
  p.begin(&pr);
  p.drawImage(-1,-1,*i);
  p.end();
  pr.setOutputFileName("print.ps");
  p.begin(&pr);
  p.drawImage(-1,-1,*i);
  p.end();*/
}


void drawingField::deleteSelect(){
  currentCell->deleteSelect();
  setModifyChanged();
}

void drawingField::mergeSelect(){
  currentCell->mergeSelect();
  setModifyChanged();
}

QPoint drawingField::snap(QPoint pos){
if (mutexReadTryLock()){
  QTime t;
  t.start();
  QPoint snap,psnapLine,psnapCenter,psnapMiddle,psnapPoint,psnapInter;
  psnapLine=psnapCenter=psnapMiddle=psnapPoint=psnapInter=QPoint(INT_MAX,INT_MAX);
  int searchDistance=element::runden(1.0/pixmap->trans.mag*30);
  //printf("%d\n",searchDistance);
  if (snapGrid) snap=raster(pos);
  else snap=QPoint(INT_MAX,INT_MAX);
  if ((snapPoint)&&(t.elapsed()<100)) {
  	psnapPoint=currentCell->nearestPoint(pos,searchDistance);
	}
  if ((snapMiddle)&&(t.elapsed()<300)) {
  	psnapMiddle=currentCell->nearestMiddleLine(pos,searchDistance);
	}
  if ((snapCenter)&&(t.elapsed()<300)) {
  	psnapCenter=currentCell->nearestCenter(pos,searchDistance);
	}
  if ((snapIntersection)&&(t.elapsed()<100)) {
  	psnapInter=currentCell->nearestIntersection(pos,searchDistance);
	}
  if ((snapLine)&&(t.elapsed()<100)) {
  	psnapLine=currentCell->nearestLine(pos,searchDistance);
	}
//printf("searchtime %d ms\n",t.elapsed());
  if (element::distance(psnapLine,pos)*pixmap->trans.mag <15){
	snap=psnapLine;
	QPoint psr=raster(snap);
	if (snapGrid) if (currentCell->nearestLine(psr,1)==psr)snap=psr;
	}
  if (element::distance(psnapMiddle,pos)*pixmap->trans.mag <20) snap=psnapMiddle;
  if (element::distance(psnapCenter,pos)*pixmap->trans.mag <25) snap=psnapCenter;
  if (element::distance(psnapInter,pos)*pixmap->trans.mag <25) snap=psnapInter;
  if (element::distance(psnapPoint,pos)*pixmap->trans.mag <25) snap=psnapPoint;
  if (snap==QPoint(INT_MAX,INT_MAX)) snap=pos;
  mutexReadUnlock();
  return snap;
  }
else {
  if (snapGrid) return raster(pos);
  return pos;
}
}

QPoint drawingField::perpendicular(const QPoint posCurrent, const QPoint posBase){
   QPoint dif=posCurrent-posBase;
   if (abs(dif.x())<abs(dif.y())){
	return QPoint(posBase.x(),posCurrent.y());
   }
   else {
	return QPoint(posCurrent.x(),posBase.y());
   }
}

QPoint drawingField::angleFine(const QPoint posCurrent, const QPoint posBase){
   double anglebase=90.0/18;
   QPoint dif=posCurrent-posBase;
   double isAng=element::angle(dif,QPoint(1000,0));
   if (isAng<0) isAng+=360;
   isAng+=(anglebase/2);
   int num=(int)(isAng/anglebase);
   //printf("%d\n",(int)(anglebase*num*100));
   QPoint p1=QPoint(10000,0);
   strans trans;
   trans.rotate(anglebase*num);
   p1=trans.matrix.map(p1);
   QPoint cp;
   if (abs(dif.x())>abs(dif.y()))
	element::cutPoint3(p1+posBase,posBase,posCurrent,QPoint(posCurrent.x(),posCurrent.y()+1000),&cp);
   else element::cutPoint3(p1+posBase,posBase,posCurrent,QPoint(posCurrent.x()+1000,posCurrent.y()),&cp);
   return cp;
}

QPoint drawingField::angle45(const QPoint posCurrent, const QPoint posBase){
    QPoint dif=posCurrent-posBase;
   int ddif=abs(abs(dif.x())-abs(dif.y()));
   if ((ddif<abs(dif.x()))&&(ddif<abs(dif.y())))
   {
	   int sigx=1;
	   if (dif.x()<0)sigx=-1;
	   int sigy=1;
	   if (dif.y()<0)sigy=-1;
	   if (abs(dif.x())<abs(dif.y()))
		   return posBase+QPoint(dif.x(),abs(dif.x())*sigy);
	   else
		   return posBase+QPoint(abs(dif.y())*sigx,dif.y());

   }
   else if (abs(dif.x())<abs(dif.y())){
	return QPoint(posBase.x(),posCurrent.y());
   }
   else {
	return QPoint(posCurrent.x(),posBase.y());
   }
}

QPoint drawingField::square(const QPoint posCurrent, const QPoint posBase){
   QPoint dif=-posBase+posCurrent;
   if (dif==QPoint(0,0)) return posCurrent;
   if (abs(dif.x())<abs(dif.y())){
	return QPoint(posCurrent.x(),posBase.y()+abs(dif.x())*(dif.y()/abs(dif.y())));
   }
   else {
	return QPoint(posBase.x()+abs(dif.y())*(dif.x()/abs(dif.x())),posCurrent.y());
   }
}

QPoint drawingField::raster(QPoint pos){
  if ((gridX>1)&&(gridY>1)){
    if (pos.x()-gridOffsetX>0) {pos.setX(((pos.x()-gridOffsetX+(gridX/2))/gridX)*gridX+gridOffsetX);}
    else {pos.setX(((pos.x()-gridOffsetX-(gridX/2))/gridX)*gridX+gridOffsetX);}
    if (pos.y()-gridOffsetY>0) {pos.setY(((pos.y()-gridOffsetY+(gridY/2))/gridY)*gridY+gridOffsetY);}
    else {pos.setY(((pos.y()-gridOffsetY-(gridY/2))/gridY)*gridY+gridOffsetY);}}
  return pos;
}

void drawingField::openView(QString library,QString cellName,QString viewName){
  fileType="";
  reset();
  resetUndo();
  deleteAllCell();
#ifdef OPENACCESS
  oaLayout::open(library, cellName,viewName,this);
#endif
  //printf("1: %d ms\n", setup::centralTimer.elapsed());
  if (firstCell!=NULL){
	if (currentCell==NULL) {
		currentCell=firstCell->thisCell;}}
  else {
	 firstCell=new cellList();         
  	currentCell=firstCell->thisCell;
  }
  firstCell->paintInfoClear();
  bool ab=autorepaint;
  autorepaint=false;
  scaleFull();
  autorepaint=ab;
  setModifySaved();
  //emit cellsChange();
  //emit selectChange(aktuell_cell->countSelect());
  emit selectReset();
  emit currentCellChanged();
  if (layout::debug) {printf("Open complete\n");}
 /* macroAdd("layout->filename=\""+s+"\";");
  macroAdd("layout->drawing->openFile(\""+s+"\");");*/
}

void drawingField::openFile(QString s){
  fileType="";
  reset();
  resetUndo();
  deleteAllCell();
  QString type=filedialog::getFileType(s);
  if (type=="gds")gds::open(s,this);
  else if (type=="dxf")dxf::open(s,this);
  else if (type=="oasis")oasis::open(s,this);
  else if (type=="cif")cif::open(s,this);
#ifdef OPENACCESS
  else if (type=="oa")oaLayout::open(s,this);
#endif
  else if (type=="ap")ap::open(s,this);
  else if (type=="tld")tld::open(s,this);
  else if (type=="gerber")gerber::open(s,this);
  else if (type=="svg")svg::open(s,this);
  else if (type=="csv")csv::open(s,this);
  else if (type=="pixel")pixel::open(s,this);
  else if (type=="gerber.layout")gerber::openMacro(s,this);
#ifdef netlistutility
#endif
  else if (type=="emask") electromask::open(s,this);
  else gds::open(s,this);

  //printf("1: %d ms\n", setup::centralTimer.elapsed());
  if (firstCell!=NULL){
	if (currentCell==NULL) {
		currentCell=firstCell->thisCell;}}
  else {
	 firstCell=new cellList();         
  	currentCell=firstCell->thisCell;
  }
  firstCell->paintInfoClear();
  bool ab=autorepaint;
  autorepaint=false;
  scaleFull();
  autorepaint=ab;
  setModifySaved();
  //emit cellsChange();
  //emit selectChange(aktuell_cell->countSelect());
  emit selectReset();
  emit currentCellChanged();
  if (layout::debug) {printf("Open complete\n");}
  macroAdd("layout->filename=\""+s+"\";");
  macroAdd("layout->drawing->openFile(\""+s+"\");");
}

void drawingField::importFile(QString fileName){
  reset();
  resetUndo();
  QString type=filedialog::getFileType(fileName);
  if (type=="gds")gds::import(fileName,this);
  else if (type=="dxf")dxf::import(fileName,this);  
  else if (type=="oasis")oasis::import(fileName,this); 
  else if (type=="cif")cif::import(fileName,this); 
#ifdef OPENACCESS
  else if (type=="oa")oaLayout::import(fileName,this);
#endif
  else if (type=="ap")ap::import(fileName,this); 
  else if (type=="tld")tld::import(fileName,this); 
  else if (type=="svg")svg::import(fileName,this); 
  else if (type=="csv")csv::import(fileName,this); 
  else if (type=="pixel")pixel::import(fileName,this);
  else if (type=="gerber")gerber::import(fileName,this); 
  else if (type=="gerber.layout")gerber::openMacro(fileName,this); 
#ifdef netlistutility
#endif
  else if (type=="emask") electromask::import(fileName,this);
  else gds::import(fileName,this);
  //emit cellsChange();
  //emit selectChange(aktuell_cell->countSelect());
  emit selectReset();
  emit currentCellChanged();
  firstCell->paintInfoClear();
  scaleFull();
  if (layout::debug) {printf("Import complet\n");}
  macroAdd("layout->drawing->importFile(\""+fileName+"\");");
}

void drawingField::updateFile(QString fileName){
  reset();
  resetUndo();
  QString type=filedialog::getFileType(fileName);
  if (type=="gds")gds::update(fileName,this);
  else if (type=="dxf")dxf::update(fileName,this);  
  else if (type=="oasis")oasis::update(fileName,this); 
  else if (type=="cif")cif::update(fileName,this); 
#ifdef OPENACCESS
  else if (type=="oa")oaLayout::update(fileName,this);
#endif
  else if (type=="ap")ap::update(fileName,this); 
  else if (type=="tld")tld::update(fileName,this); 
  else if (type=="svg")svg::update(fileName,this);
  else if (type=="csv")csv::update(fileName,this);
  else if (type=="pixel")pixel::update(fileName,this);
  else if (type=="gerber")gerber::update(fileName,this); 
#ifdef netlistutility
#endif
  else if (type=="gerber.layout")gerber::openMacro(fileName,this); 
  else if (type=="emask") electromask::update(fileName,this);
  else gds::update(fileName,this);
  //emit cellsChange();
  //emit selectChange(aktuell_cell->countSelect());
  emit selectReset();
  emit currentCellChanged();
  firstCell->paintInfoClear();
  scaleFull();
  if (layout::debug) {printf("Update complet\n");}
  macroAdd("layout->drawing->updateFile(\""+fileName+"\");");
}

void drawingField::saveFile(QString fileName){
  QString type=filedialog::getFileType(fileName);
  if (type=="gds")gds::save(fileName,this);
  else if (type=="oasis")oasis::save(fileName,this); 
  else if (type=="cif")cif::save(fileName,this); 
  else if (type=="dxf")dxf::save(fileName,this);
  else if (type=="ap")ap::save(fileName,this); 
  else if (type=="tld")tld::save(fileName,this); 
  else if (type=="gerber")gerber::save(fileName,this); 
  else if (type=="gerber.layout")gerber::save(fileName,this); 
  else if (type=="svg")svg::save(fileName,this);
  else if (type=="csv")csv::save(fileName,this);
#ifdef netlistutility
#endif
#ifdef OPENACCESS
  else if (type=="oa") emit saveOpenAccess(fileName);
	    //oaLayout::save(fileName,this);
#endif
  else if (type=="pixel")pixel::save(fileName,this);
  else gds::save(fileName,this);
  setModifySaved();
  if (layout::debug) {printf("Save complet\n");}
  macroAdd("layout->drawing->saveFile(\""+fileName+"\");");
}

void drawingField::saveScreenshot(QString filename){
  QStringList filter;
  QStringList png;
  int k=filename.indexOf(".");
  QString ext="";
  if (k<0) ext="png";
  else {
	ext=filename.mid(k+1);
	bool found=false;
	for (int i=0;i<QImageWriter::supportedImageFormats ().count();i++){
  	   QString f=QImageWriter::supportedImageFormats ().at(i);
	   if (f==ext) found=true;
	}
	if (!found) ext="png";
  }
  forcePaint();
  QImage p=pixmap->getImage();
  //QPixmap p=drawing->pixmap->getPixmap();
  p.save(filename,ext.toLatin1(),-1);	
}

cellList* drawingField::addCell(){
  setModifyAdded();
  cellList *e;
  if (firstCell!=NULL){
	e=new cellList();
	e->nextCell=firstCell;
	firstCell=e;
	//for (e=firstCell;e->nextCell!=NULL;e=e->nextCell){;}
	//e->nextCell=new cellList();
	//e=e->nextCell;
	return e;
	}
  else {
	firstCell=new cellList();
	return firstCell;}

}

void drawingField::newCell(){
  cellList *c;
  int i=1;
  QString s1,s2;
  s1="noname_";
  s2=s1+s2.setNum(i);
  while (existCellname(s2)){i++;s2=s1+s2.setNum(i);}
  c=addCell();
  c->this_cell->cellName=s2;
  setCell(s2);
  scaleEins();
}

void drawingField::deleteCurrentCell(){
  reset();
  deleteCell(currentCell);
  if (firstCell==NULL) {firstCell=addCell();}
  currentCell=firstCell->thisCell;
  emit currentCellChanged();
}

void drawingField::deleteAllCell(){
  reset();
  emit removeAllCells();
  currentCell=NULL;
  cellList *c;
  while (firstCell!=NULL){
	c=firstCell;
	firstCell=c->nextCell;
	delete c;
	//deleteCell(first_cell->this_cell);
	}
  firstCell=NULL;
  setModifyChanged();
}

void drawingField::deleteCell(cell *cell_){
  cellList *e,*help,*f;
  for(e=firstCell;e!=NULL;e=e->nextCell){e->thisCell->deleteRefs(cell_);}
  for(e=firstCell;e->thisCell!=cell_;e=e->nextCell){;}
  delete e->thisCell;
  e->thisCell=NULL;
  help=firstCell;
  if (firstCell->nextCell!=NULL){
     for (f=firstCell->nextCell;f!=NULL;){
	if (f->thisCell==NULL){
		help->nextCell=f->nextCell;
		delete f;
		if (help->nextCell!=NULL)
		             {f=help->next_cell;}
		else f=help;
		}
	else {
		help=f;
		f=f->next_cell;
		}
	}}
  if (firstCell->thisCell==NULL){
	help=firstCell;
	firstCell=firstCell->nextCell;
	delete help;
	}
  setModifyChanged();
  if ((mode==120)||(mode==130)||(mode==121)) mode=100; //reset cellref / cellrefarray / place Cell
}

void drawingField::setPreviousCellGui(){
  if (mutexChangeGuiTryLock()) {
        QString s=currentCell->cellName;
  	setCell(previousCell);
	previousCell=s;
  	modestep=0;
  	emit selectChange(currentCell->countSelect());
  	macroAdd("layout->drawing->setCell(\"layout->drawing->previousCell\");");
  	mutexChangeUnlock();
	paint();
	emit currentCellChanged();
	}
}

void drawingField::setCellGui(const QString &s){
  //printf("setcell %s\n",s.toAscii().data());
  if (mutexChangeGuiTryLock()) {
	previousCell=currentCell->cellName;
  	setCell(s);
  	modestep=0;
  	emit selectChange(currentCell->countSelect());
  	macroAdd("layout->drawing->setCell(\""+s+"\");");
  	mutexChangeUnlock();
	paint();
	emit currentCellChanged();
	}
}

void drawingField::forceCellGui(const QString &s){
  if (mutexChangeGuiTryLock()) {
  	if (currentCell->cellName!=s) {
		setCell(s);
		if (currentCell->cellName!=s){
			if (currentCell->firstElement==NULL){
					currentCell->cellName=s;
				}
			else {
				cellList *cl=addCell();
				cl->thisCell->cellName=s;
				setCell(s);
			}
			}
		modestep=0;
		emit selectChange(currentCell->countSelect());
		macroAdd("layout->drawing->setCell(\""+s+"\");");
		mutexChangeUnlock();
		paint();
		emit cellsChange();
	}
	else mutexChangeUnlock();
	}
}

void drawingField::setCell(const QString &s){
  resetUndo();
  reset();
  cellList *e=firstCell;
  while (e->thisCell->cellName!=s){
	if (e->nextCell==NULL){return;}
	e=e->nextCell;}
  currentCell=e->thisCell;
  currentCell->paintInfoClear();
  reset();
  modestep=0;
  scaleFull();
  emit currentCellChanged();
}

void drawingField::setCell(const cell *c){
  resetUndo();
  reset();
  currentCell=(cell*)(c);
  currentCell->paintInfoClear();
  reset();
  modestep=0;
  scaleFull();
  emit currentCellChanged();
}

cell* drawingField::findCell(const QString s){
  cellList *e=firstCell;
  if (e==NULL){return NULL;}
  while (e->this_cell->cellName!=s){
				e=e->next_cell;
				if (e==NULL){return NULL;}}
  return e->this_cell;
}

void drawingField::relink(const QString &s){
 cell *c=findCell(s);
 if (c!=NULL) currentCell->relinkSelect(c);
}

bool drawingField::existCellname(QString name){
  bool b=false;
  cellList *e=firstCell;
  while (e!=NULL){
	if (e->thisCell->cellName==name) b=true;
	e=e->nextCell;}
  return b;
}

bool drawingField::depend(cell *cell_){
  bool b=false;
  cellList *e=firstCell;
  while (e!=NULL){
	if (e->thisCell->depend(cell_)) b=true;
	e=e->nextCell;}
  return b;
}

QRect drawingField::makeRect(QPoint pos,QPoint point){
  QRect rect(pos,point);
  if (pos.x()>point.x()){
		rect.setLeft(point.x());
		rect.setRight(pos.x());
	}else {
		rect.setLeft(pos.x());
		rect.setRight(point.x());
		}
  if (pos.y()<point.y()){
		rect.setTop(point.y());
		rect.setBottom(pos.y());
	}else {
		rect.setTop(pos.y());
		rect.setBottom(point.y());
		}
  return rect;
}

QRect drawingField::makeRectPaintEvent(QPoint pos,QPoint point){
  QRect rect1=makeRect(pos,point);
  QRect rect;
  rect.setLeft(rect1.right());
  rect.setTop(rect1.bottom());
  rect.setWidth(-rect1.width()+1);
  rect.setHeight(-rect1.height()+1);
  return rect;
}

QRect drawingField::makeDot(QPoint point,QPoint pos){
  QRect rect;
  int x=point.x()-pos.x();
  if (x<0) x=-x;
  int y=point.y()-pos.y();
  if (y<0) y=-y; 
  rect.setLeft(pos.x()-x);
  rect.setRight(pos.x()+x);
  rect.setTop(pos.y()+y);
  rect.setBottom(pos.y()-y);
  return rect;
}

QRect drawingField::makeDotPaintEvent(QPoint point,QPoint pos){
  QRect rect1=makeDot(point,pos);
  QRect rect;
  rect.setLeft(rect1.right());
  rect.setTop(rect1.bottom());
  rect.setWidth(-rect1.width()+1);
  rect.setHeight(-rect1.height()+1);
  return rect;
}

QStringList drawingField::undependendCells(){
 cellList *cell_list;
  QStringList list;
  QString s;
  list.clear();
  for (cell_list=firstCell;cell_list!=NULL;cell_list=cell_list->nextCell){
	if (cell_list->this_cell!=currentCell){
		if (!cell_list->thisCell->depend(currentCell)){
			s=cell_list->thisCell->cellName;
			list += s; };}
  }
  return list;
}

cell* drawingField::findTopCell(){
  cellList *cell_list;
  QHash<cell*,bool> list;
  if (firstCell==NULL) addCell();
  for (cell_list=firstCell;cell_list!=NULL;cell_list=cell_list->nextCell){
    cell_list->thisCell->marker=true;
    list[cell_list->thisCell]=true;
  }

  for (cell_list=firstCell;cell_list!=NULL;cell_list=cell_list->nextCell){
     cell_list->thisCell->removeDepend(&list);
  }
  int count=0;
  cell *result=NULL;
  for (cell_list=firstCell;cell_list!=NULL;cell_list=cell_list->nextCell){
    cell_list->thisCell->countPrepare();
    if(!list.value(cell_list->thisCell)) cell_list->thisCell->marker=false;
    else {
	count++;
	result=cell_list->thisCell;
	}
  }
  if (count==1) return result;
  int numCellref=0;
  cell *c=NULL;
   for (cell_list=firstCell;cell_list!=NULL;cell_list=cell_list->nextCell){
    if(cell_list->thisCell->marker) {
	int i=
	cell_list->thisCell->countDepend();
	//printf("%d %s\n",i,cell_list->thisCell->cellName.toAscii().data());
	if (i>numCellref){
		numCellref=i;
		c=cell_list->thisCell;
		}
	}
  }
  if (c!=NULL) return c;
/*
   for (cell_list=firstCell;cell_list!=NULL;cell_list=cell_list->nextCell){
    if(cell_list->thisCell->marker) cell_list->thisCell->unmarkDepend(firstCell);
  }
  int numCellref=0;
  cell *c=NULL;
   for (cell_list=firstCell;cell_list!=NULL;cell_list=cell_list->nextCell){
    if(cell_list->thisCell->marker) {
	QStringList sl;
	cell_list->thisCell->listDependMultilevel(firstCell,&sl);
	int i=sl.count();
	if (i>numCellref){
		numCellref=i;
		c=cell_list->thisCell;
		}
	}
  }
  if (c!=NULL) return c;//cell_list->thisCell;
*/
  /*bool topcell;
  for (cell_list=first_cell;cell_list!=NULL;cell_list=cell_list->next_cell){
  	topcell=true;
	for (celllist=first_cell;celllist!=NULL;celllist=celllist->next_cell){
		if (cell_list->this_cell!=celllist->this_cell){
			if (celllist->this_cell->depend(cell_list->this_cell)){
				topcell=false;}
			}
		}
  	if (topcell){return cell_list->this_cell;}
  }*/
  return firstCell->thisCell;
}

QList<cell*> drawingField::findTopCells(){
  QList <cell*> list_;
  cellList *cell_list;
  QHash<cell*,bool> list;
  if (firstCell==NULL) addCell();
  for (cell_list=firstCell;cell_list!=NULL;cell_list=cell_list->nextCell){
    //cell_list->thisCell->marker=true;
    list[cell_list->thisCell]=true;
  }

  for (cell_list=firstCell;cell_list!=NULL;cell_list=cell_list->nextCell){
     cell_list->thisCell->removeDepend(&list);
  }
  for (cell_list=firstCell;cell_list!=NULL;cell_list=cell_list->nextCell){
    if(list.value(cell_list->thisCell)) 
    {
	list_<<cell_list->thisCell;
	}
  }
  return list_;  
  
}

void drawingField::resetUndo(){
  for (int i=0;i<20;i++){
  	if (undo_[i]!=NULL) { 
		delete undo_[i]; 
		undo_[i]=NULL;
	}
  	if (redo_[i]!=NULL) { 
		delete redo_[i]; 
		redo_[i]=NULL;}
	}
  emit undoEnable(false);
  emit redoEnable(false);
}

void drawingField::prepareUndo(){
  if (undo_[19]!=NULL){ delete undo_[19];}
  int max=currentCell->countElements();
  if (max>800000) {
		resetUndo();
		return;
		}
  if (max!=0) max=800000/max;
  else max=20;
  for (int i=18;i>=0;i--){
	undo_[i+1]=undo_[i];
	if ((i)>max) {
		if (undo_[i+1]!=NULL) delete undo_[i+1];
		undo_[i+1]=NULL;
		}
	}
  for (int i=0;i<20;i++){
       if (redo_[i]!=NULL) { 
		delete redo_[i]; 
		redo_[i]=NULL;}
	}
  undo_[0]=currentCell->copy();
  emit redoEnable(false);
  emit undoEnable(true);
}

void drawingField::undo(){
  if (undo_[0]!=NULL){
	/*printf("undo:");
	for (int i=0;i<20;i++){
		if (undo_[i]==NULL) printf("-");
		else printf("+");
	}
	printf("\n");
	printf("redo:");
	for (int i=0;i<20;i++){
		if (redo_[i]==NULL) printf("-");
		else printf("+");
	}
	printf("\n");*/
	reset();
	cellList *c=firstCell;
	while (c->this_cell!=currentCell){c=c->next_cell;}
	if (redo_[19]!=NULL) {delete redo_[19];redo_[19]=NULL;}
	for (int i=18;i>=0;i--){
		redo_[i+1]=redo_[i];
	}
	redo_[0]=currentCell;
	c->this_cell=undo_[0];
	currentCell=undo_[0];
	updateCellref(redo_[0],undo_[0]);
	undo_[19]=NULL;
	for (int i=0;i<19;i++){
		undo_[i]=undo_[i+1];
	}
	emit redoEnable(true);
	if (undo_[0]==NULL) emit undoEnable(false);
	}
}

void drawingField::redo(){
  if (redo_[0]!=NULL){
	reset();
	cellList *c=firstCell;
	while (c->this_cell!=currentCell){c=c->next_cell;}
	if (undo_[19]!=NULL){ delete undo_[19];undo_[19]=NULL;}
  	for (int i=18;i>=0;i--){
		undo_[i+1]=undo_[i];
	}
	undo_[0]=currentCell;
	c->this_cell=redo_[0];
	currentCell=redo_[0];
	updateCellref(undo_[0],redo_[0]);
	for (int i=0;i<19;i++){
		redo_[i]=redo_[i+1];
	}
	redo_[19]=NULL;
	if (redo_[0]==NULL) emit redoEnable(false);
	emit undoEnable(true);
	}
}
void drawingField::updateCellref(cell *oldCell, cell* newCell){
cellList *c=firstCell;
	while (c!=NULL){
		if (c->this_cell!=NULL) c->this_cell->updateCellref(oldCell,newCell);
		c=c->next_cell;}
}

void drawingField::nextPoint(){
  currentCell->nextPoint();
  paint();
}



void drawingField::showGridToggle(){
  setup::showGrid = !setup::showGrid;
}

void drawingField::setAutoGrid(){
 if (gridauto){
 	double g=double(250)/(pixmap->trans.mag)/userunits;
	int exp=1;
        double d;
	while (g>=120){g/=10;exp++;}
	d=g/10;
	if (d<=3){g=1;}
	else if (d<=6) {g=2;}
	else g=5;
	while (exp>1) {g*=10;exp--;}
	setGrid(element::runden(g*userunits));
 	emit gridChange();
 	}
}

void drawingField::recountSelect(){
emit selectChange(currentCell->countSelect());
}

bool drawingField::useLayer(int layer){
    cellList *f;
    for (f=firstCell;f!=NULL;f=f->nextCell) {
        if (f->thisCell!=NULL) {
            if (f->thisCell->useLayer(layer)) return true;
        }
    }
 return false;
 }

void drawingField::setMouseHelp(){
   mouseWidget::set(mode,modestep);
   emit newMode(mode);
}

void drawingField::p(double x,double y){
   point(QPoint(element::round(x/userunits),element::round(y/userunits)));
}

void drawingField::point(int x,int y){
   point(QPoint(x,y));
}

void drawingField::pointRel(int x,int y){
  pointRel(QPoint(x,y));
}

void drawingField::pRel(double x,double y){
  pointRel(QPoint(element::round(x/userunits),element::round(y/userunits)));
}

void drawingField::pDir(double length,double dir){
  double x,y;
  x=length*cos(dir/180*M_PI);
  y=length*sin(dir/180*M_PI);
  pRel(x,y);
}

void drawingField::pointMove(int x,int y){
  pointMove(QPoint(x,y));
}

void drawingField::pMove(double x,double y){
  pointMove(QPoint(element::round(x/userunits),element::round(y/userunits)));
}


void drawingField::delPoint(){
  if ((modestep>=1)&&(pointarray.size()>1)) {
	modestep--;
	pointarray.resize(pointarray.size()-1);
 }
}

void drawingField::point(QPoint p){
   if (mode!=1) setCommandMode();
   modestep++;
   pointarray.resize(modestep+1);
   pointarray.setPoint(modestep-1,p);
}

void drawingField::pointRel(QPoint p){
   if (mode!=1) setCommandMode();
   if (modestep<=0) point(p);
   else {
   	modestep++;
   	pointarray.resize(modestep+1);
   	pointarray.setPoint(modestep-1,pointarray.point(modestep-2)+p);
   }
}

void drawingField::pointMove(QPoint p){
   if (mode!=1) setCommandMode();
   if (modestep<=0) ;
   else {
   	pointarray.setPoint(modestep-1,pointarray.point(modestep-1)+p);
   }
}

void drawingField::clearPoints(){
 if (mode!=1) setCommandMode();
 modestep=0;
 pointarray.resize(0);
}

void drawingField::box(){
   if (modestep>1){
	element *f;
   	QRect rect=makeRect(pointarray.point(0),pointarray.point(1));
 	f=currentCell->addBox(rect,activeLayer);
	modestep=0;
	setModifyAdded();
  }
}

void drawingField::dot(){
   if (modestep>1){
	element *f;
   	QRect rect=makeDot(pointarray.point(0),pointarray.point(1));
 	f=currentCell->addBox(rect,activeLayer);
	modestep=0;
	setModifyAdded();
  }
}

void drawingField::path(){
   if (modestep>1){
	element *f;
	pointarray.resize(modestep);
	f=currentCell->addPath(pointarray,activeLayer);
	f->setCap(setup::defaultPathCap);
	f->setWidth(setup::defaultPathWidth);
	modestep=0;
	setModifyAdded();
  }
}

void drawingField::polygon(){
   if (modestep>2){
	element *f;
	pointarray.resize(modestep+1);
   	pointarray.setPoint(modestep,pointarray.point(0));
	f=currentCell->addPolygon(pointarray,activeLayer);
	modestep=0;
	setModifyAdded();
  }
}

void drawingField::text(QString s){
if (modestep>=1){
		element *f;
		f=currentCell->addText(activeLayer,pointarray.point(0),s);
		f->setWidth(setup::defaultTextWidth);
		f->setPresentation(setup::defaultTextPresentation);
		setModifyAdded();
		modestep=0;}
}

void drawingField::cellRef(QString s){
if (modestep>=1){
		cell_ref=findCell(s);
		if ((cell_ref!=NULL)&&(cell_ref!=currentCell)){
			element *f;
			f=currentCell->addCellref(cell_ref,pointarray.point(0));
			setModifyAdded();
			modestep=0;}
		}
}

void drawingField::cellrefarray(QString s,int x, int y){
if (modestep>=2){
		cell_ref=findCell(s);
		if ((cell_ref!=NULL)&&(cell_ref!=currentCell)){
			element *f;
			f=currentCell->addCellrefArray(cell_ref,pointarray.point(0),pointarray.point(1),x,y);
			setModifyAdded();
			modestep=0;}
		}
}

void drawingField::spiral(){
if (modestep>=3){
		pointarray=element::spirale(pointarray.point(0),pointarray.point(1),pointarray.point(2),setup::circularDefault);
		element *f;
		f=currentCell->addPath(pointarray,activeLayer);
		modestep=0;
		setModifyAdded();
		}
}

void drawingField::circle(){
if (modestep>=2){
		pointarray=element::spirale(pointarray.point(0),pointarray.point(1),pointarray.point(1),setup::circularDefault);
		element *f;
		f=currentCell->addPolygon(pointarray,activeLayer);
		modestep=0;
		setModifyAdded();
		};
}

void drawingField::circleBox(){
if (modestep>=2){
		QPoint pc=(pointarray.point(0)+pointarray.point(1))/2;
		QPoint pr=pointarray.point(0)-pointarray.point(1);
		int r=abs(pr.x());
		if (abs(pr.y())<r) r=abs(pr.y());
		pr=pc+QPoint(r/2,0);
		pointarray=element::spirale(pc,pr,pr,setup::circularDefault);
		element *f;
		f=currentCell->addPolygon(pointarray,activeLayer);
		modestep=0;
		setModifyAdded();
		};
}

void drawingField::ellipse(){
if (modestep>=2){
		QPoint pc=(pointarray.point(0)+pointarray.point(1))/2;
		QPoint pr=pointarray.point(0)-pointarray.point(1);
		pointarray=element::ellipse(pc,pr.x()/2,pr.y()/2,setup::circularDefault);
		element *f;
		f=currentCell->addPolygon(pointarray,activeLayer);
		modestep=0;
		setModifyAdded();
		};
}

void drawingField::circleFit(){
if (modestep>=2){
		pointarray.resize(modestep);
		pointarray=element::fitToCircle(pointarray);
		element *f;
		f=currentCell->addPolygon(pointarray,activeLayer);
		modestep=0;
		setModifyAdded();
		};
}

void drawingField::sector(){
if (modestep>=3){
		pointarray.setPoint(2,(pointarray.point(2)-pointarray.point(0))*(element::distance(pointarray.point(0),pointarray.point(1))/element::distance(pointarray.point(0),pointarray.point(2)))+pointarray.point(0));
		QPoint p=pointarray.point(0);
		pointarray=element::spirale(pointarray.point(0),pointarray.point(1),pointarray.point(2),setup::circularDefault);
		int i=pointarray.size();
		pointarray.resize(i+2);
		pointarray.setPoint(i,p);
		pointarray.setPoint(i+1,pointarray.point(0));
		element *f;
		f=currentCell->addPolygon(pointarray,activeLayer);
		modestep=0;
		setModifyAdded();
		}
}

void drawingField::arc(){
if (modestep>=3){
		pointarray.setPoint(2,(pointarray.point(2)-pointarray.point(0))*(element::distance(pointarray.point(0),pointarray.point(1))/element::distance(pointarray.point(0),pointarray.point(2)))+pointarray.point(0));
		QPoint p=pointarray.point(0);
		pointarray=element::spirale(pointarray.point(0),pointarray.point(1),pointarray.point(2),setup::circularDefault);
		element *f;
		f=currentCell->addPath(pointarray,activeLayer);
		modestep=0;
		setModifyAdded();
		}
}

void drawingField::polygonArc(){
if (modestep>=3){
		pointArray a=pointarray;
		pointArray b=pointarray;
		a.setPoint(2,(pointarray.point(2)-pointarray.point(0))*(element::distance(pointarray.point(0),pointarray.point(1))/element::distance(pointarray.point(0),pointarray.point(2)))+pointarray.point(0));
		a=element::spirale(a.point(0),a.point(1),a.point(2),setup::circularDefault);
		b.setPoint(1,(pointarray.point(1)-pointarray.point(0))*(element::distance(pointarray.point(0),pointarray.point(2))/element::distance(pointarray.point(0),pointarray.point(1)))+pointarray.point(0));
		b=element::spirale(b.point(0),b.point(1),b.point(2),setup::circularDefault);
		for (int i=0;i<b.size();i++){
				a.resize(a.size()+1);
				a.setPoint(a.size()-1,b.point(b.size()-1-i));
				}
		a.resize(a.size()+1);
		a.setPoint(a.size()-1,a.point(0));
		element *f;
		f=currentCell->addPolygon(a,activeLayer);
		modestep=0;
		setModifyAdded();
		}
}

void drawingField::bezier2(){
if (modestep>=3){
		pointarray=element::bezier2(pointarray.point(0),pointarray.point(1),pointarray.point(2));
		element *f;
		f=currentCell->addPath(pointarray,activeLayer);
		modestep=0;
		setModifyAdded();
		}
}

void drawingField::bezier3(){
if (modestep>=4){
		pointarray=element::bezier3(pointarray.point(0),pointarray.point(1),pointarray.point(2),pointarray.point(3));
		element *f;
		f=currentCell->addPath(pointarray,activeLayer);
		modestep=0;
		setModifyAdded();
		}
}

void drawingField::compareCell(QString s){
{
		cell *c=findCell(s);
		if ((c!=NULL)&&(c!=currentCell)){
			currentCell->compare(c);
			modestep=0;}
		}
}

void drawingField::deleteExceptOneLayer(int layer){
  cellList *cells=firstCell;
  prepareUndo();
  while (cells!=NULL){
	if (cells->thisCell!=NULL){
		cells->thisCell->deselectAll();
		elementList *l=cells->thisCell->firstElement;
		while (l!=NULL) {
			if (l->thisElement!=NULL) {
				if (l->thisElement->isText())
					l->thisElement->select=true;
				if (l->thisElement->layerNum != layer ) {
					if (l->thisElement->isBox()) l->thisElement->select=true;
					if (l->thisElement->isPolygon()) l->thisElement->select=true;
					if (l->thisElement->isPath()) l->thisElement->select=true;
					}
				}
			l=l->nextElement;
			}
		}
	cells->thisCell->deleteSelect();
   	cells=cells->nextCell;
  	}
 setModifyChanged();
 emit selectChange(currentCell->countSelect());
 paint();
 macroAdd("layout->drawing->deleteExeptOneLayer("+str(layer)+");");
}

void drawingField::swapLayer(int i,int k){
  currentCell->swapLayer(i,k);
  setModifyChanged();
}

void drawingField::swapLayerSelect(int i,int k){
  currentCell->swapLayerSelect(i,k);
  setModifyChanged();
}

void drawingField::swapLayerAll(int i,int k){
  cellList *cells=firstCell;
  while (cells!=NULL){
	if (cells->thisCell!=NULL){
		cells->thisCell->swapLayer(i,k);
		}
   	cells=cells->nextCell;
  	}
  setModifyChanged();
}


void drawingField::mapLayer(layerTranslator *t){
	  cellList *cells=firstCell;
  while (cells!=NULL){
	if (cells->thisCell!=NULL){
		cells->thisCell->mapLayer(t);
		}
   	cells=cells->nextCell;
  	}
  setModifyChanged();
};

void drawingField::flat(){
  prepareUndo();
  currentCell->flatSelect();
  setModifyChanged();
}

void drawingField::flatAll(){
  prepareUndo();
  currentCell->flatAllSelect();
  setModifyChanged();
}

void drawingField::groupSimple(){
  cellList *c;
  int i=1;
  QString s1,s2;
  s1="noname_";
  s2=s1+s2.setNum(i);
  while (existCellname(s2)){i++;s2=s1+s2.setNum(i);}
  c=addCell();
  c->thisCell->cellName=s2;
  currentCell->group(c->this_cell);
  QPoint pos(INT_MAX,INT_MAX);
  c->thisCell->minimum(&pos);
  c->thisCell->move(-pos);
  currentCell->addCellref(c->this_cell,pos);
  setModifyChanged();
}


void drawingField::group(){
  cellList *c;
  int i=1;
  QString s1,s2;
  s1="noname_";
  s2=s1+s2.setNum(i);
  while (existCellname(s2)){i++;s2=s1+s2.setNum(i);}
  c=addCell();
  c->thisCell->cellName=s2;
  currentCell->group(c->this_cell);
  if (c->thisCell->firstElement==NULL) return;
  QPoint pos(INT_MAX,INT_MAX);
  c->thisCell->minimum(&pos);
  c->thisCell->move(-pos);
  cellList *cl=firstCell;
  cell *foundCell=NULL;
  //suche, ob cell bereits existiert
  while (cl!=NULL){
	  if (cl->thisCell!=NULL){
		  if (cl!=c){
			  if (c->thisCell->identical(cl->thisCell)){
				  foundCell=cl->thisCell;
			  }
		  }
	  }
	  cl=cl->nextCell;
  }
  if (foundCell==NULL)
    currentCell->addCellref(c->this_cell,pos);
  else {
    deleteCell(c->thisCell);
	currentCell->addCellref(foundCell,pos);
  }
  setModifyChanged();
}


int drawingField::groupStructure(){
  cellList *c;
  int i=1;
  QString s1,s2;
  s1="noname_";
  s2=s1+s2.setNum(i);
  while (existCellname(s2)){i++;s2=s1+s2.setNum(i);}
  c=addCell();
  c->thisCell->cellName=s2;
  currentCell->group(c->this_cell);
  if (c->thisCell->firstElement==NULL) return 0;
  QPoint pos(INT_MAX,INT_MAX);
  c->thisCell->minimum(&pos);
  c->thisCell->move(-pos);
  cellList *cl=firstCell;
  cell *foundCell=NULL;
  //suche, ob cell bereits existiert
  while (cl!=NULL){
	  if (cl->thisCell!=NULL){
		  if (cl!=c){
			  if (c->thisCell->identical(cl->thisCell)){
				  foundCell=cl->thisCell;
			  }
		  }
	  }
	  cl=cl->nextCell;
  }
  if (foundCell==NULL){
    currentCell->addCellref(c->this_cell,pos);
	foundCell=c->this_cell;
  }
  else {
    deleteCell(c->thisCell);
	currentCell->addCellref(foundCell,pos);
  }
  int num=currentCell->groupStructure(foundCell);
  setModifyChanged();
  return num+1;
}

int drawingField::groupGlobal(){
  cellList *c;
  int i=1;
  QString s1,s2;
  s1="noname_";
  s2=s1+s2.setNum(i);
  while (existCellname(s2)){i++;s2=s1+s2.setNum(i);}
  c=addCell();
  c->thisCell->cellName=s2;
  currentCell->group(c->this_cell);
  if (c->thisCell->firstElement==NULL) return 0;
  QPoint pos(INT_MAX,INT_MAX);
  c->thisCell->minimum(&pos);
  c->thisCell->move(-pos);
  cellList *cl=firstCell;
  cell *foundCell=NULL;
  //suche, ob cell bereits existiert
  while (cl!=NULL){
	  if (cl->thisCell!=NULL){
		  if (cl!=c){
			  if (c->thisCell->identical(cl->thisCell)){
				  foundCell=cl->thisCell;
			  }
		  }
	  }
	  cl=cl->nextCell;
  }
  if (foundCell==NULL){
    currentCell->addCellref(c->this_cell,pos);
	foundCell=c->this_cell;
  }
  else {
    deleteCell(c->thisCell);
	currentCell->addCellref(foundCell,pos);
  }
  int num=0;
  cellList *cl_=firstCell;
  uint numEl1,numEl2;
  QPoint p1,p2;
  foundCell->paintInfoGet(&p1,&p2,&numEl1);
  while (cl_!=NULL){
	  if ((cl_->thisCell!=NULL)&&(cl_->thisCell!=foundCell)) {
			cl_->thisCell->paintInfoGet(&p1,&p2,&numEl2);
			if (numEl2>numEl1) num+=cl_->thisCell->groupStructure(foundCell);
	  }
   cl_=cl_->nextCell;
  }
  setModifyChanged();
  return num+1;
}


void drawingField::toBox(){
  currentCell->toBoxSelect();
  setModifyChanged();
}

void drawingField::toCircle(){
  currentCell->toCircleSelect();
  setModifyChanged();
}

void drawingField::toPolygon(){
  currentCell->toPolygonSelect();
  setModifyChanged();
}

void drawingField::closeToPolygon(){
  currentCell->closeToPolygonSelect();
  setModifyChanged();
}

void drawingField::closedPathToPolygon(){
  currentCell->convertToPolygonIfClosedSelect();
  setModifyChanged();
}

void drawingField::setWidth(int w){
  currentCell->setWidthSelect(w);
  setModifyChanged();
}

void drawingField::setCap(int w){
  currentCell->setCapSelect(w);
  setModifyChanged();
}

void drawingField::fSelect(){
 if (modestep==1) {
	elementList *el=currentCell->nearestForm(pointarray.point(0));
	   	if (el!=NULL)
	   	if (el->thisElement!=NULL)
			el->thisElement->selectAll();
 	}
 else if (modestep>1) {
	currentCell->fSelect(makeRect(pointarray.point(1),pointarray.point(0)));
 	}
 modestep=0;
}

void drawingField::fAllSelect(){
 if (modestep>1) {
	currentCell->fAllSelect(makeRect(pointarray.point(1),pointarray.point(0)));
 	}
 modestep=0;
}

void drawingField::fDeselect(){
 if (modestep==1) {
	elementList *el=currentCell->nearestForm(pointarray.point(0));
	   	if (el!=NULL)
	   	if (el->thisElement!=NULL)
			el->thisElement->deselectAll();
 	}
 else if (modestep>1) {
	currentCell->fDeselect(makeRect(pointarray.point(1),pointarray.point(0)));
 	}
 modestep=0;
}

void drawingField::fAllDeselect(){
if (modestep>1) {
	currentCell->fAllDeselect(makeRect(pointarray.point(1),pointarray.point(0)));
 	}
 modestep=0;
}

void drawingField::pSelect(){
 if (modestep==1) {
	   	QPoint p_;
		elementList *el;
		el=currentCell->nearestPoint(pointarray.point(0),&p_);
		currentCell->pSelect(makeRect(p_,p_));
 	}
 else if (modestep>1) {
	currentCell->pSelect(makeRect(pointarray.point(1),pointarray.point(0)));
 	}
 modestep=0;
}

void drawingField::pDeselect(){
 if (modestep==1) {
	   	QPoint p_;
		elementList *el;
		el=currentCell->nearestPoint(pointarray.point(0),&p_);
		currentCell->pDeselect(makeRect(p_,p_));
 	}
 else if (modestep>1) {
	currentCell->pDeselect(makeRect(pointarray.point(1),pointarray.point(0)));
 	}
 modestep=0;
}

void drawingField::cSelect(){
 if (modestep==1) {
	elementList *el=currentCell->nearestCell(pointarray.point(0));
	 if (el!=NULL)
	  if (el->thisElement!=NULL)
			el->thisElement->selectAll();
 	}
 else if (modestep>1) {
	currentCell->cSelect(makeRect(pointarray.point(1),pointarray.point(0)));
 	}
 modestep=0;
}

void drawingField::cDeselect(){
 if (modestep==1) {
	elementList *el=currentCell->nearestCell(pointarray.point(0));
	 if (el!=NULL)
	  if (el->thisElement!=NULL)
			el->thisElement->deselectAll();
 	}
 else if (modestep>1) {
	currentCell->cDeselect(makeRect(pointarray.point(1),pointarray.point(0)));
 	}
 modestep=0;
}

void drawingField::move(){
 if (modestep==1) {
	currentCell->moveSelect(pointarray.point(0));
	setModifyChanged();
 	}
 else if (modestep>1) {
	currentCell->moveSelect(pointarray.point(1)-pointarray.point(0));
	setModifyChanged();
 	}
 modestep=0;
}

 void drawingField::moveOrigin(){
 if (modestep>=1) {
	selectAll();
	currentCell->moveSelect(-pointarray.point(0));
	deselectAll();
	cellList *e=firstCell;
  	while (e!=NULL){
		if (e->thisCell!=NULL)
			if (e->thisCell!=currentCell){
			e->thisCell->moveOrigin(currentCell,pointarray.point(0));
			}
		e=e->nextCell;
	}
	setModifyChanged();
 	}
 modestep=0;
}

void drawingField::moveX(){
if (modestep>1) {
	currentCell->moveSelect(QPoint((pointarray.point(1)-pointarray.point(0)).x(),0));
	setModifyChanged();
 	}
 modestep=0;
}

void drawingField::moveY(){
if (modestep>1) {
	currentCell->moveSelect(QPoint(0,(pointarray.point(1)-pointarray.point(0)).y()));
	setModifyChanged();
 	}
 modestep=0;
}

void drawingField::cut(){
if (modestep>=2) {
	setModifyChanged();
	currentCell->cutSelect(pointarray.point(1),pointarray.point(0));
 	}
 modestep=0;
}

void drawingField::mirror(){
if (modestep>=2) {
	setModifyChanged();
	currentCell->mirrorSelect(pointarray.point(1),pointarray.point(0));
 	}
 modestep=0;
}

void drawingField::rotate(double angle){
if (modestep>=1) {
	currentCell->rotateSelect(angle,pointarray.point(0));
	setModifyChanged();
 	}
 modestep=0;
}

void drawingField::copy(){
 if (modestep==1) {
	currentCell->copySelect(pointarray.point(0));
	setModifyChanged();
 	}
 else if (modestep>1) {
	currentCell->copySelect(pointarray.point(1)-pointarray.point(0));
	setModifyChanged();
 	}
 modestep=0;
}


void drawingField::arrayCopy(int nx, int ny ){
 QPoint p;
 if (modestep==1) {
	p=pointarray.point(0);
	setModifyChanged();
 	}
 else if (modestep>1) {
	p=(pointarray.point(1)-pointarray.point(0));
	setModifyChanged();
 	}
 else return;
 for (int y=0;y<ny;y++) {
	for (int x=1;x<nx;x++)
		currentCell->copySelect(QPoint(p.x(),0));
	if (y<ny-1) currentCell->copySelect(QPoint(-(nx-1)*p.x(),p.y()));
	}

 modestep=0;
}

void drawingField::scale(){
if (modestep>=3) {
	setModifyChanged();
	currentCell->scaleSelect(pointarray.point(0),pointarray.point(1),pointarray.point(2));
 	}
 modestep=0;
}


void drawingField::copyCurrentCell(){
   cell *old;
   old=currentCell;
   cellList *c;
   int i=1;
   QString s1,s2;
   s1=old->cellName+"_copy";
   if (existCellname(s1)){
 	 s2=s1+s2.setNum(i);
 	 while (existCellname(s2)){i++;s2=s1+s2.setNum(i);}
	 s1=s2;
	}
   c=addCell();
   c->this_cell->cellName=s1;
   setCell(s1);
   point(0,0);
   cellRef(old->cellName);
   selectAll();
   flat();
   deselectAll();
   scaleFull();
}

void drawingField::stripUnneeded(){
  cellList *cell_list;
  QHash<cell*,bool> list;
  if (firstCell==NULL) addCell();
  for (cell_list=firstCell;cell_list!=NULL;cell_list=cell_list->nextCell){
    list[cell_list->thisCell]=true;
  }
  currentCell->removeDependMultilevel(&list);
  	
//  QStringList list;
//  list.clear();
//  currentCell->listDependMultilevel(firstCell,&list);
  cellList *l=firstCell;
  cellList *help=l;
  while (l!=NULL){
	help=l->nextCell;
	if (l->thisCell!=currentCell&&(l->thisCell != NULL ))
		if ( list[l->thisCell]) {
			deleteCell(l->thisCell);
			setModifyChanged();
		}
	l=help;
	}
}

void drawingField::stripEmptyCells(){
  resetUndo();
  cellList *l=firstCell;
  bool b=false;
  while (l!=NULL){
	if ((l->thisCell != NULL )){
		if (l->thisCell->firstElement==NULL){
		cell *c=l->thisCell;
		l=l->nextCell;
		if (c==currentCell)b=true;
		deleteCell(c);
		setModifyChanged();
		}
		else
		l=l->nextCell;
	}
	else
		l=l->nextCell;
	}
  if (firstCell==NULL)addCell();
  if (b) currentCell=findTopCell();
}

void drawingField::removeCellArrays(){
  cellList *l=firstCell;
  setModifyChanged();
  while (l!=NULL){
	if ((l->thisCell != NULL ))
		l->thisCell->flatCellrefArray();
		
	l=l->nextCell;
	}
  
}

void drawingField::removeNotOrthogonalCellref(){
}

void drawingField::removeScaledCellref(){
}

void drawingField::stripIdenticalElements(){
	currentCell->stripIdenticalElements();
}

void drawingField::extractCurrentCell(){
   selectAll();
   flatAll();
   deselectAll();
   cellList *cl=new cellList();
   cellList *help=firstCell;
   firstCell=cl;
   cl->thisCell=currentCell;
   while (help!=NULL){
   	cellList *h2;
   	h2=help;
   	help=help->nextCell;
	if (h2->thisCell!=NULL) 
		if (h2->thisCell!= currentCell) delete h2->thisCell;
	h2->thisCell=NULL;
	delete h2;
   }
}


void drawingField::extractActiveLayer(){
  cellList *cells=firstCell;
  while (cells!=NULL){
	if (cells->thisCell!=NULL){
		cells->thisCell->deselectAll();
		elementList *l=cells->thisCell->firstElement;
		while (l!=NULL) {
			if (l->thisElement!=NULL) {
				if (l->thisElement->isText())
					l->thisElement->select=true;
				if (l->thisElement->layerNum != activeLayer ) {
					if (l->thisElement->isBox()) l->thisElement->select=true;
					if (l->thisElement->isPolygon()) l->thisElement->select=true;
					if (l->thisElement->isPath()) l->thisElement->select=true;
					}
				}
			l=l->nextElement;
			} 	
		}
	cells->thisCell->deleteSelect();
   	cells=cells->nextCell;
  	}
  firstCell->paintInfoClear();
}

void drawingField::writeViewMacro(QString fileName){
 errorreport report;
 report.setTitle(tr("Generate Set View Macro \"")+fileName+"\"");
 try { 
  QFile f( fileName );
  if ( !f.open( QIODevice::WriteOnly ) ) {
	throw QString(tr("Can not open File."));
  }
  QString s,t;
  QTextStream stream( &f );
  stream<<"#!/usr/bin/layout\n";
  int i=fileName.lastIndexOf("/",-1);
  if (i!=0) fileName=fileName.mid(i+1);
  stream<<"#name=View file: "<<fileName<<"\n";
  stream<<"#help=View Set Macro automatily generated\n\n\n";
  stream<<"int main(){\n";
  stream<<"layout->drawing->setCell(\""+currentCell->cellName+"\");\n";
  t="";
  double d; 
  int k;
  getView(&d,&i,&k);
  s.setNum(d,'f',9);
  t+=s+",";
  s.setNum(i);
  t+=s+",";
  s.setNum(k);
  t+=s;
  stream<<"layout->drawing->setView("+t+");\n";
  stream<<"}\n";
  f.close();
  macroAdd("layout->drawing->writeViewMacro(\""+fileName+"\");");
}
catch (QString s){
  report.addItem(tr("Aborted. "),0);
  report.addItem(s,1);
 }
  report.showReport();   
}

void drawingField::startMacroRecording(){
record=true;
macro="";
}

void drawingField::stopMacroRecording(QString fileName){
  errorreport report;
 report.setTitle(tr("Write recorded macro \"")+fileName+"\"");
 try { 
  QFile f( fileName );
  if ( !f.open( QIODevice::WriteOnly ) ) {
	throw QString(tr("Can not open File."));
  }
  QString s,t;
  QTextStream stream( &f );
  stream<<"#!/usr/bin/layout\n";
  int i=fileName.lastIndexOf("/",-1);
  if (i!=0) fileName=fileName.mid(i+1);
  stream<<"#name=Macro: "<<fileName<<"\n";
  s=QDate::currentDate().toString();
  stream<<"#help=Recorded "+s+"\n\n\n";
  stream<<"int main(){\n";
  stream<<macro;
  stream<<"\n}\n";
  f.close();
}
catch (QString s){
  report.addItem(tr("Aborted. "),0);
  report.addItem(s,1);
 }
  report.showReport();   
  record=false;
}


// function on datamutex

void drawingField::mutexInit(){
  mutexPaint=false;
  mutexChange=false;
  mutexRead=0;
  mutexAdd=false;
  
}

void drawingField::mutexStatus(){
printf("draw mutex: %d %d %d %d\n",mutexPaint,mutexChange,mutexRead,mutexAdd);
}
 /*     QReadWriteLock mutex;
   void mutexInit();
   bool mutexPaint;
   bool mutexChange;
   bool mutexAdd;
   uint mutexRead;
   QMutex mutexInternal;
   bool mutexPaintTryLock();
   void mutexPaintUnlock();
   bool mutexAddGuiTryLock();
   void mutexAddUnlock();
   bool mutexReadTryLock();
   void mutexReadUnlock();
   void mutexChangeLock();
   bool mutexChangeTryLock();
   bool mutexChangeGuiTryLock();
   void mutexChangeUnlock();
*/

bool drawingField::mutexPaintTryLock(){
  mutexInternal.lock();
  if (mutexChange) {
	mutexInternal.unlock();
	return false;
	}
  mutex.lockForRead ();
  mutexPaint=true;
  mutexInternal.unlock();
  return true;
}

void drawingField::mutexPaintUnlock(){
  mutexInternal.lock();
  mutexPaint=false;
  mutex.unlock();
  mutexInternal.unlock();
}


bool drawingField::mutexAddGuiTryLock(){
  mutexInternal.lock();
  // printf("a:readanz %d\n",mutexRead);
  if (mutexChange||mutexAdd) {
	mutexInternal.unlock();
	emit  message(QString(tr("Error: Operation in progress. Please wait!")));
	return false;
	}
  //setCursor(QCursor(Qt::WaitCursor));
  emit requestWaitCursor();
  mutex.lockForRead ();
  mutexAdd=true;
  mutexInternal.unlock();
  return true;
}

void drawingField::mutexAddUnlock(){
  mutexInternal.lock();
  mutexAdd=false;
  mutex.unlock();
 // setCursor(QCursor(Qt::BlankCursor));
  emit requestBlankCursor();
  mutexInternal.unlock();
}

bool drawingField::mutexReadTryLock(){
  mutexInternal.lock();
  if (mutexChange) {
	mutexInternal.unlock();
	return false;
	}
  mutex.lockForRead();
  mutexRead++;
  mutexInternal.unlock();
  return true;
}

bool drawingField::mutexReadGuiTryLock(){
  mutexInternal.lock();
  //printf("r:readanz %d\n",mutexRead);
  if (mutexChange) {
	mutexInternal.unlock();
	emit  message(QString(tr("Error: Operation in progress. Please wait!")));
	return false;
	}
  mutex.lockForRead();
  mutexRead++;
  mutexInternal.unlock();
  return true;
}

void drawingField::mutexReadLock(){
  mutex.lockForRead();
  mutexInternal.lock();
  mutexRead++;
  mutexInternal.unlock();
}

void drawingField::mutexReadUnlock(){
  mutexInternal.lock();
  mutexRead--;
  mutex.unlock();
  mutexInternal.unlock();
 //printf("%d\n",mutexRead);
}


bool drawingField::mutexChangeGuiTryLock(){
  mutexInternal.lock();
  //printf("c:readanz %d\n",mutexRead);
  if (mutexChange||mutexAdd||(mutexRead!=0)) {
	mutexInternal.unlock();
	emit  message(QString(tr("Error: Operation in progress. Please wait!")));
	return false;
	}
  mutexChange=true;
 // setCursor(QCursor(Qt::WaitCursor));
  emit requestWaitCursor();
  mutexInternal.unlock();
  pixmap->abortPaint();
  mutex.lockForWrite();
  return true;
}

bool drawingField::mutexChangeTryLock(){
  mutexInternal.lock();
  if (mutexChange||mutexAdd||(mutexRead!=0)) {
	mutexInternal.unlock();
	return false;
	}
 // setCursor(QCursor(Qt::WaitCursor));
  emit requestWaitCursor();
  mutexChange=true;
  mutexInternal.unlock();
  pixmap->abortPaint();
  mutex.lockForWrite();
  return true;
}

void drawingField::mutexChangeLock(){
  pixmap->abortPaint();
  mutex.lockForWrite();
  mutexInternal.lock();
  //setCursor(QCursor(Qt::WaitCursor));
  emit requestWaitCursor();
  mutexChange=true;
  mutexInternal.unlock();
}

void drawingField::mutexChangeUnlock(){
  mutexInternal.lock();
  mutexChange=false;
  //setCursor(QCursor(Qt::BlankCursor));
  emit requestBlankCursor();
  reset();
  mutex.unlock();
  mutexInternal.unlock();
}

bool drawingField::eventFilter(QObject *obj, QEvent *event){
 //   printf("eventFilter\n");
//printf("eventtype %d\n",event->type());
     if (event->type()==QEvent::ContextMenu){
		//avoids contextMenu on windows
		event->accept();
		return true;
		}
     if (event->type() == QEvent::KeyPress) {
                QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
                if (keyEvent->key()==Qt::Key_Escape) {
			//printf("modestep %d\n",modestep);
			if ((modestep==0)&&(mode==defaultMode)){
				setDefaultMode();
				if (mutexReadGuiTryLock()){
					deselectAll();
					recountSelect();
					mutexReadUnlock();
					}
				modestep=-1;
				paint();
			}
			else if ((modestep==-1)&&(mode==defaultMode)){
				modestep=-2;
			}
			else if ((modestep==-2)&&(mode==defaultMode)){
				setCommandMode();
				update();
			}
			else if (modestep==0){
				setDefaultMode();
				update();
			}
			else {
				modestep=0;
				if (mode==170){
					setDefaultMode();
					paint();
					update();
				}
				if ((mode<100)||(mode==400)||(mode==312)||(mode==313)|| (mode==182)|| (mode==183)|| (mode==121)|| (mode==120)||(mode==122)) setDefaultMode();
				if (mode>=700) modeHandler->init();
				setMouseHelp();
				update();
			}
			//printf("modestep (%d)\n",modestep);
		}
		if (keyEvent->key()==Qt::Key_Tab) {
			mode=1;
			emit tabPressed();
			update();
		}		
		if (keyEvent->isAutoRepeat()==false)
		if ((keyEvent->key()==Qt::Key_Shift)||
		   (keyEvent->key()==Qt::Key_Control)|| (keyEvent->key()==Qt::Key_Alt)) {
		        //printf("pressed %d\n",int(QApplication::keyboardModifiers ()));
		        int oldModifier=mouseModifiers;
  			mouseModifiers=QApplication::keyboardModifiers ();//keyEvent->modifiers ();
  			if (mouseVisible&&(oldModifier!=mouseModifiers)) {
					prepareOutput();
					repaint();
					}
		}
   }
     else if (event->type() == QEvent::KeyRelease) {
		QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
		if (keyEvent->isAutoRepeat()==false)
   		if ((keyEvent->key()==Qt::Key_Shift)||
		   (keyEvent->key()==Qt::Key_Control)|| (keyEvent->key()==Qt::Key_Alt)) {
		        //printf("released %d\n",int(QApplication::keyboardModifiers ()));
		        int oldModifier=mouseModifiers;
  			mouseModifiers=QApplication::keyboardModifiers ();//keyEvent->modifiers ();
  			if (mouseVisible&&(oldModifier!=mouseModifiers)) {
				prepareOutput();
				repaint();
				}
		}
	}
    if (event->type() == QEvent::WhatsThis) {
	//QWhatsThis::hideText ();
	layout::helpwindow->showModeHelp(mode);
	QWhatsThis::leaveWhatsThisMode ();
	return true;
	}

return QWidget::eventFilter(obj, event);
}

void drawingField::leaveEvent(QEvent *){
   //     printf("leaveEvent\n");
  mouseWidget::set(clear);
  mouseVisible=false;
  setCursor(QCursor(Qt::ForbiddenCursor));
  repaint();
   //       printf("leaveEvent end\n");
}

bool drawingField::mouseMoveFunction(){
  if (mode==0) return true;
  if (mode==200) return true;
  if (mode==703) return true;
  if (mode==590) return true;
  if ((mode>1)&&(mode<100)) return true;
  return false;
}

void drawingField::startDrag(){
  if (dragDropRunning) return;
  if ((mouseButton==Qt::LeftButton)&&(!mouseMoveFunction()))
   {    
	if (mutexReadTryLock()){
		dragDropRunning=true;
		QDrag *drag = new QDrag(this);
		QMimeData *mimeData = new QMimeData;
		writeMimeData(mimeData);
		QByteArray output;
		QBuffer outputBuffer(&output);
		outputBuffer.open(QIODevice::WriteOnly);
		pixmap->getImage().save(&outputBuffer, "PNG");
		mimeData->setData("image/png", output);
		drag->setMimeData(mimeData);
		drag->setPixmap(QPixmap(":/layoutIcon"));
		//mimeData->setText("dies ist der Text.");
		mutexReadUnlock();
		//Qt::DropAction dropAction = drag->start(Qt::CopyAction);
		//dragDropRunning=true;
		drag->start(Qt::CopyAction);
		dragDropRunning=false;
		}
	}
}

void drawingField::dragEnterEvent(QDragEnterEvent *event)
{
    if (!(event->source()==this)) {
	if (event->mimeData()->hasFormat("application/layouteditor"))
		{
		event->setDropAction(Qt::CopyAction);
		event->accept();
	} else
		event->ignore();
	}
}

void drawingField::dropEvent(QDropEvent *event)
{
     if (!(event->source()==this))
	if (event->mimeData()->hasFormat("application/layouteditor")){
	    if (mutexAddGuiTryLock()){
		prepareUndo();
		deselectAll();
		readMimeData(event->mimeData());
		event->acceptProposedAction();
		scaleFull();
		paint();
		emit cellsChange();
		recountSelect();
		setModifyAdded();
		mutexAddUnlock();
		event->setDropAction(Qt::CopyAction);
		event->accept();
		return;
		}
      	}
	event->ignore();
}

void drawingField::writeMimeData(QMimeData *mimeData){
  QByteArray output;
  QBuffer outputBuffer(&output);
  outputBuffer.open(QIODevice::WriteOnly);
  QDataStream stream(&outputBuffer);
  cellList *cell_list;
  QHash<cell*,bool> list;
  if (firstCell==NULL) addCell();
  for (cell_list=firstCell;cell_list!=NULL;cell_list=cell_list->nextCell){
    list[cell_list->thisCell]=true;
  }
  currentCell->removeDependSelectMultilevel(&list);
  
  //currentCell->listDependMultilevelSelect(firstCell,&list);
  for(cellList *e=firstCell;e!=NULL;e=e->next_cell){
	if (list[e->thisCell]==false){
	    e->this_cell->saved=false;
	}
	else
	    e->this_cell->saved=true;
	}
  bool saved=false;
  while (!saved){
	saved=true;
	for(cellList *e=firstCell;e!=NULL;e=e->nextCell){
		if (e->thisCell->saved==false){
			if (!e->thisCell->dependNotSaved()){
					e->thisCell->save(&stream);
					}
			else{saved=false;}};
		}}

  (stream)<<(qint8)(7);
  currentCell->saveSelect(&stream);
  outputBuffer.close();
  mimeData->setData("application/layouteditor", output);
}

void drawingField::readMimeData(const QMimeData *mimeData){
 deselectAll();
 QString cellExisting;
 bool doubleCellName=false;
 QByteArray input=mimeData->data("application/layouteditor");
 QBuffer inputBuffer(&input);
 inputBuffer.open(QIODevice::ReadOnly);
 QDataStream stream(&inputBuffer);
 qint8 el;
 cell *cell_=NULL;
 while (! stream.atEnd()){
 stream >> el;
 //printf("%d\n",el);
 switch (el){
   case 1: //box
	{
	qint16 layer,datatype;
	qint32 a1,a2,a3,a4;
	stream >>layer>>datatype;
	stream >>a1>>a2>>a3>>a4;
	QRect r;
	r.setLeft(a1);
	r.setTop(a2);
	r.setWidth(a3);
	r.setHeight(a4);
	element *e=cell_->addBox(r,layer);
	e->setDatatype(datatype);
	e->select=true;
	}
	break;
  case 2: //polygon
	{
	qint16 layer,datatype,size;
	qint32 x,y;
	stream >>layer>>datatype>>size;
	//printf("%d %d %d\n",layer,datatype,size);
	pointArray p(size);
	for (int i=0;i<size;i++){
		stream>>x>>y;
		p.setPoint(i,x,y);
		//printf("x %d y %d \n",x,y);
		}
	element *e=cell_->addPolygon(p,layer);
	e->setDatatype(datatype);
	e->select=true;
	}
	break;
  case 3: //Path
	{
	qint16 layer,datatype,size,cap;
	qint32 x,y,width;
	stream >>layer>>datatype>>cap>>width>>size;
	pointArray p(size);
	for (int i=0;i<size;i++){
		stream>>x>>y;
		p.setPoint(i,x,y);
		}
	element *e=cell_->addPath(p,layer);
	e->setDatatype(datatype);
	e->setCap(cap);
	e->setWidth(width);
	e->select=true;
	}
	break;
  case 4: //Text
	{
	qint16 layer,datatype,presentation,length;
	qint32 x,y,width;
	qint8 mir;
	qreal mag,angle;
	stream >>layer>>datatype>>presentation>>width;
	stream>>x>>y;
	stream>>angle>>mag>>mir;
	stream>>length;
	//printf("length %d\n",length);
	QString s="";
	char a[1024];
	a[length]=0;
	if (length!=0){
		stream.readRawData (&a[0], length );
		s.append(&a[0]);
	}
	element *e=cell_->addText(layer,QPoint(x,y),s);
	e->setDatatype(datatype);
	e->setPresentation(presentation);
	e->setWidth(width);
	e->rotate(angle);
	e->scale(mag);
	if (mir) e->setMirrorx();
	e->select=true;
	}
	break;
  case 5: //cell
	{
	doubleCellName=false;
	qint16 length;
	stream>>length;
	QString s="";
	char a[1024];
	a[length]=0;
	if (length!=0){
		stream.readRawData (&a[0], length );
		s.append(&a[0]);
	}
	QString s1=s+"_";
	if (existCellname(s)){
		while (existCellname(s1)){s1=s1+"_";}
		cell_=findCell(s);
		cell_->cellName=s1;
		cellExisting=s1;
 		doubleCellName=true;
	}
	cellList *c;
  	c=addCell();
  	c->thisCell->cellName=s;
	cell_=c->thisCell;
	}
	break;
  case 6: //cell end
	if (doubleCellName) {
		cell *exist=findCell(cellExisting);
		if (exist!=NULL)
			if (cell_->identical(exist)){
				cellList *e=firstCell;
  				while (e!=NULL){
					if ((e->thisCell!=NULL)&&(e->thisCell!=exist)&&(e->thisCell!=cell_))  e->thisCell->relink(exist,cell_);
					e=e->nextCell;
				  	}
				deleteCell(exist);
			}
		doubleCellName=false;
	}
	cell_->deselectAll();
	cell_=NULL;
	break;
  case 7: //main cell
	cell_=currentCell;
	break;
  case 8: //Cellref
	{
	qint16 length;
	qint32 x,y;
	qint8 mir;
	qreal mag,angle;
	stream>>x>>y;
	stream>>angle>>mag>>mir;
	stream>>length;
	//printf("length %d\n",length);
	QString s="";
	char a[1024];
	a[length]=0;
	if (length!=0){
		stream.readRawData (&a[0], length );
		s.append(&a[0]);
	}
	element *e=cell_->addCellref(findCell(s),QPoint(x,y));
	e->rotate(angle);
	e->scale(mag);
	if (mir) e->setMirrorx();
	e->select=true;
	}
	break;
  case 9: //CellrefArray
	{
	qint16 length,anzX,anzY;
	qint32 x,y,x1,x2,y1,y2;
	qint8 mir;
	qreal mag,angle;
	stream>>x>>y;
	stream>>anzX>>anzY;
	stream>>x1>>y1;
	stream>>x2>>y2;
	stream>>angle>>mag>>mir;
	stream>>length;
	//printf("length %d\n",length);
	QString s="";
	char a[1024];
	a[length]=0;
	if (length!=0){
		stream.readRawData (&a[0], length );
		s.append(&a[0]);
	}
	pointArray p(3);
	p.setPoint(0,x,y);
	p.setPoint(1,x1,y1);
	p.setPoint(2,x2,y2);
	element *e=cell_->addCellrefArray(findCell(s),p,anzX,anzY);
	e->rotate(angle);
	e->scale(mag);
	if (mir) e->setMirrorx();
	e->select=true;
	}
	break;
 }
 }
 inputBuffer.close();
 firstCell->paintInfoClear();
}


void drawingField::addBoundingBox(){
   if (modestep>1){
	pointarray.resize(modestep);
	element *f;
	int minX,minY,maxX,maxY;
	minX=pointarray.point(0).x();
	maxX=pointarray.point(0).x();
	minY=pointarray.point(0).y();
	maxY=pointarray.point(0).y();
	for (int i=1;i<pointarray.size();i++){
		if (pointarray.point(i).x()>maxX) maxX=pointarray.point(i).x();
		if (pointarray.point(i).x()<minX) minX=pointarray.point(i).x();
		if (pointarray.point(i).y()>maxY) maxY=pointarray.point(i).y();
		if (pointarray.point(i).y()<minY) minY=pointarray.point(i).y();
	}
	QRect rect=makeRect(QPoint(minX,minY),QPoint(maxX,maxY));
	f=currentCell->addBox(rect,activeLayer);
	modestep=0;
	setModifyAdded();
   }
}



void drawingField::addConvexPolygon(){
   if (modestep>2){
	pointarray.resize(modestep);
	element *f;
	QPoint p=pointarray.point(0);
	int lastpoint=0;
	for (int i=1;i<pointarray.size();i++){
	   if (p.x()>pointarray.point(i).x())
		{p=pointarray.point(i);
		lastpoint=i;}
	   else if ((p.x()==pointarray.point(i).x())&&(p.y()>pointarray.point(i).y()))
		{p=pointarray.point(i);
		lastpoint=i;}
	}
	pointArray pa;
	pa.resize(1);
	pa.setPoint(0,p);
	double angle=-500;
	double a;
	int nr=1;
	for (int i=0;i<pointarray.size();i++){
		if (i!=lastpoint) {
			a=element::angle(p,pointarray.point(i));
			if (a>angle) {
				angle=a;
				nr=i;
				}
			}
		}
	pa.resize(pa.size()+1);
	pa.setPoint(pa.size()-1,pointarray.point(nr));
		QString s,s1;
	do {
	angle=-500;
	for (int i=0;i<pointarray.size();i++){
		if (i!=lastpoint) {
			a=element::angle(pa.point(pa.size()-2),pa.point(pa.size()-1),pointarray.point(i));
			if (a>angle) {
				angle=a;
				nr=i;
				}
			}
		}
		lastpoint=nr;
		pa.resize(pa.size()+1);
		pa.setPoint(pa.size()-1,pointarray.point(nr));
	
	}
	while ((pa.point(pa.size()-1).x()>p.x()));
	
	pa.resize(pa.size()+1);
	pa.setPoint(pa.size()-1,p);
	f=currentCell->addPolygon(pa,activeLayer);
	modestep=0;
	setModifyAdded();
	}
}

void drawingField::cellUp(){
	cellList *e=firstCell;
    while (e!=NULL){
	  if (e->thisCell!=NULL){
		if (e->thisCell->useCell(currentCell)) {
			  reset();
			  currentCell=e->thisCell;
			  currentCell->paintInfoClear();
			  modestep=0;
			  scaleFull();
			  emit currentCellChanged();
			  return;
			}
	}
    	e=e->next_cell;
    }
}
void drawingField::cellUpGui(){
}

/*
void drawingField::setRouteMode(QList<pointArray> connections,QString nodename){
	placeDevicename=nodename;
	emit showMessage(nodename);
	mode=160;modestep=0; 
	placeConnections=connections;
	setMouseHelp();
	update();
	//printf("route\n");
	if (layers::num[activeLayer].layerType!=layerTypeConductor) 
		{
			int l=layers::findLevel(0);
			if (l>=0) if (layers::num[l].layerType!=layerTypeConductor) l=layers::findLevel(1);
			if (l<0) {
				setCommandMode();
				return;
			}
			if(layers::num[l].layerType!=layerTypeConductor){
				setCommandMode();
				return;
			}
			activeLayer=l;
			emit activeLayerChanged();
		}
}
*/
void drawingField::setMode(baseMode *modeH){
  if (modeH==NULL) return;
  modeHandler=modeH;
  mode=modeHandler->id();
  modeHandler->init();
}



 

