FreeCAD

Форк
0
/
TaskFillingVertex.cpp 
398 строк · 13.7 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2017 Werner Mayer <wmayer[at]users.sourceforge.net>     *
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
#ifndef _PreComp_
25
#include <QAction>
26
#include <QTimer>
27
#endif
28

29
#include <App/Document.h>
30
#include <Gui/Application.h>
31
#include <Gui/Command.h>
32
#include <Gui/Document.h>
33
#include <Gui/SelectionObject.h>
34
#include <Gui/Widgets.h>
35
#include <Mod/Part/Gui/ViewProvider.h>
36

37
#include "TaskFilling.h"
38
#include "TaskFillingVertex.h"
39
#include "ui_TaskFillingVertex.h"
40

41

42
using namespace SurfaceGui;
43

44
namespace SurfaceGui
45
{
46

47
class FillingVertexPanel::VertexSelection: public Gui::SelectionFilterGate
48
{
49
public:
50
    VertexSelection(FillingVertexPanel::SelectionMode& mode, Surface::Filling* editedObject)
51
        : Gui::SelectionFilterGate(nullPointer())
52
        , mode(mode)
53
        , editedObject(editedObject)
54
    {}
55
    ~VertexSelection() override
56
    {
57
        mode = FillingVertexPanel::None;
58
    }
59
    /**
60
     * Allow the user to pick only edges.
61
     */
62
    bool allow(App::Document*, App::DocumentObject* pObj, const char* sSubName) override
63
    {
64
        // don't allow references to itself
65
        if (pObj == editedObject) {
66
            return false;
67
        }
68
        if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId())) {
69
            return false;
70
        }
71

72
        if (!sSubName || sSubName[0] == '\0') {
73
            return false;
74
        }
75

76
        switch (mode) {
77
            case FillingVertexPanel::AppendVertex:
78
                return allowVertex(true, pObj, sSubName);
79
            case FillingVertexPanel::RemoveVertex:
80
                return allowVertex(false, pObj, sSubName);
81
            default:
82
                return false;
83
        }
84
    }
85

86
private:
87
    bool allowVertex(bool appendVertex, App::DocumentObject* pObj, const char* sSubName)
88
    {
89
        std::string element(sSubName);
90
        if (element.substr(0, 6) != "Vertex") {
91
            return false;
92
        }
93

94
        auto links = editedObject->Points.getSubListValues();
95
        for (const auto& it : links) {
96
            if (it.first == pObj) {
97
                for (const auto& jt : it.second) {
98
                    if (jt == sSubName) {
99
                        return !appendVertex;
100
                    }
101
                }
102
            }
103
        }
104

105
        return appendVertex;
106
    }
107

108
private:
109
    FillingVertexPanel::SelectionMode& mode;
110
    Surface::Filling* editedObject;
111
};
112

113
// ----------------------------------------------------------------------------
114

115
FillingVertexPanel::FillingVertexPanel(ViewProviderFilling* vp, Surface::Filling* obj)
116
{
117
    ui = new Ui_TaskFillingVertex();
118
    ui->setupUi(this);
119
    setupConnections();
120

121
    selectionMode = None;
122
    this->vp = vp;
123
    checkCommand = true;
124
    setEditedObject(obj);
125

126
    // Create context menu
127
    QAction* action = new QAction(tr("Remove"), this);
128
    action->setShortcut(QString::fromLatin1("Del"));
129
    action->setShortcutContext(Qt::WidgetShortcut);
130
    ui->listFreeVertex->addAction(action);
131
    connect(action, &QAction::triggered, this, &FillingVertexPanel::onDeleteVertex);
132
    ui->listFreeVertex->setContextMenuPolicy(Qt::ActionsContextMenu);
133
}
134

135
/*
136
 *  Destroys the object and frees any allocated resources
137
 */
138
FillingVertexPanel::~FillingVertexPanel()
139
{
140
    // no need to delete child widgets, Qt does it all for us
141
    delete ui;
142
    Gui::Selection().rmvSelectionGate();
143
}
144

145
void FillingVertexPanel::setupConnections()
146
{
147
    connect(ui->buttonVertexAdd,
148
            &QToolButton::toggled,
149
            this,
150
            &FillingVertexPanel::onButtonVertexAddToggled);
151
    connect(ui->buttonVertexRemove,
152
            &QToolButton::toggled,
153
            this,
154
            &FillingVertexPanel::onButtonVertexRemoveToggled);
155
}
156

157
void FillingVertexPanel::appendButtons(Gui::ButtonGroup* buttonGroup)
158
{
159
    buttonGroup->addButton(ui->buttonVertexAdd, int(SelectionMode::AppendVertex));
160
    buttonGroup->addButton(ui->buttonVertexRemove, int(SelectionMode::RemoveVertex));
161
}
162

