File: PythonHotPlugAction.cpp

package info (click to toggle)
camitk 6.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 389,496 kB
  • sloc: cpp: 103,476; sh: 2,448; python: 1,618; xml: 984; makefile: 128; perl: 84; sed: 20
file content (134 lines) | stat: -rw-r--r-- 5,517 bytes parent folder | download
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
/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK 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 version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/

#ifdef PYTHON_BINDING

#include "PythonHotPlugAction.h"
#include "PythonHotPlugActionExtension.h"

#include "ActionWidget.h"
#include "Application.h"
#include "Log.h"

#include <TransformEngine.h>
#include <VariantDataModel.h>

namespace camitk {

// ------------------- Constructor -------------------
PythonHotPlugAction::PythonHotPlugAction(PythonHotPlugActionExtension* extension, const VariantDataModel& data) : HotPlugAction(extension, data) {
    pythonExtension = extension;

    TransformEngine transformEngine;
    QJsonObject dataObject = data.getValue().toJsonObject();

    // determine python script name and other values
    pythonName = transformEngine.transformToString("$lowerSnakeCase(name)$", dataObject);
    noGui = (dataObject["gui"].toString() == "No GUI");
}

// ------------------- init -------------------
bool PythonHotPlugAction::init() {
    // call the init() function in python
    PythonHotPlugActionExtension::PythonCallStatus status = pythonExtension->callPython(this, "init");
    // Returns true when either everything went well or the init() method is missing in the python script
    return (status == PythonHotPlugActionExtension::PythonCallStatus::SUCCESS
            || status == PythonHotPlugActionExtension::PythonCallStatus::MISSING_FUNCTION);
}

// ------------------- getPythonName -------------------
QString PythonHotPlugAction::getPythonName() {
    return pythonName;
}

// ------------------- getWidget -------------------
QWidget* PythonHotPlugAction::getWidget() {
    if (noGui) {
        // this won't generate an error when the parameterChanged() method is missing in the python script (only an info message)
        pythonExtension->callPython(this, "targetDefined");
        return nullptr;
    }

    // Get UI, then call targetDefined
    if (actionWidget == nullptr) {
        // create default widget
        QWidget* defaultWidget = Action::getWidget();

        return defaultWidget;
    }
    else {
        // this won't generate an error when the parameterChanged() method is missing in the python script (only an info message)
        pythonExtension->callPython(this, "targetDefined");

        ActionWidget* defaultActionWidget = dynamic_cast<ActionWidget*>(actionWidget);
        if (defaultActionWidget != nullptr) {
            // this is a default action widget, make sure the widget has updated targets
            defaultActionWidget->update();
        }
        return actionWidget;
    }
}

// ------------------- apply -------------------
Action::ApplyStatus PythonHotPlugAction::apply() {
    // set waiting cursor
    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));

    // call python and check the results
    PythonHotPlugActionExtension::PythonCallStatus status = pythonExtension->callPython(this, "process");
    Action::ApplyStatus applyStatus;
    if (status == PythonHotPlugActionExtension::PythonCallStatus::SUCCESS) {
        applyStatus = Action::SUCCESS;
    }
    else {
        // process() method is missing or something went wrong
        applyStatus = Action::ERROR;
        // callPython will only use INFO level for these two errors,
        // but in this specific case, the user should know → send a warning
        if (status == PythonHotPlugActionExtension::PythonCallStatus::NOT_A_FUNCTION) {
            CAMITK_ERROR_ALT("Error during call to method process() of action '" + getName() + "': " + "Python script '" + getPythonName() + ".py" + "' has symbol 'process' but it is not a function. Expecting 'def process(self:camitk.Action):'");
        }
        else {
            if (status == PythonHotPlugActionExtension::PythonCallStatus::MISSING_FUNCTION) {
                CAMITK_ERROR_ALT("Error during call to method process() of action '" + getName() + "': " + "Python script '" + getPythonName() + ".py" + "' missing function 'process(self)'. Expecting 'def process(self:camitk.Action):'");
            }
        }
    }

    // restore normal cursor
    QApplication::restoreOverrideCursor();

    return applyStatus;
}

// ---------------------- parameterChangedEvent ----------------------------
void PythonHotPlugAction::parameterChangedEvent(QString parameterName) {
    // this won't generate an error when the parameterChanged() method is missing in the python script (only an info message)
    pythonExtension->callPython(this, "parameterChanged", parameterName);
}

} // namespace camitk

#endif // PYTHON_BINDING