FreeCAD

Форк
0
/
ViewProviderViewPart.cpp 
467 строк · 18.6 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2014 Luke Parry <l.parry@warwick.ac.uk>                 *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24

25
#ifndef _PreComp_
26
#include <QMessageBox>
27
#include <QTextStream>
28
# ifdef FC_OS_WIN32
29
#  include <windows.h>
30
# endif
31
#endif
32

33
#include <App/Application.h>
34
#include <App/Document.h>
35
#include <App/DocumentObject.h>
36
#include <Base/Parameter.h>
37
#include <Gui/Control.h>
38
#include <Gui/MainWindow.h>
39
#include <Gui/Selection.h>
40

41
#include <Mod/TechDraw/App/DrawGeomHatch.h>
42
#include <Mod/TechDraw/App/DrawHatch.h>
43
#include <Mod/TechDraw/App/DrawLeaderLine.h>
44
#include <Mod/TechDraw/App/DrawRichAnno.h>
45
#include <Mod/TechDraw/App/DrawViewBalloon.h>
46
#include <Mod/TechDraw/App/DrawViewDetail.h>
47
#include <Mod/TechDraw/App/DrawViewDimension.h>
48
#include <Mod/TechDraw/App/DrawViewMulti.h>
49
#include <Mod/TechDraw/App/LineGroup.h>
50
#include <Mod/TechDraw/App/Cosmetic.h>
51
#include <Mod/TechDraw/App/CenterLine.h>
52
#include <Mod/TechDraw/App/LineNameEnum.h>
53
#include <Mod/TechDraw/App/LineGenerator.h>
54

55

56
#include "PreferencesGui.h"
57
#include "QGIView.h"
58
#include "TaskDetail.h"
59
#include "ViewProviderViewPart.h"
60
#include "ViewProviderPage.h"
61
#include "QGIViewDimension.h"
62
#include "QGIViewBalloon.h"
63
#include "QGSPage.h"
64

65
using namespace TechDrawGui;
66
using namespace TechDraw;
67
using DU = DrawUtil;
68

69
PROPERTY_SOURCE(TechDrawGui::ViewProviderViewPart, TechDrawGui::ViewProviderDrawingView)
70

71

72
const App::PropertyIntegerConstraint::Constraints intPercent = { 0, 100, 5 };
73

74
//**************************************************************************
75
// Construction/Destruction
76

