1
/***************************************************************************
2
* Copyright (c) 2014 Joe Dowsett <dowsettjoe[at]yahoo[dot]co[dot]uk> *
3
* Copyright (c) 2014 Luke Parry <l.parry@warwick.ac.uk> *
5
* This file is part of the FreeCAD CAx development system. *
7
* This library is free software; you can redistribute it and/or *
8
* modify it under the terms of the GNU Library General Public *
9
* License as published by the Free Software Foundation; either *
10
* version 2 of the License, or (at your option) any later version. *
12
* This library is distributed in the hope that it will be useful, *
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
* GNU Library General Public License for more details. *
17
* You should have received a copy of the GNU Library General Public *
18
* License along with this library; see the file COPYING.LIB. If not, *
19
* write to the Free Software Foundation, Inc., 59 Temple Place, *
20
* Suite 330, Boston, MA 02111-1307, USA *
22
***************************************************************************/
24
#include "PreCompiled.h"
27
# include <QMessageBox>
28
#endif // #ifndef _PreComp_
30
#include <Base/Console.h>
31
#include <Base/Tools.h>
32
#include <Gui/Application.h>
33
#include <Gui/BitmapFactory.h>
34
#include <Gui/Command.h>
35
#include <Gui/Document.h>
36
#include <Gui/WaitCursor.h>
38
#include <Mod/TechDraw/App/DrawPage.h>
39
#include <Mod/TechDraw/App/DrawProjGroupItem.h>
40
#include <Mod/TechDraw/App/DrawProjGroup.h>
41
#include <Mod/TechDraw/App/DrawUtil.h>
43
#include "TaskProjGroup.h"
44
#include "ui_TaskProjGroup.h"
45
#include "MDIViewPage.h"
46
#include "ViewProviderPage.h"
47
#include "ViewProviderProjGroup.h"
51
using namespace TechDraw;
52
using namespace TechDrawGui;
54
TaskProjGroup::TaskProjGroup(TechDraw::DrawProjGroup* featView, bool mode) :
55
ui(new Ui_TaskProjGroup),
63
ui->projection->setCurrentIndex(multiView->ProjectionType.getValue());
65
setFractionalScale(multiView->getScale());
66
ui->cmbScaleType->setCurrentIndex(multiView->ScaleType.getValue());
68
//Allow or prevent scale changing initially
69
if (multiView->ScaleType.isValue("Custom")) {
70
ui->sbScaleNum->setEnabled(true);
71
ui->sbScaleDen->setEnabled(true);
74
ui->sbScaleNum->setEnabled(false);
75
ui->sbScaleDen->setEnabled(false);
78
ui->cbAutoDistribute->setChecked(multiView->AutoDistribute.getValue());
79
// disable if no AutoDistribute
80
ui->sbXSpacing->setEnabled(multiView->AutoDistribute.getValue());
81
ui->sbYSpacing->setEnabled(multiView->AutoDistribute.getValue());
82
ui->sbXSpacing->setValue(multiView->spacingX.getValue());
83
ui->sbYSpacing->setValue(multiView->spacingY.getValue());
85
// Initially toggle view checkboxes if needed
86
setupViewCheckboxes(true);
91
// Note we don't do the custom one here, as it is handled by [a different function that's held up in customs]
92
connect(ui->butTopRotate, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked);
93
connect(ui->butCWRotate, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked);
94
connect(ui->butRightRotate, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked);
95
connect(ui->butDownRotate, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked);
96
connect(ui->butLeftRotate, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked);
97
connect(ui->butCCWRotate, &QPushButton::clicked, this, &TaskProjGroup::rotateButtonClicked);
100
// connect(ui->butReset, SIGNAL(clicked()), this, SLOT(onResetClicked()));
102
// Slot for Scale Type
103
connect(ui->cmbScaleType, qOverload<int>(&QComboBox::currentIndexChanged), this, &TaskProjGroup::scaleTypeChanged);
104
connect(ui->sbScaleNum, qOverload<int>(&QSpinBox::valueChanged), this, &TaskProjGroup::scaleManuallyChanged);
105
connect(ui->sbScaleDen, qOverload<int>(&QSpinBox::valueChanged), this, &TaskProjGroup::scaleManuallyChanged);
107
// Slot for Projection Type (layout)
108
#if QT_VERSION < QT_VERSION_CHECK(5,15,0)
109
connect(ui->projection, qOverload<const QString&>(&QComboBox::currentIndexChanged), this, &TaskProjGroup::projectionTypeChanged);
111
connect(ui->projection, qOverload<int>(&QComboBox::currentIndexChanged), this, [=](int index) {
112
projectionTypeChanged(ui->projection->itemText(index));
117
connect(ui->cbAutoDistribute, &QPushButton::clicked, this, &TaskProjGroup::AutoDistributeClicked);
118
connect(ui->sbXSpacing, qOverload<double>(&QuantitySpinBox::valueChanged), this, &TaskProjGroup::spacingChanged);
119
connect(ui->sbYSpacing, qOverload<double>(&QuantitySpinBox::valueChanged), this, &TaskProjGroup::spacingChanged);
120
ui->sbXSpacing->setUnit(Base::Unit::Length);
121
ui->sbYSpacing->setUnit(Base::Unit::Length);
123
m_page = multiView->findParentPage();
124
Gui::Document* activeGui = Gui::Application::Instance->getDocument(m_page->getDocument());
125
Gui::ViewProvider* vp = activeGui->getViewProvider(m_page);
126
ViewProviderPage* dvp = static_cast<ViewProviderPage*>(vp);
127
m_mdi = dvp->getMDIViewPage();
133
void TaskProjGroup::saveGroupState()
135
// Base::Console().Message("TPG::saveGroupState()\n");
139
m_saveSource = multiView->Source.getValues();
140
m_saveProjType = multiView->ProjectionType.getValueAsString();
141
m_saveScaleType = multiView->ScaleType.getValueAsString();
142
m_saveScale = multiView->Scale.getValue();
143
m_saveAutoDistribute = multiView->AutoDistribute.getValue();
144
m_saveSpacingX = multiView->spacingX.getValue();
145
m_saveSpacingY = multiView->spacingY.getValue();
146
DrawProjGroupItem* anchor = multiView->getAnchor();
147
m_saveDirection = anchor->Direction.getValue();
149
for( const auto it : multiView->Views.getValues() ) {
150
auto view( dynamic_cast<DrawProjGroupItem *>(it) );
152
m_saveViewNames.emplace_back(view->Type.getValueAsString());
158
void TaskProjGroup::restoreGroupState()
160
Base::Console().Message("TPG::restoreGroupState()\n");
164
multiView->ProjectionType.setValue(m_saveProjType.c_str());
165
multiView->ScaleType.setValue(m_saveScaleType.c_str());
166
multiView->Scale.setValue(m_saveScale);
167
multiView->AutoDistribute.setValue(m_saveAutoDistribute);
168
multiView->spacingX.setValue(m_saveSpacingX);
169
multiView->spacingY.setValue(m_saveSpacingY);
170
multiView->purgeProjections();
171
for(auto & sv : m_saveViewNames) {
173
multiView->addProjection(sv.c_str());
178
void TaskProjGroup::viewToggled(bool toggle)
181
bool changed = false;
182
// Obtain name of checkbox
183
QString viewName = sender()->objectName();
184
int index = viewName.mid(7).toInt();
185
const char *viewNameCStr = viewChkIndexToCStr(index);
186
if ( toggle && !multiView->hasProjection( viewNameCStr ) ) {
187
Gui::Command::doCommand(Gui::Command::Doc,
188
"App.activeDocument().%s.addProjection('%s')",
189
multiView->getNameInDocument(), viewNameCStr);
191
} else if ( !toggle && multiView->hasProjection( viewNameCStr ) ) {
192
if (multiView->canDelete(viewNameCStr)) {
193
multiView->removeProjection( viewNameCStr );
198
if (multiView->ScaleType.isValue("Automatic")) {
199
double scale = multiView->getScale();
200
setFractionalScale(scale);
202
multiView->recomputeFeature();
207
void TaskProjGroup::rotateButtonClicked()
209
if ( multiView && ui ) {
210
const QObject *clicked = sender();
212
//change Front View Dir by 90
213
if ( clicked == ui->butTopRotate ) multiView->rotate("Up");
214
else if (clicked == ui->butDownRotate) multiView->rotate("Down");
215
else if (clicked == ui->butRightRotate) multiView->rotate("Right");
216
else if (clicked == ui->butLeftRotate) multiView->rotate("Left");
217
else if (clicked == ui->butCWRotate ) multiView->spin("CW");
218
else if (clicked == ui->butCCWRotate) multiView->spin("CCW");
224
//void TaskProjGroup::projectionTypeChanged(int index)
225
void TaskProjGroup::projectionTypeChanged(QString qText)
231
if (qText == QString::fromUtf8("Page")) {
232
multiView->ProjectionType.setValue("Default");
234
std::string text = qText.toStdString();
235
multiView->ProjectionType.setValue(text.c_str());
238
// Update checkboxes so checked state matches the drawing
239
setupViewCheckboxes();
241
// set the tooltips of the checkboxes
242
ui->chkView0->setToolTip(getToolTipForBox(0));
243
ui->chkView1->setToolTip(getToolTipForBox(1));
244
ui->chkView2->setToolTip(getToolTipForBox(2));
245
ui->chkView3->setToolTip(getToolTipForBox(3));
246
ui->chkView4->setToolTip(getToolTipForBox(4));
247
ui->chkView5->setToolTip(getToolTipForBox(5));
248
ui->chkView6->setToolTip(getToolTipForBox(6));
249
ui->chkView7->setToolTip(getToolTipForBox(7));
250
ui->chkView8->setToolTip(getToolTipForBox(8));
251
ui->chkView9->setToolTip(getToolTipForBox(9));
253
multiView->recomputeFeature();
256
void TaskProjGroup::scaleTypeChanged(int index)
261
//defaults to prevent scale changing
262
ui->sbScaleNum->setEnabled(false);
263
ui->sbScaleDen->setEnabled(false);
266
// Document Scale Type
267
multiView->ScaleType.setValue("Page");
268
} else if (index == 1) {
269
// Automatic Scale Type
271
multiView->ScaleType.setValue("Automatic");
272
double autoScale = multiView->autoScale();
273
multiView->Scale.setValue(autoScale);
276
} else if (index == 2) {
279
multiView->ScaleType.setValue("Custom");
280
ui->sbScaleNum->setEnabled(true);
281
ui->sbScaleDen->setEnabled(true);
283
int a = ui->sbScaleNum->value();
284
int b = ui->sbScaleDen->value();
285
double scale = (double) a / (double) b;
286
multiView->Scale.setValue(scale);
291
void TaskProjGroup::AutoDistributeClicked(bool clicked)
296
multiView->AutoDistribute.setValue(clicked);
297
multiView->recomputeFeature();
300
void TaskProjGroup::spacingChanged()
305
multiView->spacingX.setValue(ui->sbXSpacing->value().getValue());
306
multiView->spacingY.setValue(ui->sbYSpacing->value().getValue());
307
multiView->recomputeFeature();
310
void TaskProjGroup::updateTask()
312
// Update the scale type
314
ui->cmbScaleType->setCurrentIndex(multiView->ScaleType.getValue());
316
// Update the scale value
317
setFractionalScale(multiView->getScale());
323
void TaskProjGroup::setFractionalScale(double newScale)
327
std::pair<int, int> fraction = DrawUtil::nearestFraction(newScale);
329
ui->sbScaleNum->setValue(fraction.first);
330
ui->sbScaleDen->setValue(fraction.second);
334
void TaskProjGroup::scaleManuallyChanged(int unused)
339
if (!multiView->ScaleType.isValue("Custom")) { //ignore if not custom!
343
int a = ui->sbScaleNum->value();
344
int b = ui->sbScaleDen->value();
346
double scale = (double) a / (double) b;
348
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.Scale = %f", multiView->getNameInDocument()
350
multiView->recomputeFeature();
353
void TaskProjGroup::changeEvent(QEvent *event)
355
if (event->type() == QEvent::LanguageChange) {
356
ui->retranslateUi(this);
360
const char * TaskProjGroup::viewChkIndexToCStr(int index)
362
// Third Angle: FTL T FTRight
366
// First Angle: FBRight B FBL
371
bool thirdAngle = multiView->usedProjectionType().isValue("Third Angle");
373
case 0: return (thirdAngle ? "FrontTopLeft" : "FrontBottomRight");
374
case 1: return (thirdAngle ? "Top" : "Bottom");
375
case 2: return (thirdAngle ? "FrontTopRight" : "FrontBottomLeft");
376
case 3: return (thirdAngle ? "Left" : "Right");
377
case 4: return (thirdAngle ? "Front" : "Front");
378
case 5: return (thirdAngle ? "Right" : "Left");
379
case 6: return (thirdAngle ? "Rear" : "Rear");
380
case 7: return (thirdAngle ? "FrontBottomLeft" : "FrontTopRight");
381
case 8: return (thirdAngle ? "Bottom" : "Top");
382
case 9: return (thirdAngle ? "FrontBottomRight" : "FrontTopLeft");
383
default: return nullptr;
387
QString TaskProjGroup::getToolTipForBox(int boxNumber)
389
bool thirdAngle = multiView->usedProjectionType().isValue("Third Angle");
391
case 0: {return (thirdAngle ? tr("FrontTopLeft") : tr("FrontBottomRight")); break;}
392
case 1: {return (thirdAngle ? tr("Top") : tr("Bottom")); break;}
393
case 2: {return (thirdAngle ? tr("FrontTopRight") : tr("FrontBottomLeft")); break;}
394
case 3: {return (thirdAngle ? tr("Left" ): tr("Right")); break;}
395
case 4: {return (thirdAngle ? tr("Front") : tr("Front")); break;}
396
case 5: {return (thirdAngle ? tr("Right") : tr("Left")); break;}
397
case 6: {return (thirdAngle ? tr("Rear") : tr("Rear")); break;}
398
case 7: {return (thirdAngle ? tr("FrontBottomLeft") : tr("FrontTopRight")); break;}
399
case 8: {return (thirdAngle ? tr("Bottom") : tr("Top")); break;}
400
case 9: {return (thirdAngle ? tr("FrontBottomRight") : tr("FrontTopLeft")); break;}
401
default: {return {}; break;}
405
void TaskProjGroup::setupViewCheckboxes(bool addConnections)
410
// There must be a better way to construct this list...
411
QCheckBox * viewCheckboxes[] = { ui->chkView0,
423
for (int i = 0; i < 10; ++i) {
424
QCheckBox *box = viewCheckboxes[i];
425
if (addConnections) {
426
connect(box, &QCheckBox::toggled, this, &TaskProjGroup::viewToggled);
429
const char *viewStr = viewChkIndexToCStr(i);
430
if (viewStr && multiView->hasProjection(viewStr)) {
431
box->setCheckState(Qt::Checked);
432
if (!multiView->canDelete(viewStr)) {
433
box->setEnabled(false);
436
box->setCheckState(Qt::Unchecked);
438
box->setToolTip(getToolTipForBox(i));
442
void TaskProjGroup::setUiPrimary()
444
Base::Vector3d frontDir = multiView->getAnchorDirection();
445
ui->lePrimary->setText(formatVector(frontDir));
448
QString TaskProjGroup::formatVector(Base::Vector3d vec)
450
QString data = QString::fromLatin1("[%1 %2 %3]")
451
.arg(QLocale().toString(vec.x, 'f', 2),
452
QLocale().toString(vec.y, 'f', 2),
453
QLocale().toString(vec.z, 'f', 2));
457
void TaskProjGroup::saveButtons(QPushButton* btnOK,
458
QPushButton* btnCancel,
459
QPushButton* btnApply)
462
m_btnCancel = btnCancel;
463
m_btnApply = btnApply;
467
bool TaskProjGroup::apply()
469
// Base::Console().Message("TPG::apply()\n");
470
multiView->recomputeChildren();
471
multiView->recomputeFeature();
476
bool TaskProjGroup::accept()
478
// Base::Console().Message("TPG::accept()\n");
479
Gui::Document* doc = Gui::Application::Instance->getDocument(multiView->getDocument());
483
multiView->recomputeChildren();
484
multiView->recomputeFeature();
486
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
491
bool TaskProjGroup::reject()
493
Gui::Document* doc = Gui::Application::Instance->getDocument(multiView->getDocument());
497
if (getCreateMode()) {
498
//remove the object completely from the document
499
std::string multiViewName = multiView->getNameInDocument();
500
std::string PageName = multiView->findParentPage()->getNameInDocument();
502
Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().%s.purgeProjections()",
503
multiViewName.c_str());
504
Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().%s.removeView(App.activeDocument().%s)",
505
PageName.c_str(), multiViewName.c_str());
506
Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().removeObject('%s')", multiViewName.c_str());
507
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
509
//set the DPG and its views back to entry state.
510
if (Gui::Command::hasPendingCommand()) {
511
Gui::Command::abortCommand();
512
// std::vector<std::string> undos = Gui::Application::Instance->activeDocument()->getUndoVector();
513
// Gui::Application::Instance->activeDocument()->undo(1);
514
// multiView->rebuildViewList();
518
Gui::Command::runCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
522
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
523
//TODO: Do we really need to hang on to the TaskDlgProjGroup in this class? IR
524
TaskDlgProjGroup::TaskDlgProjGroup(TechDraw::DrawProjGroup* featView, bool mode)
526
, viewProvider(nullptr)
527
, multiView(featView)
529
//viewProvider = dynamic_cast<const ViewProviderProjGroup *>(featView);
530
widget = new TaskProjGroup(featView, mode);
531
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("actions/TechDraw_ProjectionGroup"),
532
widget->windowTitle(), true, nullptr);
533
taskbox->groupLayout()->addWidget(widget);
534
Content.push_back(taskbox);
537
TaskDlgProjGroup::~TaskDlgProjGroup()
541
void TaskDlgProjGroup::update()
543
widget->updateTask();
546
void TaskDlgProjGroup::setCreateMode(bool mode)
548
widget->setCreateMode(mode);
551
void TaskDlgProjGroup::modifyStandardButtons(QDialogButtonBox* box)
553
QPushButton* btnOK = box->button(QDialogButtonBox::Ok);
554
QPushButton* btnCancel = box->button(QDialogButtonBox::Cancel);
555
QPushButton* btnApply = box->button(QDialogButtonBox::Apply);
556
widget->saveButtons(btnOK, btnCancel, btnApply);
559
//==== calls from the TaskView ===============================================================
560
void TaskDlgProjGroup::open()
562
if (!widget->getCreateMode()) { //this is an edit session, start a transaction
563
App::GetApplication().setActiveTransaction("Edit Projection Group", true);
567
void TaskDlgProjGroup::clicked(int i)
570
// Base::Console().Message("TDPG::clicked(%X)\n", i);
571
if (i == QMessageBox::Apply) {
576
bool TaskDlgProjGroup::accept()
582
bool TaskDlgProjGroup::reject()
589
#include <Mod/TechDraw/Gui/moc_TaskProjGroup.cpp>