TaskDialogPython.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2011 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 
00026 #ifndef _PreComp_
00027 # include <sstream>
00028 # include <QPointer>
00029 #endif
00030 
00031 #include "TaskDialogPython.h"
00032 #include "TaskView.h"
00033 
00034 #include <Gui/Application.h>
00035 #include <Gui/BitmapFactory.h>
00036 #include <Gui/Command.h>
00037 #include <Gui/Control.h>
00038 #include <Gui/WidgetFactory.h>
00039 #include <Base/Interpreter.h>
00040 #include <Base/Console.h>
00041 #include <CXX/Objects.hxx>
00042 
00043 using namespace Gui;
00044 using namespace Gui::TaskView;
00045 
00046 ControlPy* ControlPy::instance = 0;
00047 
00048 ControlPy* ControlPy::getInstance()
00049 {
00050     if (!instance)
00051         instance = new ControlPy();
00052     return instance;
00053 }
00054 
00055 void ControlPy::init_type()
00056 {
00057     behaviors().name("Control");
00058     behaviors().doc("Control for task dialogs");
00059     // you must have overwritten the virtual functions
00060     behaviors().supportRepr();
00061     behaviors().supportGetattr();
00062     behaviors().supportSetattr();
00063     add_varargs_method("showDialog",&ControlPy::showDialog,"showDialog()");
00064     add_varargs_method("activeDialog",&ControlPy::activeDialog,"activeDialog()");
00065     add_varargs_method("closeDialog",&ControlPy::closeDialog,"closeDialog()");
00066     add_varargs_method("addTaskWatcher",&ControlPy::addTaskWatcher,"addTaskWatcher()");
00067     add_varargs_method("clearTaskWatcher",&ControlPy::clearTaskWatcher,"clearTaskWatcher()");
00068     add_varargs_method("isAllowedAlterDocument",&ControlPy::isAllowedAlterDocument,"isAllowedAlterDocument()");
00069     add_varargs_method("isAllowedAlterView",&ControlPy::isAllowedAlterView,"isAllowedAlterView()");
00070     add_varargs_method("isAllowedAlterSelection",&ControlPy::isAllowedAlterSelection,"isAllowedAlterSelection()");
00071 }
00072 
00073 ControlPy::ControlPy()
00074 {
00075 }
00076 
00077 ControlPy::~ControlPy()
00078 {
00079 }
00080 
00081 Py::Object ControlPy::repr()
00082 {
00083     std::string s;
00084     std::ostringstream s_out;
00085     s_out << "Control Task Dialog";
00086     return Py::String(s_out.str());
00087 }
00088 
00089 Py::Object ControlPy::showDialog(const Py::Tuple& args)
00090 {
00091     Gui::TaskView::TaskDialog* act = Gui::Control().activeDialog();
00092     if (act)
00093         throw Py::Exception("Active task dialog found");
00094     TaskDialogPython* dlg = new TaskDialogPython(args[0]);
00095     Gui::Control().showDialog(dlg);
00096     return Py::None();
00097 }
00098 
00099 Py::Object ControlPy::activeDialog(const Py::Tuple& args)
00100 {
00101     Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
00102     return Py::Boolean(dlg!=0);
00103 }
00104 
00105 Py::Object ControlPy::closeDialog(const Py::Tuple&)
00106 {
00107     Gui::Control().closeDialog();
00108     return Py::None();
00109 }
00110 
00111 Py::Object ControlPy::addTaskWatcher(const Py::Tuple& args)
00112 {
00113     std::vector<Gui::TaskView::TaskWatcher*> watcher;
00114     Py::List list(args[0]);
00115     for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00116         TaskWatcherPython* w = new TaskWatcherPython(*it);
00117         watcher.push_back(w);
00118     }
00119 
00120     Gui::TaskView::TaskView* taskView = Gui::Control().taskPanel();
00121     if (taskView)
00122         taskView->addTaskWatcher(watcher);
00123     return Py::None();
00124 }
00125 
00126 Py::Object ControlPy::clearTaskWatcher(const Py::Tuple&)
00127 {
00128     Gui::TaskView::TaskView* taskView = Gui::Control().taskPanel();
00129     if (taskView)
00130         taskView->clearTaskWatcher();
00131     return Py::None();
00132 }
00133 
00134 Py::Object ControlPy::isAllowedAlterDocument(const Py::Tuple&)
00135 {
00136     bool ok = Gui::Control().isAllowedAlterDocument();
00137     return Py::Boolean(ok);
00138 }
00139 
00140 Py::Object ControlPy::isAllowedAlterView(const Py::Tuple&)
00141 {
00142     bool ok = Gui::Control().isAllowedAlterView();
00143     return Py::Boolean(ok);
00144 }
00145 
00146 Py::Object ControlPy::isAllowedAlterSelection(const Py::Tuple&)
00147 {
00148     bool ok = Gui::Control().isAllowedAlterSelection();
00149     return Py::Boolean(ok);
00150 }
00151 
00152 // ------------------------------------------------------------------
00153 
00154 TaskWatcherPython::TaskWatcherPython(const Py::Object& o)
00155   : TaskWatcher(0), watcher(o)
00156 {
00157     QString title;
00158     if (watcher.hasAttr(std::string("title"))) {
00159         Py::String name(watcher.getAttr(std::string("title")));
00160         std::string s = (std::string)name;
00161         title = QString::fromUtf8(s.c_str());
00162     }
00163 
00164     QPixmap icon;
00165     if (watcher.hasAttr(std::string("icon"))) {
00166         Py::String name(watcher.getAttr(std::string("icon")));
00167         std::string s = (std::string)name;
00168         icon = BitmapFactory().pixmap(s.c_str());
00169     }
00170 
00171     Gui::TaskView::TaskBox *tb = 0;
00172     if (watcher.hasAttr(std::string("commands"))) {
00173         if (!tb) tb = new Gui::TaskView::TaskBox(icon, title, true, 0);
00174         Py::List cmds(watcher.getAttr(std::string("commands")));
00175         CommandManager &mgr = Gui::Application::Instance->commandManager();
00176         for (Py::List::iterator it = cmds.begin(); it != cmds.end(); ++it) {
00177             Py::String name(*it);
00178             std::string s = (std::string)name;
00179             Command *c = mgr.getCommandByName(s.c_str());
00180             if (c)
00181                 c->addTo(tb);
00182         }
00183     }
00184 
00185     if (watcher.hasAttr(std::string("widgets"))) {
00186         if (!tb && !title.isEmpty())
00187             tb = new Gui::TaskView::TaskBox(icon, title, true, 0);
00188         Py::List list(watcher.getAttr(std::string("widgets")));
00189         Py::Module mainmod(PyImport_AddModule((char*)"sip"));
00190         Py::Callable func = mainmod.getDict().getItem("unwrapinstance");
00191         for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00192             Py::Tuple arguments(1);
00193             arguments[0] = *it; //PyQt pointer
00194             Py::Object result = func.apply(arguments);
00195             void* ptr = PyLong_AsVoidPtr(result.ptr());
00196             QObject* object = reinterpret_cast<QObject*>(ptr);
00197             if (object) {
00198                 QWidget* w = qobject_cast<QWidget*>(object);
00199                 if (w) {
00200                     if (tb)
00201                         tb->groupLayout()->addWidget(w);
00202                     else
00203                         Content.push_back(w);
00204                 }
00205             }
00206         }
00207     }
00208 
00209     if (tb) Content.push_back(tb);
00210 
00211     if (watcher.hasAttr(std::string("filter"))) {
00212         Py::String name(watcher.getAttr(std::string("filter")));
00213         std::string s = (std::string)name;
00214         this->setFilter(s.c_str());
00215     }
00216 }
00217 
00218 TaskWatcherPython::~TaskWatcherPython()
00219 {
00220     std::vector< QPointer<QWidget> > guarded;
00221     guarded.insert(guarded.begin(), Content.begin(), Content.end());
00222     Content.clear();
00223     Base::PyGILStateLocker lock;
00224     this->watcher = Py::None();
00225     Content.insert(Content.begin(), guarded.begin(), guarded.end());
00226 }
00227 
00228 bool TaskWatcherPython::shouldShow()
00229 {
00230     Base::PyGILStateLocker lock;
00231     try {
00232         if (watcher.hasAttr(std::string("shouldShow"))) {
00233             Py::Callable method(watcher.getAttr(std::string("shouldShow")));
00234             Py::Tuple args(0);
00235             Py::Boolean ret(method.apply(args));
00236             return (bool)ret;
00237         }
00238     }
00239     catch (Py::Exception&) {
00240         Base::PyException e; // extract the Python error text
00241         Base::Console().Error("TaskWatcherPython::shouldShow: %s\n", e.what());
00242     }
00243 
00244     if (!this->Filter.empty())
00245         return match();
00246     else
00247         return TaskWatcher::shouldShow();
00248 }
00249 
00250 // ------------------------------------------------------------------
00251 
00252 TaskDialogPython::TaskDialogPython(const Py::Object& o) : dlg(o)
00253 {
00254     if (dlg.hasAttr(std::string("ui"))) {
00255         UiLoader loader;
00256 #if QT_VERSION >= 0x040500
00257         loader.setLanguageChangeEnabled(true);
00258 #endif
00259         QString fn, icon;
00260         Py::String ui(dlg.getAttr(std::string("ui")));
00261         std::string path = (std::string)ui;
00262         fn = QString::fromUtf8(path.c_str());
00263 
00264         QFile file(fn);
00265         QWidget* form = 0;
00266         if (file.open(QFile::ReadOnly))
00267             form = loader.load(&file, 0);
00268         file.close();
00269         if (form) {
00270             Gui::TaskView::TaskBox* taskbox = new Gui::TaskView::TaskBox(
00271                 QPixmap(icon), form->windowTitle(), true, 0);
00272             taskbox->groupLayout()->addWidget(form);
00273             Content.push_back(taskbox);
00274         }
00275         else {
00276             Base::Console().Error("Failed to load UI file from '%s'\n",
00277                 (const char*)fn.toUtf8());
00278         }
00279     }
00280     else if (dlg.hasAttr(std::string("form"))) {
00281         Py::Object widget(dlg.getAttr(std::string("form")));
00282         Py::Module mainmod(PyImport_AddModule((char*)"sip"));
00283         Py::Callable func = mainmod.getDict().getItem("unwrapinstance");
00284         Py::Tuple arguments(1);
00285         arguments[0] = widget; //PyQt pointer
00286         Py::Object result = func.apply(arguments);
00287         void* ptr = PyLong_AsVoidPtr(result.ptr());
00288         QObject* object = reinterpret_cast<QObject*>(ptr);
00289         if (object) {
00290             QWidget* form = qobject_cast<QWidget*>(object);
00291             if (form) {
00292                 Gui::TaskView::TaskBox* taskbox = new Gui::TaskView::TaskBox(
00293                     form->windowIcon().pixmap(32), form->windowTitle(), true, 0);
00294                 taskbox->groupLayout()->addWidget(form);
00295                 Content.push_back(taskbox);
00296             }
00297         }
00298     }
00299 }
00300 
00301 TaskDialogPython::~TaskDialogPython()
00302 {
00303     std::vector< QPointer<QWidget> > guarded;
00304     guarded.insert(guarded.begin(), Content.begin(), Content.end());
00305     Content.clear();
00306     Base::PyGILStateLocker lock;
00307     this->dlg = Py::None();
00308     Content.insert(Content.begin(), guarded.begin(), guarded.end());
00309 }
00310 
00311 void TaskDialogPython::open()
00312 {
00313     Base::PyGILStateLocker lock;
00314     try {
00315         if (dlg.hasAttr(std::string("open"))) {
00316             Py::Callable method(dlg.getAttr(std::string("open")));
00317             Py::Tuple args(0);
00318             method.apply(args);
00319         }
00320     }
00321     catch (Py::Exception&) {
00322         Base::PyException e; // extract the Python error text
00323         Base::Console().Error("TaskDialogPython::open: %s\n", e.what());
00324     }
00325 }
00326 
00327 void TaskDialogPython::clicked(int i)
00328 {
00329     Base::PyGILStateLocker lock;
00330     try {
00331         if (dlg.hasAttr(std::string("clicked"))) {
00332             Py::Callable method(dlg.getAttr(std::string("clicked")));
00333             Py::Tuple args(1);
00334             args.setItem(0, Py::Int(i));
00335             method.apply(args);
00336         }
00337     }
00338     catch (Py::Exception&) {
00339         Base::PyException e; // extract the Python error text
00340         Base::Console().Error("TaskDialogPython::clicked: %s\n", e.what());
00341     }
00342 }
00343 
00344 bool TaskDialogPython::accept()
00345 {
00346     Base::PyGILStateLocker lock;
00347     try {
00348         if (dlg.hasAttr(std::string("accept"))) {
00349             Py::Callable method(dlg.getAttr(std::string("accept")));
00350             Py::Tuple args(0);
00351             Py::Boolean ret(method.apply(args));
00352             return (bool)ret;
00353         }
00354     }
00355     catch (Py::Exception&) {
00356         Base::PyException e; // extract the Python error text
00357         Base::Console().Error("TaskDialogPython::accept: %s\n", e.what());
00358     }
00359 
00360     return TaskDialog::accept();
00361 }
00362 
00363 bool TaskDialogPython::reject()
00364 {
00365     Base::PyGILStateLocker lock;
00366     try {
00367         if (dlg.hasAttr(std::string("reject"))) {
00368             Py::Callable method(dlg.getAttr(std::string("reject")));
00369             Py::Tuple args(0);
00370             Py::Boolean ret(method.apply(args));
00371             return (bool)ret;
00372         }
00373     }
00374     catch (Py::Exception&) {
00375         Base::PyException e; // extract the Python error text
00376         Base::Console().Error("TaskDialogPython::reject: %s\n", e.what());
00377     }
00378 
00379     return TaskDialog::reject();
00380 }
00381 
00382 void TaskDialogPython::helpRequested()
00383 {
00384     Base::PyGILStateLocker lock;
00385     try {
00386         if (dlg.hasAttr(std::string("helpRequested"))) {
00387             Py::Callable method(dlg.getAttr(std::string("helpRequested")));
00388             Py::Tuple args(0);
00389             method.apply(args);
00390         }
00391     }
00392     catch (Py::Exception&) {
00393         Base::PyException e; // extract the Python error text
00394         Base::Console().Error("TaskDialogPython::helpRequested: %s\n", e.what());
00395     }
00396 }
00397 
00398 QDialogButtonBox::StandardButtons TaskDialogPython::getStandardButtons(void) const
00399 {
00400     Base::PyGILStateLocker lock;
00401     try {
00402         if (dlg.hasAttr(std::string("getStandardButtons"))) {
00403             Py::Callable method(dlg.getAttr(std::string("getStandardButtons")));
00404             Py::Tuple args(0);
00405             Py::Int ret(method.apply(args));
00406             int value = (int)ret;
00407             return QDialogButtonBox::StandardButtons(value);
00408         }
00409     }
00410     catch (Py::Exception&) {
00411         Base::PyException e; // extract the Python error text
00412         Base::Console().Error("TaskDialogPython::getStandardButtons: %s\n", e.what());
00413     }
00414 
00415     return TaskDialog::getStandardButtons();
00416 }
00417 
00418 void TaskDialogPython::modifyStandardButtons(QDialogButtonBox*)
00419 {
00420 }
00421 
00422 bool TaskDialogPython::isAllowedAlterDocument(void) const
00423 {
00424     Base::PyGILStateLocker lock;
00425     try {
00426         if (dlg.hasAttr(std::string("isAllowedAlterDocument"))) {
00427             Py::Callable method(dlg.getAttr(std::string("isAllowedAlterDocument")));
00428             Py::Tuple args(0);
00429             Py::Boolean ret(method.apply(args));
00430             return (bool)ret;
00431         }
00432     }
00433     catch (Py::Exception&) {
00434         Base::PyException e; // extract the Python error text
00435         Base::Console().Error("TaskDialogPython::isAllowedAlterDocument: %s\n", e.what());
00436     }
00437 
00438     return TaskDialog::isAllowedAlterDocument();
00439 }
00440 
00441 bool TaskDialogPython::isAllowedAlterView(void) const
00442 {
00443     Base::PyGILStateLocker lock;
00444     try {
00445         if (dlg.hasAttr(std::string("isAllowedAlterView"))) {
00446             Py::Callable method(dlg.getAttr(std::string("isAllowedAlterView")));
00447             Py::Tuple args(0);
00448             Py::Boolean ret(method.apply(args));
00449             return (bool)ret;
00450         }
00451     }
00452     catch (Py::Exception&) {
00453         Base::PyException e; // extract the Python error text
00454         Base::Console().Error("TaskDialogPython::isAllowedAlterView: %s\n", e.what());
00455     }
00456 
00457     return TaskDialog::isAllowedAlterView();
00458 }
00459 
00460 bool TaskDialogPython::isAllowedAlterSelection(void) const
00461 {
00462     Base::PyGILStateLocker lock;
00463     try {
00464         if (dlg.hasAttr(std::string("isAllowedAlterSelection"))) {
00465             Py::Callable method(dlg.getAttr(std::string("isAllowedAlterSelection")));
00466             Py::Tuple args(0);
00467             Py::Boolean ret(method.apply(args));
00468             return (bool)ret;
00469         }
00470     }
00471     catch (Py::Exception&) {
00472         Base::PyException e; // extract the Python error text
00473         Base::Console().Error("TaskDialogPython::isAllowedAlterSelection: %s\n", e.what());
00474     }
00475 
00476     return TaskDialog::isAllowedAlterSelection();
00477 }
00478 
00479 bool TaskDialogPython::needsFullSpace() const
00480 {
00481     Base::PyGILStateLocker lock;
00482     try {
00483         if (dlg.hasAttr(std::string("needsFullSpace"))) {
00484             Py::Callable method(dlg.getAttr(std::string("needsFullSpace")));
00485             Py::Tuple args(0);
00486             Py::Boolean ret(method.apply(args));
00487             return (bool)ret;
00488         }
00489     }
00490     catch (Py::Exception&) {
00491         Base::PyException e; // extract the Python error text
00492         Base::Console().Error("TaskDialogPython::needsFullSpace: %s\n", e.what());
00493     }
00494 
00495     return TaskDialog::needsFullSpace();
00496 }
00497 

Generated on Wed Nov 23 19:00:42 2011 for FreeCAD by  doxygen 1.6.1