FreeCAD

Форк
0
/
ActiveObjectList.cpp 
194 строки · 7.1 Кб
1
/**************************************************************************
2
*   Copyright (c) 2014 Jürgen Riegel <juergen.riegel@web.de>              *
3
*                                                                         *
4
*   This file is part of the FreeCAD CAx development system.              *
5
*                                                                         *
6
*   This program is free software; you can redistribute it and/or modify  *
7
*   it under the terms of the GNU Library General Public License (LGPL)   *
8
*   as published by the Free Software Foundation; either version 2 of     *
9
*   the License, or (at your option) any later version.                   *
10
*   for detail see the LICENCE text file.                                 *
11
*                                                                         *
12
*   FreeCAD 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.                  *
16
*                                                                         *
17
*   You should have received a copy of the GNU Library General Public     *
18
*   License along with FreeCAD; if not, write to the Free Software        *
19
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
20
*   USA                                                                   *
21
*                                                                         *
22
***************************************************************************/
23

24
#include "PreCompiled.h"
25

26
#include <App/Document.h>
27
#include <Gui/Application.h>
28
#include <Gui/Document.h>
29
#include <Gui/Selection.h>
30
#include <Gui/ViewProviderDocumentObject.h>
31

32
#include "ActiveObjectList.h"
33
#include "TreeParams.h"
34

35

36
FC_LOG_LEVEL_INIT("MDIView", true, true)
37

38
using namespace Gui;
39

40
App::DocumentObject *ActiveObjectList::getObject(const ObjectInfo &info, bool resolve,
41
                                                 App::DocumentObject **parent,
42
                                                 std::string *subname) const
43
{
44
    if (parent)
45
        *parent = info.obj;
46
    if (subname)
47
        *subname = info.subname;
48
    auto obj = info.obj;
49
    if (!obj || !obj->isAttachedToDocument())
50
        return nullptr;
51
    if (!info.subname.empty()) {
52
        obj = obj->getSubObject(info.subname.c_str());
53
        if (!obj)
54
            return nullptr;
55
    }
56

57
    return resolve ? obj->getLinkedObject(true) : obj;
58
}
59

60
void ActiveObjectList::setHighlight(const ObjectInfo &info, HighlightMode mode, bool enable)
61
{
62
    auto obj = getObject(info, false);
63
    if (!obj)
64
        return;
65
    auto vp = dynamic_cast<ViewProviderDocumentObject*>(Application::Instance->getViewProvider(obj));
66
    if (!vp)
67
        return;
68

69
    if (TreeParams::getTreeActiveAutoExpand()) {
70
        vp->getDocument()->signalExpandObject(*vp, enable ? TreeItemMode::ExpandPath : TreeItemMode::CollapseItem,
71
                                              info.obj, info.subname.c_str());
72
    }
73

74
    vp->getDocument()->signalHighlightObject(*vp, mode, enable, info.obj, info.subname.c_str());
75
}
76

77
Gui::ActiveObjectList::ObjectInfo Gui::ActiveObjectList::getObjectInfo(App::DocumentObject *obj, const char *subname) const
78
{
79
    ObjectInfo info;
80
    info.obj = nullptr;
81
    if (!obj || !obj->isAttachedToDocument())
82
        return info;
83

84
    if (subname) {
85
        info.obj = obj;
86
        info.subname = subname;
87
    }
88
    else {
89
        // If the input object is not from this document, it must be brought in
90
        // by some link type object of this document. We only accept the object
91
        // if we can find such object in the current selection.
92
        auto sels = Gui::Selection().getSelection(_Doc->getDocument()->getName(), ResolveMode::NoResolve);
93
        for (auto &sel : sels) {
94
            if (sel.pObject == obj || sel.pObject->getLinkedObject(true)==obj) {
95
                info.obj = sel.pObject;
96
                break;
97
            }
98

99
            for (auto dot=strchr(sel.SubName,'.');dot;dot=strchr(dot+1,'.')) {
100
                std::string subname(sel.SubName,dot-sel.SubName+1);
101
                auto sobj = sel.pObject->getSubObject(subname.c_str());
102
                if (!sobj)
103
                    break;
104
                if (sobj == obj || sobj->getLinkedObject(true) == obj) {
105
                    info.obj = sel.pObject;
106
                    info.subname = subname;
107
                    break;
108
                }
109
            }
110

111
            if (info.obj)
112
                break;
113
        }
114
        if(!info.obj) {
115
            // No selection is found, try to obtain the object hierarchy using
116
            // DocumentObject::getParents()
117
            unsigned long count = 0xffffffff;
118
            for(auto &v : obj->getParents()) {
119
                if(v.first->getDocument() != _Doc->getDocument())
120
                    continue;
121

122
                // We prioritize on non-linked group object having the least
123
                // hierarchies.
124
                unsigned long cnt = v.first->getSubObjectList(v.second.c_str()).size();
125
                if(v.first->getLinkedObject(false) != v.first)
126
                    cnt &= 0x8000000;
127
                if(cnt < count) {
128
                    count = cnt;
129
                    info.obj = v.first;
130
                    info.subname = v.second;
131
                }
132
            }
133

134
            if(!info.obj) {
135
                if (obj->getDocument()!=_Doc->getDocument())
136
                    return info;
137
                info.obj = obj;
138
            }
139
        }
140
    }
141

142
    return info;
143
}
144

145
bool Gui::ActiveObjectList::hasObject(App::DocumentObject *obj,
146
                                      const char *name, const char *subname) const
147
{
148
    auto it = _ObjectMap.find(name);
149
    if (it == _ObjectMap.end())
150
        return false;
151
    auto info = getObjectInfo(obj, subname);
152
    return info.obj == it->second.obj && info.subname == it->second.subname;
153
}
154

155
void Gui::ActiveObjectList::setObject(App::DocumentObject* obj, const char* name,
156
                                      const char *subname, const Gui::HighlightMode& mode)
157
{
158
    auto it = _ObjectMap.find(name);
159
    if (it!=_ObjectMap.end()) {
160
        setHighlight(it->second, mode, false);
161
        _ObjectMap.erase(it);
162
    }
163

164
    if (!obj)
165
        return;
166

167
    auto info = getObjectInfo(obj,subname);
168
    if (!info.obj) {
169
        FC_ERR("Cannot set active object "
170
                << obj->getFullName() << '.' << (subname?subname:"")
171
                << " in document '" << _Doc->getDocument()->getName()
172
                << "'. Not found in current selection");
173
        return;
174
    }
175

176
    _ObjectMap[name] = info;
177
    setHighlight(info, mode, true);
178
}
179

180
bool Gui::ActiveObjectList::hasObject(const char*name)const
181
{
182
    return _ObjectMap.find(name) != _ObjectMap.end();
183
}
184

185
void ActiveObjectList::objectDeleted(const ViewProviderDocumentObject &vp)
186
{
187
    //maybe boost::bimap or boost::multi_index
188
    for (auto it = _ObjectMap.begin(); it != _ObjectMap.end(); ++it) {
189
        if (it->second.obj == vp.getObject()) {
190
            _ObjectMap.erase(it);
191
            return;
192
        }
193
    }
194
}
195

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

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

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

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