77
ViewProviderViewPart::ViewProviderViewPart()
78
{
79
    sPixmap = "TechDraw_TreeView";
80

81
    static const char *group = "Lines";
82
    static const char *dgroup = "Decoration";
83
    static const char *hgroup = "Highlight";
84
    static const char *sgroup = "Section Line";
85
    static const char *fgroup = "Faces";
86

87
    //default line weights
88

89
    double weight = TechDraw::LineGroup::getDefaultWidth("Thick");
90
    ADD_PROPERTY_TYPE(LineWidth, (weight), group, App::Prop_None, "The thickness of visible lines (line groups xx.2");
91

92
    weight = TechDraw::LineGroup::getDefaultWidth("Thin");
93
    ADD_PROPERTY_TYPE(HiddenWidth, (weight), group, App::Prop_None, "The thickness of hidden lines, if enabled (line groups xx.1)");
94

95
    weight = TechDraw::LineGroup::getDefaultWidth("Graphic");
96
    ADD_PROPERTY_TYPE(IsoWidth, (weight), group, App::Prop_None, "The thickness of isoparameter lines, if enabled");
97

98
    weight = TechDraw::LineGroup::getDefaultWidth("Extra");
99
    ADD_PROPERTY_TYPE(ExtraWidth, (weight), group, App::Prop_None, "The thickness of LineGroup Extra lines, if enabled");
100

101
    double defScale = Preferences::getPreferenceGroup("Decorations")->GetFloat("CenterMarkScale", 0.50);
102
    bool   defShowCenters = Preferences::getPreferenceGroup("Decorations")->GetBool("ShowCenterMarks", false);
103

104
    //decorations
105
    ADD_PROPERTY_TYPE(HorizCenterLine ,(false), dgroup, App::Prop_None, "Show a horizontal centerline through view");
106
    ADD_PROPERTY_TYPE(VertCenterLine ,(false), dgroup, App::Prop_None, "Show a vertical centerline through view");
107
    ADD_PROPERTY_TYPE(ArcCenterMarks ,(defShowCenters), dgroup, App::Prop_None, "Center marks on/off");
108
    ADD_PROPERTY_TYPE(CenterScale, (defScale), dgroup, App::Prop_None, "Center mark size adjustment, if enabled");
109

110
    //properties that affect Section Line
111
    ADD_PROPERTY_TYPE(ShowSectionLine ,(true)    ,sgroup, App::Prop_None, "Show/hide section line if applicable");
112
    ADD_PROPERTY_TYPE(SectionLineStyle, (Preferences::SectionLineStyle()), sgroup, App::Prop_None,
113
                        "Set section line style if applicable");
114
    ADD_PROPERTY_TYPE(SectionLineColor, (prefSectionColor()), sgroup, App::Prop_None,
115
                        "Set section line color if applicable");
116

117
     bool marksDefault  = Preferences::sectionLineConvention() == 1 ? true : false;
118
    ADD_PROPERTY_TYPE(SectionLineMarks, (marksDefault), sgroup, App::Prop_None,
119
                        "Show marks at direction changes for ComplexSection");
120

121
    //properties that affect Detail Highlights
122
    ADD_PROPERTY_TYPE(HighlightLineStyle, (prefHighlightStyle()), hgroup, App::Prop_None,
123
                        "Set highlight line style if applicable");
124
    ADD_PROPERTY_TYPE(HighlightLineColor, (prefHighlightColor()), hgroup, App::Prop_None,
125
                        "Set highlight line color if applicable");
126
    ADD_PROPERTY_TYPE(HighlightAdjust, (0.0), hgroup, App::Prop_None, "Adjusts the rotation of the Detail highlight");
127

128
    ADD_PROPERTY_TYPE(ShowAllEdges ,(false),dgroup, App::Prop_None, "Temporarily show invisible lines");
129

130
    // Faces related properties
131
    ADD_PROPERTY_TYPE(FaceColor, (Preferences::getPreferenceGroup("Colors")->GetUnsigned("FaceColor", 0xFFFFFF)),
132
                      fgroup, App::Prop_None, "Set color of faces");
133
    ADD_PROPERTY_TYPE(FaceTransparency, (Preferences::getPreferenceGroup("Colors")->GetBool("ClearFace", false) ? 100 : 0),
134
                      fgroup, App::Prop_None, "Set transparency of faces");
135
    FaceTransparency.setConstraints(&intPercent);
136

137
    std::string bodyName = LineGenerator::getLineStandardsBody();
138
    if (bodyName == "ISO") {
139
        SectionLineStyle.setEnums(ISOLineName::ISOLineNameEnums);
140
        HighlightLineStyle.setEnums(ISOLineName::ISOLineNameEnums);
141
    } else if (bodyName == "ANSI") {
142
        SectionLineStyle.setEnums(ANSILineName::ANSILineNameEnums);
143
        HighlightLineStyle.setEnums(ANSILineName::ANSILineNameEnums);
144
    } else if (bodyName == "ASME") {
145
        SectionLineStyle.setEnums(ASMELineName::ASMELineNameEnums);
146
        HighlightLineStyle.setEnums(ASMELineName::ASMELineNameEnums);
147
    }
148
}
149

150
ViewProviderViewPart::~ViewProviderViewPart()
151
{
152

153
}
154

155
void ViewProviderViewPart::onChanged(const App::Property* prop)
156
{
157
    if (auto part = getViewPart(); part && part->isDerivedFrom(TechDraw::DrawViewDetail::getClassTypeId()) &&
158
        prop == &(HighlightAdjust)) {
159
        auto detail = static_cast<DrawViewDetail*>(getViewPart());
160
        auto baseDvp = dynamic_cast<DrawViewPart*>(detail->BaseView.getValue());
161
        if (baseDvp) {
162
            baseDvp->requestPaint();
163
        }
164
        return;
165
    }
166

167
    if (prop == &(LineWidth)   ||
168
        prop == &(HiddenWidth) ||
169
        prop == &(IsoWidth) ||
170
        prop == &(ExtraWidth) ||
171
        prop == &(HighlightAdjust) ||
172
        prop == &(ArcCenterMarks) ||
173
        prop == &(CenterScale) ||
174
        prop == &(ShowSectionLine)  ||
175
        prop == &(SectionLineStyle) ||
176
        prop == &(SectionLineColor) ||
177
        prop == &(SectionLineMarks) ||
178
        prop == &(HighlightLineStyle) ||
179
        prop == &(HighlightLineColor) ||
180
        prop == &(HorizCenterLine) ||
181
        prop == &(VertCenterLine)  ||
182
        prop == &(FaceColor) ||
183
        prop == &(FaceTransparency)) {
184
        // redraw QGIVP
185
        QGIView* qgiv = getQView();
186
        if (qgiv) {
187
            qgiv->updateView(true);
188
        }
189
     }
190

191
    ViewProviderDrawingView::onChanged(prop);
192
}
193

