/************************************************************************ ** ** @file mainwindow.cpp ** @author Roman Telezhinsky ** @date November 15, 2013 ** ** @brief ** @copyright ** This source code is part of the Valentine project, a pattern making ** program, whose allow create and modeling patterns of clothing. ** Copyright (C) 2013 Valentina project ** All Rights Reserved. ** ** Valentina is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** Valentina is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with Valentina. If not, see . ** *************************************************************************/ #include "mainwindow.h" #include "ui_mainwindow.h" #include "geometry/vspline.h" #include "geometry/vequidistant.h" #include "exception/vexceptionobjecterror.h" #include "exception/vexceptionconversionerror.h" #include "exception/vexceptionemptyparameter.h" #include "exception/vexceptionwrongparameterid.h" #include "exception/vexceptionuniqueid.h" #include "version.h" #include #include #include #include #include #include #include #include #include #include #include //This class need for validation pattern file using XSD shema class MessageHandler : public QAbstractMessageHandler { public: MessageHandler() : QAbstractMessageHandler(0), m_messageType(QtMsgType()), m_description(QString()), m_sourceLocation(QSourceLocation()){} inline QString statusMessage() const {return m_description;} inline qint64 line() const {return m_sourceLocation.line();} inline qint64 column() const {return m_sourceLocation.column();} protected: virtual void handleMessage(QtMsgType type, const QString &description, const QUrl &identifier, const QSourceLocation &sourceLocation) { Q_UNUSED(type); Q_UNUSED(identifier); m_messageType = type; m_description = description; m_sourceLocation = sourceLocation; } private: QtMsgType m_messageType; QString m_description; QSourceLocation m_sourceLocation; }; MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent), ui(new Ui::MainWindow), pattern(0), doc(0), tool(Tool::ArrowTool), currentScene(0), sceneDraw(0), sceneDetails(0), mouseCoordinate(0), helpLabel(0), view(0), isInitialized(false), dialogTable(0), dialogTool(0), dialogHistory(0), comboBoxDraws(0), curFile(QString()), mode(Draw::Calculation), currentDrawIndex(0), currentToolBoxIndex(0), drawMode(true), recentFileActs{0,0,0,0,0}, separatorAct(0), autoSaveTimer(0) { CreateActions(); CreateMenus(); ToolBarOption(); ToolBarDraws(); sceneDraw = new VMainGraphicsScene(); currentScene = sceneDraw; connect(sceneDraw, &VMainGraphicsScene::mouseMove, this, &MainWindow::mouseMove); sceneDetails = new VMainGraphicsScene(); connect(sceneDetails, &VMainGraphicsScene::mouseMove, this, &MainWindow::mouseMove); view = new VMainGraphicsView(); ui->LayoutView->addWidget(view); view->setScene(currentScene); sceneDraw->setTransform(view->transform()); sceneDetails->setTransform(view->transform()); connect(view, &VMainGraphicsView::NewFactor, sceneDraw, &VMainGraphicsScene::SetFactor); QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Expanding); policy.setHorizontalStretch(12); view->setSizePolicy(policy); helpLabel = new QLabel(QObject::tr("Create new pattern piece to start working.")); ui->statusBar->addWidget(helpLabel); connect(ui->toolButtonEndLine, &QToolButton::clicked, this, &MainWindow::ToolEndLine); connect(ui->toolButtonLine, &QToolButton::clicked, this, &MainWindow::ToolLine); connect(ui->toolButtonAlongLine, &QToolButton::clicked, this, &MainWindow::ToolAlongLine); connect(ui->toolButtonShoulderPoint, &QToolButton::clicked, this, &MainWindow::ToolShoulderPoint); connect(ui->toolButtonNormal, &QToolButton::clicked, this, &MainWindow::ToolNormal); connect(ui->toolButtonBisector, &QToolButton::clicked, this, &MainWindow::ToolBisector); connect(ui->toolButtonLineIntersect, &QToolButton::clicked, this, &MainWindow::ToolLineIntersect); connect(ui->toolButtonSpline, &QToolButton::clicked, this, &MainWindow::ToolSpline); connect(ui->toolButtonArc, &QToolButton::clicked, this, &MainWindow::ToolArc); connect(ui->toolButtonSplinePath, &QToolButton::clicked, this, &MainWindow::ToolSplinePath); connect(ui->toolButtonPointOfContact, &QToolButton::clicked, this, &MainWindow::ToolPointOfContact); connect(ui->toolButtonNewDetail, &QToolButton::clicked, this, &MainWindow::ToolDetail); connect(ui->toolButtonHeight, &QToolButton::clicked, this, &MainWindow::ToolHeight); connect(ui->toolButtonTriangle, &QToolButton::clicked, this, &MainWindow::ToolTriangle); connect(ui->toolButtonPointOfIntersection, &QToolButton::clicked, this, &MainWindow::ToolPointOfIntersection); connect(ui->toolButtonSplineCutPoint, &QToolButton::clicked, this, &MainWindow::ToolCutSpline); connect(ui->toolButtonSplinePathCutPoint, &QToolButton::clicked, this, &MainWindow::ToolCutSplinePath); connect(ui->toolButtonUnionDetails, &QToolButton::clicked, this, &MainWindow::ToolUnionDetails); connect(ui->toolButtonArcCutPoint, &QToolButton::clicked, this, &MainWindow::ToolCutArc); pattern = new VContainer(); doc = new VDomDocument(pattern, comboBoxDraws, &mode); doc->CreateEmptyFile(); connect(doc, &VDomDocument::patternChanged, this, &MainWindow::PatternWasModified); InitAutoSave(); ui->toolBox->setCurrentIndex(0); ReadSettings(); setCurrentFile(""); } void MainWindow::ActionNewDraw() { QString nameDraw; bool bOk; qint32 index; QString nDraw = QString(tr("Pattern piece %1")).arg(comboBoxDraws->count()+1); QInputDialog *dlg = new QInputDialog(this); dlg->setInputMode( QInputDialog::TextInput ); dlg->setLabelText(tr("Pattern piece:")); dlg->setTextEchoMode(QLineEdit::Normal); dlg->setWindowTitle(tr("Enter a label for the pattern piece.")); dlg->resize(300, 100); dlg->setTextValue(nDraw); while (1) { bOk = dlg->exec(); nameDraw = dlg->textValue(); if (bOk == false || nameDraw.isEmpty()) { delete dlg; return; } index = comboBoxDraws->findText(nameDraw); if (index != -1) {//we already have this name qCritical()<appendDraw(nameDraw); if (bOk == false) { qCritical()<(&QComboBox::currentIndexChanged), this, &MainWindow::currentDrawChanged); comboBoxDraws->addItem(nameDraw); pattern->ClearGObjects(); //Create single point qint64 id = pattern->AddGObject(new VPointF(toPixel((10+comboBoxDraws->count()*5)), toPixel(10), "А", 5, 10)); VToolSinglePoint *spoint = new VToolSinglePoint(doc, pattern, id, Tool::FromGui); sceneDraw->addItem(spoint); connect(spoint, &VToolPoint::ChoosedTool, sceneDraw, &VMainGraphicsScene::ChoosedItem); connect(sceneDraw, &VMainGraphicsScene::NewFactor, spoint, &VToolSinglePoint::SetFactor); QHash* tools = doc->getTools(); tools->insert(id, spoint); VDrawTool::AddRecord(id, Tool::SinglePointTool, doc); SetEnableTool(true); SetEnableWidgets(true); index = comboBoxDraws->findText(nameDraw); if ( index != -1 ) { // -1 for not found comboBoxDraws->setCurrentIndex(index); currentDrawChanged( index ); } connect(comboBoxDraws, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::currentDrawChanged); } void MainWindow::OptionDraw() { QString nameDraw; qint32 index; QString nDraw = doc->GetNameActivDraw(); QInputDialog *dlg = new QInputDialog(this); dlg->setInputMode( QInputDialog::TextInput ); dlg->setLabelText(tr("Pattern piece:")); dlg->setTextEchoMode(QLineEdit::Normal); dlg->setWindowTitle(tr("Enter a new label for the pattern piece.")); dlg->resize(300, 100); dlg->setTextValue(nDraw); while (1) { bool bOk = dlg->exec(); nameDraw = dlg->textValue(); if (bOk == false || nameDraw.isEmpty()) { delete dlg; return; } index = comboBoxDraws->findText(nameDraw); if (index != -1) {//we already have this name qCritical()<findText(doc->GetNameActivDraw()); if (doc->SetNameDraw(nameDraw)) { comboBoxDraws->setItemText(index, nameDraw); } else { QMessageBox::warning(this, tr("Error saving change!!!"), tr("Can't save new label of pattern piece")); } } template void MainWindow::SetToolButton(bool checked, Tool::Tools t, const QString &cursor, const QString &toolTip, Func closeDialogSlot) { if (checked) { CancelTool(); tool = t; QPixmap pixmap(cursor); QCursor cur(pixmap, 2, 3); view->setCursor(cur); helpLabel->setText(toolTip); dialogTool = new Dialog(pattern, this); Q_CHECK_PTR(dialogTool); connect(currentScene, &VMainGraphicsScene::ChoosedObject, dialogTool, &DialogTool::ChoosedObject); connect(dialogTool, &DialogTool::DialogClosed, this, closeDialogSlot); connect(dialogTool, &DialogTool::ToolTip, this, &MainWindow::ShowToolTip); connect(doc, &VDomDocument::FullUpdateFromFile, dialogTool, &DialogTool::UpdateList); } else { if (QToolButton *tButton = qobject_cast< QToolButton * >(this->sender())) { Q_CHECK_PTR(tButton); tButton->setChecked(true); } } } template void MainWindow::ClosedDialog(int result) { Q_CHECK_PTR(dialogTool); if (result == QDialog::Accepted) { DrawTool::Create(dialogTool, currentScene, doc, pattern); } ArrowTool(); } void MainWindow::ToolEndLine(bool checked) { SetToolButton(checked, Tool::EndLineTool, ":/cursor/endline_cursor.png", tr("Select point"), &MainWindow::ClosedDialogEndLine); } void MainWindow::ClosedDialogEndLine(int result) { ClosedDialog(result); } void MainWindow::ToolLine(bool checked) { SetToolButton(checked, Tool::LineTool, ":/cursor/line_cursor.png", tr("Select first point"), &MainWindow::ClosedDialogLine); } void MainWindow::ClosedDialogLine(int result) { ClosedDialog(result); } void MainWindow::ToolAlongLine(bool checked) { SetToolButton(checked, Tool::AlongLineTool, ":/cursor/alongline_cursor.png", tr("Select point"), &MainWindow::ClosedDialogAlongLine); } void MainWindow::ClosedDialogAlongLine(int result) { ClosedDialog(result); } void MainWindow::ToolShoulderPoint(bool checked) { SetToolButton(checked, Tool::ShoulderPointTool, ":/cursor/shoulder_cursor.png", tr("Select first point of line"), &MainWindow::ClosedDialogShoulderPoint); } void MainWindow::ClosedDialogShoulderPoint(int result) { ClosedDialog(result); } void MainWindow::ToolNormal(bool checked) { SetToolButton(checked, Tool::NormalTool, ":/cursor/normal_cursor.png", tr("Select first point of line"), &MainWindow::ClosedDialogNormal); } void MainWindow::ClosedDialogNormal(int result) { ClosedDialog(result); } void MainWindow::ToolBisector(bool checked) { SetToolButton(checked, Tool::BisectorTool, ":/cursor/bisector_cursor.png", tr("Select first point of angle"), &MainWindow::ClosedDialogBisector); } void MainWindow::ClosedDialogBisector(int result) { ClosedDialog(result); } void MainWindow::ToolLineIntersect(bool checked) { SetToolButton(checked, Tool::LineIntersectTool, ":/cursor/intersect_cursor.png", tr("Select first point of first line"), &MainWindow::ClosedDialogLineIntersect); } void MainWindow::ClosedDialogLineIntersect(int result) { ClosedDialog(result); } void MainWindow::ToolSpline(bool checked) { SetToolButton(checked, Tool::SplineTool, ":/cursor/spline_cursor.png", tr("Select first point curve"), &MainWindow::ClosedDialogSpline); } void MainWindow::ClosedDialogSpline(int result) { ClosedDialog(result); } void MainWindow::ToolCutSpline(bool checked) { SetToolButton(checked, Tool::CutSplineTool, ":/cursor/spline_cut_point_cursor.png", tr("Select simple curve"), &MainWindow::ClosedDialogCutSpline); } void MainWindow::ClosedDialogCutSpline(int result) { ClosedDialog(result); } void MainWindow::ToolArc(bool checked) { SetToolButton(checked, Tool::ArcTool, ":/cursor/arc_cursor.png", tr("Select point of center of arc"), &MainWindow::ClosedDialogArc); } void MainWindow::ClosedDialogArc(int result) { ClosedDialog(result); } void MainWindow::ToolSplinePath(bool checked) { SetToolButton(checked, Tool::SplinePathTool, ":/cursor/splinepath_cursor.png", tr("Select point of curve path"), &MainWindow::ClosedDialogSplinePath); } void MainWindow::ClosedDialogSplinePath(int result) { ClosedDialog(result); } void MainWindow::ToolCutSplinePath(bool checked) { SetToolButton(checked, Tool::CutSplinePathTool, ":/cursor/splinepath_cut_point_cursor.png", tr("Select curve path"), &MainWindow::ClosedDialogCutSplinePath); } void MainWindow::ClosedDialogCutSplinePath(int result) { ClosedDialog(result); } void MainWindow::ToolPointOfContact(bool checked) { SetToolButton(checked, Tool::PointOfContact, ":/cursor/pointcontact_cursor.png", tr("Select first point of line"), &MainWindow::ClosedDialogPointOfContact); } void MainWindow::ClosedDialogPointOfContact(int result) { ClosedDialog(result); } void MainWindow::ToolDetail(bool checked) { SetToolButton(checked, Tool::Detail, "://cursor/new_detail_cursor.png", tr("Select points, arcs, curves clockwise."), &MainWindow::ClosedDialogDetail); } void MainWindow::ClosedDialogDetail(int result) { if (result == QDialog::Accepted) { VToolDetail::Create(dialogTool, sceneDetails, doc, pattern); } ArrowTool(); doc->FullUpdateTree(); } void MainWindow::ToolHeight(bool checked) { SetToolButton(checked, Tool::Height, ":/cursor/height_cursor.png", tr("Select base point"), &MainWindow::ClosedDialogHeight); } void MainWindow::ClosedDialogHeight(int result) { ClosedDialog(result); } void MainWindow::ToolTriangle(bool checked) { SetToolButton(checked, Tool::Triangle, ":/cursor/triangle_cursor.png", tr("Select first point of axis"), &MainWindow::ClosedDialogTriangle); } void MainWindow::ClosedDialogTriangle(int result) { ClosedDialog(result); } void MainWindow::ToolPointOfIntersection(bool checked) { SetToolButton(checked, Tool::PointOfIntersection, ":/cursor/pointofintersect_cursor.png", tr("Select point vertically"), &MainWindow::ClosedDialogPointOfIntersection); } void MainWindow::ClosedDialogPointOfIntersection(int result) { ClosedDialog(result); } void MainWindow::ToolUnionDetails(bool checked) { SetToolButton(checked, Tool::UnionDetails, ":/cursor/union_cursor.png", tr("Select detail"), &MainWindow::ClosedDialogUnionDetails); //Must disconnect this signal here. disconnect(doc, &VDomDocument::FullUpdateFromFile, dialogTool, &DialogTool::UpdateList); } void MainWindow::ClosedDialogUnionDetails(int result) { ClosedDialog(result); doc->FullUpdateTree(); } void MainWindow::ToolCutArc(bool checked) { SetToolButton(checked, Tool::CutArcTool, ":/cursor/arc_cut_cursor.png", tr("Select arc"), &MainWindow::ClosedDialogCutArc); } void MainWindow::ClosedDialogCutArc(int result) { ClosedDialog(result); } void MainWindow::About() { QDate date = QLocale(QLocale::C).toDate(QString(__DATE__).simplified(), QLatin1String("MMM d yyyy")); QString fullName = QString("Valentina %1").arg(APP_VERSION); QString qtBase(tr("Based on Qt %2 (32 bit)").arg(QT_VERSION_STR)); QString buildOn(tr("Built on %3 at %4").arg(date.toString()).arg(__TIME__)); QString about = QString(tr("

