Verified Commit 328baa61 authored by ita1024's avatar ita1024

Bring back the reference system from Kdissert

parent 5a32794b
Semantik 1.2.0
--------------
* Add a system of references similar to what was present in kdissert
* Fix missing crossing lines when printing or exporting diagrams
Semantik 1.1.0
--------------
* Improve the looks of diagram crossing lines
......
......@@ -147,6 +147,12 @@ const color_scheme& data_item::get_color_scheme_raw(sem_mediator* i_oMediator) c
}
data_ref::data_ref(int i_iParent, int i_iChild)
{
m_iParent = i_iParent;
m_iChild = i_iChild;
}
diagram_item::diagram_item()
{
pen_style = Qt::SolidLine;
......
......@@ -240,5 +240,13 @@ class data_item
int m_iObjectHeightHint;
};
class data_ref
{
public:
data_ref(int, int);
int m_iParent;
int m_iChild;
};
#endif
......@@ -112,6 +112,61 @@ void mem_link::undo() {
///////////////////////////////////////////////////////////////////
mem_ref::mem_ref(sem_mediator* mod) : mem_command(mod)
{
}
void mem_ref::redo()
{
data_ref l_oRef(m_iParent, m_iChild);
model->m_oRefs.append(l_oRef);
model->notify_ref_items(m_iParent, m_iChild);
redo_dirty();
}
void mem_ref::undo()
{
int l_iPos = -1;
for (int i = 0 ; i < model->m_oRefs.size() ; ++ i)
{
const data_ref& l_oRef = model->m_oRefs.at(i);
if (l_oRef.m_iParent == m_iParent && l_oRef.m_iChild == m_iChild)
{
l_iPos = i;
break;
}
}
Q_ASSERT(l_iPos != -1);
model->m_oRefs.removeAt(l_iPos);
model->notify_unref_items(m_iParent, m_iChild);
undo_dirty();
}
///////////////////////////////////////////////////////////////////
mem_unref::mem_unref(sem_mediator* mod) : mem_command(mod)
{
m_iPos = 0;
}
void mem_unref::redo()
{
model->m_oRefs.removeAt(m_iPos);
model->notify_unref_items(m_iParent, m_iChild);
redo_dirty();
}
void mem_unref::undo()
{
data_ref l_oRef(m_iParent, m_iChild);
model->m_oRefs.insert(m_iPos, l_oRef);
model->notify_ref_items(m_iParent, m_iChild);
undo_dirty();
}
///////////////////////////////////////////////////////////////////
mem_sel::mem_sel(sem_mediator* mod) : mem_command(mod) {
m_iSortSel = NO_ITEM;
m_iSortUnsel = NO_ITEM;
......
......@@ -25,7 +25,7 @@ class mem_command {
enum IType {DELETE, ADD, LINK, UNLINK, SELECT, MOVE, COLOR, FLAG, EDIT, DATATYPE, TEXT, VARS, PIC, TABLE, SORT,
ADD_BOX, DEL_BOX, EDIT_BOX, LINK_BOX, UNLINK_BOX, PROP_BOX, POS_BOX, CHANGE_LINK_BOX, SIZE_BOX,
EDIT_LINK, IMPORT_BOX, SIZE_MATRIX, CHANGE_CLASS_BOX, DIAGRAM_PROPERTIES, SIZE_SEQUENCE, DOC,
TEXT_ALIGN_BOX};
TEXT_ALIGN_BOX, REF, UNREF};
virtual IType type() = 0;
};
......@@ -67,6 +67,31 @@ class mem_link : public mem_command {
IType type() { return LINK; }
};
class mem_ref : public mem_command {
public:
mem_ref(sem_mediator*);
void undo();
void redo();
int m_iParent;
int m_iChild;
IType type() { return REF; }
};
class mem_unref : public mem_command {
public:
mem_unref(sem_mediator*);
void undo();
void redo();
int m_iParent;
int m_iChild;
int m_iPos;
IType type() { return UNREF; }
};
class mem_add : public mem_command {
public:
mem_add(sem_mediator*);
......
......@@ -125,6 +125,14 @@ bool semantik_reader::startElement(const QString&, const QString&, const QString
if (!m_oMediator->m_oItems.contains(b)) return false;
m_oMediator->m_oLinks.append(QPoint(a, b));
}
else if (i_sName == notr("ref"))
{
int l_iP = i_oAttrs.value(notr("p")).toInt();
int l_iV = i_oAttrs.value(notr("v")).toInt();
if (!m_oMediator->m_oItems.contains(l_iP)) return false;
if (!m_oMediator->m_oItems.contains(l_iV)) return false;
m_oMediator->m_oRefs.append(data_ref(l_iP, l_iV));
}
else if (i_sName == notr("tblsettings"))
{
data_item& l_oItem = m_oMediator->m_oItems[m_iId];
......@@ -638,10 +646,15 @@ QString sem_mediator::doc_to_xml()
l_oS<<notr("</item>\n");
}
foreach (const data_ref& l_oRef, m_oRefs)
{
l_oS<<notr("<ref p=\"%1\" v=\"%2\"/>\n").arg(l_oRef.m_iParent, l_oRef.m_iChild);
}
for (int i=0; i<m_oLinks.size(); i++)
{
QPoint l_oP = m_oLinks.at(i);
l_oS<<notr("<link p=\"%1\" v=\"%2\"/>\n").arg(l_oP.x()).arg(l_oP.y());
l_oS<<notr("<link p=\"%1\" v=\"%2\"/>\n").arg(l_oP.x(), l_oP.y());
}
l_oS<<notr("</semantik>\n");
......@@ -856,6 +869,49 @@ void sem_mediator::notify_flags()
emit sync_flags();
}
bool sem_mediator::ref_items(int i_iParent, int i_iChild)
{
Q_ASSERT(m_oItems.contains(i_iParent) && m_oItems.contains(i_iChild));
if (i_iParent == i_iChild) return false;
foreach (const QPoint& l_oP, m_oLinks)
{
if (l_oP.x() == i_iChild && l_oP.y() == i_iParent)
{
emit sig_message(i18n("Cannot create a reference: a direct link already exists"), 5000);
return false;
}
else if (l_oP.x() == i_iParent && l_oP.y() == i_iChild)
{
emit sig_message(i18n("Cannot create a reference: a direct link already exists"), 5000);
return false;
}
}
foreach (const data_ref& l_oRef, m_oRefs)
{
if (l_oRef.m_iParent == i_iParent && l_oRef.m_iChild == i_iChild)
{
emit sig_message(i18n("Cannot create a reference: a reference already exists"), 5000);
return false;
}
else if (l_oRef.m_iChild == i_iParent && l_oRef.m_iParent == i_iChild)
{
emit sig_message(i18n("Cannot create a reference: a reference already exists"), 5000);
return false;
}
}
data_ref l_oRef(i_iParent, i_iChild);
m_oRefs.push_back(l_oRef);
mem_ref *l_oMem = new mem_ref(this);
l_oMem->m_iParent = i_iParent;
l_oMem->m_iChild = i_iChild;
l_oMem->apply();
return true;
}
bool sem_mediator::link_items(int i_iParent, int i_iChild)
{
Q_ASSERT(m_oItems.contains(i_iParent) && m_oItems.contains(i_iChild));
......@@ -867,7 +923,10 @@ bool sem_mediator::link_items(int i_iParent, int i_iChild)
{
QPoint l_oP = m_oLinks.at(i);
if (l_oP.y() == i_iChild)
{
emit sig_message(i18n("Cannot create a link: only one root is allowed (try references?)"), 5000);
return false;
}
}
// cycles
......@@ -880,7 +939,11 @@ bool sem_mediator::link_items(int i_iParent, int i_iChild)
QPoint l_oP = m_oLinks.at(i);
if (l_oP.y() == l_iIdChild)
{
if (l_oP.x() == i_iChild) return false;
if (l_oP.x() == i_iChild)
{
emit sig_message(i18n("Cannot create a link: cycles are not allowed (try references?)"), 5000);
return false;
}
l_iNew = l_oP.x();
break;
}
......@@ -888,6 +951,20 @@ bool sem_mediator::link_items(int i_iParent, int i_iChild)
l_iIdChild = l_iNew;
}
foreach (const data_ref& l_oRef, m_oRefs)
{
if (l_oRef.m_iParent == i_iParent && l_oRef.m_iChild == i_iChild)
{
emit sig_message(i18n("Cannot create a link: a reference already exists"), 5000);
return false;
}
else if (l_oRef.m_iChild == i_iParent && l_oRef.m_iParent == i_iChild)
{
emit sig_message(i18n("Cannot create a link: a reference already exists"), 5000);
return false;
}
}
mem_link *lnk = new mem_link(this);
lnk->parent = i_iParent;
lnk->child = i_iChild;
......@@ -1543,6 +1620,16 @@ void sem_mediator::notify_unlink_items(int id1, int id2)
emit sig_unlink_items(id1, id2);
}
void sem_mediator::notify_ref_items(int i_iId1, int i_iId2)
{
emit sig_ref_items(i_iId1, i_iId2);
}
void sem_mediator::notify_unref_items(int i_iId1, int i_iId2)
{
emit sig_unref_items(i_iId1, i_iId2);
}
void sem_mediator::notify_select(const QList<int>& unsel, const QList<int>& sel)
{
emit sig_select(unsel, sel);
......
......@@ -53,6 +53,8 @@ class sem_mediator: public QObject
void sig_delete_item(int id);
void sig_link_items(int id1, int id2);
void sig_unlink_items(int id1, int id2);
void sig_ref_items(int id1, int id2);
void sig_unref_items(int id1, int id2);
void sync_flags();
void sync_colors();
void sync_background_color();
......@@ -116,6 +118,7 @@ class sem_mediator: public QObject
QHash<int, data_item> m_oItems;
QList<QPoint> m_oLinks;
QList<data_ref> m_oRefs;
QList<color_scheme> m_oColorSchemes;
QList<flag_scheme*> m_oFlagSchemes;
......@@ -156,6 +159,7 @@ class sem_mediator: public QObject
// first parameter is the parent, second parameter is the wanted id
// and the third parameter is for copying the parents data
bool link_items(int id1, int id2);
bool ref_items(int, int);
int num_children(int i_iParent);
void select_root_item(int);
......@@ -167,6 +171,8 @@ class sem_mediator: public QObject
void notify_delete_item(int id);
void notify_link_items(int id1, int id2);
void notify_unlink_items(int id1, int id2);
void notify_ref_items(int, int);
void notify_unref_items(int, int);
void notify_select(const QList<int>& unsel, const QList<int>& sel);
void notify_move(const QList<int>&sel, const QList<QPointF>&pos);
void notify_repaint(int id);
......
// Thomas Nagy 2018 GPLV3
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QStyleOption>
#include <QColor>
#include <QPen>
#include <QtDebug>
#include <cmath>
#include "sem_mediator.h"
#include "con.h"
#include "canvas_item.h"
#include "canvas_ref.h"
#include "canvas_view.h"
canvas_ref::canvas_ref(canvas_view *i_oGraphWidget, canvas_item *i_oFrom, canvas_item *i_oTo)
: canvas_link(i_oGraphWidget, i_oFrom, i_oTo)
{
m_oColor = QColor(REF_DEFAULT_COLOR);
QBrush l_oBrush(m_oColor);
setBrush(l_oBrush);
setPen(m_oColor);
setZValue(40);
}
// Thomas Nagy 2018 GPLV3
#ifndef CANVAS_REF_H
#define CANVAS_REF_H
#include <QGraphicsPathItem>
#include <QList>
#include <canvas_link.h>
#include "con.h"
class QColor;
class QString;
class QGraphicsSceneMouseEvent;
class canvas_view;
class canvas_item;
class canvas_ref: public canvas_link
{
public:
canvas_ref(canvas_view *i_oGraphWidget, canvas_item *i_oFrom, canvas_item * i_oTo);
int type() const { return CANVAS_REF_T; }
QColor get_color() {return m_oColor;}
void set_color(QColor c) {m_oColor=c;}
};
#endif
......@@ -14,6 +14,7 @@
#include<KToolBar>
#include<KMessageBox>
#include <QDialog>
#include "canvas_ref.h"
#include <QUrl>
#include <QActionGroup>
#include "canvas_item.h"
......@@ -813,24 +814,6 @@ void canvas_view::mousePressEvent(QMouseEvent *i_oEv)
canvas_chain *kk=NULL;
if (l_oItem && (kk = dynamic_cast<canvas_chain*>(l_oItem)))
{
QList<int> lst;
foreach (QGraphicsItem *l_o, scene()->selectedItems())
{
l_o->setSelected(false);
canvas_item *it = dynamic_cast<canvas_item*>(l_o);
if (it)
{
lst.append(it->Id());
}
}
if (lst.size())
{
mem_sel *sel = new mem_sel(m_oMediator);
sel->unsel = lst;
sel->apply();
}
canvas_item *l_oParent = dynamic_cast<canvas_item*>(kk->parentItem());
Q_ASSERT(l_oParent);
......@@ -884,7 +867,14 @@ void canvas_view::mouseReleaseEvent(QMouseEvent *i_oEv)
if (l_oR1 && l_oR2 && l_oR1 != l_oR2)
{
m_oMediator->link_items(l_oR1->Id(), l_oR2->Id());
if (i_oEv->modifiers() & Qt::ControlModifier)
{
m_oMediator->ref_items(l_oR1->Id(), l_oR2->Id());
}
else
{
m_oMediator->link_items(l_oR1->Id(), l_oR2->Id());
}
deselect_all(); // TODO
}
m_oRubberLine->hide();
......@@ -994,6 +984,14 @@ void canvas_view::mouseDoubleClickEvent(QMouseEvent* i_oEv)
link->parent = l_oLink->m_oFrom->Id();
link->apply();
}
else if (l_oItem->type() == CANVAS_REF_T)
{
canvas_ref *l_oRef = (canvas_ref*) l_oItem;
mem_unref *l_oMem = new mem_unref(m_oMediator);
l_oMem->m_iChild = l_oRef->m_oTo->Id();
l_oMem->m_iParent= l_oRef->m_oFrom->Id();
l_oMem->apply();
}
} else if (i_oEv->modifiers() != Qt::ControlModifier) {
mem_add *add = new mem_add(m_oMediator);
add->item.m_iXX = m_oLastPoint.x();
......@@ -1070,12 +1068,12 @@ rubber_line::rubber_line(QRubberBand::Shape i, QWidget* j) : QRubberBand(i, j)
{
}
void rubber_line::paintEvent(QPaintEvent *)
void rubber_line::paintEvent(QPaintEvent *i_oEv)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
//painter.setPen(Qt::NoPen);
painter.setBrush(QColor(Qt::red));
painter.setPen(m_oColor);
if (_direction > 0)
{
painter.drawLine(QPoint(0, 0), QPoint(size().width(), size().height()));
......@@ -1431,6 +1429,41 @@ void canvas_view::notify_delete_item(int id) {
check_canvas_size();
}
void canvas_view::notify_ref_items(int i_iId1, int i_iId2)
{
canvas_item *l_oR1 = m_oItems.value(i_iId1);
canvas_item *l_oR2 = m_oItems.value(i_iId2);
canvas_ref* l_oRef = new canvas_ref(this, l_oR1, l_oR2);
l_oRef->update_pos();
l_oR2->update();
}
void canvas_view::notify_unref_items(int i_iId1, int i_iId2)
{
canvas_item * l_oR1 = m_oItems.value(i_iId1);
canvas_item *l_oR2 = m_oItems.value(i_iId2);
foreach (QGraphicsItem *l_oItem, items())
{
if (l_oItem->type() == CANVAS_REF_T)
{
canvas_ref* l_oRef = (canvas_ref*) l_oItem;
if (
(l_oRef->m_oFrom == l_oR1 && l_oRef->m_oTo == l_oR2)
||
(l_oRef->m_oFrom == l_oR2 && l_oRef->m_oTo == l_oR1)
)
{
l_oRef->hide();
l_oRef->rm_link();
delete l_oRef;
break;
}
}
}
l_oR1->update();
l_oR2->update();
}
void canvas_view::notify_link_items(int id1, int id2) {
canvas_item *l_oR1 = m_oItems.value(id1);
canvas_item *l_oR2 = m_oItems.value(id2);
......@@ -1680,3 +1713,32 @@ void canvas_view::slot_background_color()
{
setBackgroundBrush(m_oMediator->m_oColor);
}
void canvas_view::keyPressEvent(QKeyEvent *i_oEvent)
{
m_oRubberLine->m_oColor = QColor(REF_DEFAULT_COLOR);
if (m_oRubberLine->isVisible())
{
m_oRubberLine->hide();
m_oRubberLine->show();
}
else
{
QGraphicsView::keyPressEvent(i_oEvent);
}
}
void canvas_view::keyReleaseEvent(QKeyEvent *i_oEvent)
{
m_oRubberLine->m_oColor = QColor(Qt::black);
if (m_oRubberLine->isVisible())
{
m_oRubberLine->hide();
m_oRubberLine->show();
}
else
{
QGraphicsView::keyReleaseEvent(i_oEvent);
}
}
......@@ -46,7 +46,8 @@ class canvas_view : public QGraphicsView
void mousePressEvent(QMouseEvent *i_oEv);
void mouseMoveEvent(QMouseEvent *i_oEv);
void mouseReleaseEvent(QMouseEvent *i_oEv);
void keyPressEvent(QKeyEvent *);
void keyReleaseEvent(QKeyEvent* );
bool m_bPressed;
bool m_bScroll;
......@@ -132,6 +133,8 @@ class canvas_view : public QGraphicsView
void notify_delete_item(int id);
void notify_link_items(int id1, int id2);
void notify_unlink_items(int id1, int id2);
void notify_ref_items(int id1, int id2);
void notify_unref_items(int id1, int id2);
void notify_select(const QList<int>& unsel, const QList<int>& sel);
void notify_move(const QList<int>&sel, const QList<QPointF>&pos);
void notify_repaint(int id);
......@@ -155,6 +158,7 @@ class rubber_line : public QRubberBand
{
public:
int _direction;
QColor m_oColor;
rubber_line(QRubberBand::Shape, QWidget*);
void paintEvent(QPaintEvent *);
void setGeometry(const QRect& i_o);
......
......@@ -18,6 +18,7 @@
#define BOX_ITEM_T gratype(12305)
#define BOX_LINK_T gratype(12306)
#define CANVAS_CHAIN_T gratype(12307)
#define CANVAS_REF_T gratype(12309)
#define hash_params QHash<int, QVariant>
......@@ -29,6 +30,7 @@
#define data_commande 5
#define data_type 6 // change the view stuff
#define REF_DEFAULT_COLOR "#e0e0e0"
#define VIEW_CANVAS 1
#define VIEW_LINEAR 2
......
......@@ -21,8 +21,7 @@
<ul>
<li>right-click on a map item and select data type: diagram</li>
<li>in the data view, double click to add a diagram item</li>
<li>hold the control key pressed to drag connections between items</li>
<li>to remove a connection, double click on it with the control key pressed</li>
<li>to remove a connection, double click on it</li>
<li>right click on a connection or on an item to change the colors</li>
</ul>
</html>
......@@ -68,7 +67,7 @@
<html>
<h3>6. LaTeX export</h3>
<p>
Set <b>all_latex=1</b> in the variables view to let the beamer and pdf templates use LaTeX commands.
Set <b>all_latex=1</b> in the variables view to let the Beamer and Pdf templates use LaTeX commands.
</p>
</html>
......@@ -90,7 +89,7 @@ The size of the diagrams exported can be tuned by specific values in the variabl
The application called "semantik-d" can be used to create diagrams individually. The diagrams can be imported or exported from the diagram view of semantik.
Additionally, the diagrams can be exported to a variety of formats by using the command-line. Just specify the extension, and a diagram will be produced if it is supported:
<pre>semantik-d /tmp/foo.semd -o /tmp/foo.svg</pre>
The options &quot;--width&quot; and &quot;--height&quot; can be used to change the size of png files.
The options &quot;--width&quot; and &quot;--height&quot; can be used to change the size of Png files.
</p>
</html>
</tip>
......@@ -104,4 +103,17 @@ Enable Pygments by setting adding source code in the data box and adding the var
to the variables box, for example: <pre>code_lang=java</pre>
</p>
</html>
<tip category="semantik">
<html>
<h3>9. Links and references</h3>
<p>
Links can be created by selecting an item on the map, and dragging from the "+" sign to another item.
Since links reflect the structure of the document generated from the map, they can contain any cycle.
</p>
<p>
Special links called references allow cycles and do not appear in the generated documents.
They they can be inserted by holding the "Control" key pressed while creating a link (dragging from the + sign).
</p>
</html>
</tip>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -311,6 +311,8 @@ semantik_win::semantik_win(QWidget *i_oParent) : KXmlGuiWindow(i_oParent)
connect(m_oMediator, SIGNAL(sig_link_items(int, int)), ln, SLOT(notify_link_items(int, int)));
connect(m_oMediator, SIGNAL(sig_unlink_items(int, int)), m_oCanvas, SLOT(notify_unlink_items(int, int)));
connect(m_oMediator, SIGNAL(sig_unlink_items(int, int)), ln, SLOT(notify_unlink_items(int, int)));
connect(m_oMediator, SIGNAL(sig_ref_items(int, int)), m_oCanvas, SLOT(notify_ref_items(int, int)));
connect(m_oMediator, SIGNAL(sig_unref_items(int, int)), m_oCanvas, SLOT(notify_unref_items(int, int)));
connect(m_oMediator, SIGNAL(sig_repaint(int)), m_oCanvas, SLOT(notify_repaint(int)));
connect(m_oMediator, SIGNAL(sig_repaint(int)), ln, SLOT(notify_repaint(int)));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment