#include <QtWidgets>
#include "orgchartdialog.h"
#include "scene.h"
#include "node.h"
#include "link.h"
#include "insertlinkdialog.h"
#include "nodeinfodialog.h"
#include "aboutdialog.h"
OrgChartDialog::OrgChartDialog(QWidget *parent) :
QDialog(parent)
{
this->setWindowFlags(Qt::Window);
this->resize(1268, 744);
initOrgChartDialog();
createActions();
initViewActions();
m_isFirstResize = true;
}
OrgChartDialog::~OrgChartDialog()
{
qDeleteAll(m_nodeQueue);
m_nodeQueue.clear();
}
void OrgChartDialog::initOrgChartDialog()
{
m_scene = new Scene(0, 0, 50000, 60000);
connect(m_scene, SIGNAL(updateContextMenu()), this, SLOT(onSceneUpdateContextMenu()));
m_view = new QGraphicsView(this);
m_view->setScene(m_scene);
m_view->setDragMode(QGraphicsView::RubberBandDrag);
m_view->setContextMenuPolicy(Qt::ActionsContextMenu);
QHBoxLayout *hLayout = new QHBoxLayout();
hLayout->setContentsMargins(0, 0, 0, 0);
hLayout->addWidget(m_view);
this->setLayout(hLayout);
}
void OrgChartDialog::createActions()
{
m_topMenu = new QMenu(this);
m_actAdd = new QAction("Add Node", this);
m_actAdd->setShortcut(tr("Ctrl+N"));
connect(m_actAdd, SIGNAL(triggered(bool)), this, SLOT(onAdd()));
m_topMenu->addAction(m_actAdd);
m_actDel = new QAction("Delete", this);
m_actDel->setShortcut(tr("Del"));
connect(m_actDel, SIGNAL(triggered(bool)), this, SLOT(onDelete()));
m_topMenu->addAction(m_actDel);
m_topMenu->addSeparator();
m_actCut = new QAction("Cut", this);
m_actCut->setShortcut(tr("Ctrl+X"));
connect(m_actCut, SIGNAL(triggered(bool)), this, SLOT(onCut()));
m_topMenu->addAction(m_actCut);
m_actCopy = new QAction("Copy", this);
m_actCopy->setShortcut(tr("Ctrl+C"));
connect(m_actCopy, SIGNAL(triggered(bool)), this, SLOT(onCopy()));
m_topMenu->addAction(m_actCopy);
m_actPaste = new QAction("Paste", this);
m_actPaste->setShortcut(tr("Ctrl+V"));
connect(m_actPaste, SIGNAL(triggered(bool)), this, SLOT(onPaste()));
m_topMenu->addAction(m_actPaste);
m_topMenu->addSeparator();
m_actInsertLink = new QAction("Insert Link", this);
m_actInsertLink->setShortcut(tr("Ctrl+K"));
connect(m_actInsertLink, SIGNAL(triggered(bool)), this, SLOT(onInsertLink()));
m_topMenu->addAction(m_actInsertLink);
m_actInsertBgImage = new QAction("Insert Background Image", this);
connect(m_actInsertBgImage, SIGNAL(triggered(bool)), this, SLOT(onInsertBgImage()));
m_topMenu->addAction(m_actInsertBgImage);
m_topMenu->addSeparator();
m_actProperty = new QAction("Property", this);
connect(m_actProperty, SIGNAL(triggered(bool)), this, SLOT(onProperty()));
m_topMenu->addAction(m_actProperty);
m_topMenu->addSeparator();
m_actAbout = new QAction("About", this);
m_actAbout->setShortcut(tr("F1"));
connect(m_actAbout, SIGNAL(triggered(bool)), this, SLOT(onAbout()));
m_topMenu->addAction(m_actAbout);
}
void OrgChartDialog::initViewActions()
{
QList<QAction *> acts = m_topMenu->actions();
for (int i = 0; i < acts.count(); i++) {
QAction *act = acts.at(i);
if (act) {
m_view->addAction(act);
}
}
}
Scene *OrgChartDialog::getOrgChartDialogScene()
{
return m_scene;
}
Node *OrgChartDialog::getRootNode()
{
Node *rootNode = NULL;
QList<QGraphicsItem *> items = m_scene->items();
for (int i = 0; i < items.size(); i++) {
Node *node = dynamic_cast<Node *>(items.at(i));
if (node) {
if (!node->getLinkFrom()) {
rootNode = node;
}
}
}
return rootNode;
}
Node *OrgChartDialog::getSelectedNode()
{
QList<QGraphicsItem *> items = m_scene->selectedItems();
if (items.count() == 1) {
return dynamic_cast<Node *>(items.first());
}
else {
return 0;
}
}
void OrgChartDialog::adjustNodes(Node *fromNode, int nodeSpace)
{
if (!fromNode)
return;
QStack<Node *> nodeStack;
nodeStack.push(fromNode);
while (!nodeStack.isEmpty()) {
Node *topNode = nodeStack.top();
nodeStack.pop();
QList<Link *> linksTo = topNode->getLinksTo();
for (int i = 0; i < linksTo.size(); i++) {
Link *link = linksTo.at(i);
if (link) {
Node *toNode = link->getToNode();
if (toNode) {
if (!toNode->getLinksTo().isEmpty()) {
nodeStack.push(toNode);
}
toNode->setBasePoint(QPointF(toNode->x() - nodeSpace, toNode->y()));
toNode->setPos(toNode->getBasePoint().x(), toNode->getBasePoint().y());
link->adjust();
}
}
}
}
}
void OrgChartDialog::adjustNodesByLinkFrom(Link *linkFrom, int nodeX)
{
if (linkFrom) {
Node *fromNode = linkFrom->getFromNode();
if (fromNode) {
QList<Link *> linksTo = fromNode->getLinksTo();
for (int i = 0; i < linksTo.size(); i++) {
Link *link = linksTo.at(i);
if (link) {
Node *toNode = link->getToNode();
if (toNode) {
if (toNode->x() < nodeX) {
toNode->setBasePoint(QPointF(toNode->x() + 70, toNode->y()));
toNode->setPos(toNode->getBasePoint());
adjustNodes(toNode, -70);
}
else {
toNode->setBasePoint(QPointF(toNode->x() - 70, toNode->y()));
toNode->setPos(toNode->getBasePoint());
adjustNodes(toNode, +70);
}
}
link->adjust();
}
}
}
}
}
void OrgChartDialog::itemsMove()
{
Node *rootNode = getRootNode();
if (rootNode) {
if (!rootNode->getLinksTo().isEmpty()) {
int moveX = rootNode->x() - rootNode->getBasePoint().x();
int moveY = rootNode->y() - rootNode->getBasePoint().y();
QStack<Node *> nodeStack;
nodeStack.push(rootNode);
while (!nodeStack.isEmpty()) {
Node *node = nodeStack.top();
nodeStack.pop();
if (node) {
QList<Link *> linksTo = node->getLinksTo();
for (int i = 0; i < linksTo.size(); i++) {
Link *link = linksTo.at(i);
if (link) {
Node *toNode = link->getToNode();
if (toNode) {
if (!toNode->getLinksTo().isEmpty()) {
nodeStack.push(toNode);
}
toNode->setBasePoint(QPointF(toNode->x() + moveX, toNode->y() + moveY));
toNode->setPos(toNode->getBasePoint().x(), toNode->getBasePoint().y());
link->adjust();
}
}
}
}
}
}
}
}
void OrgChartDialog::resizeEvent(QResizeEvent */*event*/)
{
if (m_isFirstResize) {
m_isFirstResize = false;
m_viewSize = m_view->size();
}
QSize size = m_view->size();
int w = m_viewSize.width() - size.width();
int h = m_viewSize.height() - size.height();
Node *rootNode = getRootNode();
QStack<Node *> nodeStack;
nodeStack.push(rootNode);
while (!nodeStack.isEm