194

195
void ViewProviderViewPart::attach(App::DocumentObject *pcFeat)
196
{
197
//    Base::Console().Message("VPVP::attach(%s)\n", pcFeat->getNameInDocument());
198
    TechDraw::DrawViewMulti* dvm = dynamic_cast<TechDraw::DrawViewMulti*>(pcFeat);
199
    TechDraw::DrawViewDetail* dvd = dynamic_cast<TechDraw::DrawViewDetail*>(pcFeat);
200
    if (dvm) {
201
        sPixmap = "TechDraw_TreeMulti";
202
    } else if (dvd) {
203
        sPixmap = "actions/TechDraw_DetailView";
204
    }
205

206
    ViewProviderDrawingView::attach(pcFeat);
207
}
208

209
std::vector<App::DocumentObject*> ViewProviderViewPart::claimChildren() const
210
{
211
    // Collect any child Document Objects and put them in the right place in the Feature tree
212
    // valid children of a ViewPart are:
213
    //    - Dimensions
214
    //    - Leaders
215
    //    - Hatches
216
    //    - GeomHatches
217
    //    - any drawing views declaring this view as their parent
218
    std::vector<App::DocumentObject*> temp;
219
    const std::vector<App::DocumentObject *> &views = getViewPart()->getInList();
220
    try {
221
      for(std::vector<App::DocumentObject *>::const_iterator it = views.begin(); it != views.end(); ++it) {
222
          auto view = dynamic_cast<TechDraw::DrawView *>(*it);
223
          if (view && view->claimParent() == getViewPart()) {
224
              temp.push_back(view);
225
              continue;
226
          }
227

228
          if((*it)->isDerivedFrom<TechDraw::DrawViewDimension>()) {
229
              //TODO: make a list, then prune it.  should be faster?
230
              bool skip = false;
231
              std::string dimName = (*it)->getNameInDocument();
232
              for (auto& t: temp) {                              //only add dim once even if it references 2 geometries
233
                  std::string tName = t->getNameInDocument();
234
                  if (dimName == tName) {
235
                      skip = true;
236
                      break;
237
                  }
238
              }
239
              if (!skip) {
240
                  temp.push_back(*it);
241
              }
242
          } else if ((*it)->isDerivedFrom<TechDraw::DrawHatch>()) {
243
              temp.push_back((*it));
244
          } else if ((*it)->isDerivedFrom<TechDraw::DrawGeomHatch>()) {
245
              temp.push_back((*it));
246
          } else if ((*it)->isDerivedFrom<TechDraw::DrawViewBalloon>()) {
247
              temp.push_back((*it));
248
          } else if ((*it)->isDerivedFrom<TechDraw::DrawLeaderLine>()) {
249
              temp.push_back((*it));
250
          }
251
      }
252
      return temp;
253
    } catch (...) {
254
        return std::vector<App::DocumentObject*>();
255
    }
256
}
257

258
bool ViewProviderViewPart::setEdit(int ModNum)
259
{
260
    if (ModNum != ViewProvider::Default ) {
261
        return ViewProviderDrawingView::setEdit(ModNum);
262
    }
263

264
    if (Gui::Control().activeDialog())  {         //TaskPanel already open!
265
        return false;
266
    }
267
    TechDraw::DrawViewPart* dvp = getViewObject();
268
    TechDraw::DrawViewDetail* dvd = dynamic_cast<TechDraw::DrawViewDetail*>(dvp);
269
    if (dvd) {
270
        if (!dvd->BaseView.getValue()) {
271
            Base::Console().Error("DrawViewDetail - %s - has no BaseView!\n", dvd->getNameInDocument());
272
            return false;
273
        }
274
        // clear the selection (convenience)
275
        Gui::Selection().clearSelection();
276
        Gui::Control().showDialog(new TaskDlgDetail(dvd));
277
        Gui::Selection().clearSelection();
278
        Gui::Selection().addSelection(dvd->getDocument()->getName(),
279
                                        dvd->getNameInDocument());
280
    }
281

282
    return true;
283
}
284

