Files
create/src/Mod/TechDraw/Gui/TaskSurfaceFinishSymbols.cpp
2024-09-03 17:27:00 +02:00

477 lines
17 KiB
C++

/***************************************************************************
* Copyright (c) 2022 edi *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <boost/algorithm/string/predicate.hpp>
# include <QComboBox>
# include <QGraphicsProxyWidget>
# include <QLineEdit>
#endif
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/Command.h>
#include <Gui/Document.h>
#include <Mod/TechDraw/App/DrawPage.h>
#include <Mod/TechDraw/App/DrawUtil.h>
#include <Mod/TechDraw/App/DrawViewSymbol.h>
#include "QGIView.h"
#include "ui_TaskSurfaceFinishSymbols.h"
#include "TaskSurfaceFinishSymbols.h"
#include "ViewProviderSymbol.h"
#include "ZVALUE.h"
using namespace Gui;
using namespace TechDraw;
using namespace TechDrawGui;
SvgString::SvgString(int width, int height)
{
svgStream << "<?xml version='1.0'?>\n";
svgStream << "<svg width='" << width << "' height='" << height << "'>\n";
}
void SvgString::addLine(int xStart, int yStart, int xEnd, int yEnd)
{
svgStream << "<path stroke='#000' stroke-width='1' d='";
svgStream << " M" << xStart << ", " << yStart; // startpoint
svgStream << " L" << xEnd << ", " << yEnd; // endpoint
svgStream << "' />\n";
}
void SvgString::addCircle(int xCenter, int yCenter, int radius)
{
svgStream << "<circle cx='" << xCenter <<"' cy='" << yCenter;
svgStream << "' r='" << radius;
svgStream << "' fill='none' stroke='#000' stroke-width='1'/>\n";
}
void SvgString::addText(int xText, int yText, std::string text)
{
svgStream << "<text x='" << xText << "' y='" << yText;
svgStream << "' style='font-size:18px'>" << text << "</text>\n";
}
std::string SvgString::finish()
{
svgStream << "</svg>\n";
return svgStream.str();
}
//===========================================================================
// TaskSurfaceFinishSymbols
//===========================================================================
TaskSurfaceFinishSymbols::TaskSurfaceFinishSymbols(const std::string &ownerName) :
currentIcon(nullptr),
ui(new Ui_TaskSurfaceFinishSymbols)
{
App::Document *doc = App::GetApplication().getActiveDocument();
if (doc) {
owner = doc->getObject(ownerName.c_str());
std::string subName;
if (!owner) {
size_t dot = ownerName.rfind('.');
if (dot != std::string::npos) {
subName = ownerName.substr(dot + 1);
owner = doc->getObject(ownerName.substr(0, dot).c_str());
}
}
auto page = dynamic_cast<TechDraw::DrawPage *>(owner);
if (page) {
placement.x = page->getPageWidth()/2.0;
placement.y = page->getPageHeight()/2.0;
}
auto viewPart = dynamic_cast<TechDraw::DrawViewPart *>(owner);
if (viewPart && !subName.empty()) {
std::string subType = DrawUtil::getGeomTypeFromName(subName);
if (subType == "Vertex") {
TechDraw::VertexPtr vertex = viewPart->getVertex(subName);
if (vertex) {
placement = vertex->point();
}
}
else if (subType == "Edge") {
TechDraw::BaseGeomPtr edge = viewPart->getEdge(subName);
if (edge) {
placement = edge->getMidPoint();
}
}
else if (subType == "Face") {
TechDraw::FacePtr face = viewPart->getFace(subName);
if (face) {
placement = face->getCenter();
}
}
placement = DrawUtil::invertY(placement);
}
}
raValues = {"Ra50", "Ra25", "Ra12, 5", "Ra6, 3",
"Ra3, 2", "Ra1, 6", "Ra0, 8", "Ra0, 4",
"Ra0, 2", "Ra0, 1", "Ra0, 05", "Ra0, 025"};
laySymbols = {"", "=", "", "X", "M", "C", "R"};
roughGrades = {"", "N1", "N2", "N3", "N4", "N5",
"N6", "N7", "N8", "N9", "N10", "N11"};
ui->setupUi(this);
setUiEdit();
}
QColor TaskSurfaceFinishSymbols::getPenColor()
{
// TODO: should be dependent on global API giving pen color - not from hacking stylesheet name
const std::string stylesheetName = App::GetApplication().GetParameterGroupByPath
("User parameter:BaseApp/Preferences/MainWindow")->GetASCII("StyleSheet");
if(boost::icontains(stylesheetName, "dark")) {
return Qt::white;
}
return Qt::black;
}
QPixmap TaskSurfaceFinishSymbols::baseSymbol(symbolType type)
// return QPixmap showing a base symbol
{
QImage img (50, 64, QImage::Format_ARGB32_Premultiplied);
img.fill(Qt::transparent);
// TODO: color should depend on theme/background
QPainter painter;
painter.begin(&img);
painter.setPen(QPen(getPenColor(), 2, Qt::SolidLine,
Qt::RoundCap, Qt::RoundJoin));
painter.setRenderHints(QPainter::Antialiasing |
QPainter::SmoothPixmapTransform |
QPainter::TextAntialiasing);
painter.drawLine(QLine(0, 40, 12, 60));
painter.drawLine(QLine(12, 60, 42, 10));
if (type == removeProhibit || type == removeProhibitAll)
painter.drawEllipse(QPoint(12, 42), 9,9);
if (type == removeRequired || type == removeRequiredAll)
painter.drawLine(QLine(0, 40, 24, 40));
if (type > removeRequired)
painter.drawEllipse(QPoint(42, 10), 6,6);
painter.end();
return QPixmap::fromImage(img);
}
std::string TaskSurfaceFinishSymbols::completeSymbol()
// return string showing the complete symbol
{
SvgString symbol(150, 64);
symbol.addLine(0, 44, 12, 64);
symbol.addLine(12, 64, 42, 14);
int moveLeft(0), maxTextLength(0);
if (activeIcon == removeProhibit || activeIcon == removeProhibitAll)
symbol.addCircle(12, 46, 9);
if (activeIcon == removeRequired || activeIcon == removeRequiredAll)
symbol.addLine(0, 44, 24, 44);
if (activeIcon > removeRequired)
{
symbol.addCircle(42, 14, 6);
moveLeft = 5 ;
}
std::string methodText = leMethod->text().toStdString();
symbol.addText(42+moveLeft, 11, methodText);
int methodTextLength = methodText.length();
if (isISO)
{
std::string raText = cbRA->itemText(cbRA->currentIndex()).toStdString();
symbol.addText(42+moveLeft, 30, raText);
int raTextLength = raText.length();
maxTextLength = std::max(methodTextLength, raTextLength)*9.25+moveLeft;
}
else
{
std::string sampleText = leSamLength->text().toStdString();
symbol.addText(42+moveLeft, 30, sampleText);
int sampleTextLength = sampleText.length();
maxTextLength = std::max(methodTextLength, sampleTextLength)*9.25+moveLeft;
std::string minRoughtText = cbMinRought->itemText(cbMinRought->currentIndex()).toStdString();
symbol.addText(-10, 35, minRoughtText);
std::string maxRoughtText = cbMaxRought->itemText(cbMaxRought->currentIndex()).toStdString();
symbol.addText(-10, 20, maxRoughtText);
}
symbol.addLine(42, 14, 42+maxTextLength, 14);
symbol.addText(20, 60, cbLay->itemText(cbLay->currentIndex()).toStdString());
symbol.addText(-25, 60, leAddition->text().toStdString());
std::string symbolAsString = symbol.finish();
return symbolAsString;
}
void TaskSurfaceFinishSymbols::updateTask()
{
// blockUpdate = true;
// blockUpdate = false;
}
void TaskSurfaceFinishSymbols::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
}
}
void TaskSurfaceFinishSymbols::setUiEdit()
// arrange widget at tool start
{
setWindowTitle(tr("Surface Finish Symbols"));
// create icon pixmaps of QPushButtons
ui->pbIcon01->setIcon(baseSymbol(anyMethod));
ui->pbIcon02->setIcon(baseSymbol(removeProhibit));
ui->pbIcon03->setIcon(baseSymbol(removeRequired));
ui->pbIcon04->setIcon(baseSymbol(anyMethodAll));
ui->pbIcon05->setIcon(baseSymbol(removeProhibitAll));
ui->pbIcon06->setIcon(baseSymbol(removeRequiredAll));
int w = ui->pbIcon01->width();
int h = ui->pbIcon01->height();
ui->pbIcon01->setIconSize(QSize(w, h));
ui->pbIcon02->setIconSize(QSize(w, h));
ui->pbIcon03->setIconSize(QSize(w, h));
ui->pbIcon04->setIconSize(QSize(w, h));
ui->pbIcon05->setIconSize(QSize(w, h));
ui->pbIcon06->setIconSize(QSize(w, h));
activeIcon = anyMethod ;
isISO = true;
// Create scene and all items used in the scene
symbolScene = new(QGraphicsScene);
// symbolScene->setBackgroundBrush(Qt::blue);
ui->graphicsView->setBackgroundBrush(Qt::NoBrush);
ui->graphicsView->setScene(symbolScene);
// QLineEdit showing method
leMethod = new(QLineEdit);
leMethod->resize(90, 20);
leMethod->setToolTip(QObject::tr("Method"));
QGraphicsProxyWidget* proxyMethod = symbolScene->addWidget(leMethod);
proxyMethod->setPos(2, -142);
// QLineEdit showing addition
leAddition = new(QLineEdit);
leAddition->resize(25, 20);
leAddition->setToolTip(QObject::tr("Addition"));
QGraphicsProxyWidget* proxyAddition = symbolScene->addWidget(leAddition);
proxyAddition->setPos(-110, -85);
proxyAddition->setZValue(-2);
// QComboBox showing RA values
cbRA = new(QComboBox);
cbRA->resize(90, 20);
for (const std::string& nextValue : raValues)
cbRA->addItem(QString::fromStdString(nextValue));
cbRA->setToolTip(QObject::tr("Average roughness"));
proxyRA = symbolScene->addWidget(cbRA);
proxyRA->setPos(2, -113);
// QLineEdit showing sampling length value
leSamLength = new(QLineEdit);
leSamLength->resize(90, 20);
leSamLength->setToolTip(QObject::tr("Roughness sampling length"));
proxySamLength = symbolScene->addWidget(leSamLength);
proxySamLength->setPos(2, -113);
proxySamLength->hide();
// QComboBox showing lay symbol
cbLay = new(QComboBox);
cbLay->resize(40, 20);
for (const std::string& nextLay : laySymbols)
cbLay->addItem(QString::fromStdString(nextLay));
cbLay->setToolTip(QObject::tr("Lay symbol"));
QGraphicsProxyWidget* proxyLay = symbolScene->addWidget(cbLay);
proxyLay->setPos(-23, -85);
// QComboBox showing minimal roughness grade
cbMinRought = new(QComboBox);
cbMinRought->resize(55, 20);
for (const std::string& nextGrade : roughGrades)
cbMinRought->addItem(QString::fromStdString(nextGrade));
cbMinRought->setToolTip(QObject::tr("Minimum roughness grade number"));
proxyMinRough = symbolScene->addWidget(cbMinRought);
proxyMinRough->setPos(-100, -118);
proxyMinRough-> setZValue(1);
proxyMinRough->hide();
// QComboBox showing maximal roughness grade
cbMaxRought = new(QComboBox);
cbMaxRought->resize(55, 20);
for (const std::string& nextGrade : roughGrades)
cbMaxRought->addItem(QString::fromStdString(nextGrade));
cbMaxRought->setToolTip(QObject::tr("Maximum roughness grade number"));
proxyMaxRough = symbolScene->addWidget(cbMaxRought);
proxyMaxRough->setPos(-100, -143);
proxyMaxRough->setZValue(1);
proxyMaxRough->hide();
// add horizontal line
symbolScene->addLine(QLine(-8, -116, 90, -116),
QPen(getPenColor(), 2,Qt::SolidLine,
Qt::RoundCap, Qt::RoundJoin));
connect(ui->pbIcon01, &QPushButton::clicked, this, &TaskSurfaceFinishSymbols::onIconChanged);
connect(ui->pbIcon02, &QPushButton::clicked, this, &TaskSurfaceFinishSymbols::onIconChanged);
connect(ui->pbIcon03, &QPushButton::clicked, this, &TaskSurfaceFinishSymbols::onIconChanged);
connect(ui->pbIcon04, &QPushButton::clicked, this, &TaskSurfaceFinishSymbols::onIconChanged);
connect(ui->pbIcon05, &QPushButton::clicked, this, &TaskSurfaceFinishSymbols::onIconChanged);
connect(ui->pbIcon06, &QPushButton::clicked, this, &TaskSurfaceFinishSymbols::onIconChanged);
connect(ui->rbISO, &QPushButton::clicked, this, &TaskSurfaceFinishSymbols::onISO);
connect(ui->rbASME, &QPushButton::clicked, this, &TaskSurfaceFinishSymbols::onASME);
// set initial icon
ui->pbIcon01->click();
}
void TaskSurfaceFinishSymbols::onIconChanged()
// Slot: change icon of surface finish symbol
{
QObject* senderObj(this->sender());
QPushButton* pressedButton = qobject_cast<QPushButton*>(senderObj);
if (!pressedButton) {
return;
}
if (ui->pbIcon01 == pressedButton) activeIcon = anyMethod;
if (ui->pbIcon02 == pressedButton) activeIcon = removeProhibit;
if (ui->pbIcon03 == pressedButton) activeIcon = removeRequired;
if (ui->pbIcon04 == pressedButton) activeIcon = anyMethodAll;
if (ui->pbIcon05 == pressedButton) activeIcon = removeProhibitAll;
if (ui->pbIcon06 == pressedButton) activeIcon = removeRequiredAll;
QIcon symbolIcon = pressedButton->icon();
if(currentIcon) {
symbolScene->removeItem(currentIcon);
}
currentIcon = new(QGraphicsPixmapItem);
currentIcon->setPixmap(symbolIcon.pixmap(50, 64));
currentIcon->setPos(-50, -126);
currentIcon->setZValue(-1);
symbolScene->addItem(currentIcon);
}
void TaskSurfaceFinishSymbols::onISO()
// Slot: show ISO template in scene
{
isISO = true;
proxySamLength->hide();
proxyMinRough->hide();
proxyMaxRough->hide();
proxyRA->show();
}
void TaskSurfaceFinishSymbols::onASME()
// Slot: show ASME template in scene
{
isISO = false;
proxySamLength->show();
proxyMinRough->show();
proxyMaxRough->show();
proxyRA->hide();
}
bool TaskSurfaceFinishSymbols::accept()
// Slot: dialog finished using OK
{
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Surface Finish Symbols"));
App::Document *doc = Application::Instance->activeDocument()->getDocument();
App::DocumentObject *docObject = doc->addObject("TechDraw::DrawViewSymbol", "SurfaceSymbol");
TechDraw::DrawViewSymbol *surfaceSymbol = dynamic_cast<TechDraw::DrawViewSymbol*>(docObject);
surfaceSymbol->Symbol.setValue(completeSymbol());
surfaceSymbol->Rotation.setValue(ui->leAngle->text().toDouble());
auto view = dynamic_cast<TechDraw::DrawView *>(owner);
surfaceSymbol->Owner.setValue(view);
surfaceSymbol->X.setValue(placement.x);
surfaceSymbol->Y.setValue(placement.y);
auto viewProvider = dynamic_cast<ViewProviderSymbol *>(QGIView::getViewProvider(surfaceSymbol));
if (viewProvider) {
viewProvider->StackOrder.setValue(ZVALUE::DIMENSION);
}
auto page = dynamic_cast<TechDraw::DrawPage *>(owner);
if (!page && view) {
page = view->findParentPage();
}
if (page) {
page->addView(surfaceSymbol);
}
Gui::Command::commitCommand();
return true;
}
bool TaskSurfaceFinishSymbols::reject()
{
return true;
}
//===========================================================================
// TaskDlgSurfaceFinishSymbols//
//===========================================================================
TaskDlgSurfaceFinishSymbols::TaskDlgSurfaceFinishSymbols(const std::string &ownerName)
: TaskDialog()
{
widget = new TaskSurfaceFinishSymbols(ownerName);
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("actions/TechDraw_SurfaceFinishSymbols"),
widget->windowTitle(), true, nullptr);
taskbox->groupLayout()->addWidget(widget);
Content.push_back(taskbox);
}
TaskDlgSurfaceFinishSymbols::~TaskDlgSurfaceFinishSymbols()
{
}
void TaskDlgSurfaceFinishSymbols::update()
{
// widget->updateTask();
}
//==== calls from the TaskView ===============================================================
void TaskDlgSurfaceFinishSymbols::open()
{
}
void TaskDlgSurfaceFinishSymbols::clicked(int)
{
}
bool TaskDlgSurfaceFinishSymbols::accept()
{
widget->accept();
return true;
}
bool TaskDlgSurfaceFinishSymbols::reject()
{
widget->reject();
return true;
}
#include <Mod/TechDraw/Gui/moc_TaskSurfaceFinishSymbols.cpp>