1 /*******************************************************************
2 
3 Part of the Fritzing project - http://fritzing.org
4 Copyright (c) 2007-2015 Fachhochschule Potsdam - http://fh-potsdam.de
5 
6 Fritzing is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10 
11 Fritzing is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with Fritzing.  If not, see <http://www.gnu.org/licenses/>.
18 
19 ********************************************************************
20 
21 $Revision: 6999 $:
22 $Author: irascibl@gmail.com $:
23 $Date: 2013-04-28 14:14:07 +0200 (So, 28. Apr 2013) $
24 
25 ********************************************************************/
26 
27 
28 #ifndef SKETCHWIDGET_H
29 #define SKETCHWIDGET_H
30 
31 #include <QGraphicsView>
32 #include <QGraphicsItem>
33 #include <QUndoStack>
34 #include <QRubberBand>
35 #include <QGraphicsEllipseItem>
36 #include <QSet>
37 #include <QHash>
38 #include <QMap>
39 #include <QTimer>
40 
41 #include "../items/paletteitem.h"
42 #include "../referencemodel/referencemodel.h"
43 #include "../model/sketchmodel.h"
44 #include "../viewgeometry.h"
45 #include "infographicsview.h"
46 #include "../viewlayer.h"
47 #include "../utils/misc.h"
48 #include "../commands.h"
49 
50 struct ItemCount {
51 	int selCount;
52 	int hasLabelCount;
53 	int visLabelCount;
54 	int itemsCount;
55 	int selRotatable;
56 	int sel45Rotatable;
57 	int selHFlipable;
58 	int selVFlipable;
59 	int obsoleteCount;
60 	int moveLockCount;
61 	int wireCount;
62 };
63 
64 struct SwapThing {
65     bool firstTime;
66     long newID;
67     ItemBase * itemBase;
68     long newModelIndex;
69     QString newModuleID;
70     ViewLayer::ViewLayerPlacement viewLayerPlacement;
71     QList<Wire *> wiresToDelete;
72     QUndoCommand * parentCommand;
73     QHash<ConnectorItem *, ChangeConnectionCommand *> reconnections;
74     QHash<ConnectorItem *, Connector *> byWire;
75     QHash<ConnectorItem *, ConnectorItem *> toConnectorItems;
76     QHash<ConnectorItem *, Connector *> swappedGender;
77     SketchWidget * bbView;
78     QMap<QString, QString> propsMap;
79 };
80 
81 struct RenderThing {
82     bool selectedItems;
83     double printerScale;
84     bool blackOnly;
85     QRectF imageRect;
86     QRectF offsetRect;
87     double dpi;
88 	bool renderBlocker;
89     QRectF itemsBoundingRect;
90     QGraphicsItem * board;
91 	bool empty;
92     bool hideTerminalPoints;
93 };
94 
95 class SizeItem : public QObject, public QGraphicsLineItem
96 {
97 	Q_OBJECT
98 
99 public:
100 	SizeItem();
101 	~SizeItem();
102 };
103 
104 class SketchWidget : public InfoGraphicsView
105 {
106 	Q_OBJECT
107     Q_PROPERTY(QColor gridColor READ gridColor WRITE setGridColor DESIGNABLE true)
108     Q_PROPERTY(double ratsnestWidth READ ratsnestWidth WRITE setRatsnestWidth DESIGNABLE true)
109     Q_PROPERTY(double ratsnestOpacity READ ratsnestOpacity WRITE setRatsnestOpacity DESIGNABLE true)
110 
111 public:
112     SketchWidget(ViewLayer::ViewID, QWidget *parent=0, int size=400, int minSize=300);
113 	~SketchWidget();
114 
115 	void pushCommand(QUndoCommand *, QObject * signalTarget);
116     class WaitPushUndoStack * undoStack();
117     ItemBase * addItem(ModelPart *, ViewLayer::ViewLayerPlacement, BaseCommand::CrossViewType, const ViewGeometry &, long id, long modelIndex, AddDeleteItemCommand * originatingCommand);
118 	ItemBase * addItem(const QString & moduleID, ViewLayer::ViewLayerPlacement, BaseCommand::CrossViewType, const ViewGeometry &, long id, long modelIndex, AddDeleteItemCommand * originatingCommand);
119     void deleteItem(long id, bool deleteModelPart, bool doEmit, bool later);
120     virtual void deleteItem(ItemBase *, bool deleteModelPart, bool doEmit, bool later);
121     void simpleMoveItem(long id, QPointF);
122     void moveItem(long id, ViewGeometry &, bool updateRatsnest);
123 	void moveItem(long id, const QPointF & p, bool updateRatsnest);
124 	void updateWire(long id, const QString & connectorID, bool updateRatsnest);
125 
126     void rotateItem(long id, double degrees);
127     void transformItem(long id, const QMatrix &);
128     void flipItem(long id, Qt::Orientations orientation);
129     void selectItem(long id, bool state, bool updateInfoView, bool doEmit);
130     void selectItem(ItemBase * itemBase);
131     void selectItems(QList<ItemBase *>);
132     void selectItemsWithModuleID(ModelPart *);
133     void addToSketch(QList<ModelPart *> &);
134     void selectDeselectAllCommand(bool state);
135     void changeWire(long fromID, QLineF line, QPointF pos, bool updateConnections, bool updateRatsnest);
136     void changeLeg(long fromID, const QString & connectorID, const QPolygonF &, bool relative, const QString & why);
137     void recalcLeg(long fromID, const QString & connectorID, const QPolygonF &, bool relative, bool active, const QString & why);
138     void rotateLeg(long fromID, const QString & connectorID, const QPolygonF &, bool active);
139     void cut();
140     void copy();
141     void setReferenceModel(class ReferenceModel *referenceModel);
142     class ReferenceModel * referenceModel();
143     void setSketchModel(SketchModel *);
144     void setUndoStack(class WaitPushUndoStack *);
145     void clearSelection();
146 	virtual void loadFromModelParts(QList<ModelPart *> & modelParts, BaseCommand::CrossViewType, QUndoCommand * parentCommand,
147 									bool offsetPaste, const QRectF * boundingRect, bool seekOutsideConnections, QList<long> & newIDs);
148     void changeZ(QHash<long, RealPair * >, double (*pairAccessor)(RealPair *) );
149 	void sendToBack();
150 	void sendBackward();
151 	void bringForward();
152 	void bringToFront();
153     void alignItems(Qt::Alignment);
154 	double fitInWindow();
155 	void rotateX(double degrees, bool rubberBandLegEnabled, ItemBase * originatingItem);
156 	void flipX(Qt::Orientations orientation, bool rubberBandLegEnabled);
157 	void addBendpoint(ItemBase * lastHoverEnterItem, ConnectorItem * lastHoverEnterConnectorItem, QPointF lastLocation);
158 	void flattenCurve(ItemBase * lastHoverEnterItem, ConnectorItem * lastHoverEnterConnectorItem, QPointF lastLocation);
159 
160 	void deleteSelected(Wire *, bool minus);
161 	PaletteItem *getSelectedPart();
162 
163     void addViewLayer(ViewLayer *);
164     void setAllLayersVisible(bool visible);
165     void setLayerVisible(ViewLayer * viewLayer, bool visible, bool doChildLayers);
166 	void setLayerVisible(ViewLayer::ViewLayerID viewLayerID, bool visible, bool doChildLayers);
167     void setLayerActive(ViewLayer * viewLayer, bool active);
168 	void setLayerActive(ViewLayer::ViewLayerID viewLayerID, bool active);
169     bool layerIsVisible(ViewLayer::ViewLayerID);
170     bool layerIsActive(ViewLayer::ViewLayerID);
171 	void sortAnyByZ(const QList<QGraphicsItem *> & items, QList<ItemBase *> & bases);
172  	void mousePressConnectorEvent(ConnectorItem *, QGraphicsSceneMouseEvent *);
173  	void setBackground(QColor);
174     void setBackgroundColor(QColor, bool setPref);
175  	const QColor& background();
176 	QColor standardBackground();
177  	void setItemMenu(QMenu*);
178  	void setWireMenu(QMenu*);
179 	virtual void changeConnection(long fromID,
180 						  const QString & fromConnectorID,
181 						  long toID, const QString & toConnectorID,
182 						  ViewLayer::ViewLayerPlacement,
183 						  bool connect, bool doEmit,
184 						  bool updateConnections);
185 
186  	ItemCount calcItemCount();
187 
188 	ViewLayer::ViewID viewID();
189 	void setViewLayerIDs(ViewLayer::ViewLayerID part, ViewLayer::ViewLayerID wire, ViewLayer::ViewLayerID connector, ViewLayer::ViewLayerID ruler, ViewLayer::ViewLayerID note);
190 	void stickem(long stickTargetID, long stickSourceID, bool stick);
191 	void stickyScoop(ItemBase * stickyOne, bool checkCurrent, CheckStickyCommand *);
192 	void setChainDrag(bool);
193 	void hoverEnterItem(QGraphicsSceneHoverEvent * event, ItemBase * item);
194 	void hoverLeaveItem(QGraphicsSceneHoverEvent * event, ItemBase * item);
195 	void hoverEnterConnectorItem(QGraphicsSceneHoverEvent * event, ConnectorItem * item);
196 	void hoverLeaveConnectorItem(QGraphicsSceneHoverEvent * event, ConnectorItem * item);
197 	void cleanUpWires(bool doEmit, class CleanUpWiresCommand *);
198 
199 	void partLabelChanged(ItemBase *, const QString & oldText, const QString &newtext);
200 	void noteChanged(ItemBase *, const QString & oldText, const QString &newtext, QSizeF oldSize, QSizeF newSize);
201 
202 	void setInfoViewOnHover(bool infoViewOnHover);
203 	virtual ItemBase * addItemAux(ModelPart *, ViewLayer::ViewLayerPlacement, const ViewGeometry &, long id, bool doConnectors, ViewLayer::ViewID, bool temporary);
204 	ItemBase * addItemAuxTemp(ModelPart *, ViewLayer::ViewLayerPlacement, const ViewGeometry &, long id, bool doConnectors, ViewLayer::ViewID, bool temporary);
205 
206     bool swappingEnabled(ItemBase *);
207 
208 	virtual void addViewLayers();
209 
210 	void changeWireColor(long wireId, const QString& color, double opacity);
211 	void changeWireWidth(long wireId, double width);
212 	void changeWireFlags(long wireId, ViewGeometry::WireFlags wireFlags);
213 	void setIgnoreSelectionChangeEvents(bool);
214 	void hideConnectors(bool hide);
215 	void saveLayerVisibility();
216 	void restoreLayerVisibility();
217 	void updateRoutingStatus(CleanUpWiresCommand*, RoutingStatus &, bool manual);
218 	void updateRoutingStatus(RoutingStatus &, bool manual);
219 	virtual bool hasAnyNets();
220 	void ensureLayerVisible(ViewLayer::ViewLayerID);
221 
222 	const QString &selectedModuleID();
223 	virtual bool canDeleteItem(QGraphicsItem * item, int count);
224 	virtual bool canCopyItem(QGraphicsItem * item, int count);
225 	const QString & viewName();
226 	void makeDeleteItemCommand(ItemBase * itemBase, BaseCommand::CrossViewType, QUndoCommand * parentCommand);
227 	virtual void forwardRoutingStatus(const RoutingStatus &);
228 
229 	void collectParts(QList<ItemBase *> & partList);
230 
231 	void movePartLabel(long itemID, QPointF newPos, QPointF newOffset);
232 
233 	void updateInfoView();
234 	virtual void setCurrent(bool current);
235 	void partLabelMoved(ItemBase *, QPointF oldPos, QPointF oldOffset, QPointF newPos, QPointF newOffset);
236 	void rotateFlipPartLabel(ItemBase *, double degrees, Qt::Orientations flipDirection);
237 	void rotateFlipPartLabel(long itemID, double degrees, Qt::Orientations flipDirection);
238 	void showPartLabels(bool show);
239 	void hidePartLabel(ItemBase * item);
240 	void noteSizeChanged(ItemBase * itemBase, const QSizeF & oldSize, const QSizeF & newSize);
241 	void resizeNote(long itemID, const QSizeF & );
242 	class SelectItemCommand* stackSelectionState(bool pushIt, QUndoCommand * parentCommand);
243 	QString renderToSVG(RenderThing &, QGraphicsItem * board, const LayerList &);
244 
245 	bool spaceBarIsPressed();
246 	virtual long setUpSwap(SwapThing &, bool master);
247 	ConnectorItem * lastHoverEnterConnectorItem();
248 	ItemBase * lastHoverEnterItem();
249 	LayerHash & viewLayers();
250 	virtual void createTrace(Wire*, bool useLastWireColor);
251 	virtual void selectAllWires(ViewGeometry::WireFlag);
252 	virtual void tidyWires();
253 	const QString & getShortName();
254 	virtual void setClipEnds(class ClipableWire *, bool);
255 	void getBendpointWidths(class Wire *, double w, double & w1, double & w2, bool & negativeOffsetRect);
256 	virtual bool includeSymbols();
257 	void disconnectAll();
258 	virtual bool canDisconnectAll();
259 	virtual bool ignoreFemale();
260 	virtual ViewLayer::ViewLayerID getWireViewLayerID(const ViewGeometry & viewGeometry, ViewLayer::ViewLayerPlacement);
261 	ItemBase * findItem(long id);
262 	long createWire(ConnectorItem * from, ConnectorItem * to, ViewGeometry::WireFlags, bool dontUpdate, BaseCommand::CrossViewType, QUndoCommand * parentCommand);
263 	QList<ItemBase *> selectAllObsolete();
264 	int selectAllMoveLock();
265 	void setMoveLock(long id, bool lock);
266 	bool partLabelsVisible();
267 	void restorePartLabel(long itemID, QDomElement & element);
268 	void loadLogoImage(ItemBase *, const QString & oldSvg, const QSizeF oldAspectRatio, const QString & oldFilename, const QString & newFilename, bool addName);
269 	void loadLogoImage(long itemID, const QString & oldSvg, const QSizeF oldAspectRatio, const QString & oldFilename);
270 	void loadLogoImage(long itemID, const QString & newFilename, bool addName);
271 	void setNoteFocus(QGraphicsItem *, bool inFocus);
272 
273 	void alignToGrid(bool);
274 	bool alignedToGrid();
275 	void showGrid(bool);
276 	bool showingGrid();
277 	void setGridSize(const QString &);
278     QString gridSizeText();
279 	void saveZoom(double);
280 	double retrieveZoom();
281 	void initGrid();
282 	virtual double defaultGridSizeInches();
283 	void clearPasteOffset();
284 	virtual ViewLayer::ViewLayerPlacement defaultViewLayerPlacement(ModelPart *);
285 	void collectAllNets(QHash<class ConnectorItem *, int> & indexer, QList< QList<class ConnectorItem *>* > & allPartConnectorItems, bool includeSingletons, bool bothSides);
286 	virtual bool routeBothSides();
287 	virtual void changeLayer(long id, double z, ViewLayer::ViewLayerID viewLayerID);
288 	void ratsnestConnect(ConnectorItem * connectorItem, bool connect);
289 	void ratsnestConnect(ItemBase *, bool connect);
290 	void ratsnestConnect(ConnectorItem * c1, ConnectorItem * c2, bool connect, bool wait);
291 	virtual void addDefaultParts();
292 	float getTopZ();
293 	QGraphicsItem * addWatermark(const QString & filename);
294 	void copyHeart(QList<ItemBase *> & bases, bool saveBoundingRects, QByteArray & itemData, QList<long> & modelIndexes);
295 	void pasteHeart(QByteArray & itemData, bool seekOutsideConnections);
296 	ViewGeometry::WireFlag getTraceFlag();
297 	void changeBus(ItemBase *, bool connec, const QString & oldBus, const QString & newBus, QList<ConnectorItem *> &, const QString & message, const QString & oldLayout, const QString & newLayout);
298 	const QString & filenameIf();
299 	void setItemDropOffset(long id, QPointF offset);
300 	void prepLegBendpointMove(ConnectorItem * from, int index, QPointF oldPos, QPointF newPos, ConnectorItem * to, bool changeConnections);
301 	void prepLegCurveChange(ConnectorItem * from, int index, const class Bezier * oldB, const class Bezier * newB, bool triggerFirstTime);
302 	void prepLegBendpointChange(ConnectorItem * from, int oldCount, int newCount, int index, QPointF pos, const class Bezier *, const class Bezier *, const class Bezier *, bool triggerFirstTime);
303 	void prepLegSelection(ItemBase *);
304 	void changeWireCurve(long id, const Bezier *, bool autoroutable);
305 	void changeLegCurve(long id, const QString & connectorID, int index, const Bezier *);
306 	void addLegBendpoint(long id, const QString & connectorID, int index, QPointF, const class Bezier *, const class Bezier *);
307 	void removeLegBendpoint(long id, const QString & connectorID, int index, const class Bezier *);
308 	void moveLegBendpoint(long id, const QString & connectorID, int index, QPointF);
309 	bool curvyWires();
310 	void setCurvyWires(bool);
311 	bool curvyWiresIndicated(Qt::KeyboardModifiers);
312 	void triggerRotate(ItemBase *, double degrees);
313 	void makeWiresChangeConnectionCommands(const QList<Wire *> & wires, QUndoCommand * parentCommand);
314 	void renamePins(ItemBase *, const QStringList & oldLabels, const QStringList & newLabels, bool singleRow);
315 	void renamePins(long itemID, const QStringList & labels, bool singleRow);
316 	void getRatsnestColor(QColor &);
317 	VirtualWire * makeOneRatsnestWire(ConnectorItem * source, ConnectorItem * dest, bool routed, QColor color, bool force);
318 	double ratsnestOpacity();
319     void setRatsnestOpacity(double);
320 	double ratsnestWidth();
321     void setRatsnestWidth(double);
322 	void setAnyInRotation();
323 	ConnectorItem * findConnectorItem(ConnectorItem * foreignConnectorItem);
324 	void setGroundFillSeed(long id, const QString & connectorID, bool seed);
325     void setWireExtras(long id, QDomElement &);
326     void resolveTemporary(bool, ItemBase *);
327 	virtual bool sameElectricalLayer2(ViewLayer::ViewLayerID, ViewLayer::ViewLayerID);
328 	void deleteMiddle(QSet<ItemBase *> & deletedItems, QUndoCommand * parentCommand);
329     void setPasting(bool);
330     void showUnrouted();
331 	QPointF alignOneToGrid(ItemBase * itemBase);
332 	void showEvent(QShowEvent * event);
333     void blockUI(bool);
334     void viewItemInfo(ItemBase * item);
335     virtual QHash<QString, QString> getAutorouterSettings();
336     virtual void setAutorouterSettings(QHash<QString, QString> &);
337     void hidePartLayer(long id, ViewLayer::ViewLayerID, bool hide);
338     void hidePartLayer(ItemBase *, ViewLayer::ViewLayerID, bool hide);
339     void moveItem(ItemBase *, double x, double y);
340     QColor gridColor() const;
341     void setGridColor(QColor);
342     bool everZoomed() const;
343     void setEverZoomed(bool);
344     void testConnectors();
345     void updateWires();
346 
347 protected:
348     void dragEnterEvent(QDragEnterEvent *);
349 	bool dragEnterEventAux(QDragEnterEvent *);
350 	virtual bool canDropModelPart(ModelPart *);
351 
352     void dragLeaveEvent(QDragLeaveEvent *);
353     void dragMoveEvent(QDragMoveEvent *);
354     void dropEvent(QDropEvent *);
355 	virtual void mousePressEvent(QMouseEvent *);
356 	void mouseMoveEvent(QMouseEvent *);
357 	void mouseReleaseEvent(QMouseEvent *);
358     void mouseDoubleClickEvent (QMouseEvent *);
359     void contextMenuEvent(QContextMenuEvent *);
360     bool viewportEvent(QEvent *);
361     void paintEvent(QPaintEvent *);
362     virtual PaletteItem* addPartItem(ModelPart * , ViewLayer::ViewLayerPlacement, PaletteItem *, bool doConnectors, bool & ok, ViewLayer::ViewID, bool temporary);
363 	void clearHoldingSelectItem();
364 	bool startZChange(QList<ItemBase *> & bases);
365 	void continueZChange(QList<ItemBase *> & bases, int start, int end, bool (*test)(int current, int start), int inc, const QString & text);
366 	void continueZChangeMax(QList<ItemBase *> & bases, int start, int end, bool (*test)(int current, int start), int inc, const QString & text);
367 	void continueZChangeAux(QList<ItemBase *> & bases, const QString & text);
368 	virtual ViewLayer::ViewLayerID getDragWireViewLayerID(ConnectorItem *);
369 	ViewLayer::ViewLayerID getPartViewLayerID();
370 	ViewLayer::ViewLayerID getRulerViewLayerID();
371 	ViewLayer::ViewLayerID getConnectorViewLayerID();
372 	virtual ViewLayer::ViewLayerID getLabelViewLayerID(ItemBase *);
373 	ViewLayer::ViewLayerID getNoteViewLayerID();
374 	void dragMoveHighlightConnector(QPoint eventPos);
375 
376 	void addToScene(ItemBase * item, ViewLayer::ViewLayerID viewLayerID);
377 	ConnectorItem * findConnectorItem(ItemBase * item, const QString & connectorID, ViewLayer::ViewLayerPlacement);
378 	bool checkMoved(bool wait);
379 
380 	void changeConnectionAux(long fromID, const QString & fromConnectorID,
381 						  long toID, const QString & toConnectorID,
382 						  ViewLayer::ViewLayerPlacement,
383 						  bool connect, bool updateConnections);
384 
385 	void cutDeleteAux(QString undoStackMessage, bool minus, Wire * wire);
386 	void deleteAux(QSet<ItemBase *> & deletedItems, QUndoCommand * parentCommand, bool doPush);
387 
388 	ChangeConnectionCommand * extendChangeConnectionCommand(BaseCommand::CrossViewType, long fromID, const QString & fromConnectorID,
389 									   long toID, const QString & toConnectorID,
390 									   ViewLayer::ViewLayerPlacement,
391 									   bool connect, QUndoCommand * parent);
392 	ChangeConnectionCommand * extendChangeConnectionCommand(BaseCommand::CrossViewType, ConnectorItem * fromConnectorItem, ConnectorItem * toConnectorItem,
393 										ViewLayer::ViewLayerPlacement,
394 										bool connect, QUndoCommand * parentCommand);
395 
396 
397 	void keyPressEvent(QKeyEvent *);
398 	void keyReleaseEvent(QKeyEvent *);
399 	void clearTemporaries();
400 	void dragWireChanged(class Wire* wire, ConnectorItem * from, ConnectorItem * to);
401 	void dragRatsnestChanged();
402 	void killDroppingItem();
403 	ViewLayer::ViewLayerID getViewLayerID(ModelPart *, ViewLayer::ViewID, ViewLayer::ViewLayerPlacement);
404 	ItemBase * overSticky(ItemBase *);
405 	virtual void setNewPartVisible(ItemBase *);
406 	virtual bool collectFemaleConnectees(ItemBase *, QSet<ItemBase *> &);
407 	virtual bool checkUnder();
408 	virtual void findConnectorsUnder(ItemBase * item);
409 
410 	bool currentlyInfoviewed(ItemBase *item);
411 	void resizeEvent(QResizeEvent *);
412 
413 	void addViewLayersAux(const LayerList &, const LayerList & layersFromBelow, float startZ = 1.5);
414 	virtual bool disconnectFromFemale(ItemBase * item, QHash<long, ItemBase *> & savedItems, ConnectorPairHash &, bool doCommand, bool rubberBandLegEnabled, QUndoCommand * parentCommand);
415 	void clearDragWireTempCommand();
416 	bool draggingWireEnd();
417 	void moveItems(QPoint globalPos, bool checkAutoScroll, bool rubberBandLegEnabled);
418 	virtual ViewLayer::ViewLayerID multiLayerGetViewLayerID(ModelPart * modelPart, ViewLayer::ViewID, ViewLayer::ViewLayerPlacement, LayerList &);
419 	virtual BaseCommand::CrossViewType wireSplitCrossView();
420 	virtual bool canChainMultiple();
421 	virtual bool canChainWire(Wire *);
422 	virtual bool canDragWire(Wire *);
423 	virtual bool canCreateWire(Wire * dragWire, ConnectorItem * from, ConnectorItem * to);
424 	//virtual bool modifyNewWireConnections(Wire * dragWire, ConnectorItem * fromOnWire, ConnectorItem * from, ConnectorItem * to, QUndoCommand * parentCommand);
425 	virtual void setUpColor(ConnectorItem * fromConnectorItem, ConnectorItem * toConnectorItem, Wire * wire, QUndoCommand * parentCommand);
426 	void setupAutoscroll(bool moving);
427 	void turnOffAutoscroll();
428 	bool checkAutoscroll(QPoint globalPos);
429 	virtual void setWireVisible(Wire *);
430 	bool matchesLayer(ModelPart * modelPart);
431 
432 	QByteArray removeOutsideConnections(const QByteArray & itemData, QList<long> & modelIndexes);
433 	void addWireExtras(long newID, QDomElement & view, QUndoCommand * parentCommand);
434 	virtual const QString & hoverEnterWireConnectorMessage(QGraphicsSceneHoverEvent * event, ConnectorItem * item);
435 	virtual const QString & hoverEnterPartConnectorMessage(QGraphicsSceneHoverEvent * event, ConnectorItem * item);
436 	void partLabelChangedAux(ItemBase * pitem,const QString & oldText, const QString &newText);
437 	void drawBackground( QPainter * painter, const QRectF & rect );
438 	void handleConnect(QDomElement & connect, ModelPart *, const QString & fromConnectorID, ViewLayer::ViewLayerID, QStringList & alreadyConnected,
439 						QHash<long, ItemBase *> & newItems, QUndoCommand * parentCommand, bool seekOutsideConnections);
440 	void setUpSwapReconnect(SwapThing &, ItemBase * itemBase, long newID, bool master);
441     void makeSwapWire(SketchWidget *, ItemBase *, long newID, ConnectorItem * fromConnectorItem, ConnectorItem * toConnectorItem, Connector * newConnector, QUndoCommand * parentCommand);
442 	bool swappedGender(ConnectorItem * originalConnectorItem, Connector * newConnector);
443 	void setLastPaletteItemSelected(PaletteItem * paletteItem);
444 	void setLastPaletteItemSelectedIf(ItemBase * itemBase);
445 	void prepDragBendpoint(Wire *, QPoint eventPos, bool dragCurve);
446 	void prepDragWire(Wire *);
447 	void clickBackground(QMouseEvent *);
448 	void categorizeDragWires(QSet<Wire *> & wires, QList<ItemBase *> & freeWires);
449 	void categorizeDragLegs(bool rubberBandLegEnabled);
450 	void prepMove(ItemBase * originatingItem, bool rubberBandLegEnabled, bool includeRatsnest);
451 	void initBackgroundColor();
452 	QPointF calcNewLoc(ItemBase * moveBase, ItemBase * detachFrom);
453 	long findPartOrWire(long itemID);
454 	AddItemCommand * newAddItemCommand(BaseCommand::CrossViewType crossViewType, ModelPart *,
455 											   QString moduleID, ViewLayer::ViewLayerPlacement, ViewGeometry & viewGeometry, qint64 id,
456 											   bool updateInfoView, long modelIndex, bool addSubparts, QUndoCommand *parent);
457 	int selectAllItems(QSet<ItemBase *> & itemBases, const QString & msg);
458 	bool moveByArrow(double dx, double dy, QKeyEvent * );
459 	double gridSizeInches();
460 	virtual bool canAlignToTopLeft(ItemBase *);
461 	virtual bool canAlignToCenter(ItemBase *);
462 	virtual void findAlignmentAnchor(ItemBase * originatingItem, QHash<long, ItemBase *> & savedItems, QHash<Wire *, ConnectorItem *> & savedWires);
463 	void alignLoc(QPointF & loc, const QPointF startPoint, const QPointF newLoc, const QPointF originalLoc);
464 	void copyAux(QList<ItemBase *> & bases, bool saveBoundingRects);
465 	void copyDrop();
466 	void dropItemEvent(QDropEvent *event);
467     virtual QString checkDroppedModuleID(const QString & moduleID);
468 	QString makeWireSVG(Wire * wire, QPointF offset, double dpi, double printerscale, bool blackOnly);
469 	QString makeWireSVGAux(Wire * wire, double width, const QString & color, QPointF offset, double dpi, double printerScale, bool blackOnly, bool dashed);
470 
471 	QString makeMoveSVG(double printerScale, double dpi, QPointF & offset);
472 	void prepDeleteProps(ItemBase * itemBase, long id, const QString & newModuleID, QMap<QString, QString> & propsMap, QUndoCommand * parentCommand);
473 	void prepDeleteOtherProps(ItemBase * itemBase, long id, const QString & newModuleID, QMap<QString, QString> & propsMap, QUndoCommand * parentCommand);
474 	virtual ViewLayer::ViewLayerPlacement getViewLayerPlacement(ModelPart *, QDomElement & instance, QDomElement & view, ViewGeometry &);
475 	virtual ViewLayer::ViewLayerPlacement wireViewLayerPlacement(ConnectorItem *);
476 
477 	virtual bool resizingJumperItemPress(ItemBase *);
478 	virtual bool resizingJumperItemRelease();
479 	bool resizingBoardPress(ItemBase *);
480 	bool resizingBoardRelease();
481 	void resizeBoard();
482     void resizeWithHandle(ItemBase * itemBase, double mmW, double mmH);
483 	virtual bool acceptsTrace(const ViewGeometry &);
484 	virtual ItemBase * placePartDroppedInOtherView(ModelPart *, ViewLayer::ViewLayerPlacement, const ViewGeometry & viewGeometry, long id, SketchWidget * dropOrigin);
485 	void showPartLabelsAux(bool show, QList<ItemBase *> & itemBases);
486 	virtual void extraRenderSvgStep(ItemBase *, QPointF offset, double dpi, double printerScale, QString & outputSvg);
487 	virtual ViewLayer::ViewLayerPlacement createWireViewLayerPlacement(ConnectorItem * from, ConnectorItem * to);
488 	virtual Wire * createTempWireForDragging(Wire * fromWire, ModelPart * wireModel, ConnectorItem * connectorItem, ViewGeometry & viewGeometry, ViewLayer::ViewLayerPlacement);
489 	virtual void prereleaseTempWireForDragging(Wire*);
490 	void checkFit(ModelPart * newModelPart, ItemBase * itemBase, long newID,
491 								QHash<ConnectorItem *, Connector *> & found, QList<ConnectorItem *> & notFound,
492 								QHash<ConnectorItem *, ConnectorItem *> & m2f, QHash<ConnectorItem *, Connector *> & byWire,
493 								QHash<QString, QPolygonF> & legs, 	QHash<QString, ConnectorItem *> & formerLegs, QUndoCommand * parentCommand);
494 	void checkFitAux(ItemBase * tempItemBase, ItemBase * itemBase, long newID,
495 								QHash<ConnectorItem *, Connector *> & found, QList<ConnectorItem *> & notFound,
496 								QHash<ConnectorItem *, ConnectorItem *> & m2f, QHash<ConnectorItem *, Connector *> & byWire,
497 								QHash<QString, QPolygonF> & legs, QHash<QString, ConnectorItem *> & formerLegs, QUndoCommand * parentCommand);
498 	void changeLegAux(long fromID, const QString & fromConnectorID, const QPolygonF &, bool reset, bool relative, bool active, const QString & why);
499 	void moveLegBendpoints(bool undoOnly, QUndoCommand * parentCommand);
500 	void moveLegBendpointsAux(ConnectorItem * connectorItem, bool undoOnly, QUndoCommand * parentCommand);
501 	virtual void rotatePartLabels(double degrees, QTransform &, QPointF center, QUndoCommand * parentCommand);
502 	bool checkUpdateRatsnest(QList<ConnectorItem *> & connectorItems);
503 	void makeRatsnestViewGeometry(ViewGeometry & viewGeometry, ConnectorItem * source, ConnectorItem * dest);
504 	virtual double getTraceWidth();
505 	virtual const QString & traceColor(ViewLayer::ViewLayerPlacement);
506 	void createTrace(Wire * fromWire, const QString & commandString, ViewGeometry::WireFlag, bool useLastWireColor);
507 	bool createOneTrace(Wire * wire, ViewGeometry::WireFlag flag, bool allowAny, QList<Wire *> & done, bool useLastWireColor, QUndoCommand * parentCommand);
508 	void removeWire(Wire * w, QList<ConnectorItem *> & ends, QList<Wire *> & done, QUndoCommand * parentCommand);
509     void selectAllWiresFrom(ViewGeometry::WireFlag flag, QList<QGraphicsItem *> & items);
510     bool canConnect(ItemBase * from, ItemBase * to);
511     virtual bool canConnect(Wire * from, ItemBase * to);
512     void removeDragWire();
513     QGraphicsItem * getClickedItem(QList<QGraphicsItem *> & items);
514     void cleanupRatsnests(QList< QPointer<ConnectorItem> > & connectorItems, bool connect);
515     void rotateWire(Wire *, QTransform & rotation, QPointF center, bool undoOnly, QUndoCommand * parentCommand);
516 	QString renderToSVG(RenderThing &, const LayerList &);
517 	QString renderToSVG(RenderThing &, QList<QGraphicsItem *> & itemsAndLabels);
518     QList<ItemBase *> collectSuperSubs(ItemBase *);
519     void squashShapes(QPointF scenePos);
520     void unsquashShapes();
521     virtual bool updateOK(ConnectorItem *, ConnectorItem *);
522     virtual void viewGeometryConversionHack(ViewGeometry &, ModelPart *);
523 
524 protected:
525 	static bool lessThan(int a, int b);
526 	static bool greaterThan(int a, int b);
527 
528 signals:
529 	void itemAddedSignal(ModelPart *, ItemBase *, ViewLayer::ViewLayerPlacement, const ViewGeometry &, long id, SketchWidget * dropOrigin);
530 	void itemDeletedSignal(long id);
531 	void clearSelectionSignal();
532 	void itemSelectedSignal(long id, bool state);
533     void itemMovedSignal(ItemBase *);
534 	void wireDisconnectedSignal(long fromID, QString fromConnectorID);
535 	void wireConnectedSignal(long fromID,  QString fromConnectorID, long toID, QString toConnectorID);
536 	void changeConnectionSignal(long fromID, QString fromConnectorID,
537 								long toID, QString toConnectorID,
538 								ViewLayer::ViewLayerPlacement,
539 								bool connect, bool updateConnections);
540 	void copyBoundingRectsSignal(QHash<QString, QRectF> &);
541 	void cleanUpWiresSignal(CleanUpWiresCommand *);
542 	void selectionChangedSignal();
543 
544 	void resizeSignal();
545 	void dropSignal(const QPoint &pos);
546 	void routingStatusSignal(SketchWidget *, const RoutingStatus &);
547 	void movingSignal(SketchWidget *, QUndoCommand * parentCommand);
548 	void selectAllItemsSignal(bool state, bool doEmit);
549 	void checkStickySignal(long id, bool doEmit, bool checkCurrent, CheckStickyCommand *);
550 	void disconnectAllSignal(QList<ConnectorItem *>, QHash<ItemBase *, SketchWidget *> & itemsToDelete, QUndoCommand * parentCommand);
551 	void setResistanceSignal(long itemID, QString resistance, QString pinSpacing, bool doEmit);
552 	void setPropSignal(long itemID, const QString & prop, const QString & value, bool doRedraw, bool doEmit);
553 	void setInstanceTitleSignal(long id, const QString & oldTitle, const QString & newTitle, bool isUndoable, bool doEmit);
554 	void statusMessageSignal(QString, int timeout);
555 	void showLabelFirstTimeSignal(long itemID, bool show, bool doEmit);
556 	void dropPasteSignal(SketchWidget *);
557 	void changeBoardLayersSignal(int, bool doEmit);
558 	void deleteTracesSignal(QSet<ItemBase *> & deletedItems, QHash<ItemBase *, SketchWidget *> & otherDeletedItems, QList<long> & deletedIDs, bool isForeign, QUndoCommand * parentCommand);
559 	void makeDeleteItemCommandPrepSignal(ItemBase * itemBase, bool foreign, QUndoCommand * parentCommand);
560 	void makeDeleteItemCommandFinalSignal(ItemBase * itemBase, bool foreign, QUndoCommand * parentCommand);
561 	void cursorLocationSignal(double xinches, double yinches, double width=0.0, double height=0.0);
562 	void ratsnestConnectSignal(long id, const QString & connectorID, bool connect, bool doEmit);
563 	void updatePartLabelInstanceTitleSignal(long itemID);
564 	void filenameIfSignal(QString & filename);
565 	void collectRatsnestSignal(QList<SketchWidget *> & foreignSketchWidgets);
566 	void removeRatsnestSignal(QList<struct ConnectorEdge *> & cutSet, QUndoCommand * parentCommand);
567 	void updateLayerMenuSignal();
568     void swapBoardImageSignal(SketchWidget * sketchWidget, ItemBase * itemBase, const QString & filename, const QString & moduleID, bool addName);
569     void canConnectSignal(Wire * from, ItemBase * to, bool & connect);
570     void swapStartSignal(SwapThing & swapThing, bool master);
571 	void showing(SketchWidget *);
572     void clickedItemCandidateSignal(QGraphicsItem *, bool & ok);
573     void resizedSignal(ItemBase *);
574     void cleanupRatsnestsSignal(bool doEmit);
575     void addSubpartSignal(long id, long subpartID, bool doEmit);
576     void getDroppedItemViewLayerPlacementSignal(ModelPart * modelPart, ViewLayer::ViewLayerPlacement &);
577     void packItemsSignal(int columns, const QList<long> & ids, QUndoCommand *parent, bool doEmit);
578 
579 protected slots:
580 	void itemAddedSlot(ModelPart *, ItemBase *, ViewLayer::ViewLayerPlacement, const ViewGeometry &, long id, SketchWidget * dropOrigin);
581 	void itemDeletedSlot(long id);
582 	void clearSelectionSlot();
583 	void itemSelectedSlot(long id, bool state);
584 	void selectionChangedSlot();
585 	void wireChangedSlot(class Wire*, const QLineF & oldLine, const QLineF & newLine, QPointF oldPos, QPointF newPos, ConnectorItem * from, ConnectorItem * to);
586 	void wireChangedCurveSlot(class Wire*, const Bezier * oldB, const Bezier * newB, bool triggerFirstTime);
587 	virtual void wireSplitSlot(class Wire*, QPointF newPos, QPointF oldPos, const QLineF & oldLine);
588 	void wireJoinSlot(class Wire*, ConnectorItem * clickedConnectorItem);
589 	void toggleLayerVisibility();
590 	void wireConnectedSlot(long fromID, QString fromConnectorID, long toID, QString toConnectorID);
591 	void wireDisconnectedSlot(long fromID, QString fromConnectorID);
592 	void changeConnectionSlot(long fromID, QString fromConnectorID, long toID, QString toConnectorID, ViewLayer::ViewLayerPlacement, bool connect, bool updateConnections);
593 	void restartPasteCount();
594 	void dragIsDoneSlot(class ItemDrag *);
595 	void statusMessage(QString message, int timeout = 0);
596 	void cleanUpWiresSlot(CleanUpWiresCommand *);
597 	void updateInfoViewSlot();
598 	void spaceBarIsPressedSlot(bool);
599 	void autoScrollTimeout();
600 	void dragAutoScrollTimeout();
601 	void moveAutoScrollTimeout();
602 	void rememberSticky(long id, QUndoCommand * parentCommand);
603 	void rememberSticky(ItemBase *, QUndoCommand * parentCommand);
604 	void copyBoundingRectsSlot(QHash<QString, QRectF> &);
605 	void deleteRatsnest(Wire *, QUndoCommand * parentCommand);
606 	void deleteTracesSlot(QSet<ItemBase *> & deletedItems, QHash<ItemBase *, SketchWidget *> & otherDeletedItems, QList<long> & deletedIDs, bool isForeign, QUndoCommand * parentCommand);
607 	void vScrollToZero();
608 	void arrowTimerTimeout();
609 	void makeDeleteItemCommandPrepSlot(ItemBase * itemBase, bool foreign, QUndoCommand * parentCommand);
610 	void makeDeleteItemCommandFinalSlot(ItemBase * itemBase, bool foreign, QUndoCommand * parentCommand);
611 	void updatePartLabelInstanceTitleSlot(long itemID);
612 	void changePinLabelsSlot(ItemBase * itemBase, bool singleRow);
613 	void changePinLabels(ItemBase *, bool singleRow);
614 	void collectRatsnestSlot(QList<SketchWidget *> & foreignSketchWidgets);
615 	void removeRatsnestSlot(QList<struct ConnectorEdge *> & cutSet, QUndoCommand * parentCommand);
616     void deleteTemporary();
617     void canConnect(Wire * from, ItemBase * to, bool & connect);
618     long swapStart(SwapThing & swapThing, bool master);
619     virtual void getDroppedItemViewLayerPlacement(ModelPart * modelPart, ViewLayer::ViewLayerPlacement &);
620 
621 public slots:
622 	void changeWireColor(const QString newColor);
623 	void changeWireWidthMils(const QString newWidth);
624  	void selectAllItems(bool state, bool doEmit);
625 	void setNoteText(long itemID, const QString & newText);
626 	void setInstanceTitle(long id, const QString & oldTitle, const QString & newTitle, bool isUndoable, bool doEmit);
627 	void incInstanceTitle(long id);
628 	void showPartLabel(long id, bool showIt);
629 	void checkSticky(long id, bool doEmit, bool checkCurrent, CheckStickyCommand *);
630 	virtual ItemBase * resizeBoard(long id, double w, double h);
631 	void resizeJumperItem(long id, QPointF pos, QPointF c0, QPointF c1);
632 	void disconnectAllSlot(QList<ConnectorItem *>, QHash<ItemBase *, SketchWidget *> & itemsToDelete, QUndoCommand * parentCommand);
633 	void setResistance(long itemID, QString resistance, QString pinSpacing, bool doEmit);
634 	void setResistance(QString resistance, QString pinSpacing);
635 	void setProp(long itemID, const QString & prop, const QString & value, bool redraw, bool doEmit);
636 	virtual void setProp(ItemBase *, const QString & propName, const QString & translatedPropName, const QString & oldValue, const QString & newValue, bool redraw);
637 	void setHoleSize(ItemBase *, const QString & propName, const QString & translatedPropName, const QString & oldValue, const QString & newValue, QRectF & oldRect, QRectF & newRect, bool redraw);
638 	virtual void showLabelFirstTime(long itemID, bool show, bool doEmit);
639 	void resizeBoard(double w, double h, bool doEmit);
640 	virtual void changeBoardLayers(int layers, bool doEmit);
641 	void updateConnectors();
642 	void ratsnestConnect(long id, const QString & connectorID, bool connect, bool doEmit);
643     void cleanupRatsnests(bool doEmit);
644     void addSubpart(long id, long subpartid, bool doEmit);
645     void packItems(int columns, const QList<long> & ids, QUndoCommand *parent, bool doEmit);
646 
647 protected:
648 	enum StatusConnectStatus {
649 		StatusConnectNotTried,
650 		StatusConnectSucceeded,
651 		StatusConnectFailed
652 	};
653 
654 protected:
655 	QPointer<class ReferenceModel> m_referenceModel;
656 	QPointer<SketchModel> m_sketchModel;
657 	ViewLayer::ViewID m_viewID;
658 	class WaitPushUndoStack * m_undoStack;
659 	class SelectItemCommand * m_holdingSelectItemCommand;
660 	class SelectItemCommand * m_tempDragWireCommand;
661 	LayerHash m_viewLayers;
662 	QHash<ViewLayer::ViewLayerID, bool> m_viewLayerVisibility;
663 	QPointer<Wire> m_connectorDragWire;
664 	QPointer<Wire> m_bendpointWire;
665 	ViewGeometry m_bendpointVG;
666 	QPointer<ConnectorItem> m_connectorDragConnector;
667 	bool m_droppingWire;
668 	QPointF m_droppingOffset;
669 	QPointer<ItemBase> m_droppingItem;
670 	int m_moveEventCount;
671 	//QList<QGraphicsItem *> m_lastSelected;  hack for 4.5.something
672 	ViewLayer::ViewLayerID m_wireViewLayerID;
673 	ViewLayer::ViewLayerID m_partViewLayerID;
674 	ViewLayer::ViewLayerID m_rulerViewLayerID;
675 	ViewLayer::ViewLayerID m_connectorViewLayerID;
676 	ViewLayer::ViewLayerID m_noteViewLayerID;
677 	QList<QGraphicsItem *> m_temporaries;
678 	bool m_chainDrag;
679 	QPointF m_mousePressScenePos;
680 	QPointF m_mousePressGlobalPos;
681 	QTimer m_autoScrollTimer;
682 	volatile int m_autoScrollX;
683 	volatile int m_autoScrollY;
684 	volatile int m_autoScrollCount;
685 	QPoint m_globalPos;
686 
687 	QPointer<PaletteItem> m_lastPaletteItemSelected;
688 
689 	int m_pasteCount;
690 	QPointF m_pasteOffset;
691 
692 	// Part Menu
693 	QMenu *m_itemMenu;
694 	QMenu *m_wireMenu;
695 
696 	bool m_infoViewOnHover;
697 
698 	QHash<long, ItemBase *> m_savedItems;
699 	QHash<Wire *, ConnectorItem *> m_savedWires;
700 	QList<ItemBase *> m_additionalSavedItems;
701 	int m_ignoreSelectionChangeEvents;
702 	bool m_current;
703 
704 	QString m_lastColorSelected;
705 
706 	ConnectorPairHash m_moveDisconnectedFromFemale;
707 	bool m_spaceBarIsPressed;
708 	bool m_spaceBarWasPressed;
709 
710 	QPointer<ConnectorItem> m_lastHoverEnterConnectorItem;
711 	QPointer<ItemBase> m_lastHoverEnterItem;
712 	QString m_shortName;
713 	QPointer<Wire> m_dragBendpointWire;
714 	bool m_dragCurve;
715 	QPoint m_dragBendpointPos;
716 	StatusConnectStatus m_statusConnectState;
717 	QList<QGraphicsItem *> m_inFocus;
718 	QString m_viewName;
719 	bool m_movingByArrow;
720 	double m_arrowTotalX;
721 	double m_arrowTotalY;
722 	bool m_movingByMouse;
723 	bool m_alignToGrid;
724 	bool m_showGrid;
725 	double m_gridSizeInches;
726     QString m_gridSizeText;
727 	QPointer<ItemBase> m_alignmentItem;
728 	QPointer<ItemBase> m_originatingItem;
729 	QPointF m_alignmentStartPoint;
730 	double m_zoom;
731 	bool m_draggingBendpoint;
732 	QPointer<SizeItem> m_sizeItem;
733 	int m_autoScrollThreshold;
734 	bool m_clearSceneRect;
735 	QPointer<ItemBase> m_moveReferenceItem;
736 	QPointer<QSvgRenderer> m_movingSVGRenderer;
737 	QPointF m_movingSVGOffset;
738 	QPointer<QGraphicsSvgItem> m_movingItem;
739 	QList< QPointer<ConnectorItem> > m_ratsnestUpdateDisconnect;
740 	QList< QPointer<ConnectorItem> > m_ratsnestUpdateConnect;
741 	QList< QPointer<ConnectorItem> > m_ratsnestCacheDisconnect;
742 	QList< QPointer<ConnectorItem> > m_ratsnestCacheConnect;
743 	QList <ItemBase *> m_checkUnder;
744 	bool m_addDefaultParts;
745 	QPointer<ItemBase> m_addedDefaultPart;
746 	float m_z;
747 	QTimer m_arrowTimer;
748 	bool m_middleMouseIsPressed;
749 	QMultiHash<ItemBase *, ConnectorItem *> m_stretchingLegs;
750 	bool m_curvyWires;
751 	bool m_rubberBandLegWasEnabled;
752 	RoutingStatus m_routingStatus;
753 	bool m_anyInRotation;
754     bool m_pasting;
755 	QPointer<class ResizableBoard> m_resizingBoard;
756     QList< QPointer<ItemBase> > m_squashShapes;
757     QColor m_gridColor;
758     bool m_everZoomed;
759     double m_ratsnestOpacity;
760     double m_ratsnestWidth;
761 
762 public:
763 	static ViewLayer::ViewLayerID defaultConnectorLayer(ViewLayer::ViewID viewId);
764 	static const int PropChangeDelay;
765     static bool m_blockUI;
766 
767 protected:
768 	static const int MoveAutoScrollThreshold;
769 	static const int DragAutoScrollThreshold;
770 };
771 
772 #endif
773