285
bool ViewProviderViewPart::doubleClicked()
286
{
287
    setEdit(ViewProvider::Default);
288
    return true;
289
}
290

291
TechDraw::DrawViewPart* ViewProviderViewPart::getViewObject() const
292
{
293
    return dynamic_cast<TechDraw::DrawViewPart*>(pcObject);
294
}
295

296
TechDraw::DrawViewPart* ViewProviderViewPart::getViewPart() const
297
{
298
    return getViewObject();
299
}
300

301
void ViewProviderViewPart::handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property *prop)
302
// transforms properties that had been changed
303
{
304
    // property LineWidth had the App::PropertyFloat and was changed to App::PropertyLength
305
    if (prop == &LineWidth && strcmp(TypeName, "App::PropertyFloat") == 0) {
306
        App::PropertyFloat LineWidthProperty;
307
        // restore the PropertyFloat to be able to set its value
308
        LineWidthProperty.Restore(reader);
309
        LineWidth.setValue(LineWidthProperty.getValue());
310
    }
311
    // property HiddenWidth had the App::PropertyFloat and was changed to App::PropertyLength
312
    else if (prop == &HiddenWidth && strcmp(TypeName, "App::PropertyFloat") == 0) {
313
        App::PropertyFloat HiddenWidthProperty;
314
        HiddenWidthProperty.Restore(reader);
315
        HiddenWidth.setValue(HiddenWidthProperty.getValue());
316
    }
317
    // property IsoWidth had the App::PropertyFloat and was changed to App::PropertyLength
318
    else if (prop == &IsoWidth && strcmp(TypeName, "App::PropertyFloat") == 0) {
319
        App::PropertyFloat IsoWidthProperty;
320
        IsoWidthProperty.Restore(reader);
321
        IsoWidth.setValue(IsoWidthProperty.getValue());
322
    }
323
    // property ExtraWidth had the App::PropertyFloat and was changed to App::PropertyLength
324
    else if (prop == &ExtraWidth && strcmp(TypeName, "App::PropertyFloat") == 0) {
325
        App::PropertyFloat  ExtraWidthProperty;
326
        ExtraWidthProperty.Restore(reader);
327
        ExtraWidth.setValue(ExtraWidthProperty.getValue());
328
    }
329
    else {
330
        ViewProviderDrawingView::handleChangedPropertyType(reader, TypeName, prop);
331
    }
332
}
333

334
bool ViewProviderViewPart::onDelete(const std::vector<std::string> & subNames)
335
{
336
    // if a cosmetic subelement is in the list of selected subNames then we treat this
337
    // as a delete of the subelement and not a delete of the DVP
338
    std::vector<std::string> removables = getSelectedCosmetics(subNames);
339
    if (!removables.empty()) {
340
        // we have cosmetics, so remove them and tell Std_Delete not to remove the DVP
341
        deleteCosmeticElements(removables);
342
        getViewObject()->recomputeFeature();
343
        return false;
344
    }
345

346
    // we cannot delete if the view has a section or detail view
347
    QString bodyMessage;
348
    QTextStream bodyMessageStream(&bodyMessage);
349

350
    // get child views
351
    auto viewSection = getViewObject()->getSectionRefs();
352
    auto viewDetail = getViewObject()->getDetailRefs();
353

354
    if (!viewSection.empty() || !viewDetail.empty()) {
355
        bodyMessageStream << qApp->translate("Std_Delete",
356
            "You cannot delete this view because it has one or more dependent views that would become broken.");
357
        QMessageBox::warning(Gui::getMainWindow(),
358
            qApp->translate("Std_Delete", "Object dependencies"), bodyMessage,
359
            QMessageBox::Ok);
360
        return false;
361
    }
362
    return true;
363
}
364

