1 // Thomas Nagy 2007-2021 GPLV3
2 
3 #include <QFileDialog>
4 #include <KMessageBox>
5 #include <QMenuBar>
6 #include <KDE/KApplication>
7 #include <KStandardAction>
8 #include <KRecentFilesAction>
9 #include <KDE/KActionCollection>
10 #include <windef.h>
11 #include <QClipboard>
12 #include <QMouseEvent>
13 #include <QAction>
14 #include <QGraphicsScene>
15 #include <QApplication>
16 #include<QList>
17 #include<QPrintDialog>
18 #include <QSet>
19 #include <QRegExp>
20 #include <QScrollBar>
21 #include <QMenu>
22 #include<QTextDocument>
23 #include <QColorDialog>
24 #include <QtDebug>
25 #include <QtDebug>
26 #include <QTextEdit>
27 #include <QKeyEvent>
28 #include <QScrollBar>
29 #include <QCompleter>
30 #include <QTreeView>
31 #include <QHeaderView>
32 #include <QAction>
33 #include <QStandardItemModel>
34 #include <QPrinter>
35 #include <QSvgGenerator>
36 #include <QDesktopWidget>
37 #include <QStandardPaths>
38 #include "aux.h"
39 #include <QRadioButton>
40 #include <QSpinBox>
41 #include "con.h"
42 #include <math.h>
43 #include "kurlrequester.h"
44 #include "sem_mediator.h"
45 #include "box_item.h"
46 #include "box_dot.h"
47 #include "box_label.h"
48 #include "box_database.h"
49 #include "box_fork.h"
50 #include "box_chain.h"
51 #include "box_link.h"
52 #include "box_component.h"
53 #include "box_rectangle.h"
54 #include "box_pipe.h"
55 #include "box_node.h"
56 #include "box_decision.h"
57 #include "box_actor.h"
58 #include "box_matrix.h"
59 #include "box_frame.h"
60 #include "box_class.h"
61 #include "box_cloud.h"
62 #include "box_entity.h"
63 #include "data_item.h"
64 #include "box_usecase.h"
65 #include "box_view.h"
66  #include"box_sequence.h"
67 #include "sembind.h"
68  #include "mem_box.h"
69 	#include "export_fig_dialog.h"
70 #include "box_document_properties.h"
71 
72 #define ALIGN_LEFT 22
73 #define ALIGN_CENTER 33
74 #define ALIGN_RIGHT 44
75 #define ALIGN_TOP 55
76 #define ALIGN_MIDDLE 66
77 #define ALIGN_BOTTOM 77
78 
79 #define SAME_WIDTH 101
80 #define SAME_HEIGHT 102
81 #define SAME_WIDTH_HEIGHT 103
82 
83 #define PIPAD 20
84 
85 class box_reader : public QXmlDefaultHandler
86 {
87     public:
88 	box_reader(box_view*);
89 
90 	QString m_sBuf;
91 	int m_iVersion;
92 	box_view *m_oMediator;
93 	data_link *m_oCurrent;
94 	int m_iId;
95 
96 	bool startElement(const QString&, const QString&, const QString&, const QXmlAttributes&);
97 	bool endElement(const QString&, const QString&, const QString&);
98 	bool characters(const QString &i_sStr);
99 };
100 
box_reader(box_view * i_oControl)101 box_reader::box_reader(box_view *i_oControl)
102 {
103 	m_oMediator = i_oControl;
104 	m_iId = m_oMediator->m_iId;
105 	m_oCurrent = NULL;
106 }
107 
startElement(const QString &,const QString &,const QString & i_sName,const QXmlAttributes & i_oAttrs)108 bool box_reader::startElement(const QString&, const QString&, const QString& i_sName, const QXmlAttributes& i_oAttrs)
109 {
110 	#ifdef _DEBUG
111 		return true;
112 	#endif
113 	if (i_sName == notr("box_item"))
114 	{
115 		int id = i_oAttrs.value(notr("id")).toInt();
116 
117 		data_box *box = new data_box(id);
118 		m_oMediator->m_oMediator->m_oItems[m_iId].m_oBoxes[id] = box;
119 		box->m_iXX = i_oAttrs.value(notr("c1")).toFloat();
120 		box->m_iYY = i_oAttrs.value(notr("c2")).toFloat();
121 		box->m_sText = i_oAttrs.value(notr("text"));
122 		box->m_oCustom.m_oInnerColor = i_oAttrs.value(notr("col"));
123 		//l_o->setRect(QRectF(0., 0., i_oAttrs.value(notr("c3")).toDouble(), i_oAttrs.value(notr("c4")).toDouble()));
124 	}
125 	else if (i_sName == notr("box_link"))
126 	{
127 		data_link *link = new data_link();
128 		link->m_iParentPos = i_oAttrs.value(notr("p1")).toInt();
129 		link->m_iParent    = i_oAttrs.value(notr("c1")).toInt();
130 		link->m_iChildPos  = i_oAttrs.value(notr("p2")).toInt();
131 		link->m_iChild     = i_oAttrs.value(notr("c2")).toInt();
132 
133 		if (link->m_iChildPos == 0) link->m_iChildPos = data_link::NORTH;
134 		if (link->m_iChildPos == 1) link->m_iChildPos = data_link::WEST;
135 		if (link->m_iChildPos == 2) link->m_iChildPos = data_link::SOUTH;
136 		if (link->m_iChildPos == 3) link->m_iChildPos = data_link::EAST;
137 
138 		if (link->m_iParentPos == 0) link->m_iParentPos = data_link::NORTH;
139 		if (link->m_iParentPos == 1) link->m_iParentPos = data_link::WEST;
140 		if (link->m_iParentPos == 2) link->m_iParentPos = data_link::SOUTH;
141 		if (link->m_iParentPos == 3) link->m_iParentPos = data_link::EAST;
142 
143 		link->m_sCaption = i_oAttrs.value(notr("caption"));
144 		link->m_sParentCaption = i_oAttrs.value(notr("parent_caption"));
145 		link->m_sChildCaption = i_oAttrs.value(notr("child_caption"));
146 
147 		link->pen_style = (Qt::PenStyle) i_oAttrs.value(notr("pen_style")).toInt();
148 		link->border_width = i_oAttrs.value(notr("border_width")).toInt();
149 		m_oCurrent = link;
150 		Q_ASSERT(m_oMediator->m_oMediator->m_oItems.contains(m_iId));
151 		m_oMediator->m_oMediator->m_oItems[m_iId].m_oLinks.append(link);
152 	}
153 	else if (i_sName == notr("box_link_offset"))
154 	{
155 		if (m_oCurrent)
156 		{
157 			m_oCurrent->m_oOffsets.append(QPoint(i_oAttrs.value(notr("x")).toInt(), i_oAttrs.value(notr("y")).toInt()));
158 		}
159 	}
160 
161 	return true;
162 }
163 
endElement(const QString &,const QString &,const QString & i_sName)164 bool box_reader::endElement(const QString&, const QString&, const QString& i_sName)
165 {
166 	if (i_sName == notr("box_link"))
167 	{
168 		m_oCurrent = NULL;
169 	}
170 	return true;
171 }
172 
characters(const QString & i_s)173 bool box_reader::characters(const QString &i_s)
174 {
175 	m_sBuf += i_s;
176 	return true;
177 }
178 
fceil(qreal l_fInput,int l_iBase)179 int fceil(qreal l_fInput, int l_iBase)
180 {
181 	int l_iCal = ceil(l_fInput) + 5985670 * l_iBase;
182 	if (l_iCal % l_iBase == 0)
183 	{
184 		return l_iCal - 5985670 * l_iBase;
185 	}
186 	return l_iBase * (1 + l_iCal / l_iBase) - 5985670 * l_iBase;
187 }
188 
grid_int(int x)189 int grid_int(int x) {
190 	return GRID * (x / GRID);
191 }
192 
box_view(QWidget * i_oWidget,sem_mediator * i_oControl)193 box_view::box_view(QWidget *i_oWidget, sem_mediator *i_oControl) : QGraphicsView(i_oWidget)
194 {
195 	m_oMediator = i_oControl;
196 	m_iId = NO_ITEM;
197 	m_bDisableGradient = false;
198 	m_bShowFileMenu = false;
199 
200 	num_seq = 1111;
201 
202 	QGraphicsScene *l_oScene = new QGraphicsScene(this);
203 	setScene(l_oScene);
204 
205 	setDragMode(QGraphicsView::RubberBandDrag);
206 
207 	setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
208 
209 	//setCacheMode(CacheBackground);
210 	setRenderHint(QPainter::Antialiasing);
211 	setMinimumSize(100, 100);
212 
213 	m_oPropertiesAction = new QAction(i18n("Properties..."), this);
214 	//m_oPropertiesAction->setShortcut(i18n("Return"));
215 	connect(m_oPropertiesAction, SIGNAL(triggered()), this, SLOT(slot_edit_properties()));
216 	addAction(m_oPropertiesAction);
217 
218 	m_oAddItemAction = new QAction(i18n("Activity"), this);
219 	m_oAddItemAction->setShortcut(i18n("Ctrl+Return"));
220 	connect(m_oAddItemAction, SIGNAL(triggered()), this, SLOT(slot_add_item()));
221 	addAction(m_oAddItemAction);
222 
223 	m_oDeleteAction = new QAction(i18n("Delete selection"), this);
224 	m_oDeleteAction->setShortcut(i18n("Delete"));
225 	connect(m_oDeleteAction, SIGNAL(triggered()), this, SLOT(slot_delete()));
226 	addAction(m_oDeleteAction);
227 
228 	m_oMoveUpAction = new QAction(i18n("Raise"), this);
229 	m_oMoveUpAction->setShortcut(i18n("PgUp"));
230 	connect(m_oMoveUpAction, SIGNAL(triggered()), this, SLOT(slot_move_up()));
231 	addAction(m_oMoveUpAction);
232 
233 	m_oMoveDownAction = new QAction(i18n("Send back"), this);
234 	m_oMoveDownAction->setShortcut(i18n("PgDown"));
235 	connect(m_oMoveDownAction, SIGNAL(triggered()), this, SLOT(slot_move_down()));
236 	addAction(m_oMoveDownAction);
237 
238 	m_oAddLabel = new QAction(i18n("Floating text"), this);
239 	connect(m_oAddLabel, SIGNAL(triggered()), this, SLOT(slot_add_element()));
240 	m_oAddComponent = new QAction(i18n("Component"), this);
241 	connect(m_oAddComponent, SIGNAL(triggered()), this, SLOT(slot_add_element()));
242 	m_oAddRectangle = new QAction(i18n("Rectangle"), this);
243 	connect(m_oAddRectangle, SIGNAL(triggered()), this, SLOT(slot_add_element()));
244 	m_oAddNode = new QAction(i18n("Node"), this);
245 	connect(m_oAddNode, SIGNAL(triggered()), this, SLOT(slot_add_element()));
246 	m_oAddDecision = new QAction(i18n("Decision"), this);
247 	connect(m_oAddDecision, SIGNAL(triggered()), this, SLOT(slot_add_element()));
248 	m_oAddDatabase = new QAction(i18n("Database"), this);
249 	connect(m_oAddDatabase, SIGNAL(triggered()), this, SLOT(slot_add_element()));
250 	m_oAddPipe = new QAction(i18n("Pipe"), this);
251 	connect(m_oAddPipe, SIGNAL(triggered()), this, SLOT(slot_add_element()));
252 	m_oAddSequence = new QAction(i18n("Sequence"), this);
253 	connect(m_oAddSequence, SIGNAL(triggered()), this, SLOT(slot_add_element()));
254 	m_oAddDotStart = new QAction(i18n("Activity start"), this);
255 	connect(m_oAddDotStart, SIGNAL(triggered()), this, SLOT(slot_add_element()));
256 	m_oAddDotEnd = new QAction(i18n("Activity end"), this);
257 	connect(m_oAddDotEnd, SIGNAL(triggered()), this, SLOT(slot_add_element()));
258 	m_oAddParallelHorizontal = new QAction(i18n("Horizontal fork/join"), this);
259 	connect(m_oAddParallelHorizontal, SIGNAL(triggered()), this, SLOT(slot_add_element()));
260 	m_oAddParallelVertical = new QAction(i18n("Vertical fork/join"), this);
261 	connect(m_oAddParallelVertical, SIGNAL(triggered()), this, SLOT(slot_add_element()));
262 	m_oAddActor = new QAction(i18n("Actor"), this);
263 	connect(m_oAddActor, SIGNAL(triggered()), this, SLOT(slot_add_element()));
264 	m_oAddCloud = new QAction(i18n("Cloud"), this);
265 	connect(m_oAddCloud, SIGNAL(triggered()), this, SLOT(slot_add_element()));
266 	m_oAddUsecase = new QAction(i18n("Usecase"), this);
267 	connect(m_oAddUsecase, SIGNAL(triggered()), this, SLOT(slot_add_element()));
268 	m_oAddMatrix = new QAction(i18n("Matrix"), this);
269 	connect(m_oAddMatrix, SIGNAL(triggered()), this, SLOT(slot_add_element()));
270 	m_oAddFrame = new QAction(i18n("Boundary"), this);
271 	connect(m_oAddFrame, SIGNAL(triggered()), this, SLOT(slot_add_element()));
272 	m_oAddClass = new QAction(i18n("Class"), this);
273 	connect(m_oAddClass, SIGNAL(triggered()), this, SLOT(slot_add_element()));
274 	m_oAddEntity = new QAction(i18n("Entity"), this);
275 	connect(m_oAddEntity, SIGNAL(triggered()), this, SLOT(slot_add_element()));
276 
277 
278 	m_oFileImport = new QAction(i18n("Import from file..."), this);
279 	connect(m_oFileImport, SIGNAL(triggered()), this, SLOT(slot_import_from_file()));
280 	m_oFileExport = new QAction(i18n("Export to file..."), this);
281 	connect(m_oFileExport, SIGNAL(triggered()), this, SLOT(slot_export_to_file()));
282 	m_oCopyToClipboard = new QAction(i18n("Copy image to clipboard"), this);
283 	connect(m_oCopyToClipboard, SIGNAL(triggered()), this, SLOT(slot_copy_picture()));
284 
285 	m_oLastMovePoint = QPointF(-100, -100);
286 
287 	m_oCurrent = NULL;
288 	m_bPressed = false;
289 	m_bScroll = false;
290 
291 	setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
292 	setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
293 
294 	m_oMenu = NULL;
295 	setMouseTracking(true);
296 
297 	setBackgroundBrush(Qt::white);
298 }
299 
init_menu()300 void box_view::init_menu()
301 {
302 	m_oMenu = new QMenu(this);
303 
304 	if (m_bShowFileMenu) {
305 		m_oFileMenu = m_oMenu->addMenu(i18n("File operations"));
306 		m_oFileMenu->addAction(m_oFileImport);
307 		m_oFileMenu->addAction(m_oFileExport);
308 		m_oFileMenu->addAction(m_oCopyToClipboard);
309 		m_oMenu->addSeparator();
310 	}
311 
312 	m_oMenu->addAction(m_oAddLabel);
313 	m_oMenu->addAction(m_oAddItemAction);
314 	m_oMenu->addAction(m_oAddComponent);
315 	m_oMenu->addAction(m_oAddNode);
316 
317 	m_oAddBoxMenu = m_oMenu->addMenu(i18n("More elements"));
318 	m_oAddBoxMenu->addAction(m_oAddDotStart);
319 	m_oAddBoxMenu->addAction(m_oAddDotEnd);
320 	m_oAddBoxMenu->addAction(m_oAddParallelHorizontal);
321 	m_oAddBoxMenu->addAction(m_oAddParallelVertical);
322 	m_oAddBoxMenu->addAction(m_oAddDecision);
323 	m_oAddBoxMenu->addAction(m_oAddActor);
324 	m_oAddBoxMenu->addAction(m_oAddUsecase);
325 	m_oAddBoxMenu->addAction(m_oAddMatrix);
326 	m_oAddBoxMenu->addAction(m_oAddFrame);
327 	m_oAddBoxMenu->addAction(m_oAddRectangle);
328 	m_oAddBoxMenu->addAction(m_oAddClass);
329 	m_oAddBoxMenu->addAction(m_oAddEntity);
330 	m_oAddBoxMenu->addAction(m_oAddCloud);
331 	m_oAddBoxMenu->addAction(m_oAddPipe);
332 	m_oAddBoxMenu->addAction(m_oAddDatabase);
333 	m_oAddBoxMenu->addAction(m_oAddSequence);
334 
335 	//m_oMenu->addAction(m_oEditAction);
336 	m_oMenu->addAction(m_oDeleteAction);
337 
338 	m_oMenu->addAction(m_oMoveUpAction);
339 	m_oMenu->addAction(m_oMoveDownAction);
340 
341 	QAction *l_o;
342 
343 	/*
344 	m_oWidthMenu = m_oMenu->addMenu(i18n("Connection width"));
345 	m_oWidthGroup = new QActionGroup(this);
346 	l_o = m_oWidthMenu->addAction(i18n("1px")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_penwidth())); addAction(l_o); l_o->setData(QVariant(1)); m_oWidthGroup->addAction(l_o);
347 	l_o = m_oWidthMenu->addAction(i18n("2px")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_penwidth())); addAction(l_o); l_o->setData(QVariant(2)); m_oWidthGroup->addAction(l_o);
348 	l_o = m_oWidthMenu->addAction(i18n("3px")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_penwidth())); addAction(l_o); l_o->setData(QVariant(3)); m_oWidthGroup->addAction(l_o);
349 
350 	m_oStyleMenu = m_oMenu->addMenu(i18n("Connection style"));
351 	m_oStyleGroup = new QActionGroup(this);
352 	l_o = m_oStyleMenu->addAction(i18n("solid line")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_penstyle())); addAction(l_o); l_o->setData(QVariant(Qt::SolidLine)); m_oStyleGroup->addAction(l_o);
353 	l_o = m_oStyleMenu->addAction(i18n("dot line")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_penstyle())); addAction(l_o); l_o->setData(QVariant(Qt::DotLine)); m_oStyleGroup->addAction(l_o);
354 	l_o = m_oStyleMenu->addAction(i18n("dash line")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_penstyle())); addAction(l_o); l_o->setData(QVariant(Qt::DashLine)); m_oStyleGroup->addAction(l_o);
355 
356 	*/
357 
358 	m_oMenu->addSeparator();
359 
360 	m_oTextAlignMenu = m_oMenu->addMenu(i18n("Text Alignment"));
361 	m_oTextAlignGroup = new QActionGroup(this);
362 	l_o = m_oTextAlignMenu->addAction(i18n("Align left")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_text_align())); addAction(l_o); l_o->setData(QVariant(ALIGN_LEFT)); m_oTextAlignGroup->addAction(l_o);
363 	l_o = m_oTextAlignMenu->addAction(i18n("Align center")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_text_align())); addAction(l_o); l_o->setData(QVariant(ALIGN_CENTER)); m_oTextAlignGroup->addAction(l_o);
364 	l_o = m_oTextAlignMenu->addAction(i18n("Align right")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_text_align())); addAction(l_o); l_o->setData(QVariant(ALIGN_RIGHT)); m_oTextAlignGroup->addAction(l_o);
365 
366 	m_oAlignMenu = m_oMenu->addMenu(i18n("Alignment"));
367 	m_oAlignGroup = new QActionGroup(this);
368 	l_o = m_oAlignMenu->addAction(i18n("Align left")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_align())); addAction(l_o); l_o->setData(QVariant(ALIGN_LEFT)); m_oAlignGroup->addAction(l_o);
369 	l_o = m_oAlignMenu->addAction(i18n("Align center")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_align())); addAction(l_o); l_o->setData(QVariant(ALIGN_CENTER)); m_oAlignGroup->addAction(l_o);
370 	l_o = m_oAlignMenu->addAction(i18n("Align right")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_align())); addAction(l_o); l_o->setData(QVariant(ALIGN_RIGHT)); m_oAlignGroup->addAction(l_o);
371 
372 	l_o = m_oAlignMenu->addAction(i18n("Align top")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_align())); addAction(l_o); l_o->setData(QVariant(ALIGN_TOP)); m_oAlignGroup->addAction(l_o);
373 	l_o = m_oAlignMenu->addAction(i18n("Align middle")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_align())); addAction(l_o); l_o->setData(QVariant(ALIGN_MIDDLE)); m_oAlignGroup->addAction(l_o);
374 	l_o = m_oAlignMenu->addAction(i18n("Align bottom")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_align())); addAction(l_o); l_o->setData(QVariant(ALIGN_BOTTOM)); m_oAlignGroup->addAction(l_o);
375 
376 
377 	m_oSizeMenu = m_oMenu->addMenu(i18n("Size"));
378 	m_oSizeGroup = new QActionGroup(this);
379 	l_o = m_oSizeMenu->addAction(i18n("Same width")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_size())); addAction(l_o); l_o->setData(QVariant(SAME_WIDTH)); m_oSizeGroup->addAction(l_o);
380 	l_o = m_oSizeMenu->addAction(i18n("Same height")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_size())); addAction(l_o); l_o->setData(QVariant(SAME_HEIGHT)); m_oSizeGroup->addAction(l_o);
381 	l_o = m_oSizeMenu->addAction(i18n("Same width and height")); connect(l_o, SIGNAL(triggered()), this, SLOT(slot_size())); addAction(l_o); l_o->setData(QVariant(SAME_WIDTH_HEIGHT)); m_oSizeGroup->addAction(l_o);
382 
383 
384 	m_oAddItemAction->setEnabled(false);
385 	m_oDeleteAction->setEnabled(false);
386 
387 	//m_oEditAction->setEnabled(false);
388 	//m_oMoveUpAction->setEnabled(false);
389 	//m_oMoveDownAction->setEnabled(false);
390 	m_oMenu->addSeparator();
391 	m_oMenu->addMenu(m_oColorMenu);
392 	m_oMenu->addAction(m_oPropertiesAction);
393 }
394 
~box_view()395 box_view::~box_view()
396 {
397 
398 }
399 
resizeEvent(QResizeEvent * e)400 void box_view::resizeEvent(QResizeEvent* e)
401 {
402 	QGraphicsView::resizeEvent(e);
403 
404 	QRect l_oRect = viewport()->rect();
405 	QRectF ar = QRectF(mapToScene(l_oRect.topLeft()), mapToScene(l_oRect.bottomRight()));
406 	QRectF br = scene()->itemsBoundingRect();
407 	br = br.united(ar);
408 
409 	scene()->setSceneRect(br);
410 }
411 
notify_add_item(int id)412 void box_view::notify_add_item(int id)
413 {
414 	m_iId = id;
415 	setEnabled(true);
416 }
417 
notify_edit_box(int id,int bid)418 void box_view::notify_edit_box(int id, int bid)
419 {
420 	Q_ASSERT(id == m_iId);
421 	box_item *item = (box_item*) m_oItems.value(bid); // TODO
422 	Q_ASSERT(item != NULL);
423 	item->update_data();
424 }
425 
notify_select(const QList<int> & unsel,const QList<int> & sel)426 void box_view::notify_select(const QList<int>& unsel, const QList<int>& sel)
427 {
428 	clear_diagram();
429 
430 	if (sel.size() != 1)
431 	{
432 		m_iId = NO_ITEM;
433 		setEnabled(false);
434 		//m_oEditAction->setEnabled(false);
435 		//m_oCancelEditAction->setEnabled(false);
436 	}
437 	else
438 	{
439 		m_iId = sel.at(0);
440 		Q_ASSERT(m_oMediator->m_oItems.contains(m_iId));
441 		data_item& l_oData = m_oMediator->m_oItems[m_iId];
442 		if (l_oData.m_iDataType == VIEW_DIAG)
443 		{
444 			if (!l_oData.m_sDiag.isEmpty())
445 			{
446 				from_string(l_oData.m_sDiag);
447 				l_oData.m_sDiag = notr("");
448 			}
449 			sync_view();
450 			check_canvas_size();
451 		}
452 		setEnabled(true);
453 	}
454 }
455 
sync_view()456 void box_view::sync_view()
457 {
458 	if (!m_iId) return;
459 
460 	Q_ASSERT(m_oMediator->m_oItems.contains(m_iId));
461 	data_item& item = m_oMediator->m_oItems[m_iId];
462 	scene()->setFont(item.m_oDiagramFont);
463 
464 	if (item.m_iDataType != VIEW_DIAG)
465 	{
466 		return;
467 	}
468 	if (!item.m_sDiag.isEmpty())
469 	{
470 		from_string(item.m_sDiag);
471 		item.m_sDiag = "";
472 	}
473 
474 	foreach (data_box *box, item.m_oBoxes.values())
475 	{
476 		connectable *l_o = NULL;
477 		if (box->m_iType == data_box::ACTIVITY)
478 		{
479 			l_o = new box_item(this, box->m_iId);
480 		}
481 		else if (box->m_iType == data_box::LABEL)
482 		{
483 			l_o = new box_label(this, box->m_iId);
484 		}
485 		else if (box->m_iType == data_box::ACTOR)
486 		{
487 			l_o = new box_actor(this, box->m_iId);
488 		}
489 		else if (box->m_iType == data_box::CLOUD)
490 		{
491 			l_o = new box_cloud(this, box->m_iId);
492 		}
493 		else if (box->m_iType == data_box::USECASE)
494 		{
495 			l_o = new box_usecase(this, box->m_iId);
496 		}
497 		else if (box->m_iType == data_box::COMPONENT)
498 		{
499 			l_o = new box_component(this, box->m_iId);
500 		}
501 		else if (box->m_iType == data_box::RECTANGLE)
502 		{
503 			l_o = new box_rectangle(this, box->m_iId);
504 		}
505 		else if (box->m_iType == data_box::NODE)
506 		{
507 			l_o = new box_node(this, box->m_iId);
508 		}
509 		else if (box->m_iType == data_box::DECISION)
510 		{
511 			l_o = new box_decision(this, box->m_iId);
512 		}
513 		else if (box->m_iType == data_box::ACTIVITY_START)
514 		{
515 			l_o = new box_dot(this, box->m_iId);
516 		}
517 		else if (box->m_iType == data_box::ACTIVITY_PARALLEL)
518 		{
519 			l_o = new box_fork(this, box->m_iId);
520 		}
521 		else if (box->m_iType == data_box::MATRIX)
522 		{
523 			l_o = new box_matrix(this, box->m_iId);
524 		}
525 		else if (box->m_iType == data_box::SEQUENCE)
526 		{
527 			l_o = new box_sequence(this, box->m_iId);
528 		}
529 		else if (box->m_iType == data_box::FRAME)
530 		{
531 			l_o = new box_frame(this, box->m_iId);
532 		}
533 		else if (box->m_iType == data_box::CLASS)
534 		{
535 			l_o = new box_class(this, box->m_iId);
536 		}
537 		else if (box->m_iType == data_box::ENTITY)
538 		{
539 			l_o = new box_entity(this, box->m_iId);
540 		}
541 		else if (box->m_iType == data_box::DATABASE)
542 		{
543 			l_o = new box_database(this, box->m_iId);
544 		}
545 		else if (box->m_iType == data_box::PIPE)
546 		{
547 			l_o = new box_pipe(this, box->m_iId);
548 		}
549 		else if (box->m_iType == data_box::RECTANGLE)
550 		{
551 			l_o = new box_rectangle(this, box->m_iId);
552 		}
553 		else
554 		{
555 			Q_ASSERT(false);
556 		}
557 		m_oItems[box->m_iId] = l_o;
558 		(dynamic_cast<QGraphicsItem*> (l_o))->setPos(QPointF(box->m_iXX, box->m_iYY));
559 		l_o->update_data();
560 	}
561 
562 	foreach (data_link *link, item.m_oLinks) {
563 		box_link *l_o = new box_link(this);
564 		l_o->m_oInnerLink.copy_from(*link);
565 		l_o->m_oLink = link;
566 		l_o->update_text();
567 		l_o->update_pos();
568 		m_oLinks.append(l_o);
569 	}
570 }
571 
notify_export_item(int id)572 void box_view::notify_export_item(int id)
573 {
574 	int l_iOldId = m_iId;
575 	if (m_oMediator->m_oItems[id].m_iDataType != VIEW_DIAG)
576 		return;
577 	clear_diagram();
578 
579 	m_iId = id;
580 	sync_view();
581 
582 	QRectF l_oRect = visibleRect().adjusted(-PIPAD, -PIPAD, PIPAD, PIPAD);
583 
584 	QRectF l_oR(0, 0, l_oRect.width(), l_oRect.height());
585 
586 	QPair<int, int> p = m_oMediator->hint_size_diagram(id);
587 
588 	if (p.first != 0) {
589 		l_oR.setWidth(p.first);
590 		if (p.second == 0) {
591 			l_oR.setHeight((p.first * l_oRect.height()) / (double) l_oRect.width());
592 		}
593 	}
594 	if (p.second != 0) {
595 		l_oR.setHeight(p.second);
596 		if (p.first == 0) {
597 			l_oR.setWidth((p.second * l_oRect.width()) / (double) l_oRect.height());
598 		}
599 	}
600 
601 	Q_ASSERT(m_oMediator->m_oItems.contains(m_iId));
602 	data_item& item = m_oMediator->m_oItems[m_iId];
603 	item.m_iObjectWidthHint = l_oR.width();
604 	item.m_iObjectHeightHint = l_oR.height();
605 
606 	// fill with white
607 	QImage l_oImage((int) l_oR.width(), (int) l_oR.height(), QImage::Format_RGB32);
608 	l_oImage.fill(qRgb(255,255,255));
609 
610 	Qt::AspectRatioMode rat = (p.first == 0 || p.second == 0) ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio;
611 
612 	QPainter l_oP;
613 	if (l_oP.begin(&l_oImage))
614 	{
615 		l_oP.setRenderHints(QPainter::Antialiasing);
616 		scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
617 		scene()->render(&l_oP, l_oR, l_oRect, rat);
618 		scene()->setItemIndexMethod(QGraphicsScene::BspTreeIndex);
619 		l_oP.end();
620 	}
621 	l_oImage.save(notr("%1/%2/diag-%3.png").arg(m_oMediator->m_sOutDir, m_oMediator->m_sOutProject, QString::number(m_iId)));
622 
623 	QPrinter l_oPrinter;
624 	//l_oPrinter.setResolution(QPrinter::HighResolution);
625 	l_oPrinter.setOrientation(QPrinter::Portrait);
626 	l_oPrinter.setOutputFormat(QPrinter::PdfFormat);
627 	l_oPrinter.setPaperSize(l_oR.size(), QPrinter::DevicePixel);
628 	l_oPrinter.setPageMargins(0, 0, 0, 0, QPrinter::DevicePixel);
629 	l_oPrinter.setOutputFileName(notr("%1/%2/diag-%3.pdf").arg(m_oMediator->m_sOutDir, m_oMediator->m_sOutProject, QString::number(m_iId)));
630 
631 	QPainter l_oPdf;
632 	if (l_oPdf.begin(&l_oPrinter))
633 	{
634 		m_bDisableGradient = DISABLE_GRADIENT;
635 		scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
636 		scene()->render(&l_oPdf, l_oR, l_oRect, rat);
637 		scene()->setItemIndexMethod(QGraphicsScene::BspTreeIndex);
638 		l_oPdf.end();
639 		m_bDisableGradient = false;
640 	}
641 
642 	// and the svg for html/openoffice
643 	QSvgGenerator l_oGenerator;
644 	l_oGenerator.setFileName(notr("%1/%2/diag-%3.svg").arg(m_oMediator->m_sOutDir, m_oMediator->m_sOutProject, QString::number(m_iId)));
645 	l_oGenerator.setSize(QSize(l_oR.width(), l_oR.height()));
646 	l_oGenerator.setViewBox(l_oR);
647 	l_oGenerator.setTitle(i18n("Semantik diagram"));
648 	l_oGenerator.setDescription(notr("Generated by Semantik, if it does not render properly check your system fonts!"));
649 	l_oGenerator.setResolution(QApplication::desktop()->logicalDpiX());
650 
651 	QPainter l_oSvg;
652 	if (l_oSvg.begin(&l_oGenerator))
653 	{
654 		l_oSvg.setRenderHints(QPainter::Antialiasing);
655 		scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
656 		scene()->render(&l_oSvg, l_oR, l_oRect, rat);
657 		scene()->setItemIndexMethod(QGraphicsScene::BspTreeIndex);
658 		l_oSvg.end();
659 	}
660 
661 	clear_diagram();
662 	m_iId = l_iOldId;
663 	if (m_iId != NO_ITEM)
664 	{
665 		sync_view();
666 	}
667 }
668 
slot_delete()669 void box_view::slot_delete()
670 {
671 	QList<data_box*> boxes;
672 	QSet<data_link*> links;
673 	foreach (QGraphicsItem* el, scene()->selectedItems())
674 	{
675 		if (box_link *l = dynamic_cast<box_link*>(el))
676 		{
677 			links << l->m_oLink;
678 			Q_ASSERT(l->m_oLink);
679 		}
680 		else if (connectable* c = dynamic_cast<connectable*>(el))
681 		{
682 			data_box *b = c->m_oBox;
683 			boxes.append(b);
684 			foreach (box_link* l, m_oLinks)
685 			{
686 				if (l->m_oLink->m_iParent == b->m_iId || l->m_oLink->m_iChild == b->m_iId)
687 				{
688 					links << l->m_oLink;
689 				}
690 			}
691 		}
692 	}
693 
694 	if (boxes.size() > 0 || links.size() > 0) {
695 		mem_del_box *del = new mem_del_box(m_oMediator, m_iId);
696 		del->init(boxes, links.toList());
697 		del->apply();
698 	}
699 }
700 
enable_menu_actions()701 void box_view::enable_menu_actions()
702 {
703 	QList<QGraphicsItem*> selection = scene()->selectedItems();
704 	int selected = selection.size();
705 
706 	m_oAddItemAction->setEnabled(selected <= 1);
707 	m_oDeleteAction->setEnabled(selected >= 1);
708 	m_oColorMenu->setEnabled(selected >= 1);
709 
710 	m_oPropertiesAction->setEnabled(selected == 0 or (selected == 1 and dynamic_cast<editable*>(selection.at(0))));
711 
712 	m_oSizeMenu->setEnabled(selected > 1);
713 	foreach(QAction* l_o, m_oSizeGroup->actions())
714 	{
715 		l_o->setEnabled(selected >= 1);
716 	}
717 
718 	/*m_oWidthMenu->setEnabled(selected >= 1 and dynamic_cast<box_link*>(selection.at(0)));
719 	foreach(QAction* l_o, m_oWidthGroup->actions())
720 	{
721 		l_o->setEnabled(selected >= 1);
722 	}
723 
724 	m_oStyleMenu->setEnabled(selected >= 1 and dynamic_cast<box_link*>(selection.at(0)));
725 	foreach(QAction* l_o, m_oStyleGroup->actions())
726 	{
727 		l_o->setEnabled(selected >= 1);
728 	}*/
729 
730 	m_oTextAlignMenu->setEnabled(selected >= 1);
731 	foreach(QAction* l_o, m_oTextAlignGroup->actions())
732 	{
733 		l_o->setEnabled(selected >= 1);
734 	}
735 
736 	m_oAlignMenu->setEnabled(selected > 1);
737 	foreach(QAction* l_o, m_oAlignGroup->actions())
738 	{
739 		l_o->setEnabled(selected > 1);
740 	}
741 }
742 
enable_actions()743 void box_view::enable_actions()
744 {
745 	foreach (QAction* l_o, actions())
746 	{
747 		l_o->setEnabled(true); // TODO we could disable the move actions one by one
748 	}
749 	enable_menu_actions();
750 }
751 
slot_add_item()752 void box_view::slot_add_item()
753 {
754 	foreach(QGraphicsItem *l_o, scene()->items()) {
755 		l_o->setSelected(false);
756 	}
757 
758 	mem_add_box *add = new mem_add_box(m_oMediator, m_iId, next_seq());
759 	add->box->m_iXX = m_oLastPoint.x() - 20;
760 	add->box->m_iYY = m_oLastPoint.y() - 20;
761 	add->box->m_iWW = 80;
762 	add->apply();
763 
764 	foreach (QGraphicsItem *l_o, scene()->selectedItems())
765 	{
766 		l_o->setSelected(false);
767 	}
768 
769 	box_item *l_o = (box_item*) m_oItems.value(add->box->m_iId);
770 	l_o->setSelected(true);
771 	// l_o->setPos(m_oLastPoint - QPointF(l_oRect.width()/2, l_oRect.height()/2)); // TODO
772 }
773 
change_colors(QAction * i_oAct)774 void box_view::change_colors(QAction* i_oAct)
775 {
776 	if (!hasFocus()) return;
777 	if (scene()->selectedItems().size() < 1) return;
778 
779 	int l_iColor = -1;
780 	QColor l_oColor;
781 	static QColor selected_color;
782 
783 	QList<QAction*> l_oActs = i_oAct->actionGroup()->actions();
784 	for (int i=1; i < l_oActs.size(); ++i)
785 	{
786 		if (l_oActs[i] == i_oAct)
787 		{
788 			if (i == l_oActs.size()-1)
789 			{
790 				selected_color = QColorDialog::getColor(selected_color, this);
791 				if (!selected_color.isValid())
792 				{
793 					return;
794 				}
795 				l_oColor = selected_color;
796 			}
797 			else
798 			{
799 				selected_color = l_oColor = m_oMediator->m_oColorSchemes[i].m_oInnerColor;
800 			}
801 			l_iColor = i;
802 			break;
803 		}
804 	}
805 
806 	mem_prop_box *mem = new mem_prop_box(m_oMediator, m_iId);
807 	foreach (QGraphicsItem *l_o, scene()->selectedItems())
808 	{
809 		if (box_link *k = dynamic_cast<box_link*>(l_o))
810 		{
811 			mem->items.append(k->m_oLink);
812 		}
813 		else if (connectable* t = dynamic_cast<connectable*>(l_o))
814 		{
815 			mem->items.append(t->m_oBox);
816 		}
817 	}
818 	mem->change_type = CH_COLOR;
819 	mem->new_props.m_iColor = l_iColor;
820 	mem->new_props.m_oCustom.m_oInnerColor = l_oColor;
821 	mem->apply();
822 }
823 
slot_penstyle()824 void box_view::slot_penstyle()
825 {
826 	int l_i = ((QAction*) QObject::sender())->data().toInt();
827 	mem_prop_box *mem = new mem_prop_box(m_oMediator, m_iId);
828 	foreach (QGraphicsItem* l_o, scene()->selectedItems())
829 	{
830 		if (box_link *k = dynamic_cast<box_link*>(l_o))
831 		{
832 			mem->items.append(k->m_oLink);
833 		}
834 	}
835 	mem->change_type = CH_PENST;
836 	mem->new_props.pen_style = (Qt::PenStyle) l_i;
837 	mem->apply();
838 }
839 
slot_add_element()840 void box_view::slot_add_element()
841 {
842 	QAction *sender = (QAction*) QObject::sender();
843 	mem_add_box *add = new mem_add_box(m_oMediator, m_iId, next_seq());
844 	add->box->m_iXX = GRID * (int) (m_oLastPoint.x() / GRID);
845 	add->box->m_iYY = GRID * (int) (m_oLastPoint.y() / GRID);
846 
847 	if (sender == m_oAddDotStart || sender == m_oAddDotEnd)
848 	{
849 		add->box->m_iHH = 20;
850 		add->box->m_iWW = 20;
851 	}
852 	else if (sender == m_oAddParallelVertical)
853 	{
854 		add->box->m_iWW = FORK_WIDTH;
855 		add->box->m_iHH = FORK_LENGTH;
856 		add->box->m_bIsVertical = true;
857 	}
858 	else if (sender == m_oAddParallelHorizontal)
859 	{
860 		add->box->m_iHH = FORK_WIDTH;
861 		add->box->m_iWW = FORK_LENGTH;
862 		add->box->m_bIsVertical = false;
863 	}
864 
865 	add->box->m_bIsEnd = sender == m_oAddDotEnd;
866 
867 	if (sender == m_oAddDotEnd || sender == m_oAddDotStart) {
868 		add->box->m_iType = data_box::ACTIVITY_START;
869 		add->box->m_oCustom.m_oInnerColor = QColor(Qt::black);
870 	}
871 	if (sender == m_oAddParallelHorizontal || sender == m_oAddParallelVertical) {
872 		add->box->m_iType = data_box::ACTIVITY_PARALLEL;
873 		add->box->m_oCustom.m_oInnerColor = QColor(Qt::black);
874 	}
875 	if (sender == m_oAddLabel)
876 	{
877 		add->box->m_iType = data_box::LABEL;
878 		add->box->m_iAlign = Qt::AlignLeft;
879 		add->box->m_iWW = 60;
880 		add->box->m_iHH = 30;
881 		add->box->m_oCustom.m_oInnerColor = Qt::black;
882 		add->box->m_sText = QString("...");
883 	}
884 	else if (sender == m_oAddActor)
885 	{
886 		add->box->m_iType = data_box::ACTOR;
887 		add->box->m_iWW = 30;
888 		add->box->m_iHH = 70;
889 	}
890 	else if (sender == m_oAddCloud)
891 	{
892 		add->box->m_iType = data_box::CLOUD;
893 		add->box->m_iWW = 150;
894 		add->box->m_iHH = 120;
895 		add->box->m_oCustom.m_oInnerColor = QColor("#FCF2E2");
896 	}
897 	else if (sender == m_oAddUsecase)
898 	{
899 		add->box->m_iType = data_box::USECASE;
900 		add->box->m_iWW = 100;
901 		add->box->m_iHH = 50;
902 	}
903 	else if (sender == m_oAddComponent)
904 	{
905 		add->box->m_iType = data_box::COMPONENT;
906 		add->box->m_iWW = 120;
907 		add->box->m_iHH = 60;
908 		add->box->m_oCustom.m_oInnerColor = QColor("#FCF2E2");
909 	}
910 	else if (sender == m_oAddRectangle)
911 	{
912 		add->box->m_iType = data_box::RECTANGLE;
913 		add->box->m_iWW = 100;
914 		add->box->m_iHH = 40;
915 		add->box->m_oCustom.m_oInnerColor = QColor("#FFFFCC");
916 	}
917 	else if (sender == m_oAddNode)
918 	{
919 		add->box->m_iType = data_box::NODE;
920 		add->box->m_iWW = 180;
921 		add->box->m_iHH = 180;
922 		add->box->m_oCustom.m_oInnerColor = QColor("#FCF2E2");
923 	}
924 	else if (sender == m_oAddDecision)
925 	{
926 		add->box->m_iType = data_box::DECISION;
927 		add->box->m_iWW = 40;
928 		add->box->m_iHH = 40;
929 	}
930 	else if (sender == m_oAddMatrix)
931 	{
932 		add->box->m_iType = data_box::MATRIX;
933 		add->box->m_iWW = 510;
934 		add->box->m_iHH = 320;
935 		add->box->m_oRowSizes.push_back(160);
936 		add->box->m_oColSizes.push_back(170);
937 		add->box->m_oColSizes.push_back(170);
938 	}
939 	else if (sender == m_oAddSequence)
940 	{
941 		add->box->m_iType = data_box::SEQUENCE;
942 		add->box->m_iWW = 80;
943 		add->box->m_iHH = 280;
944 		add->box->m_iBoxHeight = 40;
945 	}
946 	else if (sender == m_oAddFrame)
947 	{
948 		add->box->m_iType = data_box::FRAME;
949 		add->box->m_iWW = 510;
950 		add->box->m_iHH = 320;
951 	}
952 	else if (sender == m_oAddDatabase)
953 	{
954 		add->box->m_iType = data_box::DATABASE;
955 		add->box->m_oCustom.m_oInnerColor = QColor("#FCF2E2");
956 		add->box->m_iWW = 60;
957 		add->box->m_iHH = 90;
958 	}
959 	else if (sender == m_oAddPipe)
960 	{
961 		add->box->m_iType = data_box::PIPE;
962 		add->box->m_oCustom.m_oInnerColor = QColor("#FCF2E2");
963 		add->box->m_iWW = 90;
964 		add->box->m_iHH = 30;
965 	}
966 	else if (sender == m_oAddClass)
967 	{
968 		add->box->m_iType = data_box::CLASS;
969 		add->box->m_oCustom.m_oInnerColor = QColor("#FCF2E2");
970 		add->box->m_iWW = 150;
971 		add->box->m_iHH = 80;
972 
973 		add->box->m_sText = "MyClass";
974 		add->box->m_sStereotype = "entity";
975 		add->box->m_bStatic = false;
976 		add->box->m_bAbstract = false;
977 
978 		{
979 			data_box_method l_o;
980 			l_o.m_oVisibility = visibility::PUBLIC;
981 			l_o.m_sText = "hello() : void";
982 			l_o.m_bStatic = false;
983 			l_o.m_bAbstract = false;
984 			add->box->m_oMethods.push_back(l_o);
985 		}
986 
987 		{
988 			data_box_attribute l_o;
989 			l_o.m_oVisibility = visibility::PUBLIC;
990 			l_o.m_bStatic = false;
991 			l_o.m_sText = "id: int";
992 			add->box->m_oAttributes.push_back(l_o);
993 		}
994 	}
995 	else if (sender == m_oAddEntity)
996 	{
997 		add->box->m_iType = data_box::ENTITY;
998 		add->box->m_oCustom.m_oInnerColor = QColor("#FCF2E2");
999 		add->box->m_iWW = 220;
1000 		add->box->m_iHH = 80;
1001 		add->box->m_sText = "MyTable";
1002 
1003 		{
1004 			data_box_entity_value l_o;
1005 			l_o.m_sName = "id";
1006 			l_o.m_sKey = "PK";
1007 			l_o.m_sType = "INTEGER";
1008 			add->box->m_oEntityValues.push_back(l_o);
1009 		}
1010 		{
1011 			data_box_entity_value l_o;
1012 			l_o.m_sName = "customer_id";
1013 			l_o.m_sKey = "FK";
1014 			l_o.m_sType = "INTEGER";
1015 			add->box->m_oEntityValues.push_back(l_o);
1016 		}
1017 		{
1018 			data_box_entity_value l_o;
1019 			l_o.m_sName = "name";
1020 			l_o.m_sType = "VARCHAR2(50)";
1021 			add->box->m_oEntityValues.push_back(l_o);
1022 		}
1023 	}
1024 
1025 	add->apply();
1026 
1027 	foreach (QGraphicsItem *l_o, scene()->selectedItems())
1028 	{
1029 		l_o->setSelected(false);
1030 	}
1031 
1032 	QGraphicsItem *l_o = dynamic_cast<QGraphicsItem*>(m_oItems.value(add->box->m_iId));
1033 	l_o->setSelected(true);
1034 }
1035 
slot_penwidth()1036 void box_view::slot_penwidth()
1037 {
1038 	int l_i = ((QAction*) QObject::sender())->data().toInt();
1039 	mem_prop_box *mem = new mem_prop_box(m_oMediator, m_iId);
1040 	foreach (QGraphicsItem* l_o, scene()->selectedItems())
1041 	{
1042 		if (box_link *k = dynamic_cast<box_link*>(l_o))
1043 		{
1044 			mem->items.append(k->m_oLink);
1045 		}
1046 	}
1047 	mem->change_type = CH_BORDER;
1048 	mem->new_props.border_width = l_i;
1049 	mem->apply();
1050 }
1051 
slot_edit_properties()1052 void box_view::slot_edit_properties()
1053 {
1054 	QList<QGraphicsItem*> l_o = scene()->selectedItems();
1055 	if (l_o.length() == 1)
1056 	{
1057 		if (editable*e = dynamic_cast<editable*>(l_o.at(0)))
1058 		{
1059 			e->properties();
1060 		}
1061 	}
1062 	else if (l_o.length() == 0)
1063 	{
1064 		box_document_properties l_oProps(this);
1065 		l_oProps.exec();
1066 	}
1067 }
1068 
1069 #if 0
1070 void box_view::slot_toggle_edit()
1071 {
1072 	if (!hasFocus()) {
1073 		return;
1074 	}
1075 
1076 	box_item* sel = NULL;
1077 	foreach (QGraphicsItem *tmp, items())
1078 	{
1079 		box_item* k;
1080 		if (tmp->isSelected() && (k = dynamic_cast<box_item*>(tmp)))
1081 		{
1082 			if (sel) {
1083 				sel = NULL;
1084 				break;
1085 			} else {
1086 				sel = k;
1087 			}
1088 		}
1089 	}
1090 
1091 	if (sel) {
1092 		if (sel->textInteractionFlags() & Qt::TextEditorInteraction) {
1093 			sel->setTextInteractionFlags(Qt::NoTextInteraction);
1094 			/*if (sel->toPlainText() == i18n("")) {
1095 				sel->setPlainText(i18n("Empty"));
1096 				sel->update(); // seems to update faster
1097 				//sel->update_links();
1098 
1099 			}*/
1100 			if (sel->toPlainText() != m_oMediator->m_oItems[m_iId]->m_oBoxes[sel->m_iId]->m_sText) {
1101 				mem_edit_box *ed = new mem_edit_box(m_oMediator, m_iId, sel->m_iId);
1102 				ed->newText = sel->toPlainText();
1103 				ed->apply();
1104 			}
1105 		} else {
1106 			sel->setTextInteractionFlags(Qt::TextEditorInteraction);
1107 			sel->setFocus();
1108 
1109 			m_oAddItemAction->setEnabled(false);
1110 			m_oDeleteAction->setEnabled(false);
1111 			m_oCancelEditAction->setEnabled(true);
1112 
1113 			/*
1114 			m_oInsertSiblingAction->setEnabled(false);
1115 			m_oNextRootAction->setEnabled(false);
1116 
1117 			m_oMoveUpAction->setEnabled(false);
1118 			m_oMoveDownAction->setEnabled(false);
1119 			m_oMoveLeftAction->setEnabled(false);
1120 			m_oMoveRightAction->setEnabled(false);
1121 			m_oSelectUpAction->setEnabled(false);
1122 			m_oSelectDownAction->setEnabled(false);
1123 			m_oSelectLeftAction->setEnabled(false);
1124 			m_oSelectRightAction->setEnabled(false);
1125 			m_oMediator->check_undo(false);
1126 			*/
1127 			return;
1128 		}
1129 	}
1130 
1131 	m_oAddItemAction->setEnabled(true);
1132 	m_oDeleteAction->setEnabled(true);
1133 	m_oCancelEditAction->setEnabled(false);
1134 
1135 	/*
1136 	m_oInsertSiblingAction->setEnabled(true);
1137 	m_oNextRootAction->setEnabled(true);
1138 
1139 	m_oMoveUpAction->setEnabled(true);
1140 	m_oMoveDownAction->setEnabled(true);
1141 	m_oMoveLeftAction->setEnabled(true);
1142 	m_oMoveRightAction->setEnabled(true);
1143 	m_oSelectUpAction->setEnabled(true);
1144 	m_oSelectDownAction->setEnabled(true);
1145 	m_oSelectLeftAction->setEnabled(true);
1146 	m_oSelectRightAction->setEnabled(true);
1147 	m_oMediator->check_undo(true);
1148 	*/
1149 }
1150 
1151 void box_view::slot_cancel_edit()
1152 {
1153 	//qDebug()<<"slot cancel edit";
1154 	box_item* sel = NULL;
1155 	foreach (QGraphicsItem *tmp, items()) {
1156 		box_item *k;
1157 		if (tmp->isSelected() && (k = dynamic_cast<box_item*>(tmp)))
1158 		{
1159 			if (sel) {
1160 				sel = NULL;
1161 				break;
1162 			} else {
1163 				sel = k;
1164 			}
1165 		}
1166 	}
1167 
1168 	if (sel && sel->textInteractionFlags() & Qt::TextEditorInteraction) {
1169 		//qDebug()<<"cancel edit!"<<sel;
1170 		sel->setTextInteractionFlags(Qt::NoTextInteraction);
1171 		sel->update_data();
1172 	}
1173 
1174 	m_oAddItemAction->setEnabled(true);
1175 	m_oDeleteAction->setEnabled(true);
1176 }
1177 #endif
1178 
slot_move_up()1179 void box_view::slot_move_up()
1180 {
1181 	foreach (QGraphicsItem *l_oItem, scene()->selectedItems())
1182 	{
1183 		l_oItem->setZValue(l_oItem->zValue()+1);
1184 	}
1185 }
1186 
slot_move_down()1187 void box_view::slot_move_down()
1188 {
1189 	foreach (QGraphicsItem *l_oItem, scene()->selectedItems())
1190 	{
1191 		l_oItem->setZValue(l_oItem->zValue()-1);
1192 	}
1193 }
1194 
from_string(const QString & i_s)1195 void box_view::from_string(const QString &i_s)
1196 {
1197 	box_reader l_oHandler(this);
1198 	QXmlInputSource l_oSource;
1199 	l_oSource.setData(i_s);
1200 	QXmlSimpleReader l_oReader;
1201 	l_oReader.setContentHandler(&l_oHandler);
1202 	if (!l_oReader.parse(l_oSource))
1203 	{
1204 		//qDebug()<<"parse error!!";
1205 		clear_diagram();
1206 	}
1207 }
1208 
clear_diagram()1209 void box_view::clear_diagram()
1210 {
1211 	foreach (box_link *l_o, m_oLinks) {
1212 		l_o->hide();
1213 		scene()->removeItem(l_o);
1214 		delete l_o;
1215 	}
1216 	m_oLinks.clear();
1217 	foreach (connectable *l_o, m_oItems.values()) {
1218 		QGraphicsItem* l_oTmp = dynamic_cast<QGraphicsItem*>(l_o);
1219 		l_oTmp->hide();
1220 		scene()->removeItem(l_oTmp);
1221 		delete l_o;
1222 	}
1223 	scene()->update();
1224 	m_oItems.clear();
1225 }
1226 
check_canvas_size()1227 void box_view::check_canvas_size()
1228 {
1229 	QRectF br = scene()->itemsBoundingRect();
1230 	br.adjust(-GAP, -GAP, GAP, GAP);
1231 	br = br.united(scene()->sceneRect());
1232 	scene()->setSceneRect(br);
1233 }
1234 
focusInEvent(QFocusEvent * i_oEv)1235 void box_view::focusInEvent(QFocusEvent *i_oEv)
1236 {
1237 	QGraphicsView::focusInEvent(i_oEv);
1238 	m_oMediator->notify_focus(this);
1239 }
1240 
focusOutEvent(QFocusEvent * i_oEv)1241 void box_view::focusOutEvent(QFocusEvent *i_oEv)
1242 {
1243 	QGraphicsView::focusOutEvent(i_oEv);
1244 }
1245 
notify_add_box(int id,int box)1246 void box_view::notify_add_box(int id, int box)
1247 {
1248 	Q_ASSERT(m_iId == id);
1249 	data_item& item = m_oMediator->m_oItems[m_iId];
1250 	data_box *db = item.m_oBoxes[box];
1251 	connectable *l_o = NULL;
1252 	if (db->m_iType == data_box::ACTIVITY)
1253 	{
1254 		l_o = new box_item(this, box);
1255 	}
1256 	else if (db->m_iType == data_box::LABEL)
1257 	{
1258 		l_o = new box_label(this, box);
1259 	}
1260 	else if (db->m_iType == data_box::ACTOR)
1261 	{
1262 		l_o = new box_actor(this, box);
1263 	}
1264 	else if (db->m_iType == data_box::CLOUD)
1265 	{
1266 		l_o = new box_cloud(this, box);
1267 	}
1268 	else if (db->m_iType == data_box::USECASE)
1269 	{
1270 		l_o = new box_usecase(this, box);
1271 	}
1272 	else if (db->m_iType == data_box::COMPONENT)
1273 	{
1274 		l_o = new box_component(this, box);
1275 	}
1276 	else if (db->m_iType == data_box::RECTANGLE)
1277 	{
1278 		l_o = new box_rectangle(this, box);
1279 	}
1280 	else if (db->m_iType == data_box::NODE)
1281 	{
1282 		l_o = new box_node(this, box);
1283 	}
1284 	else if (db->m_iType == data_box::DECISION)
1285 	{
1286 		l_o = new box_decision(this, box);
1287 	}
1288 	else if (db->m_iType == data_box::ACTIVITY_START)
1289 	{
1290 		l_o = new box_dot(this, box);
1291 	}
1292 	else if (db->m_iType == data_box::MATRIX)
1293 	{
1294 		l_o = new box_matrix(this, box);
1295 	}
1296 	else if (db->m_iType == data_box::SEQUENCE)
1297 	{
1298 		l_o = new box_sequence(this, box);
1299 	}
1300 	else if (db->m_iType == data_box::FRAME)
1301 	{
1302 		l_o = new box_frame(this, box);
1303 	}
1304 	else if (db->m_iType == data_box::CLASS)
1305 	{
1306 		l_o = new box_class(this, box);
1307 	}
1308 	else if (db->m_iType == data_box::ENTITY)
1309 	{
1310 		l_o = new box_entity(this, box);
1311 	}
1312 	else if (db->m_iType == data_box::ACTIVITY_PARALLEL)
1313 	{
1314 		l_o = new box_fork(this, box);
1315 	}
1316 	else if (db->m_iType == data_box::DATABASE)
1317 	{
1318 		l_o = new box_database(this, box);
1319 	}
1320 	else if (db->m_iType == data_box::PIPE)
1321 	{
1322 		l_o = new box_pipe(this, box);
1323 	}
1324 	Q_ASSERT(l_o != NULL);
1325 	m_oItems[box] = l_o;
1326 	l_o->update_data();
1327 }
1328 
notify_del_box(int id,int box)1329 void box_view::notify_del_box(int id, int box)
1330 {
1331 	connectable *l_o = m_oItems.value(box);
1332 	Q_ASSERT(l_o!=NULL);
1333 	QGraphicsItem *l_oTmp = dynamic_cast<QGraphicsItem*>(l_o);
1334 	l_oTmp->hide();
1335 	scene()->removeItem(l_oTmp);
1336 	m_oItems.remove(box);
1337 	delete l_o;
1338 	scene()->update();
1339 }
1340 
notify_link_box(int id,data_link * link)1341 void box_view::notify_link_box(int id, data_link* link)
1342 {
1343 	box_link *l_o = m_oCurrent;
1344 	if (!l_o)
1345 	{
1346 		l_o = new box_link(this);
1347 	}
1348 	m_oLinks.push_back(l_o);
1349 	l_o->m_oInnerLink.copy_from(*link);
1350 	l_o->m_oLink = link;
1351 	l_o->update_text();
1352 	l_o->update_pos();
1353 }
1354 
notify_unlink_box(int id,data_link * link)1355 void box_view::notify_unlink_box(int id, data_link* link)
1356 {
1357 	Q_ASSERT(!m_oCurrent);
1358 	foreach (box_link *cur, m_oLinks) {
1359 		if (cur->m_oLink == link)
1360 		{
1361 			delete cur;
1362 			m_oLinks.removeAll(cur);
1363 			break;
1364 		}
1365 	}
1366 }
1367 
notify_change_link_box(int id,data_link * link)1368 void box_view::notify_change_link_box(int id, data_link*link)
1369 {
1370 	foreach (box_link *cur, m_oLinks)
1371 	{
1372 		if (cur->m_oLink == link)
1373 		{
1374 			cur->m_oInnerLink.copy_from(*cur->m_oLink);
1375 			cur->update_pos();
1376 			break;
1377 		}
1378 	}
1379 }
1380 
wheelEvent(QWheelEvent * i_oEvent)1381 void box_view::wheelEvent(QWheelEvent *i_oEvent)
1382 {
1383 	bool l_bCtrl = i_oEvent->modifiers() & Qt::ControlModifier;
1384 	if (m_oMediator->m_oWindef->m_bUseTouchpad xor l_bCtrl)
1385 	{
1386 		QGraphicsView::wheelEvent(i_oEvent);
1387 		return;
1388 	}
1389 
1390 	QPointF l_o = mapToScene(i_oEvent->pos());
1391 	qreal i_iScaleFactor = pow(2.0, i_oEvent->delta() / 440.0);
1392 	qreal i_rFactor = matrix().scale(i_iScaleFactor, i_iScaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
1393 	if (i_rFactor < 0.01 || i_rFactor > 1000) return;
1394 
1395 	QRectF l_oRect;
1396 	if (scene()->selectedItems().size())
1397 	{
1398 		l_oRect = scene()->selectedItems().at(0)->sceneBoundingRect();
1399 		foreach (QGraphicsItem *l_o, scene()->selectedItems())
1400 		{
1401 			l_oRect |= l_o->sceneBoundingRect();
1402 		}
1403 	}
1404 	else
1405 	{
1406 		l_oRect = visibleRect();
1407 	}
1408 
1409 	qreal l_fPad;
1410 	QSize l_oSize = viewport()->size();
1411 	if (l_oSize.width() * l_oRect.height() < l_oSize.height() * l_oRect.width())
1412 	{
1413 		l_fPad = (1.0 * l_oRect.width() * (1.0 * PIPAD / (l_oSize.width() - PIPAD * 1.0)));
1414 	}
1415 	else
1416 	{
1417 		l_fPad = (1.0 * l_oRect.height() * (1.0 * PIPAD / (l_oSize.height() - PIPAD * 1.0)));
1418 	}
1419 	l_oRect.adjust(-l_fPad, -l_fPad, l_fPad, l_fPad);
1420 	QRectF l_oViewRect = viewport()->rect();
1421 	QRectF l_oNewRect = matrix().scale(i_iScaleFactor, i_iScaleFactor).mapRect(l_oRect);
1422 
1423 	if (scene()->selectedItems().size())
1424 	{
1425 		if (l_oNewRect.width() > l_oViewRect.width() or l_oNewRect.height() > l_oViewRect.height())
1426 		{
1427 			return;
1428 		}
1429 		scale(i_iScaleFactor, i_iScaleFactor);
1430 
1431 		QPointF l_oB = l_oViewRect.center();
1432 		QPointF l_oOrig = mapToScene(l_oB.x(), l_oB.y());
1433 		QPointF l_oCenter = l_oOrig + (1 - 1 / i_iScaleFactor) * (l_o - l_oOrig);
1434 		centerOn(l_oCenter);
1435 
1436 		ensureVisible(l_oRect);
1437 	}
1438 	else
1439 	{
1440 		qreal l_oDiff = qMin(l_oViewRect.width() - l_oRect.width(), l_oViewRect.height() - l_oRect.height()) / 2.;
1441 		if (l_oDiff > 0)
1442 		{
1443 			l_oRect.adjust(-l_oDiff, -l_oDiff, l_oDiff, l_oDiff);
1444 			l_oNewRect = matrix().scale(i_iScaleFactor, i_iScaleFactor).mapRect(l_oRect);
1445 		}
1446 
1447 		if (i_iScaleFactor < 1 and i_iScaleFactor * l_oNewRect.width() < l_oViewRect.width() and i_iScaleFactor * l_oNewRect.height() < l_oViewRect.height())
1448 		{
1449 			fitInView(l_oRect, Qt::KeepAspectRatio);
1450 			centerOn(l_oRect.center());
1451 		}
1452 		else
1453 		{
1454 			QPointF l_oB = l_oViewRect.center();
1455 			QPointF l_oOrig = mapToScene(l_oB.x(), l_oB.y());
1456 			QPointF l_oCenter = l_oOrig + (1 - 1 / i_iScaleFactor) * (l_o - l_oOrig);
1457 
1458 			scale(i_iScaleFactor, i_iScaleFactor);
1459 			centerOn(l_oCenter);
1460 		}
1461 	}
1462 
1463 	i_rFactor = matrix().mapRect(QRectF(0, 0, 1, 1)).width();
1464 	emit sig_message(i18n("Zoom: %1%", QString::number(i_rFactor * 100, 'g', 4)), 2000);
1465 }
1466 
visibleRect()1467 QRectF box_view::visibleRect()
1468 {
1469 	if (scene()->items().size())
1470 	{
1471 		int l_iCount = 0;
1472 		QRectF l_oRect;
1473 		foreach (QGraphicsItem *l_o, scene()->items())
1474 		{
1475 			if (!l_o->isVisible())
1476 			{
1477 				continue;
1478 			}
1479 			if (l_iCount == 0)
1480 			{
1481 				l_oRect = l_o->sceneBoundingRect();
1482 			}
1483 			else
1484 			{
1485 				l_oRect |= l_o->sceneBoundingRect();
1486 			}
1487 			l_iCount += 1;
1488 		}
1489 		if (l_iCount)
1490 		{
1491 			return l_oRect;
1492 		}
1493 	}
1494 	return scene()->itemsBoundingRect();
1495 }
1496 
1497 
fit_zoom()1498 void box_view::fit_zoom()
1499 {
1500 	QRectF l_oRect;
1501 	if (scene()->selectedItems().size())
1502 	{
1503 		l_oRect = scene()->selectedItems().at(0)->sceneBoundingRect();
1504 		foreach (QGraphicsItem *l_o, scene()->selectedItems())
1505 		{
1506 			l_oRect |= l_o->sceneBoundingRect();
1507 		}
1508 	}
1509 	else
1510 	{
1511 		l_oRect = visibleRect();
1512 	}
1513 
1514 	qreal l_fPad;
1515 	QSize l_oSize = viewport()->size();
1516 	if (l_oSize.width() * l_oRect.height() < l_oSize.height() * l_oRect.width())
1517 	{
1518 		l_fPad = (1.0 * l_oRect.width() * (1.0 * PIPAD / (l_oSize.width() - PIPAD * 1.0)));
1519 	}
1520 	else
1521 	{
1522 		l_fPad = (1.0 * l_oRect.height() * (1.0 * PIPAD / (l_oSize.height() - PIPAD * 1.0)));
1523 
1524 	}
1525 	fitInView(l_oRect.adjusted(-l_fPad, -l_fPad, l_fPad, l_fPad), Qt::KeepAspectRatio);
1526 	//centerOn(mapToScene(QPoint(l_oRect.left() + l_oRect.width() / 2., l_oRect.right() + l_oRect.height() / 2.)));
1527 }
1528 
keyPressEvent(QKeyEvent * i_oEvent)1529 void box_view::keyPressEvent(QKeyEvent *i_oEvent)
1530 {
1531 	if (i_oEvent->key() == Qt::Key_Enter || i_oEvent->key() == Qt::Key_Return)
1532 	{
1533 		slot_edit_properties();
1534 	}
1535 	QGraphicsView::keyPressEvent(i_oEvent);
1536 }
1537 
keyReleaseEvent(QKeyEvent * i_oEvent)1538 void box_view::keyReleaseEvent(QKeyEvent *i_oEvent)
1539 {
1540 	QGraphicsView::keyReleaseEvent(i_oEvent);
1541 	setCursor(Qt::ArrowCursor);
1542 }
1543 
slot_size()1544 void box_view::slot_size()
1545 {
1546 	if (scene()->selectedItems().size() < 2) return;
1547 
1548 	int l_i = ((QAction*) QObject::sender())->data().toInt();
1549 	int w = 0;
1550 	int h = 0;
1551 	foreach (QGraphicsItem* l_oItem, scene()->selectedItems())
1552 	{
1553 		if (connectable* c = dynamic_cast<connectable*>(l_oItem))
1554 		{
1555 			QRectF r = c->rectPos();
1556 			if ((l_i == SAME_WIDTH || l_i == SAME_WIDTH_HEIGHT) && r.width() > w)
1557 			{
1558 				w = r.width();
1559 			}
1560 			if ((l_i == SAME_HEIGHT || l_i == SAME_WIDTH_HEIGHT) && r.height() > h)
1561 			{
1562 				h = r.height();
1563 			}
1564 		}
1565 	}
1566 	mem_size_box *mem = new mem_size_box(m_oMediator, m_iId);
1567 	foreach (QGraphicsItem* l_oItem, scene()->selectedItems())
1568 	{
1569 		if (connectable* c = dynamic_cast<connectable*>(l_oItem))
1570 		{
1571 			data_box *box = c->m_oBox;
1572 			mem->prev_values[box] = QRect(box->m_iXX, box->m_iYY, box->m_iWW, box->m_iHH);
1573 			mem->next_values[box] = QRect(box->m_iXX, box->m_iYY, w, h);
1574 		}
1575 	}
1576 	mem->apply();
1577 }
1578 
slot_text_align()1579 void box_view::slot_text_align()
1580 {
1581 	int l_i = ((QAction*) QObject::sender())->data().toInt();
1582 	Qt::AlignmentFlag l_oAlign = Qt::AlignCenter;
1583 	if (l_i == ALIGN_LEFT)
1584 	{
1585 		l_oAlign = Qt::AlignLeft;
1586 	}
1587 	else if (l_i == ALIGN_RIGHT)
1588 	{
1589 		l_oAlign = Qt::AlignRight;
1590 	}
1591 
1592 	mem_text_align_box *l_oMem = new mem_text_align_box(m_oMediator, m_iId);
1593 	l_oMem->m_oAlign = l_oAlign;
1594 	foreach (QGraphicsItem* l_oItem, scene()->selectedItems())
1595         {
1596 		if (connectable* c = dynamic_cast<connectable*>(l_oItem))
1597 		{
1598 			data_box *box = c->m_oBox;
1599 			l_oMem->m_oPrevValues.append(*box);
1600 		}
1601 	}
1602 	l_oMem->apply();
1603 }
1604 
slot_align()1605 void box_view::slot_align()
1606 {
1607 	int l_i = ((QAction*) QObject::sender())->data().toInt();
1608 
1609 	int n = 0;
1610 	qreal best = 0;
1611 	if (l_i == ALIGN_LEFT || l_i == ALIGN_TOP)
1612 		best =  99999999;
1613 	else if (l_i == ALIGN_BOTTOM || l_i == ALIGN_RIGHT)
1614 		best = -99999999;
1615 
1616 	foreach (QGraphicsItem* l_oItem, scene()->selectedItems())
1617 	{
1618 		if (connectable* c = dynamic_cast<connectable*>(l_oItem))
1619 		{
1620 			n++;
1621 			QRectF r = c->rectPos();
1622 			if (l_i == ALIGN_LEFT)
1623 				best = qMin(r.x(), best);
1624 			if (l_i == ALIGN_RIGHT)
1625 				best = qMax(r.x() + r.width(), best);
1626 			if (l_i == ALIGN_BOTTOM)
1627 				best = qMax(r.y() + r.height(), best);
1628 			if (l_i == ALIGN_TOP)
1629 				best = qMin(r.y(), best);
1630 			if (l_i == ALIGN_CENTER)
1631 				best = r.x() + r.width() / 2.; // TODO do not pick one randomly
1632 			if (l_i == ALIGN_MIDDLE)
1633 				best = r.y() + r.height()/2.;
1634 		}
1635 	}
1636 
1637 	if (l_i == ALIGN_CENTER || l_i == ALIGN_MIDDLE)
1638 		best = (int) best;
1639 
1640 	mem_pos_box *mem = new mem_pos_box(m_oMediator, m_iId);
1641 
1642 	foreach (QGraphicsItem* l_oItem, scene()->selectedItems())
1643 	{
1644 		if (connectable* c = dynamic_cast<connectable*>(l_oItem))
1645 		{
1646 			data_box *box = c->m_oBox;
1647 			mem->prev_values[box] = QPointF(box->m_iXX, box->m_iYY);
1648 			switch (l_i)
1649 			{
1650 				case ALIGN_LEFT:
1651 					mem->next_values[box] = QPoint(best, box->m_iYY);
1652 					break;
1653 				case ALIGN_RIGHT:
1654 					mem->next_values[box] = QPoint(best - box->m_iWW, box->m_iYY);
1655 					break;
1656 				case ALIGN_TOP:
1657 					mem->next_values[box] = QPoint(box->m_iXX, best);
1658 					break;
1659 				case ALIGN_BOTTOM:
1660 					mem->next_values[box] = QPoint(box->m_iXX, best - box->m_iHH);
1661 					break;
1662 				case ALIGN_CENTER:
1663 					mem->next_values[box] = QPoint(best - box->m_iWW / 2., box->m_iYY);
1664 					break;
1665 				case ALIGN_MIDDLE:
1666 					mem->next_values[box] = QPoint(box->m_iXX, best - box->m_iHH / 2.);
1667 					break;
1668 				default:
1669 					Q_ASSERT(false);
1670 			}
1671 		}
1672 	}
1673 	mem->apply();
1674 }
1675 
mouseDoubleClickEvent(QMouseEvent * i_oEv)1676 void box_view::mouseDoubleClickEvent(QMouseEvent* i_oEv)
1677 {
1678 	if (i_oEv->button() != Qt::LeftButton)
1679 	{
1680 		//qDebug()<<"left button on click, leaving";
1681 		return;
1682 	}
1683 
1684 	QGraphicsItem *l_oItem = itemAt(i_oEv->pos());
1685 	if (l_oItem)
1686 	{
1687 		editable *l_o = dynamic_cast<editable*>(l_oItem);
1688 		if (l_o)
1689 		{
1690 			l_o->properties();
1691 		}
1692 	}
1693 	else
1694 	{
1695 		slot_add_item();
1696 	}
1697 }
1698 
mousePressEvent(QMouseEvent * i_oEv)1699 void box_view::mousePressEvent(QMouseEvent *i_oEv)
1700 {
1701 	if (m_oMenu == NULL) {
1702 		init_menu();
1703 	}
1704 
1705 	if (i_oEv->button() == Qt::RightButton)
1706 	{
1707 		m_oLastPoint = mapToScene(i_oEv->pos());
1708 		enable_menu_actions();
1709 		m_oMenu->popup(i_oEv->globalPos());
1710 		return;
1711 	}
1712 
1713 	m_bPressed = true;
1714 	m_oLastMovePoint = m_oLastPoint = mapToScene(i_oEv->pos());
1715 
1716 	if (i_oEv->button() == Qt::MidButton)
1717 	{
1718 		m_oScrollPoint = i_oEv->pos();
1719 		viewport()->setCursor(Qt::OpenHandCursor);
1720 		m_bScroll = true;
1721 		return;
1722 	}
1723 
1724 	box_item *k = NULL;
1725 	box_chain *kk = NULL;
1726 	foreach (QGraphicsItem *l_oTmp, items(i_oEv->pos()))
1727 	{
1728 		if (!kk)
1729 		{
1730 			kk = dynamic_cast<box_chain*>(l_oTmp);
1731 			if (kk)
1732 			{
1733 				break;
1734 			}
1735 		}
1736 		if (!k)
1737 		{
1738 			k = dynamic_cast<box_item*>(l_oTmp);
1739 			if (k )
1740 			{
1741 				break;
1742 			}
1743 		}
1744 	}
1745 
1746 	if (kk)
1747 	{
1748 		Q_ASSERT(!m_oCurrent);
1749 
1750 		foreach (QGraphicsItem *l_o, scene()->selectedItems())
1751 		{
1752 			l_o->setSelected(false);
1753 		}
1754 
1755 		connectable *l_oParent = dynamic_cast<connectable*>(kk->parentItem());
1756 		Q_ASSERT(l_oParent);
1757 
1758 		QPoint p = QPoint(m_oLastPoint.x(), m_oLastPoint.y());
1759 
1760 		m_oCurrent = new box_link(this);
1761 		m_oCurrent->m_oInnerLink.m_iParent = l_oParent->m_iId;
1762 		m_oCurrent->m_oInnerLink.m_iParentPos = l_oParent->optimize_position(p);
1763 		m_oCurrent->m_oInnerLink.m_iChild = NO_ITEM;
1764 		m_oCurrent->m_oInnerLink.m_iChildPos = data_link::NORTH;
1765 		m_oCurrent->m_oInnerLink.m_oStartPoint = m_oCurrent->m_oInnerLink.m_oEndPoint = p;
1766 		m_oCurrent->m_oInnerLink.m_iId = m_oMediator->next_box_link_seq(m_iId);
1767 		m_oCurrent->m_oInnerLink.m_iLeftArrow = m_oMediator->m_oLinkState.m_iLeftArrow;
1768 		m_oCurrent->m_oInnerLink.m_iRightArrow = m_oMediator->m_oLinkState.m_iRightArrow;
1769 		m_oCurrent->m_oInnerLink.m_iLineType = m_oMediator->m_oLinkState.m_iLineType;
1770 		m_oCurrent->m_oInnerLink.pen_style = m_oMediator->m_oLinkState.pen_style;
1771 
1772 		if (dynamic_cast<box_label*>(l_oParent))
1773 		{
1774 			m_oCurrent->m_oInnerLink.pen_style = Qt::DotLine;
1775 			m_oCurrent->m_oInnerLink.m_iLeftArrow = data_link::NONE;
1776 			m_oCurrent->m_oInnerLink.m_iRightArrow = data_link::NONE;
1777 			m_oCurrent->m_oInnerLink.m_iLineType = data_link::LINE;
1778 		}
1779 
1780 		m_oCurrent->setSelected(true);
1781 	}
1782 	else if (k)
1783 	{
1784 		QPointF l_o = k->pos();
1785 		// TODO used by the handle for resizing the boxes - check that the click was on the handle
1786 		if (m_oLastPoint.x() + m_oLastPoint.y() - l_o.x() - l_o.y() >
1787 			k->rect().width() + k->rect().height() - 2*GRID)
1788 		{
1789 			m_oOffsetPoint = QPointF(k->rect().width(), k->rect().height());
1790 		}
1791 		else
1792 		{
1793 			m_oOffsetPoint = QPointF(-1, -1);
1794 		}
1795 	}
1796 
1797 	QGraphicsView::mousePressEvent(i_oEv);
1798 }
1799 
mouseMoveEvent(QMouseEvent * i_oEv)1800 void box_view::mouseMoveEvent(QMouseEvent *i_oEv)
1801 {
1802 	if (m_bScroll)
1803 	{
1804 		QScrollBar *l_h_bar = horizontalScrollBar();
1805 		QScrollBar *l_v_bar = verticalScrollBar();
1806 
1807 		QPoint l_o = i_oEv->pos() - m_oScrollPoint;
1808 
1809 		l_h_bar->setValue(l_h_bar->value() + (isRightToLeft() ? l_o.x() : - l_o.x()));
1810 		l_v_bar->setValue(l_v_bar->value() - l_o.y());
1811 
1812 		m_oScrollPoint = i_oEv->pos();
1813 		return;
1814 	}
1815 
1816 	if (m_bPressed) m_oLastMovePoint = mapToScene(i_oEv->pos());
1817 	QGraphicsView::mouseMoveEvent(i_oEv);
1818 }
1819 
mouseReleaseEvent(QMouseEvent * i_oEv)1820 void box_view::mouseReleaseEvent(QMouseEvent *i_oEv)
1821 {
1822 	if (m_oCurrent)
1823 	{
1824 		if (m_oItems.value(m_oCurrent->m_oInnerLink.m_iChild))
1825 		{
1826 			mem_link_box *ln = new mem_link_box(m_oMediator, m_iId);
1827 			ln->link = new data_link();
1828 			ln->link->copy_from(m_oCurrent->m_oInnerLink);
1829 			ln->apply();
1830 
1831 			m_oCurrent = NULL;
1832 		}
1833 		else
1834 		{
1835 			// assume cancel
1836 			delete m_oCurrent;
1837 			m_oCurrent = NULL;
1838 		}
1839 		m_bPressed = false;
1840 		QGraphicsView::mouseReleaseEvent(i_oEv);
1841 		return;
1842 	}
1843 
1844 
1845 	if (m_bScroll)
1846 	{
1847 		QGraphicsView::mouseReleaseEvent(i_oEv);
1848 		m_bPressed = false;
1849 		m_bScroll = false;
1850 		viewport()->setCursor(Qt::ArrowCursor);
1851 		return;
1852 	}
1853 
1854 	QGraphicsView::mouseReleaseEvent(i_oEv);
1855 
1856 	m_bPressed = false;
1857 	{
1858 		//if (qAbs(p->m_iXX - v->pos().x()) + qAbs(p->m_iYY - v->pos().y()) > 0.1) {
1859 
1860 		QPointF p = mapToScene(i_oEv->pos()) - m_oLastPoint;
1861 		if (qAbs(p.x()) > 3 || qAbs(p.y()) > 3)
1862 		{
1863 			mem_pos_box *mem = new mem_pos_box(m_oMediator, m_iId);
1864 			foreach (QGraphicsItem *l_oI1, scene()->selectedItems())
1865 			{
1866 				if (connectable* item = dynamic_cast<connectable*>(l_oI1))
1867 				{
1868 					data_box *box = item->m_oBox;
1869 					mem->prev_values[box] = QPointF(box->m_iXX, box->m_iYY);
1870 					mem->next_values[box] = l_oI1->pos();
1871 				}
1872 			}
1873 			if (mem->prev_values.size() > 0)
1874 			{
1875 				mem->apply();
1876 			}
1877 			else
1878 			{
1879 				delete mem;
1880 			}
1881 		}
1882 	}
1883 	check_canvas_size();
1884 }
1885 
notify_box_props(int id,const QList<diagram_item * > & items)1886 void box_view::notify_box_props(int id, const QList<diagram_item*>& items)
1887 {
1888 	Q_ASSERT(id == m_iId);
1889 	foreach (diagram_item* it, items) {
1890 		foreach (box_link *lnk, m_oLinks)
1891 		{
1892 			if (lnk->m_oLink == it) {
1893 				data_link* dat = static_cast<data_link*>(it);
1894 				lnk->m_oInnerLink.copy_from(*dat);
1895 				lnk->update_text();
1896 				lnk->update_pos();
1897 				lnk->update();
1898 				goto end;
1899 			}
1900 		}
1901 
1902 		foreach (connectable *box, m_oItems.values())
1903 		{
1904 			if (box->m_oBox == it) {
1905 				(dynamic_cast<QGraphicsItem*>(box))->update();
1906 				goto end;
1907 			}
1908 		}
1909 		end:
1910 			;
1911 	}
1912 }
1913 
notify_pos_box(int id,const QList<data_box * > & items)1914 void box_view::notify_pos_box(int id, const QList<data_box*>& items)
1915 {
1916 	Q_ASSERT(id == m_iId);
1917 	foreach (data_box *box, items)
1918 	{
1919 		m_oItems[box->m_iId]->update_data();
1920 	}
1921 }
1922 
notify_text_align(int id,const QList<data_box> & items)1923 void box_view::notify_text_align(int id, const QList<data_box>& items)
1924 {
1925 	Q_ASSERT(id == m_iId);
1926 	foreach (data_box box, items)
1927 	{
1928 		m_oItems[box.m_iId]->update_data();
1929 	}
1930 }
1931 
notify_size_box(int id,const QList<data_box * > & items)1932 void box_view::notify_size_box(int id, const QList<data_box*>& items)
1933 {
1934 	Q_ASSERT(id == m_iId);
1935 	foreach (data_box *box, items)
1936 	{
1937 		Q_ASSERT(m_oItems.contains(box->m_iId));
1938 		m_oItems[box->m_iId]->update_size();
1939 	}
1940 }
1941 
notify_sequence_box(int i_iId,int i_iBoxId)1942 void box_view::notify_sequence_box(int i_iId, int i_iBoxId)
1943 {
1944 	Q_ASSERT(i_iId == m_iId);
1945 	m_oItems[i_iBoxId]->update_data();
1946 }
1947 
next_seq()1948 int box_view::next_seq()
1949 {
1950 	do {
1951 		++num_seq;
1952 	} while (m_oItems.contains(num_seq));
1953 	return num_seq;
1954 }
1955 
notify_focus(void * ptr)1956 void box_view::notify_focus(void* ptr)
1957 {
1958 	bool cond = ptr == this;
1959 	m_oAddItemAction->setEnabled(cond);
1960 	m_oDeleteAction->setEnabled(cond);
1961 	//m_oEditAction->setEnabled(cond);
1962 }
1963 
message(const QString & s,int d)1964 void box_view::message(const QString &s, int d)
1965 {
1966 	emit sig_message(s, d);
1967 }
1968 
slot_import_from_file()1969 bool box_view::slot_import_from_file() {
1970 	Q_ASSERT(m_oMediator->m_oItems.contains(m_iId));
1971 	data_item& l_oItem = m_oMediator->m_oItems[m_iId];
1972 
1973 	QUrl l_oDefault = QUrl(l_oItem.m_sExportUrl);
1974 	if (!l_oDefault.isValid())
1975 	{
1976 		l_oDefault = QUrl(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
1977 	}
1978 
1979 	QUrl l_o = QFileDialog::getOpenFileUrl(this, i18n("Choose a file to open"),
1980                 l_oDefault,
1981 		i18n("*.semd|Semantik diagram (*.semd)"));
1982 	bool l_bRet = import_from_file(l_o);
1983 	if (l_bRet)
1984 	{
1985 		l_oItem.m_sExportUrl = l_o.url();
1986 	}
1987 	return l_bRet;
1988 }
1989 
import_from_file(const QUrl & l_o)1990 bool box_view::import_from_file(const QUrl& l_o)
1991 {
1992 	if (l_o.path().isEmpty()) {
1993 		return false;
1994 	}
1995 
1996 	// use a full semantik document, even if we are only interested in one item
1997 	sem_mediator *x = new sem_mediator(this);
1998 
1999 	bool l_bOk = false;
2000 	if (x->open_raw(l_o.path()) && x->m_oItems.size() == 1) {
2001 		l_bOk = true;
2002 		data_item& tmp = x->m_oItems[x->m_oItems.keys().at(0)];
2003 
2004 		mem_import_box *imp = new mem_import_box(m_oMediator, m_iId);
2005 		imp->init(tmp.m_oBoxes.values(), tmp.m_oLinks);
2006 		imp->m_iNewFont = tmp.m_oDiagramFont;
2007 		imp->m_oOldColorSchemes = m_oMediator->m_oColorSchemes;
2008 		imp->m_oNewColorSchemes = x->m_oColorSchemes;
2009 
2010 		imp->m_bExportIsWidthNew = tmp.m_bExportIsWidth;
2011 		imp->m_iExportWidthNew = tmp.m_iExportWidth;
2012 		imp->m_iExportHeightNew = tmp.m_iExportHeight;
2013 		imp->m_sExportUrlNew = tmp.m_sExportUrl;
2014 
2015 		imp->apply();
2016 
2017 		m_oCurrentUrl = l_o;
2018 		emit sig_Url(m_oCurrentUrl);
2019 	}
2020 
2021 	delete x;
2022 
2023 	return l_bOk;
2024 }
2025 
slot_export_to_file()2026 bool box_view::slot_export_to_file() {
2027 	Q_ASSERT(m_oMediator->m_oItems.contains(m_iId));
2028 	data_item& l_oItem = m_oMediator->m_oItems[m_iId];
2029 
2030 	QUrl l_oDefault = QUrl(l_oItem.m_sExportUrl);
2031 	if (!l_oDefault.isValid())
2032 	{
2033 		l_oDefault = QUrl(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
2034 	}
2035 
2036 	choose_export:
2037 	QUrl l_o = QFileDialog::getSaveFileUrl(this, i18n("Choose a file name"),
2038                 l_oDefault,
2039 		i18n("*.semd|Semantik diagram (*.semd)"));
2040 
2041 	if (l_o.path().isEmpty()) return false;
2042 	if (!l_o.path().endsWith(notr(".semd")))
2043 	{
2044 		l_o = QUrl(l_o.path()+notr(".semd"));
2045 	}
2046 
2047 	m_oCurrentUrl = l_o;
2048 	emit sig_Url(m_oCurrentUrl);
2049 
2050 	// now the magic
2051 	sem_mediator *x = new sem_mediator(this);
2052 	Q_ASSERT(m_oMediator->m_oItems.contains(m_iId));
2053 	data_item& l_oData = m_oMediator->m_oItems[m_iId];
2054 	l_oData.m_iDataType = VIEW_DIAG;
2055 	x->m_oItems.insert(1, l_oData);
2056 	x->m_oColorSchemes = m_oMediator->m_oColorSchemes;
2057 
2058 	l_oItem.m_sExportUrl = l_o.url();
2059 	if (x->save_file(l_o.path()))
2060 	{
2061 		emit sig_message(i18n("Saved '%1'", l_o.path()), 2000);
2062 		m_oMediator->set_dirty(false);
2063 		return true;
2064 	}
2065 	else
2066 	{
2067 		int mu = KMessageBox::questionYesNo(NULL, //this,
2068 		i18n("The file \"%1\" could not be saved because an error happened.\nTry again?", l_o.path()),
2069 		i18n("Try again?"),
2070 		KStandardGuiItem::yes(),
2071 		KStandardGuiItem::no(),
2072 		notr("ContinueSaveAs"));
2073 		if (!mu) {
2074 			goto choose_export;
2075 		}
2076 		else
2077 		{
2078 			return false;
2079 		}
2080 	}
2081 	return false;
2082 }
2083 
slot_save()2084 bool box_view::slot_save() {
2085 	if (m_oCurrentUrl.isValid())
2086 	{
2087 		sem_mediator *x = new sem_mediator(this);
2088 		Q_ASSERT(m_oMediator->m_oItems.contains(m_iId));
2089 		data_item& l_oData = m_oMediator->m_oItems[m_iId];
2090 		l_oData.m_iDataType = VIEW_DIAG;
2091 		x->m_oItems.insert(1, l_oData);
2092 		x->m_oColorSchemes = m_oMediator->m_oColorSchemes;
2093 
2094 		if (x->save_file(m_oCurrentUrl.path())) {
2095 			m_oMediator->set_dirty(false);
2096 			emit sig_message(i18n("Saved '%1'", m_oCurrentUrl.path()), 2000);
2097 			return true;
2098 		}
2099 	}
2100 	else
2101 	{
2102 		return slot_export_to_file();
2103 	}
2104 	return false;
2105 }
2106 
drawThumb(QPainter * i_oPainter,QRectF & i_oRect,int i_iId)2107 QRectF box_view::drawThumb(QPainter* i_oPainter, QRectF& i_oRect, int i_iId)
2108 {
2109 	clear_diagram();
2110 
2111 	m_iId = i_iId;
2112 	Q_ASSERT(m_oMediator->m_oItems.contains(m_iId));
2113 	data_item& l_oData = m_oMediator->m_oItems[m_iId];
2114 	if (l_oData.m_iDataType == VIEW_DIAG)
2115 	{
2116 		if (!l_oData.m_sDiag.isEmpty())
2117 		{
2118 			from_string(l_oData.m_sDiag);
2119 			l_oData.m_sDiag = notr("");
2120 		}
2121 		sync_view();
2122 		check_canvas_size();
2123 	}
2124 	else
2125 	{
2126 		return QRectF();
2127 	}
2128 
2129 	QRectF l_oRect = visibleRect().adjusted(-PIPAD, -PIPAD, PIPAD, PIPAD);
2130 	QRectF l_oR(0, 0, l_oRect.width(), l_oRect.height());
2131 
2132 	QRectF l_oDrawRect(i_oRect);
2133 
2134 	if (l_oRect.width() > l_oRect.height())
2135 	{
2136 		l_oDrawRect.setHeight(l_oDrawRect.height() * (1. * l_oRect.height() / l_oRect.width()));
2137 	}
2138 	else
2139 	{
2140 		l_oDrawRect.setWidth(l_oDrawRect.width() * (1. * l_oRect.width() / l_oRect.height()));
2141 	}
2142 
2143 	i_oPainter->save();
2144 	QPen l_oPen;
2145 	l_oPen.setCosmetic(true);
2146 	i_oPainter->setPen(l_oPen);
2147 	i_oPainter->setBrush(Qt::white);
2148 	i_oPainter->drawRect(l_oDrawRect);
2149 	i_oPainter->restore();
2150 
2151 	scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
2152 	scene()->render(i_oPainter, i_oRect, l_oRect, Qt::KeepAspectRatio);
2153 	scene()->setItemIndexMethod(QGraphicsScene::BspTreeIndex);
2154 	return l_oDrawRect;
2155 }
2156 
2157 
batch_print_map(const QUrl & i_oUrl,QPair<int,int> & p)2158 int box_view::batch_print_map(const QUrl& i_oUrl, QPair<int, int> & p)
2159 {
2160 	QString url = i_oUrl.path();
2161 	QRectF l_oRect = visibleRect().adjusted(-PIPAD, -PIPAD, PIPAD, PIPAD);
2162 
2163 	QRectF l_oR(0, 0, l_oRect.width(), l_oRect.height());
2164 
2165 	if (p.first != 0) {
2166 		l_oR.setWidth(p.first);
2167 		if (p.second == 0) {
2168 			l_oR.setHeight((p.first * l_oRect.height()) / (double) l_oRect.width());
2169 		}
2170 	}
2171 	if (p.second != 0) {
2172 		l_oR.setHeight(p.second);
2173 		if (p.first == 0) {
2174 			l_oR.setWidth((p.second * l_oRect.width()) / (double) l_oRect.height());
2175 		}
2176 	}
2177 
2178 	Qt::AspectRatioMode rat = (p.first == 0 || p.second == 0) ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio;
2179 
2180 	if (url.endsWith("png")) {
2181 		// fill with white
2182 		QImage l_oImage((int) l_oR.width(), (int) l_oR.height(), QImage::Format_RGB32);
2183 		l_oImage.fill(qRgb(255,255,255));
2184 
2185 		QPainter l_oP;
2186 		l_oP.begin(&l_oImage);
2187 		l_oP.setRenderHints(QPainter::Antialiasing);
2188 		scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
2189 		scene()->render(&l_oP, l_oR, l_oRect, rat);
2190 		scene()->setItemIndexMethod(QGraphicsScene::BspTreeIndex);
2191 		l_oP.end();
2192 
2193 		l_oImage.save(url);
2194 	} else if (url.endsWith("pdf") or url.endsWith("ps") or url.endsWith("eps")) {
2195 		QPrinter l_oPrinter;
2196 		l_oPrinter.setOrientation(QPrinter::Portrait);
2197 		if (url.endsWith("pdf"))
2198 		{
2199 			l_oPrinter.setOutputFormat(QPrinter::PdfFormat);
2200 		}
2201 		else
2202 		{
2203 			l_oPrinter.setOutputFormat(QPrinter::NativeFormat);
2204 			l_oPrinter.setResolution(QPrinter::HighResolution);
2205 		}
2206 		l_oPrinter.setPaperSize(l_oR.size(), QPrinter::DevicePixel);
2207 		l_oPrinter.setPageMargins(0, 0, 0, 0, QPrinter::DevicePixel);
2208 		l_oPrinter.setOutputFileName(url);
2209 
2210 		QPainter l_oPdf;
2211 		if (l_oPdf.begin(&l_oPrinter))
2212 		{
2213 			m_bDisableGradient = DISABLE_GRADIENT;
2214 			scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
2215 			scene()->render(&l_oPdf, l_oR, l_oRect, rat);
2216 			scene()->setItemIndexMethod(QGraphicsScene::BspTreeIndex);
2217 			l_oPdf.end();
2218 			m_bDisableGradient = false;
2219 		}
2220 	}
2221 	else if (url.endsWith("svg"))
2222 	{
2223 		QSvgGenerator l_oGenerator;
2224 		l_oGenerator.setFileName(url);
2225 		l_oGenerator.setSize(QSize(l_oR.width(), l_oR.height()));
2226 		l_oGenerator.setViewBox(l_oR);
2227 		l_oGenerator.setTitle(i18n("Semantik diagram"));
2228 		l_oGenerator.setDescription(notr("Generated by Semantik, if it does not render properly check your system fonts!"));
2229 		l_oGenerator.setResolution(QApplication::desktop()->logicalDpiX());
2230 
2231 		QPainter l_oP;
2232 		l_oP.begin(&l_oGenerator);
2233 		l_oP.setRenderHints(QPainter::Antialiasing);
2234 		scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
2235 		scene()->render(&l_oP, l_oR, l_oRect, rat);
2236 		scene()->setItemIndexMethod(QGraphicsScene::BspTreeIndex);
2237 		l_oP.end();
2238 	} else {
2239 		return 12;
2240 	}
2241 	return 0;
2242 }
2243 
2244 // The following is copy-pasted. Watch carefully
slot_print()2245 void box_view::slot_print()
2246 {
2247         QPrinter *l_oP = new QPrinter;
2248 
2249 	QRectF l_oRect = visibleRect().adjusted(-PIPAD, -PIPAD, PIPAD, PIPAD);
2250 	foreach (QGraphicsItem*it, scene()->items())
2251 	{
2252 		it->setCacheMode(QGraphicsItem::NoCache); // the magic happens here
2253 	}
2254 
2255 	QRectF l_oR(0, 0, l_oRect.width(), l_oRect.height());
2256 
2257 	l_oP->setOrientation(QPrinter::Portrait);
2258 	l_oP->setOutputFormat(QPrinter::PdfFormat);
2259 	l_oP->setPaperSize(l_oR.size(), QPrinter::DevicePixel);
2260 	l_oP->setPageMargins(0, 0, 0, 0, QPrinter::DevicePixel);
2261 
2262         QPrintDialog l_oD(l_oP, this);
2263         if (l_oD.exec() != QDialog::Accepted)
2264         {
2265 		emit sig_message(i18n("Printing cancelled"), 3000);
2266 		return;
2267 	}
2268 
2269 	QPainter l_oPdf;
2270 	if (l_oPdf.begin(l_oP))
2271 	{
2272 		m_bDisableGradient = DISABLE_GRADIENT;
2273 		scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
2274 		scene()->render(&l_oPdf, QRectF(), l_oRect, Qt::KeepAspectRatio);
2275 		scene()->setItemIndexMethod(QGraphicsScene::BspTreeIndex);
2276 		l_oPdf.end();
2277 		m_bDisableGradient = false;
2278 		emit sig_message(i18n("Printing completed"), 5000);
2279 	}
2280 	else
2281 	{
2282 		emit sig_message(i18n("Problem during printing :-("), 5000);
2283 	}
2284 }
2285 
slot_copy_picture()2286 void box_view::slot_copy_picture()
2287 {
2288 	QRectF l_oRect = visibleRect().adjusted(-PIPAD, -PIPAD, PIPAD, PIPAD);
2289 
2290 	QRectF l_oR(0, 0, 2*l_oRect.width(), 2*l_oRect.height());
2291 	Qt::AspectRatioMode rat = Qt::KeepAspectRatio;
2292 
2293 	QImage l_oImage((int) l_oR.width(), (int) l_oR.height(), QImage::Format_RGB32);
2294 	l_oImage.fill(qRgb(255,255,255));
2295 
2296 	QPainter l_oP;
2297 	l_oP.begin(&l_oImage);
2298 	l_oP.setRenderHints(QPainter::Antialiasing);
2299 	scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
2300 	scene()->render(&l_oP, l_oR, l_oRect, rat);
2301 	scene()->setItemIndexMethod(QGraphicsScene::BspTreeIndex);
2302 	l_oP.end();
2303 
2304 	//QApplication::clipboard()->setMimeType("application/x-png");
2305 	QApplication::clipboard()->setImage(l_oImage);
2306 }
2307 
notify_change_properties(void *)2308 void box_view::notify_change_properties(void *)
2309 {
2310 	// this may be the wrong approach entirely
2311 	Q_ASSERT(m_oMediator->m_oItems.contains(m_iId));
2312 	data_item& l_oData = m_oMediator->m_oItems[m_iId];
2313 	if (l_oData.m_oDiagramFont != font()) {
2314 		scene()->setFont(l_oData.m_oDiagramFont);
2315 		foreach (QGraphicsItem *l_o, scene()->items())
2316 		{
2317 			if (connectable* t = dynamic_cast<connectable*>(l_o))
2318 			{
2319 				t->update_size();
2320 			}
2321 			else if (box_link *t = dynamic_cast<box_link*>(l_o))
2322 			{
2323 				t->update_text();
2324 				t->update_pos();
2325 			}
2326 			l_o->update();
2327 		}
2328 	}
2329 }
2330 
export_fig_size()2331 void box_view::export_fig_size()
2332 {
2333 	QRectF l_oRect = visibleRect().adjusted(-PIPAD, -PIPAD, PIPAD, PIPAD);
2334 
2335 	export_fig_dialog* exp = new export_fig_dialog(this);
2336 
2337 	exp->kurlrequester->setMode(KFile::File | KFile::LocalOnly);
2338 	exp->kurlrequester->setFilter(i18n("*.png|PNG Files (*.png)\n*.svg|SVG Files (*.svg)\n*.pdf|PDF Files (*.pdf)"));
2339 
2340 	Q_ASSERT(m_oMediator->m_oItems.contains(m_iId));
2341 	data_item& l_oItem = m_oMediator->m_oItems[m_iId];
2342 
2343 	exp->kurlrequester->setUrl(QUrl(l_oItem.m_sExportUrl));
2344 	exp->m_oWidthC->setChecked(l_oItem.m_bExportIsWidth);
2345 	exp->m_oHeightC->setChecked(!l_oItem.m_bExportIsWidth);
2346 	exp->m_iBaseWidth = l_oRect.width();
2347 	exp->m_iBaseHeight = l_oRect.height();
2348 
2349 	if (l_oItem.m_bExportIsWidth)
2350 	{
2351 		if (l_oItem.m_iExportWidth > 0)
2352 			exp->m_oWidth->setValue(l_oItem.m_iExportWidth);
2353 		else
2354 			exp->m_oWidth->setValue(l_oRect.width());
2355 	}
2356 	else
2357 	{
2358 		if (l_oItem.m_iExportHeight > 0)
2359 			exp->m_oHeight->setValue(l_oItem.m_iExportHeight);
2360 		else
2361 			exp->m_oHeight->setValue(l_oRect.height());
2362 	}
2363 
2364 	if (exp->exec() == QDialog::Accepted)
2365 	{
2366 		if (l_oItem.m_iExportWidth != exp->m_oWidth->value())
2367 		{
2368 			l_oItem.m_iExportWidth = exp->m_oWidth->value();
2369 			m_oMediator->set_dirty();
2370 		}
2371 
2372 		if (l_oItem.m_iExportHeight != exp->m_oHeight->value())
2373 		{
2374 			l_oItem.m_iExportHeight = exp->m_oHeight->value();
2375 			m_oMediator->set_dirty();
2376 		}
2377 
2378 		if (!exp->kurlrequester->url().isValid() || exp->kurlrequester->url().isEmpty())
2379 		{
2380 			emit sig_message(i18n("No destination file selected"), 5000);
2381 			return;
2382 		}
2383 
2384 		if (l_oItem.m_sExportUrl != exp->kurlrequester->url().url())
2385 		{
2386 			l_oItem.m_sExportUrl = exp->kurlrequester->url().url();
2387 			m_oMediator->set_dirty();
2388 		}
2389 
2390 		QPair<int, int> p;
2391 		if (exp->m_oWidthC->isChecked()) {
2392 			p.first = exp->m_oWidth->value();
2393 		} else {
2394 			p.second = exp->m_oHeight->value();
2395 		}
2396 
2397 		// TODO upload remote files?
2398 		QUrl url = exp->kurlrequester->url();
2399 		if (url.isRelative()) {
2400 			url.setPath(QDir::homePath() + notr("/") + url.toLocalFile());
2401 		}
2402 		int status = batch_print_map(url, p);
2403 		if (status == 0)
2404 			emit sig_message(i18n("Exported '%1'", url.fileName()), 2000);
2405 		else
2406 			KMessageBox::sorry(this, i18n("Could not save to %1", url.fileName()), i18n("Missing picture"));
2407 	}
2408 }
2409 
2410 
2411