Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
// -*- C++ -*-
//
// Package:     Core
// Class  :     FWParameterSetterBase
//
// Implementation:
//     <Notes on implementation>
//
// Original Author:  Chris Jones
//         Created:  Fri Mar  7 14:16:20 EST 2008
//

// system include files
#include "FWCore/Reflection/interface/TypeWithDict.h"
#include "FWCore/Reflection/interface/ObjectWithDict.h"

#include <cassert>
#include <iostream>
#include <functional>

// user include files
#include "FWCore/Utilities/interface/TypeID.h"

#include "Fireworks/Core/interface/FWParameterSetterBase.h"
#include "Fireworks/Core/interface/FWParameterBase.h"
#include "Fireworks/Core/interface/FWParameterSetterEditorBase.h"
#include "Fireworks/Core/interface/fwLog.h"

//
// constants, enums and typedefs
//

//
// static data member definitions
//

//
// constructors and destructor
//
FWParameterSetterBase::FWParameterSetterBase() : m_frame(nullptr) {}

// FWParameterSetterBase::FWParameterSetterBase(const FWParameterSetterBase& rhs)
// {
//    // do actual copying here;
// }

FWParameterSetterBase::~FWParameterSetterBase() {}

//
// assignment operators
//
// const FWParameterSetterBase& FWParameterSetterBase::operator=(const FWParameterSetterBase& rhs)
// {
//   //An exception safe implementation is
//   FWParameterSetterBase temp(rhs);
//   swap(rhs);
//
//   return *this;
// }

//
// member functions
//

void FWParameterSetterBase::attach(FWParameterBase* iBase, FWParameterSetterEditorBase* iFrame) {
  m_frame = iFrame;
  attach(iBase);
}

//
// const member functions
//

void FWParameterSetterBase::update() const {
  if (m_frame != nullptr)
    m_frame->updateEditor();
}

//
// static member functions
//

std::shared_ptr<FWParameterSetterBase> FWParameterSetterBase::makeSetterFor(FWParameterBase* iParam) {
  static std::map<edm::TypeID, edm::TypeWithDict> s_paramToSetterMap;
  edm::TypeID paramType(typeid(*iParam));
  std::map<edm::TypeID, edm::TypeWithDict>::iterator itFind = s_paramToSetterMap.find(paramType);
  if (itFind == s_paramToSetterMap.end()) {
    edm::TypeWithDict paramClass(typeid(*iParam));
    if (paramClass == edm::TypeWithDict()) {
      fwLog(fwlog::kError) << " the type " << typeid(*iParam).name() << " is not known to Root" << std::endl;
    }
    assert(paramClass != edm::TypeWithDict());

    //the corresponding setter has the same name but with 'Setter' at the end
    std::string name = paramClass.name();
    // FIXME: there was a convention between parameter class names and associated
    //        setters. The following works around the problem introduced by
    //        the generic parameter class but it is clear that a better
    //        way of doing the binding is required. Notice that there are only 5
    //        different type of FW*Parameter.
    if (name == "FWGenericParameter<bool>")
      name = "FWBoolParameterSetter";
    else if (name == "FWGenericParameterWithRange<double>")
      name = "FWDoubleParameterSetter";
    else if (name == "FWGenericParameterWithRange<long int>")
      name = "FWLongParameterSetter";
    else if (name == "FWGenericParameterWithRange<long>")
      name = "FWLongParameterSetter";
    else if (paramClass.friendlyClassName() == "StringFWGenericParameter")
      name = "FWStringParameterSetter";
    else {
      name += "Setter";
      fwLog(fwlog::kWarning) << "can't find setter type for " << iParam->name() << ", guessing to " << name << "\n";
    }
    edm::TypeWithDict setterClass(edm::TypeWithDict::byName(name));

    if (setterClass == edm::TypeWithDict()) {
      fwLog(fwlog::kError) << " the type " << name << " has no dictionary" << std::endl;
    }
    assert(setterClass != edm::TypeWithDict());

    s_paramToSetterMap[paramType] = setterClass;
    itFind = s_paramToSetterMap.find(paramType);
  }
  //create the instance we want
  //NOTE: 'construct' will use 'malloc' to allocate the memory if the object is not of class type.
  // This means the object cannot be deleted using 'delete'!  So we must call destruct on the object.
  edm::ObjectWithDict setterObj = itFind->second.construct();

  //make it into the base class
  FWParameterSetterBase* p = static_cast<FWParameterSetterBase*>(setterObj.address());
  //Make a shared pointer to the base class that uses a destructor for the derived class, in order to match the above construct call.
  std::shared_ptr<FWParameterSetterBase> ptr(
      p, std::bind(&edm::TypeWithDict::destruct, itFind->second, setterObj.address(), true));
  return ptr;
}

/* Virtual function which sets widgets enabled state.*/
void FWParameterSetterBase::setEnabled(bool) {}