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