163
// stores object pointer, its old fill type and adjusts radio buttons according to it.
164
void FillingVertexPanel::setEditedObject(Surface::Filling* obj)
165
{
166
    editedObject = obj;
167

168
    auto objects = editedObject->Points.getValues();
169
    auto element = editedObject->Points.getSubValues();
170
    auto it = objects.begin();
171
    auto jt = element.begin();
172

173
    App::Document* doc = editedObject->getDocument();
174
    for (; it != objects.end() && jt != element.end(); ++it, ++jt) {
175
        QListWidgetItem* item = new QListWidgetItem(ui->listFreeVertex);
176
        ui->listFreeVertex->addItem(item);
177

178
        QString text = QString::fromLatin1("%1.%2").arg(QString::fromUtf8((*it)->Label.getValue()),
179
                                                        QString::fromStdString(*jt));
180
        item->setText(text);
181

182
        QList<QVariant> data;
183
        data << QByteArray(doc->getName());
184
        data << QByteArray((*it)->getNameInDocument());
185
        data << QByteArray(jt->c_str());
186
        item->setData(Qt::UserRole, data);
187
    }
188
    attachDocument(Gui::Application::Instance->getDocument(doc));
189
}
190

191
void FillingVertexPanel::changeEvent(QEvent* e)
192
{
193
    if (e->type() == QEvent::LanguageChange) {
194
        ui->retranslateUi(this);
195
    }
196
    else {
197
        QWidget::changeEvent(e);
198
    }
199
}
200

201
void FillingVertexPanel::open()
202
{
203
    checkOpenCommand();
204
    this->vp->highlightReferences(ViewProviderFilling::Vertex,
205
                                  editedObject->Points.getSubListValues(),
206
                                  true);
207
    Gui::Selection().clearSelection();
208
}
209

210
void FillingVertexPanel::reject()
211
{
212
    this->vp->highlightReferences(ViewProviderFilling::Vertex,
213
                                  editedObject->Points.getSubListValues(),
214
                                  false);
215
}
216

217
void FillingVertexPanel::clearSelection()
218
{
219
    Gui::Selection().clearSelection();
220
}
221

222
void FillingVertexPanel::checkOpenCommand()
223
{
224
    if (checkCommand && !Gui::Command::hasPendingCommand()) {
225
        std::string Msg("Edit ");
226
        Msg += editedObject->Label.getValue();
227
        Gui::Command::openCommand(Msg.c_str());
228
        checkCommand = false;
229
    }
230
}
231

232
void FillingVertexPanel::slotUndoDocument(const Gui::Document&)
233
{
234
    checkCommand = true;
235
}
236

237
void FillingVertexPanel::slotRedoDocument(const Gui::Document&)
238
{
239
    checkCommand = true;
240
}
241

242
void FillingVertexPanel::slotDeletedObject(const Gui::ViewProviderDocumentObject& Obj)
243
{
244
    // If this view provider is being deleted then reset the colors of
245
    // referenced part objects. The dialog will be deleted later.
246
    if (this->vp == &Obj) {
247
        this->vp->highlightReferences(ViewProviderFilling::Vertex,
248
                                      editedObject->Points.getSubListValues(),
249
                                      false);
250
    }
251
}
252

253
void FillingVertexPanel::onButtonVertexAddToggled(bool checked)
254
{
255
    if (checked) {
256
        // 'selectionMode' is passed by reference and changed when the filter is deleted
257
        Gui::Selection().addSelectionGate(new VertexSelection(selectionMode, editedObject));
258
        selectionMode = AppendVertex;
259
    }
260
    else if (selectionMode == AppendVertex) {
261
        exitSelectionMode();
262
    }
263
}
264

265
void FillingVertexPanel::onButtonVertexRemoveToggled(bool checked)
266
{
267
    if (checked) {
268
        // 'selectionMode' is passed by reference and changed when the filter is deleted
269
        Gui::Selection().addSelectionGate(new VertexSelection(selectionMode, editedObject));
270
        selectionMode = RemoveVertex;
271
    }
272
    else if (selectionMode == RemoveVertex) {
273
        exitSelectionMode();
274
    }
275
}
276

