Gui/Command.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de>              *
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 #ifndef _PreComp_
00026 # include <QDir>
00027 # include <QKeySequence>
00028 # include <QMessageBox>
00029 # include <Inventor/actions/SoGetBoundingBoxAction.h>
00030 # include <Inventor/nodes/SoOrthographicCamera.h>
00031 # include <Inventor/nodes/SoPerspectiveCamera.h>
00032 #endif
00033 
00034 #include "Command.h"
00035 #include "Action.h"
00036 #include "Application.h"
00037 #include "Document.h"
00038 #include "Selection.h"
00039 #include "HelpView.h"
00040 #include "Macro.h"
00041 #include "MainWindow.h"
00042 #include "DlgUndoRedo.h"
00043 #include "BitmapFactory.h"
00044 #include "WhatsThis.h"
00045 #include "WaitCursor.h"
00046 #include "Control.h"
00047 #include "View3DInventor.h"
00048 #include "View3DInventorViewer.h"
00049 
00050 #include <Base/Console.h>
00051 #include <Base/Exception.h>
00052 #include <Base/Interpreter.h>
00053 #include <Base/Sequencer.h>
00054 
00055 #include <App/Document.h>
00056 #include <App/DocumentObject.h>
00057 
00058 
00059 using Base::Interpreter;
00060 using namespace Gui;
00061 using namespace Gui::Dialog;
00062 using namespace Gui::DockWnd;
00063 
00121 CommandBase::CommandBase( const char* sMenu, const char* sToolTip, const char* sWhat,
00122                           const char* sStatus, const char* sPixmap, const char* sAcc)
00123         : sMenuText(sMenu), sToolTipText(sToolTip), sWhatsThis(sWhat?sWhat:sToolTip),
00124         sStatusTip(sStatus?sStatus:sToolTip), sPixmap(sPixmap), sAccel(sAcc), _pcAction(0)
00125 {
00126 }
00127 
00128 CommandBase::~CommandBase()
00129 {
00130     //Note: The Action object becomes a children of MainWindow which gets destoyed _before_ the
00131     //command manager hence before any command object. So the action pointer is a dangling pointer
00132     //at this state.
00133 }
00134 
00135 Action* CommandBase::getAction() const
00136 {
00137     return _pcAction;
00138 }
00139 
00140 Action * CommandBase::createAction()
00141 {
00142     // does nothing
00143     return 0;
00144 }
00145 
00146 void CommandBase::setMenuText(const char* s)
00147 {
00148 #if defined (_MSC_VER)
00149     this->sMenuText = _strdup(s);
00150 #else
00151     this->sMenuText = strdup(s);
00152 #endif
00153 }
00154 
00155 void CommandBase::setToolTipText(const char* s)
00156 {
00157 #if defined (_MSC_VER)
00158     this->sToolTipText = _strdup(s);
00159 #else
00160     this->sToolTipText = strdup(s);
00161 #endif
00162 }
00163 
00164 void CommandBase::setStatusTip(const char* s)
00165 {
00166 #if defined (_MSC_VER)
00167     this->sStatusTip = _strdup(s);
00168 #else
00169     this->sStatusTip = strdup(s);
00170 #endif
00171 }
00172 
00173 void CommandBase::setWhatsThis(const char* s)
00174 {
00175 #if defined (_MSC_VER)
00176     this->sWhatsThis = _strdup(s);
00177 #else
00178     this->sWhatsThis = strdup(s);
00179 #endif
00180 }
00181 
00182 void CommandBase::setPixmap(const char* s)
00183 {
00184 #if defined (_MSC_VER)
00185     this->sPixmap = _strdup(s);
00186 #else
00187     this->sPixmap = strdup(s);
00188 #endif
00189 }
00190 
00191 void CommandBase::setAccel(const char* s)
00192 {
00193 #if defined (_MSC_VER)
00194     this->sAccel = _strdup(s);
00195 #else
00196     this->sAccel = strdup(s);
00197 #endif
00198 }
00199 
00200 //===========================================================================
00201 // Command
00202 //===========================================================================
00203 
00204 /* TRANSLATOR Gui::Command */
00205 
00206 Command::Command(const char* name)
00207         : CommandBase(0), sName(name), sHelpUrl(0)
00208 {
00209     sAppModule  = "FreeCAD";
00210     sGroup      = QT_TR_NOOP("Standard");
00211     eType       = AlterDoc | Alter3DView | AlterSelection;
00212 }
00213 
00214 Command::~Command()
00215 {
00216 }
00217 
00218 bool Command::isViewOfType(Base::Type t) const
00219 {
00220     Gui::Document *d = getGuiApplication()->activeDocument();
00221     if (!d) return false;
00222     Gui::BaseView *v = d->getActiveView();
00223     if (!v) return false;
00224     if (v->getTypeId().isDerivedFrom(t))
00225         return true;
00226     else
00227         return false;
00228 }
00229 
00230 void Command::addTo(QWidget *pcWidget)
00231 {
00232     if (!_pcAction)
00233         _pcAction = createAction();
00234 
00235     _pcAction->addTo(pcWidget);
00236 }
00237 
00238 Application *Command::getGuiApplication(void)
00239 {
00240     return Application::Instance;
00241 }
00242 
00243 Gui::Document* Command::getActiveGuiDocument(void) const
00244 {
00245     return getGuiApplication()->activeDocument();
00246 }
00247 
00248 App::Document* Command::getDocument(const char* Name) const
00249 {
00250     if (Name) {
00251         return App::GetApplication().getDocument(Name);
00252     }
00253     else {
00254         Gui::Document * pcDoc = getGuiApplication()->activeDocument();
00255         if (pcDoc)
00256             return pcDoc->getDocument();
00257         else
00258             return 0l;
00259     }
00260 }
00261 
00262 App::DocumentObject* Command::getObject(const char* Name) const
00263 {
00264     App::Document*pDoc = getDocument();
00265     if (pDoc)
00266         return pDoc->getObject(Name);
00267     else
00268         return 0;
00269 }
00270 
00271 void Command::invoke(int i)
00272 {
00273     // Do not query _pcAction since it isn't created necessarily
00274 #ifdef FC_LOGUSERACTION
00275     Base::Console().Log("CmdG: %s\n",sName);
00276 #endif
00277     // set the application module type for the macro
00278     getGuiApplication()->macroManager()->setModule(sAppModule);
00279     try {
00280         // check if it really works NOW (could be a delay between click deactivation of the button)
00281         if (isActive())
00282             activated( i );
00283     }
00284     catch (Base::PyException &e) {
00285         e.ReportException();
00286         Base::Console().Error("Stack Trace: %s\n",e.getStackTrace().c_str());
00287     }
00288     catch (Base::AbortException&) {
00289     }
00290     catch (Base::Exception &e) {
00291         e.ReportException();
00292         // Pop-up a dialog for FreeCAD-specific exceptions
00293         QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Exception"), QLatin1String(e.what()));
00294     }
00295     catch (std::exception &e) {
00296         Base::Console().Error("C++ exception thrown (%s)\n", e.what());
00297     }
00298     catch (const char* e) {
00299         Base::Console().Error("%s\n", e);
00300     }
00301 #ifndef FC_DEBUG
00302     catch (...) {
00303         Base::Console().Error("Gui::Command::activated(%d): Unknown C++ exception thrown", i);
00304     }
00305 #endif
00306 }
00307 
00308 void Command::testActive(void)
00309 {
00310     if (!_pcAction) return;
00311 
00312     if (_blockCmd) {
00313         _pcAction->setEnabled(false);
00314         return;
00315     }
00316 
00317     if (!(eType & ForEdit))  // special case for commands which are only in some edit modes active
00318         
00319         if ((!Gui::Control().isAllowedAlterDocument()  && eType & AlterDoc)    ||
00320             (!Gui::Control().isAllowedAlterView()      && eType & Alter3DView) ||
00321             (!Gui::Control().isAllowedAlterSelection() && eType & AlterSelection)) {
00322              _pcAction->setEnabled(false);
00323             return;
00324         }
00325 
00326     bool bActive = isActive();
00327     _pcAction->setEnabled(bActive);
00328 }
00329 
00330 //--------------------------------------------------------------------------
00331 // Helper methods
00332 //--------------------------------------------------------------------------
00333 
00334 bool Command::hasActiveDocument(void) const
00335 {
00336     return getActiveGuiDocument() != 0;
00337 }
00339 bool Command::hasObject(const char* Name)
00340 {
00341     return getDocument() != 0 && getDocument()->getObject(Name) != 0;
00342 }
00343 
00344 Gui::SelectionSingleton&  Command::getSelection(void)
00345 {
00346     return Gui::Selection();
00347 }
00348 
00349 std::string Command::getUniqueObjectName(const char *BaseName) const
00350 {
00351     assert(hasActiveDocument());
00352 
00353     return getActiveGuiDocument()->getDocument()->getUniqueObjectName(BaseName);
00354 }
00355 
00356 
00357 //--------------------------------------------------------------------------
00358 // UNDO REDO transaction handling
00359 //--------------------------------------------------------------------------
00368 void Command::openCommand(const char* sCmdName)
00369 {
00370     // Using OpenCommand with no active document !
00371     assert(Gui::Application::Instance->activeDocument());
00372 
00373     if (sCmdName)
00374         Gui::Application::Instance->activeDocument()->openCommand(sCmdName);
00375     else
00376         Gui::Application::Instance->activeDocument()->openCommand("Command");
00377 }
00378 
00379 void Command::commitCommand(void)
00380 {
00381     Gui::Application::Instance->activeDocument()->commitCommand();
00382 }
00383 
00384 void Command::abortCommand(void)
00385 {
00386     Gui::Application::Instance->activeDocument()->abortCommand();
00387 }
00388 
00389 bool Command::_blockCmd = false;
00390 
00391 void Command::blockCommand(bool block)
00392 {
00393     Command::_blockCmd = block;
00394 }
00395 
00397 void Command::doCommand(DoCmd_Type eType,const char* sCmd,...)
00398 {
00399     // temp buffer
00400     size_t format_len = std::strlen(sCmd)+4024;
00401     char* format = (char*) malloc(format_len);
00402     va_list namelessVars;
00403     va_start(namelessVars, sCmd);  // Get the "..." vars
00404     vsnprintf(format, format_len, sCmd, namelessVars);
00405     va_end(namelessVars);
00406 
00407     if (eType == Gui)
00408         Gui::Application::Instance->macroManager()->addLine(MacroManager::Gui,format);
00409     else
00410         Gui::Application::Instance->macroManager()->addLine(MacroManager::Base,format);
00411 
00412     try {
00413         Base::Interpreter().runString(format);
00414     }
00415     catch (...) {
00416         // free memory to avoid a leak if an exception occurred
00417         free (format);
00418         throw;
00419     }
00420 
00421 #ifdef FC_LOGUSERACTION
00422     Base::Console().Log("CmdC: %s\n",format);
00423 #endif
00424     free (format);
00425 }
00426 
00427 void Command::copyVisual(const char* to, const char* attr, const char* from)
00428 {
00429     doCommand(Gui,"Gui.ActiveDocument.%s.%s=Gui.ActiveDocument.%s.%s", to, attr, from, attr);
00430 }
00431 
00432 void Command::copyVisual(const char* to, const char* attr_to, const char* from, const char* attr_from)
00433 {
00434     doCommand(Gui,"Gui.ActiveDocument.%s.%s=Gui.ActiveDocument.%s.%s", to, attr_to, from, attr_from);
00435 }
00436 
00437 const std::string Command::strToPython(const char* Str)
00438 {
00439     return Base::InterpreterSingleton::strToPython(Str);
00440 }
00441 
00443 void Command::updateActive(void)
00444 {
00445     WaitCursor wc;
00446     doCommand(Gui,"App.ActiveDocument.recompute()");
00447 }
00448 
00449 bool Command::isActiveObjectValid(void)
00450 {
00451     Gui::Document* active = Gui::Application::Instance->activeDocument();
00452     assert(active);
00453     App::Document* document = active->getDocument();
00454     App::DocumentObject* object = document->getActiveObject();
00455     assert(object);
00456     return object->isValid();
00457 }
00458 
00460 void Command::updateAll(std::list<Gui::Document*> cList)
00461 {
00462     if (cList.size()>0) {
00463         for (std::list<Gui::Document*>::iterator It= cList.begin();It!=cList.end();It++)
00464             (*It)->onUpdate();
00465     }
00466     else {
00467         Gui::Application::Instance->onUpdate();
00468     }
00469 }
00470 
00471 //--------------------------------------------------------------------------
00472 // Online help handling
00473 //--------------------------------------------------------------------------
00474 
00476 const char * Command::beginCmdHelp(void)
00477 {
00478     return  "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
00479             "<html>\n"
00480             "<head>\n"
00481             "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\n"
00482             "<title>FreeCAD Main Index</title>\n"
00483             "</head>\n"
00484             "<body bgcolor=\"#ffffff\">\n\n";
00485 }
00486 
00488 const char * Command::endCmdHelp(void)
00489 {
00490     return "</body></html>\n\n";
00491 }
00492 
00493 void Command::applyCommandData(Action* action)
00494 {
00495     action->setText(QCoreApplication::translate(
00496         this->className(), sMenuText, 0,
00497         QCoreApplication::CodecForTr));
00498     action->setToolTip(QCoreApplication::translate(
00499         this->className(), sToolTipText, 0,
00500         QCoreApplication::CodecForTr));
00501     if (sStatusTip)
00502         action->setStatusTip(QCoreApplication::translate(
00503             this->className(), sStatusTip, 0,
00504             QCoreApplication::CodecForTr));
00505     else
00506         action->setStatusTip(QCoreApplication::translate(
00507             this->className(), sToolTipText, 0,
00508             QCoreApplication::CodecForTr));
00509     if (sWhatsThis)
00510         action->setWhatsThis(QCoreApplication::translate(
00511             this->className(), sWhatsThis, 0,
00512             QCoreApplication::CodecForTr));
00513     else
00514         action->setWhatsThis(QCoreApplication::translate(
00515             this->className(), sToolTipText, 0,
00516             QCoreApplication::CodecForTr));
00517 }
00518 
00519 const char* Command::keySequenceToAccel(int sk) const
00520 {
00521     QKeySequence::StandardKey type = (QKeySequence::StandardKey)sk;
00522     QKeySequence ks(type);
00523     QString qs = ks.toString();
00524     QByteArray data = qs.toAscii();
00525 #if defined (_MSC_VER)
00526     return _strdup((const char*)data);
00527 #else
00528     return strdup((const char*)data);
00529 #endif
00530 }
00531 
00532 void Command::adjustCameraPosition()
00533 {
00534     Gui::Document* doc = Gui::Application::Instance->activeDocument();
00535     if (doc) {
00536         Gui::View3DInventor* view = static_cast<Gui::View3DInventor*>(doc->getActiveView());
00537         Gui::View3DInventorViewer* viewer = view->getViewer();
00538         SoCamera* camera = viewer->getCamera();
00539         if (!camera || !camera->isOfType(SoOrthographicCamera::getClassTypeId()))
00540             return;
00541 
00542         // get scene bounding box
00543         SoGetBoundingBoxAction action(viewer->getViewportRegion());
00544         action.apply(viewer->getSceneGraph());
00545         SbBox3f box = action.getBoundingBox();
00546         if (box.isEmpty()) return;
00547 
00548         // get cirumscribing sphere and check if camera is inside
00549         SbVec3f cam_pos = camera->position.getValue();
00550         SbVec3f box_cnt = box.getCenter();
00551         SbSphere bs;
00552         bs.circumscribe(box);
00553         float radius = bs.getRadius();
00554         float distance_to_midpoint = (box_cnt-cam_pos).length();
00555         if (radius >= distance_to_midpoint) {
00556             // Move the camera to the edge of the bounding sphere, while still
00557             // pointing at the scene.
00558             SbVec3f direction = cam_pos - box_cnt;
00559             (void) direction.normalize(); // we know this is not a null vector
00560             camera->position.setValue(box_cnt + direction * radius);
00561 
00562             // New distance to mid point
00563             distance_to_midpoint =
00564                 (camera->position.getValue() - box.getCenter()).length();
00565             camera->nearDistance = distance_to_midpoint - radius;
00566             camera->farDistance = distance_to_midpoint + radius;
00567             camera->focalDistance = distance_to_midpoint;
00568         }
00569     }
00570 }
00571 
00572 Action * Command::createAction(void)
00573 {
00574     Action *pcAction;
00575 
00576     pcAction = new Action(this,getMainWindow());
00577     applyCommandData(pcAction);
00578     if (sPixmap)
00579         pcAction->setIcon(Gui::BitmapFactory().pixmap(sPixmap));
00580       pcAction->setShortcut(QString::fromAscii(sAccel));
00581 
00582     return pcAction;
00583 }
00584 
00585 void Command::languageChange()
00586 {
00587     if (_pcAction) {
00588         applyCommandData(_pcAction);
00589     }
00590 }
00591 
00592 //===========================================================================
00593 // MacroCommand
00594 //===========================================================================
00595 
00596 /* TRANSLATOR Gui::MacroCommand */
00597 
00598 MacroCommand::MacroCommand(const char* name)
00599 #if defined (_MSC_VER)
00600   : Command( _strdup(name) )
00601 #else
00602   : Command( strdup(name) )
00603 #endif
00604 {
00605     sGroup = QT_TR_NOOP("Macros");
00606 }
00607 
00608 void MacroCommand::activated(int iMsg)
00609 {
00610     std::string cMacroPath = App::GetApplication().GetParameterGroupByPath
00611                              ("User parameter:BaseApp/Preferences/Macro")->GetASCII("MacroPath",
00612                                      App::Application::getUserAppDataDir().c_str());
00613 
00614     QDir d(QString::fromUtf8(cMacroPath.c_str()));
00615     QFileInfo fi(d, QString::fromUtf8(sScriptName));
00616     Application::Instance->macroManager()->run(MacroManager::File, fi.filePath().toUtf8());
00617     // after macro run recalculate the document
00618     if (Application::Instance->activeDocument())
00619         Application::Instance->activeDocument()->getDocument()->recompute();
00620 }
00621 
00622 Action * MacroCommand::createAction(void)
00623 {
00624     Action *pcAction;
00625     pcAction = new Action(this,getMainWindow());
00626     pcAction->setText(QString::fromUtf8(sMenuText));
00627     pcAction->setToolTip(QString::fromUtf8(sToolTipText));
00628     pcAction->setStatusTip(QString::fromUtf8(sStatusTip));
00629     pcAction->setWhatsThis(QString::fromUtf8(sWhatsThis));
00630     if ( sPixmap )
00631         pcAction->setIcon(Gui::BitmapFactory().pixmap(sPixmap));
00632       pcAction->setShortcut(QString::fromAscii(sAccel));
00633     return pcAction;
00634 }
00635 
00636 void MacroCommand::setScriptName( const char* s )
00637 {
00638 #if defined (_MSC_VER)
00639     this->sScriptName = _strdup( s );
00640 #else
00641     this->sScriptName = strdup( s );
00642 #endif
00643 }
00644 
00645 void MacroCommand::load()
00646 {
00647     ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Macro");
00648 
00649     if (hGrp->HasGroup("Macros")) {
00650         hGrp = hGrp->GetGroup("Macros");
00651         std::vector<Base::Reference<ParameterGrp> > macros = hGrp->GetGroups();
00652         for (std::vector<Base::Reference<ParameterGrp> >::iterator it = macros.begin(); it!=macros.end(); ++it ) {
00653             MacroCommand* macro = new MacroCommand((*it)->GetGroupName());
00654             macro->setScriptName  ( (*it)->GetASCII( "Script"     ).c_str() );
00655             macro->setMenuText    ( (*it)->GetASCII( "Menu"       ).c_str() );
00656             macro->setToolTipText ( (*it)->GetASCII( "Tooltip"    ).c_str() );
00657             macro->setWhatsThis   ( (*it)->GetASCII( "WhatsThis"  ).c_str() );
00658             macro->setStatusTip   ( (*it)->GetASCII( "Statustip"  ).c_str() );
00659             if ((*it)->GetASCII("Pixmap", "nix") != "nix")
00660                 macro->setPixmap    ( (*it)->GetASCII( "Pixmap"     ).c_str() );
00661             macro->setAccel       ( (*it)->GetASCII( "Accel",0    ).c_str() );
00662             Application::Instance->commandManager().addCommand( macro );
00663         }
00664     }
00665 }
00666 
00667 void MacroCommand::save()
00668 {
00669     ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Macro")->GetGroup("Macros");
00670     hGrp->Clear();
00671 
00672     std::vector<Command*> macros = Application::Instance->commandManager().getGroupCommands("Macros");
00673     if ( macros.size() > 0 ) {
00674         for (std::vector<Command*>::iterator it = macros.begin(); it!=macros.end(); ++it ) {
00675             MacroCommand* macro = (MacroCommand*)(*it);
00676             ParameterGrp::handle hMacro = hGrp->GetGroup(macro->getName());
00677             hMacro->SetASCII( "Script",    macro->getScriptName () );
00678             hMacro->SetASCII( "Menu",      macro->getMenuText   () );
00679             hMacro->SetASCII( "Tooltip",   macro->getToolTipText() );
00680             hMacro->SetASCII( "WhatsThis", macro->getWhatsThis  () );
00681             hMacro->SetASCII( "Statustip", macro->getStatusTip  () );
00682             hMacro->SetASCII( "Pixmap",    macro->getPixmap     () );
00683             hMacro->SetASCII( "Accel",     macro->getAccel      () );
00684         }
00685     }
00686 }
00687 
00688 //===========================================================================
00689 // PythonCommand
00690 //===========================================================================
00691 
00692 PythonCommand::PythonCommand(const char* name,PyObject * pcPyCommand, const char* pActivationString)
00693   : Command(name),_pcPyCommand(pcPyCommand)
00694 {
00695     if (pActivationString)
00696         Activation = pActivationString;
00697 
00698     sGroup = "Python";
00699 
00700     Py_INCREF(_pcPyCommand);
00701 
00702     // call the method "GetResources()" of the command object
00703     _pcPyResourceDict = Interpreter().runMethodObject(_pcPyCommand, "GetResources");
00704     // check if the "GetResources()" method returns a Dict object
00705     if (!PyDict_Check(_pcPyResourceDict))
00706         throw Base::Exception("PythonCommand::PythonCommand(): Method GetResources() of the Python command object returns the wrong type (has to be Py Dictonary)");
00707 }
00708 
00709 const char* PythonCommand::getResource(const char* sName) const
00710 {
00711     PyObject* pcTemp;
00712 
00713     // get the "MenuText" resource string
00714     pcTemp = PyDict_GetItemString(_pcPyResourceDict,sName);
00715     if (!pcTemp)
00716         return "";
00717     if (!PyString_Check(pcTemp))
00718         throw Base::Exception("PythonCommand::getResource(): Method GetResources() of the Python command object returns a dictionary which holds not only strings");
00719 
00720     return PyString_AsString(pcTemp);
00721 }
00722 
00723 void PythonCommand::activated(int iMsg)
00724 {
00725     if (Activation == "") {
00726         try {
00727             Interpreter().runMethodVoid(_pcPyCommand, "Activated");
00728         }
00729         catch (const Base::PyException& e) {
00730             Base::Console().Error("Running the Python command '%s' failed:\n%s\n%s",
00731                                   sName, e.getStackTrace().c_str(), e.what());
00732         }
00733         catch (const Base::Exception&) {
00734             Base::Console().Error("Running the Python command '%s' failed, try to resume",sName);
00735         }
00736     }
00737     else {
00738         doCommand(Doc,Activation.c_str());
00739     }
00740 }
00741 
00742 bool PythonCommand::isActive(void)
00743 {
00744     try {
00745         Base::PyGILStateLocker lock;
00746         Py::Object cmd(_pcPyCommand);
00747         if (cmd.hasAttr("IsActive")) {
00748             Py::Callable call(cmd.getAttr("IsActive"));
00749             Py::Tuple args;
00750             Py::Object ret = call.apply(args);
00751             // if return type is not boolean or not true
00752             if (!PyBool_Check(ret.ptr()) || ret.ptr() != Py_True)
00753                 return false;
00754         }
00755     }
00756     catch(Py::Exception& e) {
00757         Base::PyGILStateLocker lock;
00758         e.clear();
00759         return false;
00760     }
00761 
00762     return true;
00763 }
00764 
00765 void PythonCommand::languageChange()
00766 {
00767     if (_pcAction) {
00768         _pcAction->setText         (qApp->translate(getName(), getMenuText   ()));
00769         _pcAction->setToolTip      (qApp->translate(getName(), getToolTipText()));
00770         _pcAction->setStatusTip    (qApp->translate(getName(), getStatusTip  ()));
00771         _pcAction->setWhatsThis    (qApp->translate(getName(), getWhatsThis  ()));
00772         if (_pcAction->statusTip().isEmpty())
00773             _pcAction->setStatusTip(qApp->translate(getName(), getToolTipText()));
00774     }
00775 }
00776 
00777 const char* PythonCommand::getHelpUrl(void)
00778 {
00779     PyObject* pcTemp;
00780     pcTemp = Interpreter().runMethodObject(_pcPyCommand, "CmdHelpURL");
00781     if (! pcTemp )
00782         return "";
00783     if (! PyString_Check(pcTemp) )
00784         throw Base::Exception("PythonCommand::CmdHelpURL(): Method CmdHelpURL() of the Python command object returns no string");
00785     return PyString_AsString(pcTemp);
00786 }
00787 
00788 Action * PythonCommand::createAction(void)
00789 {
00790     Action *pcAction;
00791 
00792     pcAction = new Action(this,getMainWindow());
00793 
00794     pcAction->setText         (qApp->translate(getName(), getMenuText   ()));
00795     pcAction->setToolTip      (qApp->translate(getName(), getToolTipText()));
00796     pcAction->setStatusTip    (qApp->translate(getName(), getStatusTip  ()));
00797     pcAction->setWhatsThis    (qApp->translate(getName(), getWhatsThis  ()));
00798     if (pcAction->statusTip().isEmpty())
00799         pcAction->setStatusTip(qApp->translate(getName(), getToolTipText()));
00800     if (strcmp(getResource("Pixmap"),"") != 0)
00801         pcAction->setIcon(Gui::BitmapFactory().pixmap(getResource("Pixmap")));
00802     pcAction->setShortcut     (QString::fromAscii(getAccel()));
00803 
00804     return pcAction;
00805 }
00806 
00807 const char* PythonCommand::getWhatsThis() const
00808 {
00809     const char* whatsthis = getResource("WhatsThis");
00810     if (!whatsthis || whatsthis[0] == '\0')
00811         whatsthis = this->getName();
00812     return whatsthis;
00813 }
00814 
00815 const char* PythonCommand::getMenuText() const
00816 {
00817     return getResource("MenuText");
00818 }
00819 
00820 const char* PythonCommand::getToolTipText() const
00821 {
00822     return getResource("ToolTip");
00823 }
00824 
00825 const char* PythonCommand::getStatusTip() const
00826 {
00827     return getResource("StatusTip");
00828 }
00829 
00830 const char* PythonCommand::getPixmap() const
00831 {
00832     return getResource("Pixmap");
00833 }
00834 
00835 const char* PythonCommand::getAccel() const
00836 {
00837     return getResource("Accel");
00838 }
00839 
00840 //===========================================================================
00841 // CommandManager
00842 //===========================================================================
00843 
00844 CommandManager::CommandManager()
00845 {
00846 }
00847 
00848 CommandManager::~CommandManager()
00849 {
00850     clearCommands();
00851 }
00852 
00853 void CommandManager::addCommand(Command* pCom)
00854 {
00855     _sCommands[pCom->getName()] = pCom;// pCom->Init();
00856 }
00857 
00858 void CommandManager::removeCommand(Command* pCom)
00859 {
00860     std::map <std::string,Command*>::iterator It = _sCommands.find(pCom->getName());
00861     if (It != _sCommands.end()) {
00862         delete It->second;
00863         _sCommands.erase(It);
00864     }
00865 }
00866 
00867 void CommandManager::clearCommands()
00868 {
00869     for ( std::map<std::string,Command*>::iterator it = _sCommands.begin(); it != _sCommands.end(); ++it )
00870         delete it->second;
00871     _sCommands.clear();
00872 }
00873 
00874 bool CommandManager::addTo(const char* Name, QWidget *pcWidget)
00875 {
00876     if (_sCommands.find(Name) == _sCommands.end()) {
00877         // Print in release mode only a log message instead of an error message to avoid to annoy the user
00878 #ifdef FC_DEBUG
00879         Base::Console().Error("CommandManager::addTo() try to add an unknown command (%s) to a widget!\n",Name);
00880 #else
00881         Base::Console().Warning("Unknown command '%s'\n",Name);
00882 #endif
00883         return false;
00884     }
00885     else {
00886         Command* pCom = _sCommands[Name];
00887         pCom->addTo(pcWidget);
00888         return true;
00889     }
00890 }
00891 
00892 std::vector <Command*> CommandManager::getModuleCommands(const char *sModName) const
00893 {
00894     std::vector <Command*> vCmds;
00895 
00896     for ( std::map<std::string, Command*>::const_iterator It= _sCommands.begin();It!=_sCommands.end();It++) {
00897         if ( strcmp(It->second->getAppModuleName(),sModName) == 0)
00898             vCmds.push_back(It->second);
00899     }
00900 
00901     return vCmds;
00902 }
00903 
00904 std::vector <Command*> CommandManager::getAllCommands(void) const
00905 {
00906     std::vector <Command*> vCmds;
00907 
00908     for ( std::map<std::string, Command*>::const_iterator It= _sCommands.begin();It!=_sCommands.end();It++) {
00909         vCmds.push_back(It->second);
00910     }
00911 
00912     return vCmds;
00913 }
00914 
00915 std::vector <Command*> CommandManager::getGroupCommands(const char *sGrpName) const
00916 {
00917     std::vector <Command*> vCmds;
00918 
00919     for ( std::map<std::string, Command*>::const_iterator It= _sCommands.begin();It!=_sCommands.end();It++) {
00920         if ( strcmp(It->second->getGroupName(),sGrpName) == 0)
00921             vCmds.push_back(It->second);
00922     }
00923 
00924     return vCmds;
00925 }
00926 
00927 Command* CommandManager::getCommandByName(const char* sName) const
00928 {
00929     std::map<std::string,Command*>::const_iterator it = _sCommands.find( sName );
00930     return ( it != _sCommands.end() ) ? it->second : 0;
00931 }
00932 
00933 void CommandManager::runCommandByName (const char* sName) const
00934 {
00935     Command* pCmd = getCommandByName(sName);
00936 
00937     if (pCmd)
00938         pCmd->invoke(0);
00939 }
00940 
00941 void CommandManager::testActive(void)
00942 {
00943     for ( std::map<std::string, Command*>::iterator It= _sCommands.begin();It!=_sCommands.end();It++) {
00944         It->second->testActive();
00945     }
00946 }
00947 

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