%1

%2

%3

%4")).arg(fullName).arg(qtBase).arg(buildOn) .arg(WARRANTY); QMessageBox::about(this, tr("About Valentina"), about); } void MainWindow::AboutQt() { QMessageBox::aboutQt(this, tr("About Qt")); } void MainWindow::ShowToolTip(const QString &toolTip) { helpLabel->setText(toolTip); } void MainWindow::tableClosed() { show(); MinimumScrollBar(); } void MainWindow::OpenRecentFile() { QAction *action = qobject_cast(sender()); if (action) { LoadPattern(action->data().toString()); } } void MainWindow::showEvent( QShowEvent *event ) { QMainWindow::showEvent( event ); if ( event->spontaneous() ) { return; } if (isInitialized) { return; } // do your init stuff here MinimumScrollBar(); isInitialized = true;//first show windows are held } void MainWindow::closeEvent(QCloseEvent *event) { if (MaybeSave()) { WriteSettings(); event->accept(); } else { event->ignore(); } } void MainWindow::ToolBarOption() { QLabel * labelGrowth = new QLabel; labelGrowth->setText(tr("Height: ")); ui->toolBarOption->addWidget(labelGrowth); QStringList list; list <<"92"<<"98"<<"104"<<"110"<<"116"<<"122"<<"128"<<"134"<<"140"<<"146"<<"152"<<"158"<<"164"<<"170"<<"176" <<"182"<<"188"; QComboBox *comboBoxGrow = new QComboBox; comboBoxGrow->clear(); comboBoxGrow->addItems(list); comboBoxGrow->setCurrentIndex(14); ui->toolBarOption->addWidget(comboBoxGrow); connect(comboBoxGrow, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::ChangedHeight); QLabel * labelSize = new QLabel; labelSize->setText(tr(" Size: ")); ui->toolBarOption->addWidget(labelSize); list.clear(); list <<"22"<<"24"<<"26"<<"28"<<"30"<<"32"<<"34"<<"36"<<"38"<<"40"<<"42"<<"44"<<"46"<<"48"<<"50"<<"52"<<"54"<<"56"; QComboBox *comboBoxSize = new QComboBox; comboBoxSize->clear(); comboBoxSize->addItems(list); comboBoxSize->setCurrentIndex(14); ui->toolBarOption->addWidget(comboBoxSize); connect(comboBoxSize, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::ChangedSize); ui->toolBarOption->addSeparator(); mouseCoordinate = new QLabel; mouseCoordinate ->setText("0, 0"); ui->toolBarOption->addWidget(mouseCoordinate); } void MainWindow::ToolBarDraws() { QLabel * labelNameDraw = new QLabel; labelNameDraw ->setText(tr("Pattern Piece: ")); ui->toolBarDraws->addWidget(labelNameDraw); comboBoxDraws = new QComboBox; ui->toolBarDraws->addWidget(comboBoxDraws); comboBoxDraws->setSizeAdjustPolicy(QComboBox::AdjustToContents); connect(comboBoxDraws, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::currentDrawChanged); ui->toolBarDraws->addAction(ui->actionOptionDraw); ui->actionOptionDraw->setEnabled(false); ui->toolBarDraws->addAction(ui->actionTable); ui->actionTable->setEnabled(false); ui->toolBarDraws->addAction(ui->actionHistory); ui->actionHistory->setEnabled(false); connect(ui->actionHistory, &QAction::triggered, this, &MainWindow::ActionHistory); ui->toolBarDraws->addAction(ui->actionLayout); connect(ui->actionLayout, &QAction::triggered, this, &MainWindow::ActionLayout); ui->actionLayout->setEnabled(false); } void MainWindow::currentDrawChanged( int index ) { if (index != -1) { doc->setCurrentData(); doc->ChangeActivDraw(comboBoxDraws->itemText(index)); if (drawMode) { ArrowTool(); qint64 id = doc->SPointActiveDraw(); if (id != 0) { const VPointF *p = pattern->GeometricObject(id); view->centerOn(p->toQPointF()); } } } } void MainWindow::mouseMove(const QPointF &scenePos) { QString string = QString("%1, %2") .arg(static_cast(toMM(scenePos.x()))) .arg(static_cast(toMM(scenePos.y()))); mouseCoordinate->setText(string); } void MainWindow::CancelTool() { delete dialogTool; dialogTool = 0; switch ( tool ) { case Tool::ArrowTool: ui->actionArrowTool->setChecked(false); helpLabel->setText(""); break; case Tool::SinglePointTool: Q_UNREACHABLE(); //Nothing to do here because we can't create this tool from main window. break; case Tool::EndLineTool: ui->toolButtonEndLine->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::LineTool: ui->toolButtonLine->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearFocus(); break; case Tool::AlongLineTool: ui->toolButtonAlongLine->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::ShoulderPointTool: ui->toolButtonShoulderPoint->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::NormalTool: ui->toolButtonNormal->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::BisectorTool: ui->toolButtonBisector->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::LineIntersectTool: ui->toolButtonLineIntersect->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::SplineTool: ui->toolButtonSpline->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::ArcTool: ui->toolButtonArc->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::SplinePathTool: ui->toolButtonSplinePath->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::PointOfContact: ui->toolButtonPointOfContact->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::Detail: ui->toolButtonNewDetail->setChecked(false); break; case Tool::Height: ui->toolButtonHeight->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::Triangle: ui->toolButtonTriangle->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::PointOfIntersection: ui->toolButtonPointOfIntersection->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::CutSplineTool: ui->toolButtonSplineCutPoint->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::CutSplinePathTool: ui->toolButtonSplinePathCutPoint->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::UnionDetails: ui->toolButtonUnionDetails->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; case Tool::CutArcTool: ui->toolButtonArcCutPoint->setChecked(false); currentScene->setFocus(Qt::OtherFocusReason); currentScene->clearSelection(); break; default: qWarning()<<"Got wrong tool type. Ignored."; break; } } void MainWindow::ArrowTool() { CancelTool(); ui->actionArrowTool->setChecked(true); tool = Tool::ArrowTool; QCursor cur(Qt::ArrowCursor); view->setCursor(cur); helpLabel->setText(""); } void MainWindow::ActionAroowTool() { ArrowTool(); } void MainWindow::keyPressEvent ( QKeyEvent * event ) { switch (event->key()) { case Qt::Key_Escape: ArrowTool(); break; default: break; } QMainWindow::keyPressEvent ( event ); } void MainWindow::SaveCurrentScene() { /*Save transform*/ currentScene->setTransform(view->transform()); /*Save scroll bars value for previous scene.*/ QScrollBar *horScrollBar = view->horizontalScrollBar(); currentScene->setHorScrollBar(horScrollBar->value()); QScrollBar *verScrollBar = view->verticalScrollBar(); currentScene->setVerScrollBar(verScrollBar->value()); } void MainWindow::RestoreCurrentScene() { /*Set transform for current scene*/ view->setTransform(currentScene->transform()); /*Set value for current scene scroll bar.*/ QScrollBar *horScrollBar = view->horizontalScrollBar(); horScrollBar->setValue(currentScene->getHorScrollBar()); QScrollBar *verScrollBar = view->verticalScrollBar(); verScrollBar->setValue(currentScene->getVerScrollBar()); } void MainWindow::ActionDraw(bool checked) { if (checked) { ui->actionDetails->setChecked(false); SaveCurrentScene(); currentScene = sceneDraw; view->setScene(currentScene); connect(view, &VMainGraphicsView::NewFactor, sceneDraw, &VMainGraphicsScene::SetFactor); RestoreCurrentScene(); mode = Draw::Calculation; comboBoxDraws->setEnabled(true); comboBoxDraws->setCurrentIndex(currentDrawIndex);//restore current pattern peace drawMode = true; SetEnableTool(true); doc->setCurrentData(); ui->toolBox->setCurrentIndex(currentToolBoxIndex); ui->actionHistory->setEnabled(true); ui->actionLayout->setEnabled(false); ui->actionOptionDraw->setEnabled(true); ui->actionNewDraw->setEnabled(true); } else { ui->actionDraw->setChecked(true); } } void MainWindow::ActionDetails(bool checked) { if (checked) { ui->actionDraw->setChecked(false); SaveCurrentScene(); currentScene = sceneDetails; view->setScene(sceneDetails); disconnect(view, &VMainGraphicsView::NewFactor, sceneDraw, &VMainGraphicsScene::SetFactor); RestoreCurrentScene(); drawMode = false; currentDrawIndex = comboBoxDraws->currentIndex();//save current pattern peace comboBoxDraws->setCurrentIndex(comboBoxDraws->count()-1); comboBoxDraws->setEnabled(false); mode = Draw::Modeling; SetEnableTool(true); currentToolBoxIndex = ui->toolBox->currentIndex(); ui->toolBox->setCurrentIndex(4); ui->actionHistory->setEnabled(false); ui->actionLayout->setEnabled(true); ui->actionOptionDraw->setEnabled(false); ui->actionNewDraw->setEnabled(false); } else { ui->actionDetails->setChecked(true); } } bool MainWindow::SaveAs() { QString filters(tr("Pattern files (*.val)")); QString dir; if (curFile.isEmpty()) { dir = QDir::homePath() + tr("/pattern.val"); } else { dir = QFileInfo(curFile).absolutePath() + tr("/pattern.val"); } QString fileName = QFileDialog::getSaveFileName(this, tr("Save as"), dir, filters); if (fileName.isEmpty()) { return false; } QFileInfo f( fileName ); if (f.suffix().isEmpty() && f.suffix() != "val") { fileName += ".val"; } return SavePattern(fileName); } bool MainWindow::Save() { if (curFile.isEmpty()) { return SaveAs(); } else { bool result = SavePattern(curFile); if (result) { QString autofile = curFile +".autosave"; QFile file(autofile); file.remove(); } return result; } } void MainWindow::Open() { if (MaybeSave()) { QString filter(tr("Pattern files (*.val)")); QString dir; if (curFile.isEmpty()) { dir = QDir::homePath(); } else { dir = QFileInfo(curFile).absolutePath(); } QString fileName = QFileDialog::getOpenFileName(this, tr("Open file"), dir, filter); if (fileName.isEmpty() == false) { LoadPattern(fileName); VAbstractTool::NewSceneRect(sceneDraw, view); VAbstractTool::NewSceneRect(sceneDetails, view); } } } void MainWindow::Options() { ConfigDialog dlg(this); if (dlg.exec() == QDialog::Accepted) { InitAutoSave(); } } void MainWindow::Clear() { setCurrentFile(""); pattern->Clear(); doc->clear(); sceneDraw->clear(); sceneDetails->clear(); CancelTool(); comboBoxDraws->clear(); ui->actionOptionDraw->setEnabled(false); ui->actionSave->setEnabled(false); SetEnableTool(false); } void MainWindow::NewPattern() { QProcess *v = new QProcess(this); v->startDetached(QCoreApplication::applicationFilePath ()); delete v; } void MainWindow::PatternWasModified() { setWindowModified(doc->isPatternModified()); ui->actionSave->setEnabled(true); } void MainWindow::ChangedSize(const QString & text) { qint32 size = text.toInt(); pattern->SetSize(size*10); doc->FullUpdateTree(); } void MainWindow::ChangedHeight(const QString &text) { qint32 growth = text.toInt(); pattern->SetGrowth(growth*10); doc->FullUpdateTree(); } void MainWindow::SetEnableWidgets(bool enable) { ui->actionSaveAs->setEnabled(enable); ui->actionDraw->setEnabled(enable); ui->actionDetails->setEnabled(enable); ui->actionOptionDraw->setEnabled(enable); if (enable == true && curFile.isEmpty() == false) { ui->actionSave->setEnabled(enable); } ui->actionTable->setEnabled(enable); ui->actionHistory->setEnabled(enable); } void MainWindow::ActionTable(bool checked) { if (checked) { dialogTable = new DialogIncrements(pattern, doc, this); Q_CHECK_PTR(dialogTable); connect(dialogTable, &DialogIncrements::DialogClosed, this, &MainWindow::ClosedActionTable); dialogTable->show(); } else { ui->actionTable->setChecked(true); dialogTable->activateWindow(); } } void MainWindow::ClosedActionTable() { ui->actionTable->setChecked(false); delete dialogTable; dialogTable = 0; } void MainWindow::ActionHistory(bool checked) { if (checked) { dialogHistory = new DialogHistory(pattern, doc, this); dialogHistory->setWindowFlags(Qt::Window); connect(dialogHistory, &DialogHistory::DialogClosed, this, &MainWindow::ClosedActionHistory); dialogHistory->show(); } else { ui->actionHistory->setChecked(true); dialogHistory->activateWindow(); } } void MainWindow::ActionLayout(bool checked) { Q_UNUSED(checked); hide(); QVector listDetails; const QHash *details = pattern->DataDetails(); QHashIterator idetail(*details); while (idetail.hasNext()) { idetail.next(); QPainterPath path = VEquidistant().ContourPath(idetail.key(), pattern); listDetails.append(new VItem(path, listDetails.size())); } emit ModelChosen(listDetails, curFile); } void MainWindow::ClosedActionHistory() { ui->actionHistory->setChecked(false); delete dialogHistory; } void MainWindow::SetEnableTool(bool enable) { bool drawTools = false; bool modelingTools = false; if (mode == Draw::Calculation) { drawTools = enable; } else { modelingTools = enable; } //Drawing Tools ui->toolButtonEndLine->setEnabled(drawTools); ui->toolButtonLine->setEnabled(drawTools); ui->toolButtonAlongLine->setEnabled(drawTools); ui->toolButtonShoulderPoint->setEnabled(drawTools); ui->toolButtonNormal->setEnabled(drawTools); ui->toolButtonBisector->setEnabled(drawTools); ui->toolButtonLineIntersect->setEnabled(drawTools); ui->toolButtonSpline->setEnabled(drawTools); ui->toolButtonArc->setEnabled(drawTools); ui->toolButtonSplinePath->setEnabled(drawTools); ui->toolButtonPointOfContact->setEnabled(drawTools); ui->toolButtonNewDetail->setEnabled(drawTools); ui->toolButtonHeight->setEnabled(drawTools); ui->toolButtonTriangle->setEnabled(drawTools); ui->toolButtonPointOfIntersection->setEnabled(drawTools); ui->toolButtonSplineCutPoint->setEnabled(drawTools); ui->toolButtonSplinePathCutPoint->setEnabled(drawTools); ui->toolButtonArcCutPoint->setEnabled(drawTools); //Modeling Tools ui->toolButtonUnionDetails->setEnabled(modelingTools); } void MainWindow::MinimumScrollBar() { QScrollBar *horScrollBar = view->horizontalScrollBar(); horScrollBar->setValue(horScrollBar->minimum()); QScrollBar *verScrollBar = view->verticalScrollBar(); verScrollBar->setValue(verScrollBar->minimum()); } bool MainWindow::ValidatePattern(const QString &schema, const QString &fileName, QString &errorMsg, qint64 &errorLine, qint64 &errorColumn) const { errorLine = -1; errorColumn = -1; QFile pattern(fileName); if (pattern.open(QIODevice::ReadOnly) == false) { errorMsg = QString(tr("Can't open pattern file %1:\n%2.").arg(fileName).arg(pattern.errorString())); return false; } QFile fileSchema(schema); if (fileSchema.open(QIODevice::ReadOnly) == false) { errorMsg = QString(tr("Can't open schema file %1:\n%2.").arg(schema).arg(fileSchema.errorString())); return false; } MessageHandler messageHandler; QXmlSchema sch; sch.setMessageHandler(&messageHandler); sch.load(&fileSchema, QUrl::fromLocalFile(fileSchema.fileName())); bool errorOccurred = false; if (sch.isValid() == false) { errorOccurred = true; } else { QXmlSchemaValidator validator(sch); if (validator.validate(&pattern, QUrl::fromLocalFile(pattern.fileName())) == false) { errorOccurred = true; } } if (errorOccurred) { errorMsg = messageHandler.statusMessage(); errorLine = messageHandler.line(); errorColumn = messageHandler.column(); return false; } else { return true; } } bool MainWindow::SavePattern(const QString &fileName) { try { doc->TestUniqueId(); } catch (const VExceptionUniqueId &e) { e.CriticalMessageBox(tr("Error no unique id."), this); return false; } if (fileName.isEmpty()) { qWarning()<save(out, Indent); tempFile.close(); } //Replace temp file our bool result = false; QFile patternFile(fileName); // We need here temporary file because we need restore pattern after error of copying temp file. QTemporaryFile tempOfPattern; if (tempOfPattern.open()) { patternFile.copy(tempOfPattern.fileName()); } if ( patternFile.exists() == false || patternFile.remove() ) { if ( tempFile.copy(patternFile.fileName()) == false ) { qWarning()<setText(tr("File saved")); } } return result; } void MainWindow::AutoSavePattern() { if (curFile.isEmpty() == false && doc->isPatternModified() == true) { QString autofile = curFile +".autosave"; if (SavePattern(autofile) == false) { qWarning()<setPatternModified(false); setWindowModified(false); QString shownName = strippedName(curFile); if (curFile.isEmpty()) { shownName = tr("untitled.val"); } else { QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), QApplication::applicationName()); QStringList files = settings.value("recentFileList").toStringList(); files.removeAll(fileName); files.prepend(fileName); while (files.size() > MaxRecentFiles) { files.removeLast(); } settings.setValue("recentFileList", files); UpdateRecentFileActions(); } shownName+="[*]"; setWindowTitle(shownName); } QString MainWindow::strippedName(const QString &fullFileName) { return QFileInfo(fullFileName).fileName(); } void MainWindow::ReadSettings() { QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), QApplication::applicationName()); QPoint pos = settings.value("pos", QPoint(10, 10)).toPoint(); QSize size = settings.value("size", QSize(1000, 800)).toSize(); resize(size); move(pos); } void MainWindow::WriteSettings() { QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), QApplication::applicationName()); settings.setValue("pos", pos()); settings.setValue("size", size()); } bool MainWindow::MaybeSave() { if (doc->isPatternModified()) { QMessageBox::StandardButton ret; ret = QMessageBox::warning(this, tr("Unsaved change"), tr("The pattern has been modified.\n" "Do you want to save your changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); if (ret == QMessageBox::Save) return Save(); else if (ret == QMessageBox::Cancel) return false; } return true; } void MainWindow::UpdateRecentFileActions() { QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), QApplication::applicationName()); QStringList files = settings.value("recentFileList").toStringList(); int numRecentFiles = qMin(files.size(), static_cast(MaxRecentFiles)); for (int i = 0; i < numRecentFiles; ++i) { QString text = QString("&%1 %2").arg(i + 1).arg(strippedName(files[i])); recentFileActs[i]->setText(text); recentFileActs[i]->setData(files[i]); recentFileActs[i]->setVisible(true); } for (int j = numRecentFiles; j < MaxRecentFiles; ++j) { recentFileActs[j]->setVisible(false); } separatorAct->setVisible(numRecentFiles > 0); } void MainWindow::CreateMenus() { for (int i = 0; i < MaxRecentFiles; ++i) { ui->menuFile->insertAction(ui->actionExit, recentFileActs[i]); } separatorAct = new QAction(this); Q_CHECK_PTR(separatorAct); separatorAct->setSeparator(true); ui->menuFile->insertAction(ui->actionExit, separatorAct); UpdateRecentFileActions(); } void MainWindow::CreateActions() { ui->setupUi(this); static const char * GENERIC_ICON_TO_CHECK = "document-open"; if (QIcon::hasThemeIcon(GENERIC_ICON_TO_CHECK) == false) { //If there is no default working icon theme then we should //use an icon theme that we provide via a .qrc file //This case happens under Windows and Mac OS X //This does not happen under GNOME or KDE QIcon::setThemeName("win.icon.theme"); ui->actionNew->setIcon(QIcon::fromTheme("document-new")); ui->actionOpen->setIcon(QIcon::fromTheme("document-open")); ui->actionSave->setIcon(QIcon::fromTheme("document-save")); ui->actionSaveAs->setIcon(QIcon::fromTheme("document-save-as")); } connect(ui->actionArrowTool, &QAction::triggered, this, &MainWindow::ActionAroowTool); connect(ui->actionDraw, &QAction::triggered, this, &MainWindow::ActionDraw); connect(ui->actionDetails, &QAction::triggered, this, &MainWindow::ActionDetails); connect(ui->actionNewDraw, &QAction::triggered, this, &MainWindow::ActionNewDraw); connect(ui->actionOptionDraw, &QAction::triggered, this, &MainWindow::OptionDraw); connect(ui->actionSaveAs, &QAction::triggered, this, &MainWindow::SaveAs); connect(ui->actionSave, &QAction::triggered, this, &MainWindow::Save); connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::Open); connect(ui->actionNew, &QAction::triggered, this, &MainWindow::NewPattern); connect(ui->actionTable, &QAction::triggered, this, &MainWindow::ActionTable); connect(ui->actionAbout_Qt, &QAction::triggered, this, &MainWindow::AboutQt); connect(ui->actionAbout_Valentina, &QAction::triggered, this, &MainWindow::About); connect(ui->actionExit, &QAction::triggered, this, &MainWindow::close); connect(ui->actionOptions, &QAction::triggered, this, &MainWindow::Options); //Actions for recent files loaded by a main window application. for (int i = 0; i < MaxRecentFiles; ++i) { recentFileActs[i] = new QAction(this); Q_CHECK_PTR(recentFileActs[i]); recentFileActs[i]->setVisible(false); connect(recentFileActs[i], &QAction::triggered, this, &MainWindow::OpenRecentFile); } } void MainWindow::InitAutoSave() { //Autosaving file each 5 minutes delete autoSaveTimer; autoSaveTimer = 0; QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), QApplication::applicationName()); bool autoSave = settings.value("configuration/autosave/state", 1).toBool(); if (autoSave) { bool ok = true; qint32 autoTime = settings.value("configuration/autosave/time", 5).toInt(&ok); if (ok == false) { autoTime = 5; } autoSaveTimer = new QTimer(this); Q_CHECK_PTR(autoSaveTimer); autoSaveTimer->setTimerType(Qt::VeryCoarseTimer); connect(autoSaveTimer, &QTimer::timeout, this, &MainWindow::AutoSavePattern); autoSaveTimer->start(autoTime*60000); } } MainWindow::~MainWindow() { CancelTool(); delete ui; delete pattern; delete doc; delete sceneDetails; delete sceneDraw; } void MainWindow::LoadPattern(const QString &fileName) { QFile file(fileName); QString errorMsg; qint64 errorLine = 0; qint64 errorColumn = 0; if (file.open(QIODevice::ReadOnly)) { if (ValidatePattern("://schema/pattern.xsd", fileName, errorMsg, errorLine, errorColumn)) { qint32 errorLine = 0; qint32 errorColumn = 0; if (doc->setContent(&file, &errorMsg, &errorLine, &errorColumn)) { disconnect(comboBoxDraws, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::currentDrawChanged); try { #ifndef QT_NO_CURSOR QApplication::setOverrideCursor(Qt::WaitCursor); #endif doc->Parse(Document::FullParse, sceneDraw, sceneDetails); #ifndef QT_NO_CURSOR QApplication::restoreOverrideCursor(); #endif } catch (const VExceptionObjectError &e) { e.CriticalMessageBox(tr("Error parsing file."), this); file.close(); Clear(); return; } catch (const VExceptionConversionError &e) { e.CriticalMessageBox(tr("Error can't convert value."), this); file.close(); Clear(); return; } catch (const VExceptionEmptyParameter &e) { e.CriticalMessageBox(tr("Error empty parameter."), this); file.close(); Clear(); return; } catch (const VExceptionWrongParameterId &e) { e.CriticalMessageBox(tr("Error wrong id."), this); file.close(); Clear(); return; } catch (const VExceptionUniqueId &e) { e.CriticalMessageBox(tr("Error no unique id."), this); file.close(); Clear(); return; } connect(comboBoxDraws, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::currentDrawChanged); QString nameDraw = doc->GetNameActivDraw(); qint32 index = comboBoxDraws->findText(nameDraw); if ( index != -1 ) { // -1 for not found comboBoxDraws->setCurrentIndex(index); } if (comboBoxDraws->count() > 0) { SetEnableTool(true); } else { SetEnableTool(false); } SetEnableWidgets(true); } else { QMessageBox msgBox(this); msgBox.setWindowTitle(tr("Error!")); msgBox.setText(tr("Parsing pattern file error.")); msgBox.setInformativeText(errorMsg); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); QString error = QString(tr("Error in line %1 column %2")).arg(errorLine).arg(errorColumn); msgBox.setDetailedText(error); msgBox.exec(); file.close(); Clear(); return; } } else { QMessageBox msgBox(this); msgBox.setWindowTitle(tr("Error!")); msgBox.setText(tr("Validation file error.")); msgBox.setInformativeText(errorMsg); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); QString error = QString(tr("Error in line %1 column %2")).arg(errorLine).arg(errorColumn); msgBox.setDetailedText(error); msgBox.exec(); file.close(); Clear(); return; } file.close(); } else { QMessageBox::warning(this, tr("Valentina"), tr("Cannot read file %1:\n%2.") .arg(fileName) .arg(file.errorString())); } setCurrentFile(fileName); helpLabel->setText(tr("File loaded")); }