277
void FillingVertexPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
278
{
279
    if (selectionMode == None) {
280
        return;
281
    }
282

283
    if (msg.Type == Gui::SelectionChanges::AddSelection) {
284
        checkOpenCommand();
285
        if (selectionMode == AppendVertex) {
286
            QListWidgetItem* item = new QListWidgetItem(ui->listFreeVertex);
287
            ui->listFreeVertex->addItem(item);
288

289
            Gui::SelectionObject sel(msg);
290
            QString text = QString::fromLatin1("%1.%2").arg(
291
                QString::fromUtf8(sel.getObject()->Label.getValue()),
292
                QString::fromLatin1(msg.pSubName));
293
            item->setText(text);
294

295
            QList<QVariant> data;
296
            data << QByteArray(msg.pDocName);
297
            data << QByteArray(msg.pObjectName);
298
            data << QByteArray(msg.pSubName);
299
            item->setData(Qt::UserRole, data);
300

301
            auto objects = editedObject->Points.getValues();
302
            objects.push_back(sel.getObject());
303
            auto element = editedObject->Points.getSubValues();
304
            element.emplace_back(msg.pSubName);
305
            editedObject->Points.setValues(objects, element);
306
            this->vp->highlightReferences(ViewProviderFilling::Vertex,
307
                                          editedObject->Points.getSubListValues(),
308
                                          true);
309
        }
310
        else if (selectionMode == RemoveVertex) {
311
            Gui::SelectionObject sel(msg);
312
            QList<QVariant> data;
313
            data << QByteArray(msg.pDocName);
314
            data << QByteArray(msg.pObjectName);
315
            data << QByteArray(msg.pSubName);
316
            for (int i = 0; i < ui->listFreeVertex->count(); i++) {
317
                QListWidgetItem* item = ui->listFreeVertex->item(i);
318
                if (item && item->data(Qt::UserRole) == data) {
319
                    ui->listFreeVertex->takeItem(i);
320
                    delete item;
321
                }
322
            }
323

324
            this->vp->highlightReferences(ViewProviderFilling::Vertex,
325
                                          editedObject->Points.getSubListValues(),
326
                                          false);
327
            App::DocumentObject* obj = sel.getObject();
328
            std::string sub = msg.pSubName;
329
            auto objects = editedObject->Points.getValues();
330
            auto element = editedObject->Points.getSubValues();
331
            auto it = objects.begin();
332
            auto jt = element.begin();
333
            for (; it != objects.end() && jt != element.end(); ++it, ++jt) {
334
                if (*it == obj && *jt == sub) {
335
                    objects.erase(it);
336
                    element.erase(jt);
337
                    editedObject->Points.setValues(objects, element);
338
                    break;
339
                }
340
            }
341
            this->vp->highlightReferences(ViewProviderFilling::Vertex,
342
                                          editedObject->Points.getSubListValues(),
343
                                          true);
344
        }
345

346
        editedObject->recomputeFeature();
347
        QTimer::singleShot(50, this, &FillingVertexPanel::clearSelection);
348
    }
349
}
350

351
void FillingVertexPanel::onDeleteVertex()
352
{
353
    int row = ui->listFreeVertex->currentRow();
354
    QListWidgetItem* item = ui->listFreeVertex->item(row);
355
    if (item) {
356
        checkOpenCommand();
357
        QList<QVariant> data;
358
        data = item->data(Qt::UserRole).toList();
359
        ui->listFreeVertex->takeItem(row);
360
        delete item;
361

362
        App::Document* doc = App::GetApplication().getDocument(data[0].toByteArray());
363
        App::DocumentObject* obj = doc ? doc->getObject(data[1].toByteArray()) : nullptr;
364
        std::string sub = data[2].toByteArray().constData();
365
        auto objects = editedObject->Points.getValues();
366
        auto element = editedObject->Points.getSubValues();
367
        auto it = objects.begin();
368
        auto jt = element.begin();
369
        this->vp->highlightReferences(ViewProviderFilling::Vertex,
370
                                      editedObject->Points.getSubListValues(),
371
                                      false);
372

373
        for (; it != objects.end() && jt != element.end(); ++it, ++jt) {
374
            if (*it == obj && *jt == sub) {
375
                objects.erase(it);
376
                element.erase(jt);
377
                editedObject->Points.setValues(objects, element);
378
                editedObject->recomputeFeature();
379
                break;
380
            }
381
        }
382

383
        this->vp->highlightReferences(ViewProviderFilling::Vertex,
384
                                      editedObject->Points.getSubListValues(),
385
                                      true);
386
    }
387
}
388

389
void FillingVertexPanel::exitSelectionMode()
390
{
391
    // 'selectionMode' is passed by reference to the filter and changed when the filter is deleted
392
    Gui::Selection().clearSelection();
393
    Gui::Selection().rmvSelectionGate();
394
}
395

396
}  // namespace SurfaceGui
397

398
#include "moc_TaskFillingVertex.cpp"
399

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

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

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

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