From 0b6311d4cdfd63448c640066fbe4431c426951a9 Mon Sep 17 00:00:00 2001 From: dismine Date: Sat, 13 Jul 2013 13:51:31 +0300 Subject: [PATCH] Creating ToolSimplePoint complit --- Valentina.pro | 17 +- container/vcontainer.cpp | 43 ++++ container/vcontainer.h | 23 ++ container/vpointf.cpp | 46 ++++ container/vpointf.h | 26 +++ dialogs/dialogsinglepoint.cpp | 53 ++++- dialogs/dialogsinglepoint.h | 28 ++- dialogs/dialogsinglepoint.ui | 21 +- icon.qrc | 2 + icon/32x32/new_draw.png | Bin 0 -> 944 bytes icon/32x32/option_draw.png | Bin 0 -> 1814 bytes mainwindow.cpp | 318 +++++++++++++++++++++---- mainwindow.h | 30 ++- mainwindow.ui | 50 +++- options.h | 2 + tools/vtoolsimplepoint.cpp | 301 ++++++++++++++++++++++++ tools/vtoolsimplepoint.h | 56 +++++ widgets/vgraphicssimpletextitem.cpp | 28 +++ widgets/vgraphicssimpletextitem.h | 18 ++ widgets/vmaingraphicsscene.cpp | 1 + xml/vdomdocument.cpp | 350 ++++++++++++++++++++++++++++ xml/vdomdocument.h | 63 +++++ 22 files changed, 1406 insertions(+), 70 deletions(-) create mode 100644 container/vcontainer.cpp create mode 100644 container/vcontainer.h create mode 100644 container/vpointf.cpp create mode 100644 container/vpointf.h create mode 100644 icon/32x32/new_draw.png create mode 100644 icon/32x32/option_draw.png create mode 100644 tools/vtoolsimplepoint.cpp create mode 100644 tools/vtoolsimplepoint.h create mode 100644 widgets/vgraphicssimpletextitem.cpp create mode 100644 widgets/vgraphicssimpletextitem.h create mode 100644 xml/vdomdocument.cpp create mode 100644 xml/vdomdocument.h diff --git a/Valentina.pro b/Valentina.pro index 0a3e5acd1..df9d5cfd1 100644 --- a/Valentina.pro +++ b/Valentina.pro @@ -4,23 +4,32 @@ # #------------------------------------------------- -QT += core gui +QT += core gui xml greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = Valentina TEMPLATE = app - SOURCES += main.cpp\ mainwindow.cpp \ widgets/vmaingraphicsscene.cpp \ - dialogs/dialogsinglepoint.cpp + dialogs/dialogsinglepoint.cpp \ + tools/vtoolsimplepoint.cpp \ + widgets/vgraphicssimpletextitem.cpp \ + xml/vdomdocument.cpp \ + container/vpointf.cpp \ + container/vcontainer.cpp HEADERS += mainwindow.h \ widgets/vmaingraphicsscene.h \ dialogs/dialogsinglepoint.h \ - options.h + options.h \ + tools/vtoolsimplepoint.h \ + widgets/vgraphicssimpletextitem.h \ + xml/vdomdocument.h \ + container/vpointf.h \ + container/vcontainer.h FORMS += mainwindow.ui \ dialogs/dialogsinglepoint.ui diff --git a/container/vcontainer.cpp b/container/vcontainer.cpp new file mode 100644 index 000000000..1dec202a6 --- /dev/null +++ b/container/vcontainer.cpp @@ -0,0 +1,43 @@ +#include "vcontainer.h" +#include + +VContainer::VContainer(){ + _id = 0; +} + +VPointF VContainer::GetPoint(qint64 id) const{ + if(points.contains(id)){ + return points.value(id); + } else { + qCritical()<<"Не можу знайти id = "< _id){ + _id = id; + } +} + +void VContainer::Clear(){ + _id = 0; + points.clear(); +} diff --git a/container/vcontainer.h b/container/vcontainer.h new file mode 100644 index 000000000..1abab3561 --- /dev/null +++ b/container/vcontainer.h @@ -0,0 +1,23 @@ +#ifndef VCONTAINER_H +#define VCONTAINER_H + +#include + +#include "vpointf.h" + +class VContainer +{ +public: + VContainer(); + VPointF GetPoint(qint64 id) const; + qint64 getId(); + qint64 AddPoint(const VPointF& point); + void UpdatePoint(qint64 id, const VPointF& point); + void Clear(); +private: + qint64 _id; + QMap points; + qint64 getNextId(); +}; + +#endif // VCONTAINER_H diff --git a/container/vpointf.cpp b/container/vpointf.cpp new file mode 100644 index 000000000..447789af6 --- /dev/null +++ b/container/vpointf.cpp @@ -0,0 +1,46 @@ +#include "vpointf.h" + +VPointF::VPointF():QPointF(){ + _mx = 0; + _my = 0; +} + +VPointF::VPointF ( const VPointF & point ):QPointF(point){ + _name = point.name(); + _mx = point.mx(); + _my = point.my(); +} + +VPointF::VPointF (qreal x, qreal y , QString name, qreal mx, qreal my):QPointF(x, y){ + _name = name; + _mx = mx; + _my = my; +} + +QString VPointF::name() const{ + return _name; +} + +qreal VPointF::mx() const{ + return _mx; +} + +qreal VPointF::my() const{ + return _my; +} + +void VPointF::setName(const QString& name){ + _name = name; +} + +void VPointF::setMx(qreal mx){ + _mx = mx; +} + +void VPointF::setMy(qreal my){ + _my = my; +} + +QPointF VPointF::toQPointF()const{ + return QPointF(this->x(), this->y()); +} diff --git a/container/vpointf.h b/container/vpointf.h new file mode 100644 index 000000000..ffb58be3e --- /dev/null +++ b/container/vpointf.h @@ -0,0 +1,26 @@ +#ifndef VPOINTF_H +#define VPOINTF_H + +#include +#include + +class VPointF : public QPointF +{ +public: + VPointF(); + VPointF (const VPointF &point ); + VPointF ( qreal x, qreal y, QString name, qreal mx, qreal my ); + QString name() const; + qreal mx() const; + qreal my() const; + void setName(const QString &name); + void setMx(qreal mx); + void setMy(qreal my); + QPointF toQPointF()const; +private: + QString _name; + qreal _mx; + qreal _my; +}; + +#endif // VPOINTF_H diff --git a/dialogs/dialogsinglepoint.cpp b/dialogs/dialogsinglepoint.cpp index 43687e9dd..530f72ba7 100644 --- a/dialogs/dialogsinglepoint.cpp +++ b/dialogs/dialogsinglepoint.cpp @@ -2,6 +2,7 @@ #include "ui_dialogsinglepoint.h" #include #include +#include #include "../options.h" @@ -11,21 +12,24 @@ DialogSinglePoint::DialogSinglePoint(QWidget *parent) : { ui->setupUi(this); isInitialized = false; - ui->spinBoxX->setRange(0,(qint32)(PaperSize*PrintDPI/25.4)); - ui->spinBoxY->setRange(0,(qint32)(PaperSize*PrintDPI/25.4)); + ui->doubleSpinBoxX->setRange(0,PaperSize/PrintDPI*25.4); + ui->doubleSpinBoxY->setRange(0,PaperSize/PrintDPI*25.4); QPushButton* pOkButton = ui->buttonBox->button(QDialogButtonBox::Ok); pOkButton->setEnabled(false); + connect(pOkButton, &QPushButton::clicked, this, &DialogSinglePoint::OkOperation); connect(ui->lineEditName, &QLineEdit::textChanged, this, &DialogSinglePoint::NameChanged); + QPushButton* pCanselButton = ui->buttonBox->button(QDialogButtonBox::Cancel); + connect(pCanselButton, &QPushButton::clicked, this, &DialogSinglePoint::CanselOperation); } void DialogSinglePoint::mousePress(QPointF scenePos){ if(isInitialized == false){ - ui->spinBoxX->setValue((qint32)(scenePos.x()*PrintDPI/25.4)); - ui->spinBoxY->setValue((qint32)(scenePos.y()*PrintDPI/25.4)); + ui->doubleSpinBoxX->setValue(scenePos.x()/PrintDPI*25.4); + ui->doubleSpinBoxY->setValue(scenePos.y()/PrintDPI*25.4); this->show(); } else { - ui->spinBoxX->setValue((qint32)(scenePos.x()*PrintDPI/25.4)); - ui->spinBoxY->setValue((qint32)(scenePos.y()*PrintDPI/25.4)); + ui->doubleSpinBoxX->setValue(scenePos.x()/PrintDPI*25.4); + ui->doubleSpinBoxY->setValue(scenePos.y()/PrintDPI*25.4); } } @@ -55,7 +59,40 @@ void DialogSinglePoint::NameChanged(){ } } -DialogSinglePoint::~DialogSinglePoint() -{ +void DialogSinglePoint::CanselOperation(){ + emit ToolCanseled(); +} + +void DialogSinglePoint::OkOperation(){ + point = QPointF(ui->doubleSpinBoxX->value()*PrintDPI/25.4, + ui->doubleSpinBoxY->value()*PrintDPI/25.4); + name = ui->lineEditName->text(); + emit SinglePointCreated(ui->lineEditName->text(), point); +} + +void DialogSinglePoint::closeEvent ( QCloseEvent * event ){ + emit ToolCanseled(); + event->accept(); +} + +void DialogSinglePoint::setData(const QString name, const QPointF point){ + this->name = name; + this->point = point; + isInitialized = true; + ui->lineEditName->setText(name); + ui->doubleSpinBoxX->setValue(point.x()/PrintDPI*25.4); + ui->doubleSpinBoxY->setValue(point.y()/PrintDPI*25.4); +} + +QString DialogSinglePoint::getName()const{ + return name; +} + +QPointF DialogSinglePoint::getPoint()const{ + return point; +} + +DialogSinglePoint::~DialogSinglePoint(){ delete ui; } + diff --git a/dialogs/dialogsinglepoint.h b/dialogs/dialogsinglepoint.h index 70d861d2c..3b948b44f 100644 --- a/dialogs/dialogsinglepoint.h +++ b/dialogs/dialogsinglepoint.h @@ -9,19 +9,29 @@ class DialogSinglePoint; class DialogSinglePoint : public QDialog { - Q_OBJECT - + Q_OBJECT public: - explicit DialogSinglePoint(QWidget *parent = 0); - ~DialogSinglePoint(); -protected: - void showEvent( QShowEvent *event ); + explicit DialogSinglePoint(QWidget *parent = 0); + void setData(const QString name, const QPointF point); + QString getName()const; + QPointF getPoint()const; + ~DialogSinglePoint(); +signals: + void ToolCanseled(); + void SinglePointCreated(const QString name, const QPointF point); public slots: - void mousePress(QPointF scenePos); - void NameChanged(); + void mousePress(QPointF scenePos); + void NameChanged(); + void CanselOperation(); + void OkOperation(); +protected: + void showEvent( QShowEvent *event ); + void closeEvent ( QCloseEvent * event ); private: Ui::DialogSinglePoint *ui; - bool isInitialized; + bool isInitialized; + QString name; + QPointF point; }; #endif // DIALOGSINGLEPOINT_H diff --git a/dialogs/dialogsinglepoint.ui b/dialogs/dialogsinglepoint.ui index a57a23848..b69f8133b 100644 --- a/dialogs/dialogsinglepoint.ui +++ b/dialogs/dialogsinglepoint.ui @@ -32,9 +32,6 @@ Координати - - - @@ -42,9 +39,6 @@ - - - @@ -52,6 +46,12 @@ + + + + + + @@ -76,6 +76,9 @@ 27 + + + @@ -94,6 +97,12 @@ + + lineEditName + doubleSpinBoxX + doubleSpinBoxY + buttonBox + diff --git a/icon.qrc b/icon.qrc index 257b236f6..7f8b073da 100644 --- a/icon.qrc +++ b/icon.qrc @@ -5,5 +5,7 @@ icon/32x32/kontur.png icon/32x32/spoint.png icon/32x32/arrow_cursor.png + icon/32x32/new_draw.png + icon/32x32/option_draw.png diff --git a/icon/32x32/new_draw.png b/icon/32x32/new_draw.png new file mode 100644 index 0000000000000000000000000000000000000000..aae5242729e12f101dbc13533b975635c2f0c88e GIT binary patch literal 944 zcmV;h15f;kP)CcJety1Kuh*YEw2Mfi1!rexFIHDq zUoyt-dEMRJNG6k?zDpZ71YnH)xxKypqF5}xw({ra=izp{?E?US>+9?9cXoCx0aR5* zDwVPq0KjdzT(&eE4hKY0v=@Le_A|$E25b;{+jeYbXxUMMF4Hty3ee{DdeKUNSR@i5 zEdijEQorB-c`B9S?Es*SKEHuLAT>8Pm*jc=ao+(-DFF~2A0PiFlgapa-j)Nne*%+PPLoP0VnGc)4z`6z6XRp9YlF86IZoo<(9*(Hi1PYA(d0=S2VhrQu&7>^-> z7VAC0dw`Y$SPmFX(;&+-tnT}QAV5(RIGs-00E+p1{@MQi{;AvTuD)rQrs*JrgcL;y zc|4wvR8@5agTem{UaQqmC=^gE7EcR>!Vds0?>&^oD1HK<9YBpSR=?x%9LISiN%ABT ziLl@AA5j$LX)G3t_V)II<2V?GfrEnsXqt9XsZ@T{b$$Ez`1seYt*w`gu~Wv_?SuXe zEkHQ{?Sq4ZE|<&IRjE`yxw*ONl4bc9r_)&wMe+CD-QC-Zi;LTTu9eKRit{(wE==}v SS2I5V0000V3_Eb)Ttzx`cVn3xM7F^6tY1qi|j5R`@w$j?!Eot zlo(tEg`B_Vyyto5J?A{{d0EWUIF17$M6T26RH><{-&L#Cm43h9EsEmEoX$TYs0@Gr zV8m=T%T+4Xi_4cUFI%;0Rj$QiNvx@9H*R% zXjN6c0EHqMot+MN+%AYQ7EKL}ICAt)^DaTABuUc*BvFJUN%sWp-Mb&Jy;g@e-gpx% zVX(RMCunGF#^J;7Vrpt?UXPJntJMMkJRhCI=|k@V&u_%0A8&>r2-EUwv#kXHD3vl) z?aYF0{W@5StT_039ZsA$F`aDR%dZ+_l2|c3{NK}ay@6b_*-QZ7=9T~8UtTxfIa-hM zZ9j#>@!7QePP3KEVJ*}l({P7eK|ujhQc?f_wFllT{Ej*6LO2vWsncoyLFQ0@&R{V7 z&}Or-0Pw`_U8q@MLO}w-z^x(d-1!1T@tggboUDO+ECx>gwLlU=P`2%7tCgyRi{9I} z(qaph>p%{~YmK(^g(udS@C%-3i%)7j)Y9TY#>fFzlS zNFaz$JFep9SA$r)<|z=CgD8sdyBi_si;=iUhnCj!a1Re*%YJ4&1gs^)LLJUiG=%S8$;#l)vL88lWER! zs?_UY{aXV7z~>7hFn$XP1>p7jK)7@~w_yX$wzMD?qvC=rr4KUa%|ZA)6UZ=^fXcjh zHopuy-4dK_X<4|f`0m{=5DbFjIE;*V&~xKU+;n~gM8Ck{dKcb${a4WGmMr{Q{(tLt z4&ZWIJDQrBk)EbU@%O)nF|P+%nOZnH&!GEy7ZmDDs8ouDConlViNC(r0HZ+<|F{Pe zNeLL8@Zkr=Ymt=TMS`4QQIZTiuY%j{p7&#Pj~)BVdsrlAz<@xj)xqoaVql;j7E1xb z;SdPRfnfkb7zjcNmMvR`l9Cerf)I$sM3gFg894 z!V)m#PSdk2iyJrk@buHqJlWRPwr+AFM_V%6! z;Cnph@jt(`uX^`=zh)fAB?CwR5TukwX82f!VHT^^>cv*8)nqUjY$+)zn{sk;R<2yR z5)8vY6h&OQ(t*pLwg(8Lc9tc79~>O)Ja_KgbxNs+QW}1wzhNAr41k1!f&zs?p~xH= z8F?xc3T0|E8b@McVlU701MThY;jyu?@SU}iO7Zgi534e>UB;Iv9{>OV07*qoM6N<$ Ef;-e| #include #include #include #include +#include +#include +#include #include "options.h" @@ -13,11 +15,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); - tool = Tools::ArrayTool; + tool = Tools::ArrowTool; isInitialized = false; ToolBarOption(); ToolBarDraws(); - QRectF sceneRect = QRectF(0, 0, PaperSize*PrintDPI/25.4, PaperSize*PrintDPI/25.4); + QRectF sceneRect = QRectF(0, 0, PaperSize, PaperSize); scene = new VMainGraphicsScene(sceneRect); ui->graphicsView->setScene(scene); @@ -28,19 +30,126 @@ MainWindow::MainWindow(QWidget *parent) : ui->statusBar->addWidget(helpLabel); connect(ui->actionArrowTool, &QAction::triggered, this, &MainWindow::triggeredActionAroowTool); + connect(ui->actionDraw, &QAction::triggered, this, &MainWindow::triggeredActionDraw); + connect(ui->actionDetails, &QAction::triggered, this, &MainWindow::triggeredActionDetails); + connect(ui->actionNewDraw, &QAction::triggered, this, &MainWindow::triggeredActionNewDraw); + connect(ui->actionOptionDraw, &QAction::triggered, this, &MainWindow::triggeredOptionDraw); + connect(ui->actionSaveAs, &QAction::triggered, this, &MainWindow::triggeredActionSaveAs); + connect(ui->actionSave, &QAction::triggered, this, &MainWindow::triggeredActionSave); + connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::triggeredActionOpen); + connect(ui->actionNew, &QAction::triggered, this, &MainWindow::triggeredActionNew); + + data = new VContainer; + + doc = new VDomDocument(data); + doc->CreateEmptyFile(); + connect(doc, &VDomDocument::haveChange, this, &MainWindow::haveChange); + + fileName.clear(); + changeInFile = false; +} + +void MainWindow::triggeredActionNewDraw(){ + QString nameDraw; + bool bOk; + qint32 index; + QString nDraw = QString("Креслення %1").arg(comboBoxDraws->count()+1); + QInputDialog *dlg = new QInputDialog(this); + dlg->setInputMode( QInputDialog::TextInput ); + dlg->setLabelText("Креслення:"); + dlg->setTextEchoMode(QLineEdit::Normal); + dlg->setWindowTitle("Введіть назву креслення."); + dlg->resize(300,100); + dlg->setTextValue(nDraw); + while(1){ + bOk = false; + bOk = dlg->exec(); + nameDraw = dlg->textValue(); + if(!bOk || nameDraw.isEmpty()){ + delete dlg; + return; + } + index = comboBoxDraws->findText(nameDraw); + if(index != -1){//we already have this name + qCritical()<<"Помилка. Креслення з таким ім'ям вже існує."; + } else { + break; + } + } + delete dlg; + bOk = doc->appendDraw(nameDraw); + if(bOk == false){ + qCritical()<<"Помилка створення креслення з ім'ям"<addItem(nameDraw, true); + index = comboBoxDraws->findText(nameDraw); + if ( index != -1 ) { // -1 for not found + comboBoxDraws->setCurrentIndex(index); + } + ui->actionSaveAs->setEnabled(true); + ui->actionDraw->setEnabled(true); + ui->actionDetails->setEnabled(true); + ui->toolButtonSinglePoint->setEnabled(true); + ui->actionOptionDraw->setEnabled(true); + ui->actionSave->setEnabled(true); +} + +void MainWindow::triggeredOptionDraw(){ + QString nameDraw; + bool bOk; + qint32 index; + QString nDraw = doc->GetNameActivDraw(); + QInputDialog *dlg = new QInputDialog(this); + dlg->setInputMode( QInputDialog::TextInput ); + dlg->setLabelText("Креслення:"); + dlg->setTextEchoMode(QLineEdit::Normal); + dlg->setWindowTitle("Введіть нову назву креслення."); + dlg->resize(300,100); + dlg->setTextValue(nDraw); + while(1){ + bOk = false; + bOk = dlg->exec(); + nameDraw = dlg->textValue(); + if(!bOk || nameDraw.isEmpty()){ + delete dlg; + return; + } + index = comboBoxDraws->findText(nameDraw); + if(index != -1){//we already have this name + qCritical()<<"Помилка. Креслення з таким ім'ям вже існує."; + } else { + break; + } + } + delete dlg; + index = comboBoxDraws->findText(doc->GetNameActivDraw()); + doc->SetNameDraw(nameDraw); + comboBoxDraws->setItemText(index, nameDraw); } /* * Інструмет базова точка креслення. */ -void MainWindow::clickedToolButtonSinglePoint(){ - tool = Tools::SinglePointTool; - QPixmap pixmap(":/cursor/spoint_cursor.png"); - QCursor cur(pixmap, 2, 3); - ui->graphicsView->setCursor(cur); - helpLabel->setText("Виберіть розташування для точки."); - dialogSinglePoint = new DialogSinglePoint; - connect(scene, &VMainGraphicsScene::mousePress, dialogSinglePoint, &DialogSinglePoint::mousePress); +void MainWindow::clickedToolButtonSinglePoint(bool checked){ + if(checked){ + CanselTool(); + tool = Tools::SinglePointTool; + QPixmap pixmap(":/cursor/spoint_cursor.png"); + QCursor cur(pixmap, 2, 3); + ui->graphicsView->setCursor(cur); + helpLabel->setText("Виберіть розташування для точки."); + dialogSinglePoint = new DialogSinglePoint; + //покажемо вікно як тільки буде вибрано місце розташування для точки + connect(scene, &VMainGraphicsScene::mousePress, dialogSinglePoint, + &DialogSinglePoint::mousePress); + //головне вікно отримає сигнал відміни створення точки + connect(dialogSinglePoint, &DialogSinglePoint::ToolCanseled, this, &MainWindow::ToolCanseled); + connect(dialogSinglePoint, &DialogSinglePoint::SinglePointCreated, this, + &MainWindow::SinglePointCreated); + } else { //не даємо користувачу зняти виділення кнопки + ui->toolButtonSinglePoint->setChecked(true); + } } void MainWindow::showEvent( QShowEvent *event ){ @@ -101,38 +210,28 @@ void MainWindow::ToolBarDraws(){ labelNameDraw ->setText("Креслення: "); ui->toolBarDraws->addWidget(labelNameDraw); - QComboBox* comboBoxDraws = new QComboBox; + comboBoxDraws = new QComboBox; ui->toolBarDraws->addWidget(comboBoxDraws); + comboBoxDraws->setSizeAdjustPolicy(QComboBox::AdjustToContents); + connect(comboBoxDraws, static_cast(&QComboBox::currentIndexChanged), + this, &MainWindow::currentDrawChanged); - ui->toolBarDraws->addSeparator(); + ui->toolBarDraws->addAction(ui->actionOptionDraw); + ui->actionOptionDraw->setEnabled(false); +} - QLabel* labelTranslateX = new QLabel; - labelTranslateX ->setText(" Зміщення по Х: "); - ui->toolBarDraws->addWidget(labelTranslateX); - - QSpinBox* spinBoxTranslateX = new QSpinBox; - spinBoxTranslateX->setRange(0,(qint32)(PaperSize*PrintDPI/25.4)); - spinBoxTranslateX->setFixedSize(80,25); - ui->toolBarDraws->addWidget(spinBoxTranslateX); - - QLabel* labelTranslateY = new QLabel; - labelTranslateY ->setText(" Зміщення по Y: "); - ui->toolBarDraws->addWidget(labelTranslateY); - - QSpinBox* spinBoxTranslateY = new QSpinBox; - spinBoxTranslateY->setRange(0,(qint32)(PaperSize*PrintDPI/25.4)); - spinBoxTranslateY->setFixedSize(80,25); - ui->toolBarDraws->addWidget(spinBoxTranslateY); - - QPushButton* pushButtonTranslate = new QPushButton; - pushButtonTranslate->setText("Застосувати"); - ui->toolBarDraws->addWidget(pushButtonTranslate); +void MainWindow::currentDrawChanged( int index ){ + if(index != -1) { + bool status = qvariant_cast(comboBoxDraws->itemData(index)); + ui->toolButtonSinglePoint->setEnabled(status); + doc->ChangeActivDraw(comboBoxDraws->itemText(index)); + } } void MainWindow::mouseMove(QPointF scenePos){ QString string = QString("%1, %2") - .arg((qint32)(scenePos.x()*PrintDPI/25.4)) - .arg((qint32)(scenePos.y()*PrintDPI/25.4)); + .arg((qint32)(scenePos.x()/PrintDPI*25.4)) + .arg((qint32)(scenePos.y()/PrintDPI*25.4)); mouseCoordinate->setText(string); } @@ -140,17 +239,19 @@ void MainWindow::CanselTool(){ switch( tool ) { case Tools::ArrowTool: - //Покищо нічого тут не робимо. + ui->actionArrowTool->setChecked(false); break; case Tools::SinglePointTool: //Знищимо діалогове вікно. delete dialogSinglePoint; + ui->toolButtonSinglePoint->setChecked(false); break; } } void MainWindow::ArrowTool(){ CanselTool(); + ui->actionArrowTool->setChecked(true); tool = Tools::ArrowTool; QCursor cur(Qt::ArrowCursor); ui->graphicsView->setCursor(cur); @@ -161,8 +262,147 @@ void MainWindow::triggeredActionAroowTool(){ ArrowTool(); } -MainWindow::~MainWindow() -{ +void MainWindow::keyPressEvent ( QKeyEvent * event ){ + switch(event->key()){ + case Qt::Key_Escape: + ArrowTool(); + break; + } + QMainWindow::keyPressEvent ( event ); +} + +void MainWindow::ToolCanseled(){ + ArrowTool(); +} + +void MainWindow::SinglePointCreated(const QString name, const QPointF point){ + qint64 id = data->AddPoint(VPointF(point.x(), point.y(), name, 5, 10)); + VToolSimplePoint *spoint = new VToolSimplePoint(doc, data, id, Tool::FromGui); + scene->addItem(spoint); + ArrowTool(); + ui->toolButtonSinglePoint->setEnabled(false); + qint32 index = comboBoxDraws->currentIndex(); + comboBoxDraws->setItemData(index, false); + ui->actionSave->setEnabled(true); +} + +void MainWindow::triggeredActionDraw(bool checked){ + if(checked){ + ui->actionDetails->setChecked(false); + } else { + ui->actionDraw->setChecked(true); + } +} + +void MainWindow::triggeredActionDetails(bool checked){ + if(checked){ + ui->actionDraw->setChecked(false); + } else { + ui->actionDetails->setChecked(true); + } +} + +void MainWindow::triggeredActionSaveAs(){ + QString filters("Lekalo files (*.xml);;All files (*.*)"); + QString defaultFilter("Lekalo files (*.xml)"); + QString fName = QFileDialog::getSaveFileName(this, "Зберегти файл як", QDir::homePath(), + filters, &defaultFilter); + if(fName.indexOf(".xml",fName.size()-4)<0){ + fName.append(".xml"); + } + fileName = fName; + QFileInfo info(fileName); + QString title(info.fileName()); + title.append("-Valentina"); + setWindowTitle(title); + + QFile file(fileName); + if(file.open(QIODevice::WriteOnly| QIODevice::Truncate)){ + const int Indent = 4; + QTextStream out(&file); + doc->save(out, Indent); + file.close(); + } + ui->actionSave->setEnabled(false); + changeInFile = false; +} + +void MainWindow::triggeredActionSave(){ + if(!fileName.isEmpty()){ + QFile file(fileName); + if(file.open(QIODevice::WriteOnly| QIODevice::Truncate)){ + const int Indent = 4; + QTextStream out(&file); + doc->save(out, Indent); + file.close(); + } + ui->actionSave->setEnabled(false); + changeInFile = false; + } +} + +void MainWindow::triggeredActionOpen(){ + QString filter("Lekalo files (*.xml)"); + QString fName = QFileDialog::getOpenFileName(this, tr("Відкрити файл"), QDir::homePath(), filter); + fileName = fName; + QFileInfo info(fileName); + QString title(info.fileName()); + title.append("-Valentina"); + setWindowTitle(title); + QFile file(fileName); + if(file.open(QIODevice::ReadOnly)){ + if(doc->setContent(&file)){ + comboBoxDraws->clear(); + disconnect(comboBoxDraws, static_cast(&QComboBox::currentIndexChanged), + this, &MainWindow::currentDrawChanged); + doc->Parse(Document::FullParse, scene, comboBoxDraws); + connect(comboBoxDraws, static_cast(&QComboBox::currentIndexChanged), + this, &MainWindow::currentDrawChanged); + ui->actionSave->setEnabled(true); + ui->actionSaveAs->setEnabled(true); + QString nameDraw = doc->GetNameActivDraw(); + qint32 index = comboBoxDraws->findText(nameDraw); + if ( index != -1 ) { // -1 for not found + comboBoxDraws->setCurrentIndex(index); + } + + } + file.close(); + } +} + +void MainWindow::triggeredActionNew(){ + setWindowTitle("Valentina"); + data->Clear(); + doc->clear(); + CanselTool(); + comboBoxDraws->clear(); + fileName.clear(); + ui->toolButtonSinglePoint->setEnabled(true); + ui->actionOptionDraw->setEnabled(false); + ui->actionSave->setEnabled(false); +} + +void MainWindow::haveChange(){ + if(!fileName.isEmpty()){ + ui->actionSave->setEnabled(true); + } +} + +MainWindow::~MainWindow(){ CanselTool(); delete ui; + + QFile file("lekalo.xml"); + if(file.open(QIODevice::WriteOnly | QIODevice::Truncate)){ + const int Indent = 4; + QTextStream out(&file); + doc->save(out, Indent); + file.close(); + } + + delete data; + if(!doc->isNull()){ + delete doc; + } } diff --git a/mainwindow.h b/mainwindow.h index 1fadc45c5..b348c5ad7 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -3,9 +3,14 @@ #include #include +#include +#include #include "widgets/vmaingraphicsscene.h" #include "dialogs/dialogsinglepoint.h" +#include "tools/vtoolsimplepoint.h" +#include "xml/vdomdocument.h" +#include "container/vcontainer.h" namespace Ui { class MainWindow; @@ -27,17 +32,36 @@ public: ~MainWindow(); public slots: void mouseMove(QPointF scenePos); - void showEvent( QShowEvent *event ); - void clickedToolButtonSinglePoint(); + void clickedToolButtonSinglePoint(bool checked); void triggeredActionAroowTool(); + void triggeredActionDraw(bool checked); + void triggeredActionDetails(bool checked); + void ToolCanseled(); + void SinglePointCreated(const QString name, const QPointF point); + void triggeredActionNewDraw(); + void currentDrawChanged( int index ); + void triggeredOptionDraw(); + void triggeredActionSaveAs(); + void triggeredActionSave(); + void triggeredActionOpen(); + void triggeredActionNew(); + void haveChange(); +protected: + virtual void keyPressEvent ( QKeyEvent * event ); + virtual void showEvent( QShowEvent *event ); private: Ui::MainWindow *ui; - Tools::Enum tool; + Tools::Enum tool; VMainGraphicsScene *scene; QLabel *mouseCoordinate; QLabel *helpLabel; bool isInitialized; DialogSinglePoint *dialogSinglePoint; + VDomDocument *doc; + VContainer *data; + QComboBox *comboBoxDraws; + QString fileName; + bool changeInFile; void ToolBarOption(); void ToolBarDraws(); void CanselTool(); diff --git a/mainwindow.ui b/mainwindow.ui index 300d96322..ce219cf96 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -32,9 +32,20 @@ true + + + 0.000000000000000 + 0.000000000000000 + 50000.000000000000000 + 50000.000000000000000 + + Qt::AlignBottom|Qt::AlignRight|Qt::AlignTrailing + + QPainter::Antialiasing|QPainter::TextAntialiasing + @@ -90,6 +101,9 @@ + + false + Точка @@ -258,6 +272,9 @@ + + true + toolBar @@ -281,6 +298,7 @@ false + @@ -320,6 +338,9 @@ + + false + @@ -333,6 +354,9 @@ + + false + @@ -353,7 +377,7 @@ true - true + false @@ -370,6 +394,9 @@ true + + false + :/icon/32x32/kontur.png:/icon/32x32/kontur.png @@ -399,6 +426,27 @@ Інструмент вказівник + + + + :/icon/32x32/new_draw.png:/icon/32x32/new_draw.png + + + Нове креслення + + + Додати нове креслення + + + + + + :/icon/32x32/option_draw.png:/icon/32x32/option_draw.png + + + Змінити ім'я креслення + + diff --git a/options.h b/options.h index 25772ccc6..6bd4ae480 100644 --- a/options.h +++ b/options.h @@ -3,5 +3,7 @@ #define PrintDPI 96 #define PaperSize 50000 +#define WidthMainLine 0.8*PrintDPI/25.4 +#define widthHairLine WidthMainLine/3 #endif // OPTIONS_H diff --git a/tools/vtoolsimplepoint.cpp b/tools/vtoolsimplepoint.cpp new file mode 100644 index 000000000..14eb78adb --- /dev/null +++ b/tools/vtoolsimplepoint.cpp @@ -0,0 +1,301 @@ +#include "vtoolsimplepoint.h" +#include +#include +#include +#include +#include +#include +#include + +#include "../options.h" +#include "../container/vpointf.h" +#include "../dialogs/dialogsinglepoint.h" + +VToolSimplePoint::VToolSimplePoint (VDomDocument *doc, VContainer *data, qint64 id, Tool::Enum typeCreation, + QGraphicsItem * parent ):QGraphicsEllipseItem(parent){ + InitializeSimplePoint(doc, data, id); + if(typeCreation == Tool::FromGui){ + AddSimplePointToFile(); + } +} + +void VToolSimplePoint::InitializeSimplePoint(VDomDocument *doc, VContainer *data, qint64 id){ + ignoreContextMenuEvent = false;//don't ignore context menu events; + this->doc = doc; + this->data = data; + radius = 1.5*PrintDPI/25.4; + this->id = id; + nameActivDraw = doc->GetNameActivDraw(); + //create circle + VPointF point = data->GetPoint(id); + QRectF rec = QRectF(point.x(), point.y(), radius*2, radius*2); + rec.translate(point.x()-rec.center().x(), point.y()-rec.center().y()); + this->setRect(rec); + this->setPen(QPen(Qt::black, widthHairLine)); + this->setBrush(QBrush(Qt::NoBrush)); + this->setFlag(QGraphicsItem::ItemIsSelectable, true); + + //Тексто мітка точки + namePoint = new VGraphicsSimpleTextItem(point.name(), this); + rec = this->rect(); + namePoint->setPos(QPointF(rec.center().x()+point.mx(), rec.center().y()+point.my())); + connect(namePoint, &VGraphicsSimpleTextItem::NameChangePosition, this, + &VToolSimplePoint::NameChangePosition); + + //Лінія, що з'єднує точку і мітку + QRectF nameRec = namePoint->sceneBoundingRect(); + QPointF p1, p2; + LineIntersectCircle(rec.center(), radius, QLineF(rec.center(), nameRec.center()), p1, p2); + QPointF pRec = LineIntersectRect(nameRec, QLineF(rec.center(), nameRec.center())); + line = new QGraphicsLineItem(QLineF(p1, pRec), this); + line->setFlag(QGraphicsItem::ItemStacksBehindParent, true); + if(QLineF(p1, pRec).length() <= 4*PrintDPI/25.4){ + line->setVisible(false); + } else { + line->setVisible(true); + } + + connect(this->doc, &VDomDocument::ChangedActivDraw, this, &VToolSimplePoint::ChangedActivDraw); + connect(this->doc, &VDomDocument::ChangedNameDraw, this, &VToolSimplePoint::ChangedNameDraw); + connect(this, &VToolSimplePoint::FullUpdateTree, this->doc, &VDomDocument::FullUpdateTree); + connect(this, &VToolSimplePoint::haveLiteChange, this->doc, &VDomDocument::haveLiteChange); + connect(this->doc, &VDomDocument::FullUpdateFromFile, this, &VToolSimplePoint::FullUpdateFromFile); +} + +void VToolSimplePoint::NameChangePosition(const QPointF pos){ + VPointF point = data->GetPoint(id); + QRectF rec = this->rect(); + point.setMx(pos.x() - rec.center().x()); + point.setMy(pos.y() - rec.center().y()); + RefreshLine(); + LiteUpdateFromGui(point.name(), point.mx(), point.my()); + data->UpdatePoint(id, point); +} + +/* + * Взято з сайту http://hardfire.ru/cross_line_circle + */ +qint32 VToolSimplePoint::LineIntersectCircle(QPointF center, qreal radius, QLineF line, QPointF &p1, + QPointF &p2) const{ + const qreal eps = 1e-8; + //коефіцієнти для рівняння відрізку + qreal a = line.p2().y() - line.p1().y(); + qreal b = line.p1().x() - line.p2().x(); + // В даному випадку не використовується. + //qreal c = - a * line.p1().x() - b * line.p1().y(); + // проекция центра окружности на прямую + QPointF p = ClosestPoint (line, center); + // сколько всего решений? + qint32 flag = 0; + qreal d = QLineF (center, p).length(); + if (qAbs (d - radius) <= eps){ + flag = 1; + } else { + if (radius > d){ + flag = 2; + } else { + return 0; + } + } + // находим расстояние от проекции до точек пересечения + qreal k = sqrt (radius * radius - d * d); + qreal t = QLineF (QPointF (0, 0), QPointF (b, - a)).length(); + // добавляем к проекции векторы направленные к точкам пеерсечения + p1 = add_vector (p, QPointF (0, 0), QPointF (- b, a), k / t); + p2 = add_vector (p, QPointF (0, 0), QPointF (b, - a), k / t); + return flag; +} + +/* + * Добавление вектора к точке + * Взято з сайту http://hardfire.ru/add_vector + */ +QPointF VToolSimplePoint::add_vector (QPointF p, QPointF p1, QPointF p2, qreal k) const{ + return QPointF (p.x() + (p2.x() - p1.x()) * k, p.y() + (p2.y() - p1.y()) * k); +} + +QPointF VToolSimplePoint::ClosestPoint(QLineF line, QPointF p) const{ + QLineF lineP2pointFrom = QLineF(line.p2(), p); + qreal angle = 180-line.angleTo(lineP2pointFrom)-90; + QLineF pointFromlineP2 = QLineF(p, line.p2()); + pointFromlineP2.setAngle(pointFromlineP2.angle()+angle); + QPointF point; + QLineF::IntersectType type = pointFromlineP2.intersect(line,&point); + if ( type == QLineF::BoundedIntersection ){ + return point; + } else{ + if ( type == QLineF::NoIntersection || type == QLineF::UnboundedIntersection ){ + Q_ASSERT_X(type != QLineF::BoundedIntersection, Q_FUNC_INFO, "Немає точки перетину."); + return point; + } + } + return point; +} + +QPointF VToolSimplePoint::LineIntersectRect(QRectF rec, QLineF line) const{ + qreal x1, y1, x2, y2; + rec.getCoords(&x1, &y1, &x2, &y2); + QPointF point; + QLineF::IntersectType type = line.intersect(QLineF(QPointF(x1,y1), QPointF(x1,y2)),&point); + if ( type == QLineF::BoundedIntersection ){ + return point; + } + type = line.intersect(QLineF(QPointF(x1,y1), QPointF(x2,y1)),&point); + if ( type == QLineF::BoundedIntersection ){ + return point; + } + type = line.intersect(QLineF(QPointF(x1,y2), QPointF(x2,y2)),&point); + if ( type == QLineF::BoundedIntersection ){ + return point; + } + type = line.intersect(QLineF(QPointF(x2,y1), QPointF(x2,y2)),&point); + if ( type == QLineF::BoundedIntersection ){ + return point; + } + Q_ASSERT_X(type != QLineF::BoundedIntersection, Q_FUNC_INFO, "Немає точки перетину."); + return point; +} + +void VToolSimplePoint::ChangedActivDraw(const QString newName){ + if(nameActivDraw == newName){ + this->setPen(QPen(Qt::black, widthHairLine)); + this->setFlag(QGraphicsItem::ItemIsSelectable, true); + namePoint->setFlag(QGraphicsItem::ItemIsMovable, true); + namePoint->setFlag(QGraphicsItem::ItemIsSelectable, true); + namePoint->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); + namePoint->setBrush(QBrush(Qt::black)); + line->setPen(QPen(Qt::black, widthHairLine)); + ignoreContextMenuEvent = false; + } else { + this->setPen(QPen(Qt::gray, widthHairLine)); + this->setFlag(QGraphicsItem::ItemIsSelectable, false); + namePoint->setFlag(QGraphicsItem::ItemIsMovable, false); + namePoint->setFlag(QGraphicsItem::ItemIsSelectable, false); + namePoint->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false); + namePoint->setBrush(QBrush(Qt::gray)); + line->setPen(QPen(Qt::gray, widthHairLine)); + ignoreContextMenuEvent = true; + } +} + +void VToolSimplePoint::AddSimplePointToFile() const{ + VPointF point = data->GetPoint(id); + QDomElement domElement = doc->createElement("point"); + + QDomAttr domAttr = doc->createAttribute("id"); + domAttr.setValue(QString().setNum(id)); + domElement.setAttributeNode(domAttr); + + domAttr = doc->createAttribute("type"); + domAttr.setValue("simple"); + domElement.setAttributeNode(domAttr); + + domAttr = doc->createAttribute("name"); + domAttr.setValue(point.name()); + domElement.setAttributeNode(domAttr); + + domAttr = doc->createAttribute("x"); + domAttr.setValue(QString().setNum(point.x()/PrintDPI*25.4)); + domElement.setAttributeNode(domAttr); + + domAttr = doc->createAttribute("y"); + domAttr.setValue(QString().setNum(point.y()/PrintDPI*25.4)); + domElement.setAttributeNode(domAttr); + + domAttr = doc->createAttribute("mx"); + domAttr.setValue(QString().setNum(point.mx()/PrintDPI*25.4)); + domElement.setAttributeNode(domAttr); + + domAttr = doc->createAttribute("my"); + domAttr.setValue(QString().setNum(point.my()/PrintDPI*25.4)); + domElement.setAttributeNode(domAttr); + + QDomElement calcElement; + bool ok = doc->GetActivCalculationElement(calcElement); + if(ok){ + calcElement.appendChild(domElement); + } else { + qCritical("Не можу знайти тег калькуляції. VToolSimplePoint::AddSimplePoint"); + } +} + +void VToolSimplePoint::LiteUpdateFromGui(const QString& name, qreal mx, qreal my){ + QDomElement domElement = doc->elementById(QString().setNum(id)); + if(domElement.isElement()){ + domElement.setAttribute("name", name); + domElement.setAttribute("mx", QString().setNum(mx/PrintDPI*25.4)); + domElement.setAttribute("my", QString().setNum(my/PrintDPI*25.4)); + emit haveLiteChange(); + } +} + +void VToolSimplePoint::FullUpdateFromGui(const QString &name, qreal x, qreal y){ + QDomElement domElement = doc->elementById(QString().setNum(id)); + if(domElement.isElement()){ + domElement.setAttribute("name", name); + domElement.setAttribute("x", QString().setNum(x/PrintDPI*25.4)); + domElement.setAttribute("y", QString().setNum(y/PrintDPI*25.4)); + emit FullUpdateTree(); + } +} + +void VToolSimplePoint::ChangedNameDraw(const QString oldName, const QString newName){ + if(nameActivDraw == oldName){ + nameActivDraw = newName; + } +} + +void VToolSimplePoint::contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ){ + if(!ignoreContextMenuEvent){ + QMenu menu; + QAction *actionOption = menu.addAction("Властивості"); + QAction *selectedAction = menu.exec(event->screenPos()); + if(selectedAction == actionOption){ + DialogSinglePoint *dialogSinglePoint = new DialogSinglePoint; + VPointF p = data->GetPoint(id); + dialogSinglePoint->setData(p.name(), p.toQPointF()); + qint32 result = dialogSinglePoint->exec(); + if(result == QDialog::Accepted){ + QPointF p = dialogSinglePoint->getPoint(); + FullUpdateFromGui(dialogSinglePoint->getName(), p.x(), p.y()); + } + delete dialogSinglePoint; + } + } +} + +void VToolSimplePoint::FullUpdateFromFile(){ + QString name; + qreal x, y, mx, my; + QDomElement domElement = doc->elementById(QString().setNum(id)); + if(domElement.isElement()){ + name = domElement.attribute("name", ""); + x = domElement.attribute("x", "").toDouble()*PrintDPI/25.4; + y = domElement.attribute("y", "").toDouble()*PrintDPI/25.4; + mx = domElement.attribute("mx", "").toDouble()*PrintDPI/25.4; + my = domElement.attribute("my", "").toDouble()*PrintDPI/25.4; + } + QRectF rec = QRectF(x, y, radius*2, radius*2); + rec.translate(x-rec.center().x(), y-rec.center().y()); + this->setRect(rec); + + rec = this->rect(); + namePoint->setText(name); + namePoint->setPos(QPointF(rec.center().x()+mx, rec.center().y()+my)); + + RefreshLine(); +} + +void VToolSimplePoint::RefreshLine(){ + QRectF nameRec = namePoint->sceneBoundingRect(); + QPointF p1, p2; + QRectF rec = this->rect(); + LineIntersectCircle(rec.center(), radius, QLineF(rec.center(), nameRec.center()), p1, p2); + QPointF pRec = LineIntersectRect(nameRec, QLineF(rec.center(), nameRec.center())); + line->setLine(QLineF(p1, pRec)); + if(QLineF(p1, pRec).length() <= 4*PrintDPI/25.4){ + line->setVisible(false); + } else { + line->setVisible(true); + } +} diff --git a/tools/vtoolsimplepoint.h b/tools/vtoolsimplepoint.h new file mode 100644 index 000000000..94f6ac407 --- /dev/null +++ b/tools/vtoolsimplepoint.h @@ -0,0 +1,56 @@ +#ifndef VTOOLSIMPLEPOINT_H +#define VTOOLSIMPLEPOINT_H + +#include +#include + +#include "../widgets/vgraphicssimpletextitem.h" +#include "../container/vcontainer.h" +#include "../xml/vdomdocument.h" + +namespace Tool{ + enum Enum + { + FromGui, + FromFile + }; +} + +class VToolSimplePoint : public QObject, public QGraphicsEllipseItem +{ + Q_OBJECT +public: + VToolSimplePoint (VDomDocument *doc, VContainer *data, qint64 id, + Tool::Enum typeCreation, QGraphicsItem * parent = 0 ); +public slots: + void NameChangePosition(const QPointF pos); + void ChangedActivDraw(const QString newName); + void ChangedNameDraw(const QString oldName, const QString newName); + void FullUpdateFromFile(); +signals: + void FullUpdateTree(); + void haveLiteChange(); +protected: + virtual void contextMenuEvent ( QGraphicsSceneContextMenuEvent * event ); +private: + qreal radius; + VDomDocument *doc; + VContainer *data; + VGraphicsSimpleTextItem *namePoint; + QGraphicsLineItem *line; + qint64 id; + QString nameActivDraw; + bool ignoreContextMenuEvent; + qint32 LineIntersectCircle(QPointF center, qreal radius, QLineF line, QPointF &p1, + QPointF &p2) const; + QPointF LineIntersectRect(QRectF rec, QLineF line) const; + QPointF ClosestPoint(QLineF line, QPointF p) const; + QPointF add_vector (QPointF p, QPointF p1, QPointF p2, qreal k) const; + void AddSimplePointToFile() const; + void LiteUpdateFromGui(const QString& name, qreal mx, qreal my); + void FullUpdateFromGui(const QString& name, qreal x, qreal y); + void InitializeSimplePoint(VDomDocument *doc, VContainer *data, qint64 id); + void RefreshLine(); +}; + +#endif // VTOOLSIMPLEPOINT_H diff --git a/widgets/vgraphicssimpletextitem.cpp b/widgets/vgraphicssimpletextitem.cpp new file mode 100644 index 000000000..339654831 --- /dev/null +++ b/widgets/vgraphicssimpletextitem.cpp @@ -0,0 +1,28 @@ +#include "vgraphicssimpletextitem.h" +#include + +VGraphicsSimpleTextItem::VGraphicsSimpleTextItem(QGraphicsItem * parent):QGraphicsSimpleTextItem(parent){ +} + +VGraphicsSimpleTextItem::VGraphicsSimpleTextItem( const QString & text, QGraphicsItem * parent ):QGraphicsSimpleTextItem(text, parent){ + this->setFlag(QGraphicsItem::ItemIsMovable, true); + this->setFlag(QGraphicsItem::ItemIsSelectable, true); + this->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); +} + +QVariant VGraphicsSimpleTextItem::itemChange(GraphicsItemChange change, const QVariant &value){ + if (change == ItemPositionChange && scene()) { + // value - это новое положение. + QPointF newPos = value.toPointF(); + QRectF rect = scene()->sceneRect(); + if (!rect.contains(newPos)) { + // Сохраняем элемент внутри прямоугольника сцены. + newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left()))); + newPos.setY(qMin(rect.bottom(), qMax(newPos.y(), rect.top()))); + emit NameChangePosition(newPos); + return newPos; + } + emit NameChangePosition(newPos); + } + return QGraphicsItem::itemChange(change, value); + } diff --git a/widgets/vgraphicssimpletextitem.h b/widgets/vgraphicssimpletextitem.h new file mode 100644 index 000000000..4a07edccc --- /dev/null +++ b/widgets/vgraphicssimpletextitem.h @@ -0,0 +1,18 @@ +#ifndef VGRAPHICSSIMPLETEXTITEM_H +#define VGRAPHICSSIMPLETEXTITEM_H + +#include + +class VGraphicsSimpleTextItem : public QObject, public QGraphicsSimpleTextItem +{ + Q_OBJECT +public: + VGraphicsSimpleTextItem(QGraphicsItem * parent = 0); + VGraphicsSimpleTextItem( const QString & text, QGraphicsItem * parent = 0 ); +signals: + void NameChangePosition(const QPointF pos); +protected: + QVariant itemChange ( GraphicsItemChange change, const QVariant &value ); +}; + +#endif // VGRAPHICSSIMPLETEXTITEM_H diff --git a/widgets/vmaingraphicsscene.cpp b/widgets/vmaingraphicsscene.cpp index 1633c1d6d..08e6bceaa 100644 --- a/widgets/vmaingraphicsscene.cpp +++ b/widgets/vmaingraphicsscene.cpp @@ -1,4 +1,5 @@ #include "vmaingraphicsscene.h" +#include VMainGraphicsScene::VMainGraphicsScene():QGraphicsScene() diff --git a/xml/vdomdocument.cpp b/xml/vdomdocument.cpp new file mode 100644 index 000000000..56420d0e4 --- /dev/null +++ b/xml/vdomdocument.cpp @@ -0,0 +1,350 @@ +#include "vdomdocument.h" +#include "../tools/vtoolsimplepoint.h" +#include "../options.h" + +#include + +VDomDocument::VDomDocument(VContainer *data) : QDomDocument() { + this->data = data; +} + +VDomDocument::VDomDocument(const QString& name, VContainer *data) : QDomDocument(name) { + this->data = data; +} + +VDomDocument::VDomDocument(const QDomDocumentType& doctype, VContainer *data) : QDomDocument(doctype){ + this->data = data; +} + +QDomElement VDomDocument::elementById(const QString& id){ + if (map.contains(id)) { + QDomElement e = map[id]; + if (e.parentNode().nodeType() != QDomNode::BaseNode) { + return e; + } + + map.remove(id); + } + + bool res = this->find(this->documentElement(), id); + if (res) { + return map[id]; + } + + return QDomElement(); +} + +bool VDomDocument::find(QDomElement node, const QString& id){ + if (node.hasAttribute("id")) { + QString value = node.attribute("id"); + this->map[value] = node; + if (value == id) { + return true; + } + } + + for (qint32 i=0; ifind(n.toElement(), id); + if (res) { + return true; + } + } + } + + return false; +} + +void VDomDocument::CreateEmptyFile(){ + QDomElement domElement = this->createElement("lekalo"); + this->appendChild(domElement); + QDomNode xmlNode = this->createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""); + this->insertBefore(xmlNode, this->firstChild()); +} + +bool VDomDocument::CheckNameDraw(const QString& name) const{ + QDomNodeList elements = this->documentElement().elementsByTagName( "draw" ); + if(elements.size() == 0){ + return false; + } + for ( qint32 i = 0; i < elements.count(); i++ ){ + QDomElement elem = elements.at( i ).toElement(); + if(!elem.isNull()){ + QString fieldName = elem.attribute( "name" ); + if ( fieldName == name ){ + return true; + } + } + } + return false; +} + +bool VDomDocument::appendDraw(const QString& name){ + if(name.isEmpty()){ + return false; + } + if(CheckNameDraw(name)== false){ + QDomElement rootElement = this->documentElement(); + + QDomElement drawElement = this->createElement("draw"); + QDomAttr drawAttr = this->createAttribute("name"); + drawAttr.setValue(name); + drawElement.setAttributeNode(drawAttr); + + QDomElement calculationElement = this->createElement("calculation"); + QDomElement modelingElement = this->createElement("modeling"); + QDomElement pathsElement = this->createElement("paths"); + drawElement.appendChild(calculationElement); + drawElement.appendChild(modelingElement); + drawElement.appendChild(pathsElement); + + rootElement.appendChild(drawElement); + + if(nameActivDraw.isEmpty()){ + SetActivDraw(name); + } else { + ChangeActivDraw(name); + } + return true; + } else { + return false; + } + return false; +} + +void VDomDocument::ChangeActivDraw(const QString& name){ + if(CheckNameDraw(name) == true){ + this->nameActivDraw = name; + VMainGraphicsScene *scene = new VMainGraphicsScene(); + QDomElement domElement; + bool ok = GetActivDrawElement(domElement); + if(ok){ + ParseDrawElement(scene, domElement, Document::LiteParse); + } + delete scene; + emit ChangedActivDraw(name); + } +} + +void VDomDocument::SetNameDraw(const QString& name){ + QString oldName = nameActivDraw; + nameActivDraw = name; + emit ChangedNameDraw(oldName, nameActivDraw); +} + +void VDomDocument::SetActivDraw(const QString& name){ + this->nameActivDraw = name; +} + +QString VDomDocument::GetNameActivDraw() const{ + return nameActivDraw; +} + +bool VDomDocument::GetActivDrawElement(QDomElement &element){ + if(!nameActivDraw.isEmpty()){ + QDomNodeList elements = this->documentElement().elementsByTagName( "draw" ); + if(elements.size() == 0){ + return false; + } + for ( qint32 i = 0; i < elements.count(); i++ ){ + element = elements.at( i ).toElement(); + if(!element.isNull()){ + QString fieldName = element.attribute( "name" ); + if ( fieldName == nameActivDraw ){ + return true; + } + } + } + } + return false; +} + +bool VDomDocument::GetActivCalculationElement(QDomElement &element){ + bool ok = GetActivNodeElement("calculation", element); + if(ok){ + return true; + } else { + return false; + } +} + +bool VDomDocument::GetActivModelingElement(QDomElement &element){ + bool ok = GetActivNodeElement("modeling", element); + if(ok){ + return true; + } else { + return false; + } +} + +bool VDomDocument::GetActivPathsElement(QDomElement &element){ + bool ok = GetActivNodeElement("paths", element); + if(ok){ + return true; + } else { + return false; + } +} + +bool VDomDocument::GetActivNodeElement(const QString& name, QDomElement &element){ + QDomElement drawElement; + bool drawOk = this->GetActivDrawElement(drawElement); + if(drawOk == true){ + QDomNodeList listElement = drawElement.elementsByTagName(name); + if(listElement.size() == 0 || listElement.size() > 1){ + return false; + } + element = listElement.at( 0 ).toElement(); + if(!element.isNull()){ + return true; + } else { + return false; + } + } else { + return false; + } +} + +void VDomDocument::Parse(Document::Enum parse, VMainGraphicsScene *scene, QComboBox *comboBoxDraws){ + if(parse == Document::FullParse){ + data->Clear(); + nameActivDraw.clear(); + scene->clear(); + comboBoxDraws->clear(); + } + QDomElement rootElement = this->documentElement(); + QDomNode domNode = rootElement.firstChild(); + while(!domNode.isNull()){ + if(domNode.isElement()){ + QDomElement domElement = domNode.toElement(); + if(!domElement.isNull()){ + if(domElement.tagName()=="draw"){ + if(parse == Document::FullParse){ + if(nameActivDraw.isEmpty()){ + SetActivDraw(domElement.attribute("name")); + } else { + ChangeActivDraw(domElement.attribute("name")); + } + AddNewDraw(domElement, comboBoxDraws); + } + ParseDrawElement(scene, domElement, parse); + domNode = domNode.nextSibling(); + continue; + } + } + } + domNode = domNode.nextSibling(); + } +} + +void VDomDocument::AddNewDraw(const QDomElement& node, QComboBox *comboBoxDraws)const{ + QString name = node.attribute("name"); + QDomNode domNode = node.firstChild(); + if(!domNode.isNull()){ + if(domNode.isElement()){ + QDomElement domElement = domNode.toElement(); + if(!domElement.isNull()){ + if(domElement.tagName() == "calculation"){ + QDomNode domCal = domElement.firstChild(); + if(!domCal.isNull()){ + if(domCal.isElement()){ + QDomElement domElementPoint = domCal.toElement(); + if(!domElementPoint.isNull()){ + if(domElementPoint.tagName() == "point"){ + if(domElementPoint.attribute("type","") == "simple"){ + comboBoxDraws->addItem(name, false); + return; + } else { + comboBoxDraws->addItem(name, true); + return; + } + } + } + } + } + } + } + } + } +} + +void VDomDocument::ParseDrawElement(VMainGraphicsScene *scene, const QDomNode& node, + Document::Enum parse){ + QDomNode domNode = node.firstChild(); + while(!domNode.isNull()){ + if(domNode.isElement()){ + QDomElement domElement = domNode.toElement(); + if(!domElement.isNull()){ + if(domElement.tagName() == "calculation"){ + ParseCalculationElement(scene, domElement, parse); + } + if(domElement.tagName() == "modeling"){ + + } + if(domElement.tagName() == "paths"){ + + } + } + } + domNode = domNode.nextSibling(); + } +} + +void VDomDocument::ParseCalculationElement(VMainGraphicsScene *scene, const QDomNode& node, + Document::Enum parse){ + QDomNodeList nodeList = node.childNodes(); + qint32 num = nodeList.size(); + for(qint32 i = 0; i < num; ++i){ + QDomElement domElement = nodeList.at(i).toElement(); + if(!domElement.isNull()){ + if(domElement.tagName() == "point"){ + ParsePointElement(scene, domElement, parse, domElement.attribute("type", "")); + qDebug()<UpdatePoint(id, VPointF(x, y, name, mx, my)); + if(parse == Document::FullParse){ + VToolSimplePoint *spoint = new VToolSimplePoint(this, data, id, Tool::FromFile); + scene->addItem(spoint); + } + } + } + } +} + +void VDomDocument::FullUpdateTree(){ + VMainGraphicsScene *scene = new VMainGraphicsScene(); + QComboBox *comboBoxDraws = new QComboBox(); + Parse(Document::LiteParse, scene, comboBoxDraws ); + delete scene; + delete comboBoxDraws; + emit FullUpdateFromFile(); + emit haveChange(); +} + +void VDomDocument::haveLiteChange(){ + emit haveChange(); +} diff --git a/xml/vdomdocument.h b/xml/vdomdocument.h new file mode 100644 index 000000000..1eb80aff6 --- /dev/null +++ b/xml/vdomdocument.h @@ -0,0 +1,63 @@ +#ifndef VDOMDOCUMENT_H +#define VDOMDOCUMENT_H + +#include +#include +#include +#include + +#include "../container/vcontainer.h" +#include "../widgets/vmaingraphicsscene.h" + +namespace Document{ + enum Enum + { + LiteParse, + FullParse + }; +} + +class VDomDocument : public QObject, public QDomDocument +{ + Q_OBJECT +public: + VDomDocument(VContainer *data); + VDomDocument(const QString& name, VContainer *data); + VDomDocument(const QDomDocumentType& doctype, VContainer *data); + QDomElement elementById(const QString& id); + void CreateEmptyFile(); + void ChangeActivDraw(const QString& name); + QString GetNameActivDraw() const; + bool GetActivDrawElement(QDomElement &element); + bool GetActivCalculationElement(QDomElement &element); + bool GetActivModelingElement(QDomElement &element); + bool GetActivPathsElement(QDomElement &element); + bool appendDraw(const QString& name); + void SetNameDraw(const QString& name); + void Parse(Document::Enum parse, VMainGraphicsScene *scene, QComboBox *comboBoxDraws); +signals: + void ChangedActivDraw(const QString newName); + void ChangedNameDraw(const QString oldName, const QString newName); + void FullUpdateFromFile(); + void haveChange(); +public slots: + void FullUpdateTree(); + void haveLiteChange(); +private: + QMap map; + QString nameActivDraw; + VContainer *data; + bool find(QDomElement node, const QString& id); + bool CheckNameDraw(const QString& name) const; + void SetActivDraw(const QString& name); + bool GetActivNodeElement(const QString& name, QDomElement& element); + void ParseDrawElement(VMainGraphicsScene *scene, + const QDomNode& node, Document::Enum parse); + void ParseCalculationElement(VMainGraphicsScene *scene, const QDomNode& node, + Document::Enum parse); + void ParsePointElement(VMainGraphicsScene *scene, const QDomElement& domElement, + Document::Enum parse, const QString &type); + void AddNewDraw(const QDomElement &node, QComboBox *comboBoxDraws)const; +}; + +#endif // VDOMDOCUMENT_H