1 //////////////////////////////////////////////////////////////////////////
2 //
3 // pgAdmin III - PostgreSQL Tools
4 //
5 // Copyright (C) 2002 - 2016, The pgAdmin Development Team
6 // This software is released under the PostgreSQL Licence
7 //
8 // hdCompositeFigure.cpp - Base class for all figures composite with figures
9 //
10 //////////////////////////////////////////////////////////////////////////
11 
12 #include "pgAdmin3.h"
13 
14 // wxWindows headers
15 #include <wx/wx.h>
16 #include <wx/dcbuffer.h>
17 #include <wx/pen.h>
18 
19 // App headers
20 #include "hotdraw/figures/hdCompositeFigure.h"
21 #include "hotdraw/figures/hdIFigure.h"
22 #include "hotdraw/utilities/hdArrayCollection.h"
23 #include "hotdraw/tools/hdCompositeFigureTool.h"
24 
hdCompositeFigure()25 hdCompositeFigure::hdCompositeFigure()
26 {
27 	figureFigures = new hdCollection(new hdArrayCollection());
28 	figureHandles = new hdCollection(new hdArrayCollection());
29 }
30 
AddPosForNewDiagram()31 void hdCompositeFigure::AddPosForNewDiagram()
32 {
33 	//Add position for new displaybox at new diagram
34 	hdAttributeFigure::AddPosForNewDiagram();
35 	//Add position to each figure inside this composite figure
36 	hdIteratorBase *iterator = figuresEnumerator();
37 	while(iterator->HasNext())
38 	{
39 		hdIFigure *f = (hdIFigure *) iterator->Next();
40 		f->AddPosForNewDiagram();
41 	}
42 	delete iterator;
43 }
44 
RemovePosOfDiagram(int posIdx)45 void hdCompositeFigure::RemovePosOfDiagram(int posIdx)
46 {
47 	hdAttributeFigure::RemovePosOfDiagram(posIdx);
48 	hdIteratorBase *iterator = figuresEnumerator();
49 	while(iterator->HasNext())
50 	{
51 		hdIFigure *f = (hdIFigure *) iterator->Next();
52 		f->RemovePosOfDiagram(posIdx);
53 	}
54 	delete iterator;
55 }
56 
~hdCompositeFigure()57 hdCompositeFigure::~hdCompositeFigure()
58 {
59 	hdIHandle *tmpH;
60 	//Handles should be delete by their owner (figure)
61 	while(figureHandles->count() > 0)
62 	{
63 		tmpH = (hdIHandle *) figureHandles->getItemAt(0);
64 		figureHandles->removeItemAt(0);
65 		delete tmpH;
66 	}
67 	if(figureHandles)
68 		delete figureHandles;
69 
70 	hdIFigure *tmp;
71 	while(figureFigures->count() > 0)
72 	{
73 		tmp = (hdIFigure *) figureFigures->getItemAt(0);
74 		figureFigures->removeItemAt(0);
75 		delete tmp;
76 	}
77 	if(figureFigures)
78 		delete figureFigures;
79 }
80 
basicMoveBy(int posIdx,int x,int y)81 void hdCompositeFigure::basicMoveBy(int posIdx, int x, int y)
82 {
83 	hdIteratorBase *iterator = figuresEnumerator();
84 	while(iterator->HasNext())
85 	{
86 		hdIFigure *f = (hdIFigure *) iterator->Next();
87 		f->moveBy(posIdx, x, y);
88 	}
89 
90 	basicDisplayBox.x[posIdx] += x;
91 	basicDisplayBox.y[posIdx] += y;
92 	delete iterator;
93 }
94 
containsPoint(int posIdx,int x,int y)95 bool hdCompositeFigure::containsPoint(int posIdx, int x, int y)
96 {
97 	bool out = false;
98 	hdIteratorBase *iterator = figuresEnumerator();
99 	while(iterator->HasNext())
100 	{
101 		hdIFigure *f = (hdIFigure *) iterator->Next();
102 		if(f->containsPoint(posIdx, x, y))
103 		{
104 			out = true; //avoid memory leak
105 		}
106 	}
107 	delete iterator;
108 	return out;
109 }
110 
figuresEnumerator()111 hdIteratorBase *hdCompositeFigure::figuresEnumerator()
112 {
113 	return figureFigures->createIterator();
114 }
115 
figuresInverseEnumerator()116 hdIteratorBase *hdCompositeFigure::figuresInverseEnumerator()
117 {
118 	return figureFigures->createDownIterator();
119 }
120 
121 //Ignore figures at negative positions
getBasicDisplayBox()122 hdMultiPosRect &hdCompositeFigure::getBasicDisplayBox()
123 {
124 	basicDisplayBox.SetSize(wxSize(0, 0));
125 
126 	int posIdx;
127 	hdIteratorBase *iterator = figuresEnumerator();
128 	for(posIdx = 0; posIdx < basicDisplayBox.CountPositions(); posIdx++)
129 	{
130 		basicDisplayBox.SetPosition(posIdx, wxPoint(0, 0));
131 		bool firstFigure = true;
132 
133 		while(iterator->HasNext())
134 		{
135 			hdIFigure *f = (hdIFigure *) iterator->Next();
136 			if(firstFigure)
137 			{
138 				basicDisplayBox.SetPosition(posIdx, f->displayBox().GetPosition(posIdx));
139 				basicDisplayBox.SetSize( f->displayBox().GetSize());
140 				if(f->displayBox().GetPosition(posIdx).x > 0 && f->displayBox().GetPosition(posIdx).y > 0)
141 					firstFigure = false;
142 			}
143 			else
144 			{
145 				if(f->displayBox().GetPosition(posIdx).x > 0 && f->displayBox().GetPosition(posIdx).y > 0)
146 					basicDisplayBox.add(posIdx, f->displayBox().gethdRect(posIdx) );
147 			}
148 		}
149 		iterator->ResetIterator();
150 	}
151 	delete iterator;
152 	return basicDisplayBox;
153 
154 }
155 
handlesEnumerator()156 hdCollection *hdCompositeFigure::handlesEnumerator()
157 {
158 	return figureHandles;
159 }
160 
add(hdIFigure * figure)161 void hdCompositeFigure::add(hdIFigure *figure)
162 {
163 	if(includes(figure))
164 		return;
165 
166 	//Add figure
167 	figureFigures->addItem(figure);
168 	//Check figure available positions for diagrams.
169 	int i, start;
170 	start = figure->displayBox().CountPositions();
171 	for(i = start; i < basicDisplayBox.CountPositions(); i++)
172 	{
173 		figure->AddPosForNewDiagram();
174 	}
175 	//Add figure handles
176 	hdIteratorBase *handlesIterator = figure->handlesEnumerator()->createIterator();
177 	while(handlesIterator->HasNext())
178 	{
179 		hdIHandle *h = (hdIHandle *) handlesIterator->Next();
180 		figureHandles->addItem(h);
181 	}
182 	delete handlesIterator;
183 }
184 
remove(hdIFigure * figure)185 void hdCompositeFigure::remove(hdIFigure *figure)
186 {
187 	if(!includes(figure))
188 		return;
189 
190 	//Remove figure handles
191 	hdIteratorBase *handlesIterator = figure->handlesEnumerator()->createIterator();
192 	while(handlesIterator->HasNext())
193 	{
194 		hdIHandle *h = (hdIHandle *) handlesIterator->Next();
195 		figureHandles->removeItem(h);
196 	}
197 	delete handlesIterator;
198 	//Remove figure
199 	figureFigures->removeItem(figure);
200 }
201 
includes(hdIFigure * figure)202 bool hdCompositeFigure::includes(hdIFigure *figure)
203 {
204 	if(hdAbstractFigure::includes(figure))
205 		return true;
206 
207 	bool out = false;
208 
209 	hdIteratorBase *iterator = figuresEnumerator();
210 	while(iterator->HasNext())
211 	{
212 		hdIFigure *f = (hdIFigure *) iterator->Next();
213 		if(f->includes(figure))
214 			out = true;
215 	}
216 	delete iterator;
217 	return out;
218 }
219 
basicDraw(wxBufferedDC & context,hdDrawingView * view)220 void hdCompositeFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view)
221 {
222 	hdIteratorBase *iterator = figuresEnumerator();
223 	hdIFigure *f = NULL;
224 	while(iterator->HasNext())
225 	{
226 		f = (hdIFigure *) iterator->Next();
227 		f->draw(context, view);
228 	}
229 	delete iterator;
230 }
231 
basicDrawSelected(wxBufferedDC & context,hdDrawingView * view)232 void hdCompositeFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view)
233 {
234 	hdIteratorBase *iterator = figuresEnumerator();
235 	hdIFigure *f = NULL;
236 	while(iterator->HasNext())
237 	{
238 		f = (hdIFigure *) iterator->Next();
239 		f->drawSelected(context, view);
240 	}
241 	delete iterator;
242 }
243 
findFigure(int posIdx,int x,int y)244 hdIFigure *hdCompositeFigure::findFigure(int posIdx, int x, int y)
245 {
246 	hdIFigure *tmp = NULL, *out = NULL;
247 	hdIteratorBase *iterator = figuresInverseEnumerator();
248 	while(iterator->HasNext())
249 	{
250 		tmp = (hdIFigure *)iterator->Next();
251 		if(tmp->containsPoint(posIdx, x, y))
252 		{
253 			out = tmp;
254 			break;
255 		}
256 	}
257 
258 	delete iterator;
259 
260 	return out;
261 }
262 
CreateFigureTool(hdDrawingView * view,hdITool * defaultTool)263 hdITool *hdCompositeFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool)
264 {
265 	return new hdCompositeFigureTool(view, this, defaultTool);
266 }
267 
getFigureAt(int indexOfCollection)268 hdIFigure *hdCompositeFigure::getFigureAt(int indexOfCollection)
269 {
270 	return (hdIFigure *) figureFigures->getItemAt(indexOfCollection);
271 }
272