File: sip_handler.hh

package info (click to toggle)
openstructure 2.9.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 205,228 kB
  • sloc: cpp: 188,129; python: 35,361; ansic: 34,298; fortran: 3,275; sh: 286; xml: 146; makefile: 29
file content (106 lines) | stat: -rw-r--r-- 3,104 bytes parent folder | download | duplicates (4)
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
//------------------------------------------------------------------------------
// This file is part of the OpenStructure project <www.openstructure.org>
//
// Copyright (C) 2008-2020 by the OpenStructure authors
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 3.0 of the License, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//------------------------------------------------------------------------------
#ifndef OST_GUI_SIP_HANDLER_HH
#define OST_GUI_SIP_HANDLER_HH

#include <boost/python.hpp>
#include <iostream>
#include <QWidget>

#include <ost/message.hh>

using namespace boost::python;

/*
   Author: Ansgar Philippsen, Marco Biasini
 */

namespace ost { namespace gui {


template <class O> object get_py_qobject(O* cpp_object)
{
  if (cpp_object != NULL){
    static object pyqt5_module=import("PyQt5.QtCore");
    static object sip_module=import("sip");
    QObject* qobject = qobject_cast<QObject*>(cpp_object);
    unsigned long addr = reinterpret_cast<unsigned long>(qobject);
    object py_qobject = pyqt5_module.attr("QObject");
    object object = sip_module.attr("wrapinstance")(addr, py_qobject);
    return object;
  }
  return object();
};


template <class O> O* get_cpp_qobject(object py_object)
{
  if(py_object.ptr() != Py_None){
    if(PyObject_HasAttrString(py_object.ptr(), "qobject")){
      py_object = py_object.attr("qobject");
    }
    static object pyqt5_module=import("PyQt5.QtCore");
    static object sip_module=import("sip");
    unsigned long addr = extract<unsigned long>(sip_module.attr("unwrapinstance")(py_object));
    if(addr){
      return reinterpret_cast<O*>(addr);
    }
  }
  return NULL;
};

class SipHandlerBase {
public:
  virtual ~SipHandlerBase() {}  
  virtual unsigned long GetSipHandle() const { return 0; }
};

template <typename T>
class SipHandler : public SipHandlerBase {
public:
  explicit SipHandler(T* instance):
    instance_(instance)
  { }

  virtual unsigned long GetSipHandle() const 
  {
    // cast to QWidget first, before doing reinterpret cast to avoid problems
    // with multiple inheritance.
    return reinterpret_cast<unsigned long>((QWidget*)instance_);
  }
  T* Me() { 
    if(!instance_) throw Error("SipHandler is no longer valid");
    return instance_; 
  }
  const T* Me() const { 
    if(!instance_) throw Error("SipHandler is no longer valid");
    return instance_; 
  }
  void Release(T* p){
    if(Me()==p){
      instance_=0;
    }
  }
private:
  T* instance_;
};
 
}}

#endif