365
bool ViewProviderViewPart::canDelete(App::DocumentObject *obj) const
366
{
367
    // deletions of part objects (detail view, View etc.) are valid
368
    // that it cannot be deleted if it has a child view is handled in the onDelete() function
369
    Q_UNUSED(obj)
370
    return true;
371
}
372

373
//! extract the names of cosmetic subelements from the list of all selected elements
374
std::vector<std::string> ViewProviderViewPart::getSelectedCosmetics(std::vector<std::string> subNames)
375
{
376

377
    std::vector<std::string> result;
378
    // pick out any cosmetic vertices or edges in the selection
379
    for (auto& sub : subNames) {
380
        if (DU::getGeomTypeFromName(sub) == "Vertex") {
381
            if (DU::isCosmeticVertex(getViewObject(), sub)) {
382
                result.emplace_back(sub);
383
            }
384
        } else if (DU::getGeomTypeFromName(sub) == "Edge") {
385
            if (DU::isCosmeticEdge(getViewObject(), sub)  ||
386
                DU::isCenterLine(getViewObject(), sub)) {
387
                result.emplace_back(sub);
388
            }
389
        }
390
    }
391
    return result;
392
}
393

394
//! delete cosmetic elements for a list of subelement names
395
void ViewProviderViewPart::deleteCosmeticElements(std::vector<std::string> removables)
396
{
397
    for (auto& name : removables) {
398
        if (DU::getGeomTypeFromName(name) == "Vertex") {
399
            CosmeticVertex* vert = getViewObject()->getCosmeticVertexBySelection(name);
400
            getViewObject()->removeCosmeticVertex(vert->getTagAsString());
401
            continue;
402
        }
403
        if (DU::getGeomTypeFromName(name) == "Edge") {
404
            CosmeticEdge* edge = getViewObject()->getCosmeticEdgeBySelection(name);
405
            if (edge) {
406
                // if not edge, something has gone very wrong!
407
                getViewObject()->removeCosmeticEdge(edge->getTagAsString());
408
                continue;
409
            }
410
            CenterLine* line = getViewObject()->getCenterLineBySelection(name);
411
            if (line) {
412
                getViewObject()->removeCenterLine(line->getTagAsString());
413
                continue;
414
            }
415
        }
416
    }
417
}
418

419
App::Color ViewProviderViewPart::prefSectionColor()
420
{
421
    return PreferencesGui::sectionLineColor();
422
}
423

424
App::Color ViewProviderViewPart::prefHighlightColor()
425
{
426
    App::Color fcColor;
427
    fcColor.setPackedValue(Preferences::getPreferenceGroup("Decorations")->GetUnsigned("HighlightColor", 0x00000000));
428
    return fcColor;
429
}
430

431
int ViewProviderViewPart::prefHighlightStyle()
432
{
433
    return Preferences::getPreferenceGroup("Decorations")->GetInt("HighlightStyle", 2);
434
}
435

436
// it can happen that Dimensions/Balloons/etc can lose their parent item if the
437
// the parent is deleted, then undo is invoked.  The linkages on the App side are
438
// handled by the undo mechanism, but the QGraphicsScene parentage is not reset.
439
// TODO: does this need to be implemented for Leaderlines and ???? others?
440
void ViewProviderViewPart::fixSceneDependencies()
441
{
442
    auto page = getViewProviderPage();
443
    if (!page) {
444
        return;
445
    }
446

447
    auto scene = page->getQGSPage();
448
    auto partQView = getQView();
449

450
    auto dimensions =  getViewPart()->getDimensions();
451
    for (auto& dim : dimensions) {
452
        auto dimQView = dynamic_cast<QGIViewDimension *>(scene->findQViewForDocObj(dim));
453
        if (dimQView && dimQView->parentItem() != partQView) {
454
            // need to add the dim QView to this QGIViewPart
455
            scene->addDimToParent(dimQView, partQView);
456
        }
457
    }
458

459
    auto balloons = getViewPart()->getBalloons();
460
    for (auto& bal : balloons) {
461
        auto balQView = dynamic_cast<QGIViewBalloon*>(scene->findQViewForDocObj(bal));
462
        if (balQView && balQView->parentItem() != partQView) {
463
            // need to add the balloon QView to this QGIViewPart
464
            scene->addBalloonToParent(balQView, partQView);
465
        }
466
    }
467
}
468

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.