ATLAS Offline Software
AscObjSelectionManager.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
7 // //
8 // Implementation of class AscObjSelectionManager //
9 // //
10 // Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
11 // Initial version: April 2008 //
12 // //
14 
18 #include "VP1Base/IVP13DSystem.h"
21 #include "VP1Base/VP1Msg.h"
22 #include <Inventor/nodes/SoSeparator.h>
23 #include <Inventor/SoPath.h>
24 #include <QApplication>
25 #include<map>
26 
27 //____________________________________________________________________
29 public:
31  : theclass(tc),
32  eventRoot(root),
33  system(sys),
34  controller(c),
35  mode(SINGLE)
36  {
37  eventRoot->ref();
39  sel_assocobjs_click->setName("sel_assocobjs_click");
40  sel_assocobjs_click->ref();
42  sel_assocobjs_click->policy = SoCooperativeSelection::SINGLE;
43  sys->registerSelectionNode(sel_assocobjs_click);
44 
46  sel_assocobjs->setName("sel_assocobjs");
47  sel_assocobjs->ref();
49  sel_assocobjs_click->policy = SoCooperativeSelection::SINGLE;
50  sys->registerSelectionNode(sel_assocobjs);
51 
53  root->addChild(sel_assocobjs);
54  }
55  Imp(const Imp &) = delete;
56  Imp & operator=(const Imp &) = delete;
57  ~Imp()
58  {
60  sel_assocobjs_click->unref();
61  sel_assocobjs->unref();
62  eventRoot->unref();
63  }
64 
66  SoSeparator* eventRoot;
72 
73  std::map<SoSeparator*,AssociatedObjectHandleBase*> ascobjs_simpleToHandle;
74  std::map<SoSeparator*,AssociatedObjectHandleBase*> ascobjs_detailedToHandle;
75 
76 // bool ascObjHandleFixSelectionPath(AssociatedObjectHandleBase*,SoPath*);
78  AssociatedObjectHandleBase* ascObjHandle(const SoSeparator*);
79  QList<AssociatedObjectHandleBase*> selAscObjHandles;
80 
82  static bool shiftIsDown() { return Qt::ShiftModifier & QApplication::keyboardModifiers(); }
83 
84 };
85 
86 
87 
88 //____________________________________________________________________
90  : QObject(sys), VP1HelperClassBase(sys,"AscObjSelectionManager"), m_d(new Imp(this,event_root,sys,controller))
91 {
92  connect(controller,SIGNAL(assocObjDetailLevelChanged(TrackCommonFlags::DETAILLEVEL)),this,SLOT(ascObjDetailLevelChanged()));
94 }
95 
96 //____________________________________________________________________
98 {
99  //fixme: clear maps and emit signals!
100 }
101 
102 //____________________________________________________________________
104 {
105  //Fixme: sanity check that maps are cleared.
106  delete m_d;
107 }
108 
109 //____________________________________________________________________
111 {
112  if (m==SINGLE) return "SINGLE";
113  else if (m==TOGGLE) return "TOGGLE";
114  else if (m==SHIFT) return "SHIFT";
115  else return "UNKNOWN(ERROR)";
116 }
117 
118 //____________________________________________________________________
120 {
121  return m_d->mode;
122 }
123 
124 //____________________________________________________________________
126 {
127  if (m_d->mode==m)
128  return;
129  message("Mode changed to "+toString(m));
130  m_d->mode=m;
131 }
132 
133 
134 //____________________________________________________________________
136 {
137  return m_d->sel_assocobjs_click;
138 }
139 //____________________________________________________________________
140 void AscObjSelectionManager::registerAscObj(SoSeparator*simple,SoSeparator *detailed,AssociatedObjectHandleBase*handle)
141 {
142  if (VP1Msg::verbose()) {
143  if (!simple||!detailed||!handle) {
144  message("registerAscObj ERROR: Received null pointer!");
145  return;
146  }
148  itE = m_d->ascobjs_simpleToHandle.end();
149  for (it=m_d->ascobjs_simpleToHandle.begin();it!=itE;++it) {
150  if (it->first==simple||it->second==handle)
151  message("registerAscObj ERROR: Simple separator/handle already registered!");
152  }
154  for (it=m_d->ascobjs_detailedToHandle.begin();it!=itE;++it) {
155  if (it->first==detailed||it->second==handle)
156  message("registerAscObj ERROR: Detailed separator/handle already registered!");
157  }
158  }
159  m_d->ascobjs_simpleToHandle[simple]=handle;
160  m_d->ascobjs_detailedToHandle[detailed]=handle;
161 }
162 
163 //____________________________________________________________________
164 void AscObjSelectionManager::unregisterAscObj(SoSeparator*simple,SoSeparator *detailed)
165 {
166  if (VP1Msg::verbose()) {
167  if (!simple||!detailed) {
168  message("unregisterAscObj ERROR: Received null pointer!");
169  return;
170  }
171  }
173  if (itSimple==m_d->ascobjs_simpleToHandle.end()) {
174  message("unregisterAscObj ERROR: Not previously registered simple sep!");
175  } else {
176  m_d->ascobjs_simpleToHandle.erase(itSimple);
177  }
179  if (itDetailed==m_d->ascobjs_detailedToHandle.end()) {
180  message("unregisterAscObj ERROR: Not previously registered detailed sep!");
181  } else {
182  m_d->ascobjs_detailedToHandle.erase(itDetailed);
183  }
184 }
185 
186 //____________________________________________________________________
188 {
189  const int n(path?path->getLength():0);
190  AssociatedObjectHandleBase * handle(nullptr);
191  for (int i = 0; i < n; ++i) {
192  if (path->getNodeFromTail(i)->getTypeId()==SoSeparator::getClassTypeId()) {
193  handle = ascObjHandle(static_cast<SoSeparator*>(path->getNodeFromTail(i)));
194  if (handle)
195  return handle;
196  }
197  }
198  return nullptr;
199 }
200 
201 //____________________________________________________________________
203 {
204  std::map<SoSeparator*,AssociatedObjectHandleBase*>::const_iterator
205  it(ascobjs_simpleToHandle.find(const_cast<SoSeparator*>(s)));
206  if (it!=ascobjs_simpleToHandle.end())
207  return it->second;
208  it = ascobjs_detailedToHandle.find(const_cast<SoSeparator*>(s));
209  return it==ascobjs_detailedToHandle.end() ? 0 : it->second;
210 }
211 
212 //____________________________________________________________________
214 {
215  const bool isSimpleMode = controller->assocObjDetailLevel()==TrackCommonFlags::SIMPLE;
216  sel_assocobjs->deselectAll();
217  for (AssociatedObjectHandleBase* handle : selAscObjHandles) {
218  SoPath * path = new SoPath(sel_assocobjs);
219  path->ref();
220  if (!VP1QtInventorUtils::changePathTail(path,sel_assocobjs,
221  (isSimpleMode?handle->shapeSimple():handle->shapeDetailed()))) {
222  theclass->message("updateSelectionVisuals ERROR: Failed to relocate picked node.");
223  path->unref();
224  continue;
225  }
226  sel_assocobjs->select(path);
227  path->unref();
228  }
229 }
230 
231 
232 //____________________________________________________________________
234 {
235  messageVerbose("handleUserSelectedSingleNode");
236  pickedHandle = nullptr;
237  if (sel==m_d->sel_assocobjs) {
238  messageVerbose(" => ignore selections for m_d->sel_assocobjs");
239  return true;//We simply ignore those
240  }
241  if (sel!=m_d->sel_assocobjs_click) {
242  messageVerbose(" => We don't handle this selection.");
243  return false;
244  }
245 
246  AssociatedObjectHandleBase* handle = m_d->ascObjHandle(pickedPath);
247  m_d->sel_assocobjs_click->deselectAll();
248  if (!handle) {
249  message("ERROR: Unknown associated object.");
250  return true;
251  }
252  messageVerbose(" => Found handle. Mode is "+toString(m_d->mode)+", and number of previously selected handles is "+str(m_d->selAscObjHandles.count()));
253  pickedHandle = handle;
254  pretendUserClicked(handle);//we are not really pretending in this case of course...
255  return true;
256 }
257 
258 //____________________________________________________________________
260 {
261  assert(handle);
262  if (!handle)
263  return;
264  const bool alreadyselected = m_d->selAscObjHandles.contains(handle);
265  std::sort(m_d->selAscObjHandles.begin(), m_d->selAscObjHandles.end());
266  QList<AssociatedObjectHandleBase*> selHandlesBefore = m_d->selAscObjHandles;
267 
268  if (m_d->mode==SINGLE) {
269  if (m_d->selAscObjHandles.isEmpty()) {
270  //Add handle to selection.
271  m_d->selAscObjHandles << handle;
273  m_d->system->message(handle->clicked());
274  } else {
275  //Clear selection.
276  m_d->selAscObjHandles.clear();
277  //Add if not already selected:
278  if (!alreadyselected) {
279  m_d->selAscObjHandles << handle;
281  m_d->system->message(handle->clicked());
282  }
283  }
284  } else if (m_d->mode==SHIFT) {
285  if (Imp::shiftIsDown()) {
286  if (alreadyselected)
287  m_d->selAscObjHandles.removeAll(handle);
288  else
289  m_d->selAscObjHandles << handle;
290  } else {
291  m_d->selAscObjHandles.clear();
292  if (!alreadyselected)
293  m_d->selAscObjHandles << handle;
294  }
295  } else if (m_d->mode==TOGGLE) {
296  if (alreadyselected) {
297  m_d->selAscObjHandles.removeAll(handle);
298  } else {
299  m_d->selAscObjHandles << handle;
300  }
301  } else {
302  message("ERROR: Should not happen!");
303  deselectAll();
304  return;
305  }
306  std::sort(m_d->selAscObjHandles.begin(), m_d->selAscObjHandles.end());
307 
308  if (selHandlesBefore!=m_d->selAscObjHandles) {
311  }
312 }
313 
314 
315 //____________________________________________________________________
317 {
318  if (m_d->mode==TOGGLE)
319  return;
320  if (m_d->mode==SHIFT&&Imp::shiftIsDown())
321  return;
322  deselectAll();
323 }
324 
325 //____________________________________________________________________
327 {
328  if (m_d->selAscObjHandles.isEmpty())
329  return;
330  m_d->selAscObjHandles.clear();
333 }
334 
335 //____________________________________________________________________
336 void AscObjSelectionManager::ensureDeselected(const QList<AssociatedObjectHandleBase*>& handles)
337 {
338  if (handles.isEmpty())
339  return;
340  QList<AssociatedObjectHandleBase*> selHandlesBefore = m_d->selAscObjHandles;
341  for (AssociatedObjectHandleBase*handle : handles)
342  m_d->selAscObjHandles.removeAll(handle);
343  if (selHandlesBefore!=m_d->selAscObjHandles) {
346  }
347 }
348 
349 //____________________________________________________________________
350 void AscObjSelectionManager::ensureSelected(const QList<AssociatedObjectHandleBase*>& handles)
351 {
352  if (handles.isEmpty())
353  return;
354  if (m_d->mode==SINGLE) {
355  //Single selections
356  if (handles.count()>1)
357  message("WARNING: ensureSelected called with more than one handle in SINGLE mode. Ignoring all but the first.");
358  if (m_d->selAscObjHandles.contains(handles.at(0)))
359  return;
360  m_d->selAscObjHandles.clear();
361  m_d->selAscObjHandles << handles.at(0);
364  } else {
365  //Multi selections allowed
366  QList<AssociatedObjectHandleBase*> selHandlesBefore = m_d->selAscObjHandles;
367  for (AssociatedObjectHandleBase*handle : handles) {
368  if (!m_d->selAscObjHandles.contains(handle))
369  m_d->selAscObjHandles << handle;
370  }
371  std::sort(m_d->selAscObjHandles.begin(), m_d->selAscObjHandles.end());
372  if (selHandlesBefore!=m_d->selAscObjHandles) {
375  }
376  }
377 
378 }
379 
380 //____________________________________________________________________
382 {
383  messageVerbose("Signal received in ascObjDetailLevelChanged slot");
384  if (m_d->selAscObjHandles.isEmpty()) {
385  m_d->sel_assocobjs->deselectAll();
386  return;
387  }
388  const SoPathList * pathlist = m_d->sel_assocobjs->getList();
389  if (!pathlist||pathlist->getLength()!=m_d->selAscObjHandles.count())
390  return;
391 
392  const bool isSimpleMode = (m_d->controller->assocObjDetailLevel()==TrackCommonFlags::SIMPLE);
393  int i(0);
395  SoPath * path = (*pathlist)[i++];
396  if (!path)
397  continue;
399  (isSimpleMode?handle->shapeSimple():handle->shapeDetailed()))) {
400  message("Warning: Failed to relocate picked node.");
401  deselectAll();
402  return;
403  }
404  }
405 }
406 
407 //____________________________________________________________________
408 QList<AssociatedObjectHandleBase*> AscObjSelectionManager::currentSelection() const
409 {
410  return m_d->selAscObjHandles;
411 }
412 
414 {
415  return m_d->eventRoot;
416 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
SoCooperativeSelection::INERT
@ INERT
Definition: SoCooperativeSelection.h:41
AscObjSelectionManager::registerAscObj
void registerAscObj(SoSeparator *simple, SoSeparator *detailed, AssociatedObjectHandleBase *)
Definition: AscObjSelectionManager.cxx:140
AssociatedObjectHandleBase
Definition: AssociatedObjectHandleBase.h:33
AscObjSelectionManager::deselectAll
void deselectAll()
Definition: AscObjSelectionManager.cxx:326
AscObjSelectionManager::Imp::system
IVP13DSystem * system
Definition: AscObjSelectionManager.cxx:67
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
AscObjSelectionManager::Imp::~Imp
~Imp()
Definition: AscObjSelectionManager.cxx:57
AscObjSelectionManager::handleUserSelectedSingleNode
bool handleUserSelectedSingleNode(SoCooperativeSelection *, SoNode *, SoPath *, AssociatedObjectHandleBase *&)
Definition: AscObjSelectionManager.cxx:233
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
AscObjSelectionManager::Imp
Definition: AscObjSelectionManager.cxx:28
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:126
AscObjSelectionManager::aboutTodelete
void aboutTodelete()
Definition: AscObjSelectionManager.cxx:97
TrackCommonFlags::SIMPLE
@ SIMPLE
Definition: TrackCommonFlags.h:39
TrackSystemController.h
AscObjSelectionManager::currentSelection
QList< AssociatedObjectHandleBase * > currentSelection() const
Definition: AscObjSelectionManager.cxx:408
AscObjSelectionManager::toString
static QString toString(MODE)
Definition: AscObjSelectionManager.cxx:110
AscObjSelectionManager::getAscObjAttachSep
SoSeparator * getAscObjAttachSep() const
Definition: AscObjSelectionManager.cxx:135
AscObjSelectionManager::Imp::ascObjHandle
AssociatedObjectHandleBase * ascObjHandle(const SoPath *)
Definition: AscObjSelectionManager.cxx:187
VP1Msg.h
AscObjSelectionManager::TOGGLE
@ TOGGLE
Definition: AscObjSelectionManager.h:52
VP1HelperClassBase::messageVerbose
void messageVerbose(const QString &) const
Definition: VP1HelperClassBase.cxx:78
AscObjSelectionManager::Imp::selAscObjHandles
QList< AssociatedObjectHandleBase * > selAscObjHandles
Definition: AscObjSelectionManager.cxx:79
AscObjSelectionManager::Imp::sel_assocobjs_click
SoCooperativeSelection * sel_assocobjs_click
Definition: AscObjSelectionManager.cxx:70
fillPileUpNoiseLumi.connect
string connect
Definition: fillPileUpNoiseLumi.py:70
AscObjSelectionManager::SINGLE
@ SINGLE
Definition: AscObjSelectionManager.h:52
CSV_InDetExporter.new
new
Definition: CSV_InDetExporter.py:145
AscObjSelectionManager::Imp::operator=
Imp & operator=(const Imp &)=delete
SoCooperativeSelection::activePolicy
SoSFEnum activePolicy
Definition: SoCooperativeSelection.h:49
skel.it
it
Definition: skel.GENtoEVGEN.py:423
TrackSystemController::assocObjDetailLevel
TrackCommonFlags::DETAILLEVEL assocObjDetailLevel() const
Definition: TrackSystemController.cxx:1762
AscObjSelectionManager::mode
MODE mode() const
Definition: AscObjSelectionManager.cxx:119
AscObjSelectionManager::ensureSelected
void ensureSelected(const QList< AssociatedObjectHandleBase * > &)
Definition: AscObjSelectionManager.cxx:350
sendEI_SPB.root
root
Definition: sendEI_SPB.py:34
AscObjSelectionManager::m_d
Imp * m_d
Definition: AscObjSelectionManager.h:94
mapkey::sys
@ sys
Definition: TElectronEfficiencyCorrectionTool.cxx:42
TruthTest.itE
itE
Definition: TruthTest.py:25
VP1QtInventorUtils.h
AscObjSelectionManager::~AscObjSelectionManager
virtual ~AscObjSelectionManager()
Definition: AscObjSelectionManager.cxx:103
AscObjSelectionManager::pretendUserClicked
void pretendUserClicked(AssociatedObjectHandleBase *)
Definition: AscObjSelectionManager.cxx:259
AscObjSelectionManager::Imp::ascobjs_simpleToHandle
std::map< SoSeparator *, AssociatedObjectHandleBase * > ascobjs_simpleToHandle
Definition: AscObjSelectionManager.cxx:73
AssociatedObjectHandleBase.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
sel
sel
Definition: SUSYToolsTester.cxx:92
IVP13DSystem.h
AscObjSelectionManager::ascObjDetailLevelChanged
void ascObjDetailLevelChanged()
Definition: AscObjSelectionManager.cxx:381
AscObjSelectionManager.h
AscObjSelectionManager::Imp::updateSelectionVisuals
void updateSelectionVisuals()
Definition: AscObjSelectionManager.cxx:213
TrackSystemController::printInfoOnSingleSelection
bool printInfoOnSingleSelection() const
Definition: TrackSystemController.cxx:1967
VP1HelperClassBase
Definition: VP1HelperClassBase.h:28
AscObjSelectionManager::MODE
MODE
Definition: AscObjSelectionManager.h:52
AscObjSelectionManager::Imp::theclass
AscObjSelectionManager * theclass
Definition: AscObjSelectionManager.cxx:65
AscObjSelectionManager::userClickedOnBgd
void userClickedOnBgd()
Definition: AscObjSelectionManager.cxx:316
AscObjSelectionManager::Imp::Imp
Imp(AscObjSelectionManager *tc, SoSeparator *root, IVP13DSystem *sys, TrackSystemController *c)
Definition: AscObjSelectionManager.cxx:30
AscObjSelectionManager::Imp::eventRoot
SoSeparator * eventRoot
Definition: AscObjSelectionManager.cxx:66
SoCooperativeSelection::ACTIVE
@ ACTIVE
Definition: SoCooperativeSelection.h:41
SoCooperativeSelection.h
TrackSystemController
Definition: TrackSystemController.h:53
AscObjSelectionManager::unregisterAscObj
void unregisterAscObj(SoSeparator *simple, SoSeparator *detailed)
Definition: AscObjSelectionManager.cxx:164
AscObjSelectionManager
Definition: AscObjSelectionManager.h:37
AscObjSelectionManager::setMode
void setMode(MODE)
Definition: AscObjSelectionManager.cxx:125
AscObjSelectionManager::Imp::Imp
Imp(const Imp &)=delete
AscObjSelectionManager::Imp::controller
TrackSystemController * controller
Definition: AscObjSelectionManager.cxx:68
AscObjSelectionManager::SHIFT
@ SHIFT
Definition: AscObjSelectionManager.h:52
IVP13DSystem::unregisterSelectionNode
void unregisterSelectionNode(SoCooperativeSelection *)
Definition: IVP13DSystem.cxx:281
IVP13DSystem
Definition: IVP13DSystem.h:31
AscObjSelectionManager::Imp::mode
MODE mode
Definition: AscObjSelectionManager.cxx:69
AssociatedObjectHandleBase::shapeSimple
SoSeparator * shapeSimple() const
Definition: AssociatedObjectHandleBase.cxx:200
VP1HelperClassBase::message
void message(const QString &) const
Definition: VP1HelperClassBase.cxx:49
TrackCommonFlags::DETAILLEVEL
DETAILLEVEL
Definition: TrackCommonFlags.h:39
str
Definition: BTagTrackIpAccessor.cxx:11
AscObjSelectionManager::Imp::shiftIsDown
static bool shiftIsDown()
Definition: AscObjSelectionManager.cxx:82
AscObjSelectionManager::AscObjSelectionManager
AscObjSelectionManager(SoSeparator *eventRoot, IVP13DSystem *, TrackSystemController *)
Definition: AscObjSelectionManager.cxx:89
AssociatedObjectHandleBase::shapeDetailed
SoSeparator * shapeDetailed() const
Definition: AssociatedObjectHandleBase.cxx:206
VP1Msg::verbose
static bool verbose()
Definition: VP1Msg.h:31
AssociatedObjectHandleBase::clicked
virtual QStringList clicked()=0
AscObjSelectionManager::Imp::ascobjs_detailedToHandle
std::map< SoSeparator *, AssociatedObjectHandleBase * > ascobjs_detailedToHandle
Definition: AscObjSelectionManager.cxx:74
AscObjSelectionManager::ensureDeselected
void ensureDeselected(const QList< AssociatedObjectHandleBase * > &)
Definition: AscObjSelectionManager.cxx:336
python.compressB64.c
def c
Definition: compressB64.py:93
AscObjSelectionManager::currentSelectionChanged
void currentSelectionChanged(const QList< AssociatedObjectHandleBase * > &)
AscObjSelectionManager::Imp::sel_assocobjs
SoCooperativeSelection * sel_assocobjs
Definition: AscObjSelectionManager.cxx:71
VP1QtInventorUtils::changePathTail
static bool changePathTail(SoPath *path, SoNode *commonBranchPoint, SoNode *newtail)
Definition: VP1QtInventorUtils.cxx:1346
IVP1System::message
void message(const QString &) const
Definition: IVP1System.cxx:336
SoCooperativeSelection
Definition: SoCooperativeSelection.h:29
AscObjSelectionManager::eventRoot
SoSeparator * eventRoot()
Definition: AscObjSelectionManager.cxx:413