<commit_before>/** @file poisson2d_example_adaptRef.cpp

    @brief Example for using the gsPoissonSolver with adaptive refinement with THB-splines.

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): S. Kleiss
*/

#include <iostream>

#include <gismo.h>

#include <gsAssembler/gsAdaptiveRefUtils.h>

#include <gsAssembler/gsErrEstPoissonResidual.h>

using namespace std;
using namespace gismo;

//S.Kleiss
//
//This is a test example for a illustrating the adaptive
//refinement procedure implemented in the gsPoissonAssembler
//
//Flags, parameters, geometry and prescribed exact solution
//are specified within the main() function

int main()
{
  int result = 0;

  // Number of initial uniform mesh refinements
  int initUnifRef = 2;
  // Number of adaptive refinement loops
  int RefineLoopMax; // ...specified below with the examples

  // Flag for refinemet criterion
  // (see doxygen documentation of the free function
  // gsMarkElementsForRef explanation)
  const int refCriterion = 2;
  // Parameter for computing adaptive refinement threshold
  // (see doxygen documentation of the free function
  // gsMarkElementsForRef explanation)
  real_t refParameter;  // ...specified below with the examples

  // Flag whether final mesh should be plotted in ParaView
  const bool plot = true;

  // ****** Prepared test examples ******
  //
  // f       ... source term
  // g       ... exact solution
  // patches ... the computational domain given as object of gsMultiPatch
  //

  /*
  // ------ Example 1 ------

  // --- Unit square, with a spike of the source function at (0.25, 0.6)
  gsMFunctionExpr<>  f("if( (x-0.25)^2 + (y-0.6)^2 < 0.2^2, 1, 0 )", 2);
  gsMFunctionExpr<>  g("0", 2);
  gsMultiPatch<> patches( *safe(gsNurbsCreator<>::BSplineRectangle(0.0,0.0,2.0,1.0) ));

  RefineLoopMax = 6;
  refParameter = 0.6;

  // ^^^^^^ Example 1 ^^^^^^
  //*/

//  /*
  // ------ Example 2 ------

  // The classical example associated with the L-Shaped domain.
  // The exact solution has a singularity at the re-entrant corner at the origin.

  gsMFunctionExpr<>  f("0", 2);
  gsMFunctionExpr<>  g("if( y>0, ( (x^2+y^2)^(1.0/3.0) )*sin( (2*atan2(y,x) - pi)/3.0 ), ( (x^2+y^2)^(1.0/3.0) )*sin( (2*atan2(y,x) +3*pi)/3.0 ) )", 2);

  gsMultiPatch<> patches( *safe(gsNurbsCreator<>::BSplineLShape_p2C1()) );

  RefineLoopMax = 4;
  refParameter = 0.85;

  // ^^^^^^ Example 2 ^^^^^^
  //*/

  cout<<"Source function "<< f << endl;
  cout<<"Exact solution "<< g <<".\n" << endl;

  // Define Boundary conditions
  gsBoundaryConditions<> bcInfo;
  // Dirichlet BCs
  bcInfo.addCondition( boundary::west,  condition_type::dirichlet, &g );
  bcInfo.addCondition( boundary::east,  condition_type::dirichlet, &g );
  bcInfo.addCondition( boundary::north, condition_type::dirichlet, &g );
  bcInfo.addCondition( boundary::south, condition_type::dirichlet, &g );

  gsTensorBSpline<2,real_t> * geo = dynamic_cast< gsTensorBSpline<2,real_t> * >( & patches.patch(0) );
  cout << " --- Geometry:\n" << *geo << endl;
  cout << "Number of patches: " << patches.nPatches() << endl;

  // With this gsTensorBSplineBasis, it's possible to call the THB-Spline constructor
  gsTHBSplineBasis<2,real_t> THB( geo->basis() );

  // Finally, create a vector (of length one) of this gsTHBSplineBasis
  gsMultiBasis<real_t> bases(THB);

  for (int i = 0; i < initUnifRef; ++i)
      bases.uniformRefine();

  // So, ready to start the adaptive refinement loop:
  for( int RefineLoop = 0; RefineLoop <= RefineLoopMax ; RefineLoop++ )
  {
      cout << "\n\n ====== Loop " << RefineLoop << " of " << RefineLoopMax << " ======" << endl << endl;

      // Create solver... maybe not the smartest thing to set up a new solver
      // in each iteration loop, but good enough for now.
      gsPoissonAssembler<real_t> pa(patches,bases,bcInfo,f,
                                    dirichlet::elimination,iFace::glue);

      // Assemble matrix and rhs
      pa.assemble();

      // Solve system
      gsMatrix<> solVector = Eigen::ConjugateGradient<gsSparseMatrix<> >(pa.matrix() ).solve( pa.rhs() );

      // Construct the solution for plotting the mesh later
      gsField<> * sol = pa.constructSolution(solVector);

      // Set up and compute the L2-error to the known exact solution
      gsNormL2<real_t> norm(*sol,g);
      gsErrEstPoissonResidual<real_t> errEst(*sol,g);

      norm.compute(1);
      errEst.compute(1);

      // Get the vector with element-wise local errors...
      const std::vector<real_t> & elError = norm.elementNorms();
      // ...or the vector with element-wise local error estimates.
      const std::vector<real_t> & elErrEst = errEst.elementNorms();

      // Mark elements for refinement, based on the computed local errors and
      // refCriterion and refParameter.
      std::vector<bool> elMarked( elError.size() );
      // Use the (in this case known) exact error...
      //gsMarkElementsForRef( elError, refCriterion, refParameter, elMarked);
      // ...or the error estimate.
      gsMarkElementsForRef( elErrEst, refCriterion, refParameter, elMarked);

      // Refine the elements of the mesh, based on elMarked.
      gsRefineMarkedElements( bases, elMarked);

      if ( (RefineLoop == RefineLoopMax) && plot)
      {
          // Write approximate solution to paraview files
          std::cout<<"Plotting in Paraview...\n";
          gsWriteParaview<>(*sol, "p2d_adaRef_sol", 1001, true);
          // Run paraview and plot the last mesh
          result = system("paraview p2d_adaRef_sol0_mesh.vtp &");
      }

      delete sol;
  }

  cout << "Test is done: Exiting" << endl;
  return  result;
}
<commit_msg>Changed plot-flag to false.<commit_after>/** @file poisson2d_example_adaptRef.cpp

    @brief Example for using the gsPoissonSolver with adaptive refinement with THB-splines.

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): S. Kleiss
*/

#include <iostream>

#include <gismo.h>

#include <gsAssembler/gsAdaptiveRefUtils.h>

#include <gsAssembler/gsErrEstPoissonResidual.h>

using namespace std;
using namespace gismo;

//S.Kleiss
//
//This is a test example for a illustrating the adaptive
//refinement procedure implemented in the gsPoissonAssembler
//
//Flags, parameters, geometry and prescribed exact solution
//are specified within the main() function

int main()
{
  int result = 0;

  // Number of initial uniform mesh refinements
  int initUnifRef = 2;
  // Number of adaptive refinement loops
  int RefineLoopMax; // ...specified below with the examples

  // Flag for refinemet criterion
  // (see doxygen documentation of the free function
  // gsMarkElementsForRef explanation)
  const int refCriterion = 2;
  // Parameter for computing adaptive refinement threshold
  // (see doxygen documentation of the free function
  // gsMarkElementsForRef explanation)
  real_t refParameter;  // ...specified below with the examples

  // Flag whether final mesh should be plotted in ParaView
  const bool plot = false;

  // ****** Prepared test examples ******
  //
  // f       ... source term
  // g       ... exact solution
  // patches ... the computational domain given as object of gsMultiPatch
  //

  /*
  // ------ Example 1 ------

  // --- Unit square, with a spike of the source function at (0.25, 0.6)
  gsMFunctionExpr<>  f("if( (x-0.25)^2 + (y-0.6)^2 < 0.2^2, 1, 0 )", 2);
  gsMFunctionExpr<>  g("0", 2);
  gsMultiPatch<> patches( *safe(gsNurbsCreator<>::BSplineRectangle(0.0,0.0,2.0,1.0) ));

  RefineLoopMax = 6;
  refParameter = 0.6;

  // ^^^^^^ Example 1 ^^^^^^
  //*/

//  /*
  // ------ Example 2 ------

  // The classical example associated with the L-Shaped domain.
  // The exact solution has a singularity at the re-entrant corner at the origin.

  gsMFunctionExpr<>  f("0", 2);
  gsMFunctionExpr<>  g("if( y>0, ( (x^2+y^2)^(1.0/3.0) )*sin( (2*atan2(y,x) - pi)/3.0 ), ( (x^2+y^2)^(1.0/3.0) )*sin( (2*atan2(y,x) +3*pi)/3.0 ) )", 2);

  gsMultiPatch<> patches( *safe(gsNurbsCreator<>::BSplineLShape_p2C1()) );

  RefineLoopMax = 4;
  refParameter = 0.85;

  // ^^^^^^ Example 2 ^^^^^^
  //*/

  cout<<"Source function "<< f << endl;
  cout<<"Exact solution "<< g <<".\n" << endl;

  // Define Boundary conditions
  gsBoundaryConditions<> bcInfo;
  // Dirichlet BCs
  bcInfo.addCondition( boundary::west,  condition_type::dirichlet, &g );
  bcInfo.addCondition( boundary::east,  condition_type::dirichlet, &g );
  bcInfo.addCondition( boundary::north, condition_type::dirichlet, &g );
  bcInfo.addCondition( boundary::south, condition_type::dirichlet, &g );

  gsTensorBSpline<2,real_t> * geo = dynamic_cast< gsTensorBSpline<2,real_t> * >( & patches.patch(0) );
  cout << " --- Geometry:\n" << *geo << endl;
  cout << "Number of patches: " << patches.nPatches() << endl;

  // With this gsTensorBSplineBasis, it's possible to call the THB-Spline constructor
  gsTHBSplineBasis<2,real_t> THB( geo->basis() );

  // Finally, create a vector (of length one) of this gsTHBSplineBasis
  gsMultiBasis<real_t> bases(THB);

  for (int i = 0; i < initUnifRef; ++i)
      bases.uniformRefine();

  // So, ready to start the adaptive refinement loop:
  for( int RefineLoop = 0; RefineLoop <= RefineLoopMax ; RefineLoop++ )
  {
      cout << "\n\n ====== Loop " << RefineLoop << " of " << RefineLoopMax << " ======" << endl << endl;

      // Create solver... maybe not the smartest thing to set up a new solver
      // in each iteration loop, but good enough for now.
      gsPoissonAssembler<real_t> pa(patches,bases,bcInfo,f,
                                    dirichlet::elimination,iFace::glue);

      // Assemble matrix and rhs
      pa.assemble();

      // Solve system
      gsMatrix<> solVector = Eigen::ConjugateGradient<gsSparseMatrix<> >(pa.matrix() ).solve( pa.rhs() );

      // Construct the solution for plotting the mesh later
      gsField<> * sol = pa.constructSolution(solVector);

      // Set up and compute the L2-error to the known exact solution
      gsNormL2<real_t> norm(*sol,g);
      gsErrEstPoissonResidual<real_t> errEst(*sol,g);

      norm.compute(1);
      errEst.compute(1);

      // Get the vector with element-wise local errors...
      const std::vector<real_t> & elError = norm.elementNorms();
      // ...or the vector with element-wise local error estimates.
      const std::vector<real_t> & elErrEst = errEst.elementNorms();

      // Mark elements for refinement, based on the computed local errors and
      // refCriterion and refParameter.
      std::vector<bool> elMarked( elError.size() );
      // Use the (in this case known) exact error...
      //gsMarkElementsForRef( elError, refCriterion, refParameter, elMarked);
      // ...or the error estimate.
      gsMarkElementsForRef( elErrEst, refCriterion, refParameter, elMarked);

      // Refine the elements of the mesh, based on elMarked.
      gsRefineMarkedElements( bases, elMarked);

      if ( (RefineLoop == RefineLoopMax) && plot)
      {
          // Write approximate solution to paraview files
          std::cout<<"Plotting in Paraview...\n";
          gsWriteParaview<>(*sol, "p2d_adaRef_sol", 1001, true);
          // Run paraview and plot the last mesh
          result = system("paraview p2d_adaRef_sol0_mesh.vtp &");
      }

      delete sol;
  }

  cout << "Test is done: Exiting" << endl;
  return  result;
}
<|endoftext|>


<commit_before><commit_msg>SvResizeHelper::ValidateRect, simplify logic<commit_after><|endoftext|>


<commit_before><commit_msg>coverity#1241199 Unchecked dynamic_cast<commit_after><|endoftext|>


<commit_before>/*
    Copyright (c) 2007 Volker Krause <vkrause@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include "messageactions.h"

#include "globalsettings.h"
#include "kmfolder.h"
#include "kmmessage.h"
#include "kmreaderwin.h"

#include <KAction>
#include <KActionMenu>
#include <KActionCollection>
#include <KToggleAction>
#include <KDebug>
#include <KLocale>
#include <KXMLGUIClient>
#include <KStandardDirs>

#include <qwidget.h>

using namespace KMail;

MessageActions::MessageActions( KActionCollection *ac, QWidget* parent ) :
    QObject( parent ),
    mParent( parent ),
    mActionCollection( ac ),
    mMessageView( 0 ),
    mRedirectAction( 0 )
{
  mReplyActionMenu = new KActionMenu( KIcon("mail-reply-sender"), i18nc("Message->","&Reply"), this );
  mActionCollection->addAction( "message_reply_menu", mReplyActionMenu );
  connect( mReplyActionMenu, SIGNAL(triggered(bool)),
           this, SLOT(slotReplyToMsg()) );

  mReplyAction = new KAction( KIcon("mail-reply-sender"), i18n("&Reply..."), this );
  mActionCollection->addAction( "reply", mReplyAction );
  mReplyAction->setShortcut(Qt::Key_R);
  connect( mReplyAction, SIGNAL(triggered(bool)),
           this, SLOT(slotReplyToMsg()) );
  mReplyActionMenu->addAction( mReplyAction );

  mReplyAuthorAction = new KAction( KIcon("mail-reply-sender"), i18n("Reply to A&uthor..."), this );
  mActionCollection->addAction( "reply_author", mReplyAuthorAction );
  mReplyAuthorAction->setShortcut(Qt::SHIFT+Qt::Key_A);
  connect( mReplyAuthorAction, SIGNAL(triggered(bool)),
           this, SLOT(slotReplyAuthorToMsg()) );
  mReplyActionMenu->addAction( mReplyAuthorAction );

  mReplyAllAction = new KAction( KIcon("mail-reply-all"), i18n("Reply to &All..."), this );
  mActionCollection->addAction( "reply_all", mReplyAllAction );
  mReplyAllAction->setShortcut( Qt::Key_A );
  connect( mReplyAllAction, SIGNAL(triggered(bool)),
           this, SLOT(slotReplyAllToMsg()) );
  mReplyActionMenu->addAction( mReplyAllAction );

  mReplyListAction = new KAction( KIcon("mail-reply-list"), i18n("Reply to Mailing-&List..."), this );
  mActionCollection->addAction( "reply_list", mReplyListAction );
  mReplyListAction->setShortcut( Qt::Key_L );
  connect( mReplyListAction, SIGNAL(triggered(bool)),
           this, SLOT(slotReplyListToMsg()) );
  mReplyActionMenu->addAction( mReplyListAction );

  mNoQuoteReplyAction = new KAction( i18n("Reply Without &Quote..."), this );
  mActionCollection->addAction( "noquotereply", mNoQuoteReplyAction );
  mNoQuoteReplyAction->setShortcut( Qt::SHIFT+Qt::Key_R );
  connect( mNoQuoteReplyAction, SIGNAL(triggered(bool)),
           this, SLOT(slotNoQuoteReplyToMsg()) );

  mCreateTodoAction = new KAction( KIcon( "task-new" ), i18n( "Create To-do/Reminder..." ), this );
  mCreateTodoAction->setIconText( i18n( "Create To-do" ) );
  mCreateTodoAction->setHelpText( i18n( "Allows you to create a calendar to-do or reminder from this message" ) );
  mCreateTodoAction->setWhatsThis( i18n( "This option starts the KOrganizer to-do editor with initial values taken from the currently selected message. Then you can edit the to-do to your liking before saving it to your calendar." ) );
  mActionCollection->addAction( "create_todo", mCreateTodoAction );
  connect( mCreateTodoAction, SIGNAL(triggered(bool)),
           this, SLOT(slotCreateTodo()) );
  mKorganizerIsOnSystem = !KStandardDirs::findExe("korganizer").isEmpty();
  mCreateTodoAction->setEnabled( mKorganizerIsOnSystem );

  mStatusMenu = new KActionMenu ( i18n( "Mar&k Message" ), this );
  mActionCollection->addAction( "set_status", mStatusMenu );

  KAction *action;

  action = new KAction( KIcon("mail-mark-read"), i18n("Mark Message as &Read"), this );
  action->setHelpText( i18n("Mark selected messages as read") );
  connect( action, SIGNAL(triggered(bool)),
           this, SLOT(slotSetMsgStatusRead()) );
  mActionCollection->addAction( "status_read", action );
  mStatusMenu->addAction( action );

  action = new KAction( KIcon("mail-mark-unread-new"), i18n("Mark Message as &New"), this );
  action->setHelpText( i18n("Mark selected messages as new") );
  connect( action, SIGNAL(triggered(bool)),
           this, SLOT(slotSetMsgStatusNew()) );
  mActionCollection->addAction( "status_new", action );
  mStatusMenu->addAction( action );

  action = new KAction( KIcon("mail-mark-unread"), i18n("Mark Message as &Unread"), this );
  action->setHelpText( i18n("Mark selected messages as unread") );
  connect( action, SIGNAL(triggered(bool)),
           this, SLOT(slotSetMsgStatusUnread()) );
  mActionCollection->addAction( "status_unread", action );
  action->setShortcut( Qt::CTRL+Qt::Key_U );
  mStatusMenu->addAction( action );

  mStatusMenu->addSeparator();

  mToggleFlagAction = new KToggleAction( KIcon("mail-mark-important"),
                                         i18n("Mark Message as &Important"), this );
  mToggleFlagAction->setShortcut( Qt::CTRL + Qt::Key_I );
  connect( mToggleFlagAction, SIGNAL(triggered(bool)),
           this, SLOT(slotSetMsgStatusFlag()) );
  mToggleFlagAction->setCheckedState( KGuiItem(i18n("Remove &Important Message Mark")) );
  mActionCollection->addAction( "status_flag", mToggleFlagAction );
  mStatusMenu->addAction( mToggleFlagAction );

  mToggleToActAction = new KToggleAction( KIcon("mail-mark-task"),
                                          i18n("Mark Message as &Action Item"), this );
  connect( mToggleToActAction, SIGNAL(triggered(bool)),
           this, SLOT(slotSetMsgStatusToAct()) );
  mToggleToActAction->setCheckedState( KGuiItem(i18n("Remove &Action Item Message Mark")) );
  mActionCollection->addAction( "status_toact", mToggleToActAction );
  mStatusMenu->addAction( mToggleToActAction );

  mEditAction = new KAction( KIcon("accessories-text-editor"), i18n("&Edit Message"), this );
  mActionCollection->addAction( "edit", mEditAction );
  connect( mEditAction, SIGNAL(triggered(bool)),
           this, SLOT(editCurrentMessage()) );
  mEditAction->setShortcut( Qt::Key_T );

  mForwardActionMenu  = new KActionMenu(KIcon("mail-forward"), i18nc("Message->","&Forward"), this);
  mActionCollection->addAction("message_forward", mForwardActionMenu );

  mForwardAttachedAction = new KAction( KIcon("mail-forward"),
                                        i18nc( "@action:inmenu Message->Forward->",
                                               "As &Attachment..." ),
                                        this );
  connect( mForwardAttachedAction, SIGNAL( triggered( bool ) ),
           parent, SLOT( slotForwardAttachedMsg() ) );
  mActionCollection->addAction( "message_forward_as_attachment", mForwardAttachedAction );

  mForwardInlineAction = new KAction( KIcon( "mail-forward" ),
                                       i18nc( "@action:inmenu Message->Forward->",
                                              "&Inline..." ),
                                       this );
  connect( mForwardInlineAction, SIGNAL( triggered( bool ) ),
           parent, SLOT( slotForwardInlineMsg() ) );
  mActionCollection->addAction( "message_forward_inline", mForwardInlineAction );

  setupForwardActions();

  mRedirectAction  = new KAction(i18nc("Message->Forward->", "&Redirect..."), this );
  mActionCollection->addAction( "message_forward_redirect", mRedirectAction );
  connect( mRedirectAction, SIGNAL( triggered( bool ) ),
           parent, SLOT( slotRedirectMsg() ) );
  mRedirectAction->setShortcut( QKeySequence( Qt::Key_E ) );
  mForwardActionMenu->addAction( mRedirectAction );

  updateActions();
}

void MessageActions::setCurrentMessage( const Akonadi::Item &msg )
{
  mCurrentItem = msg;
  if ( !msg.isValid() ) {
    mSelectedSernums.clear();
    mVisibleSernums.clear();
  }
  updateActions();
}

void MessageActions::setSelectedSernums(const QList< quint32 > & sernums)
{
  mSelectedSernums = sernums;
  updateActions();
}

void MessageActions::setSelectedVisibleSernums(const QList< quint32 > & sernums)
{
  mVisibleSernums = sernums;
  updateActions();
}

void MessageActions::updateActions()
{
#ifdef OLD_MESSAGEACTION
  bool singleMsg = (mCurrentMessage != 0);
  if ( mCurrentMessage && mCurrentMessage->parent() ) {
    if ( mCurrentMessage->parent()->isTemplates() )
      singleMsg = false;
  }
  const bool multiVisible = mVisibleSernums.count() > 0 || mCurrentMessage;
  const bool flagsAvailable = GlobalSettings::self()->allowLocalFlags() ||
      !((mCurrentMessage && mCurrentMessage->parent()) ? mCurrentMessage->parent()->isReadOnly() : true);

  mCreateTodoAction->setEnabled( singleMsg && mKorganizerIsOnSystem);
  mReplyActionMenu->setEnabled( singleMsg );
  mReplyAction->setEnabled( singleMsg );
  mNoQuoteReplyAction->setEnabled( singleMsg );
  mReplyAuthorAction->setEnabled( singleMsg );
  mReplyAllAction->setEnabled( singleMsg );
  mReplyListAction->setEnabled( singleMsg );
  mNoQuoteReplyAction->setEnabled( singleMsg );

  mStatusMenu->setEnabled( multiVisible );
  mToggleFlagAction->setEnabled( flagsAvailable );
  mToggleToActAction->setEnabled( flagsAvailable );

  if ( mCurrentMessage ) {
    mToggleToActAction->setChecked( mCurrentMessage->status().isToAct() );
    mToggleFlagAction->setChecked( mCurrentMessage->status().isImportant() );
  }

  mEditAction->setEnabled( singleMsg );
#endif
}

void MessageActions::slotCreateTodo()
{
  if ( !mCurrentItem.isValid() )
    return;
#ifdef OLD_COMMAND
  KMCommand *command = new CreateTodoCommand( mParent, mCurrentMessage );
  command->start();
#endif
}

void MessageActions::setMessageView(KMReaderWin * msgView)
{
  mMessageView = msgView;
}

void MessageActions::setupForwardActions()
{
  disconnect( mForwardActionMenu, SIGNAL( triggered(bool) ), 0, 0 );
  mForwardActionMenu->removeAction( mForwardInlineAction );
  mForwardActionMenu->removeAction( mForwardAttachedAction );

  if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
    mForwardActionMenu->insertAction( mRedirectAction, mForwardInlineAction );
    mForwardActionMenu->insertAction( mRedirectAction, mForwardAttachedAction );
    mForwardInlineAction->setShortcut(QKeySequence(Qt::Key_F));
    mForwardAttachedAction->setShortcut(QKeySequence(Qt::SHIFT+Qt::Key_F));
    QObject::connect( mForwardActionMenu, SIGNAL(triggered(bool)),
                      mParent, SLOT(slotForwardInlineMsg()) );
  }
  else {
    mForwardActionMenu->insertAction( mRedirectAction, mForwardAttachedAction );
    mForwardActionMenu->insertAction( mRedirectAction, mForwardInlineAction );
    mForwardInlineAction->setShortcut(QKeySequence(Qt::SHIFT+Qt::Key_F));
    mForwardAttachedAction->setShortcut(QKeySequence(Qt::Key_F));
    QObject::connect( mForwardActionMenu, SIGNAL(triggered(bool)),
                      mParent, SLOT(slotForwardAttachedMsg()) );
  }
}

void MessageActions::setupForwardingActionsList( KXMLGUIClient *guiClient )
{
  QList<QAction*> forwardActionList;
  guiClient->unplugActionList( "forward_action_list" );
  if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
    forwardActionList.append( mForwardInlineAction );
    forwardActionList.append( mForwardAttachedAction );
  }
  else {
    forwardActionList.append( mForwardAttachedAction );
    forwardActionList.append( mForwardInlineAction );
  }
  forwardActionList.append( mRedirectAction );
  guiClient->plugActionList( "forward_action_list", forwardActionList );
}

void MessageActions::slotReplyToMsg()
{
  replyCommand<KMReplyToCommand>();
}

void MessageActions::slotReplyAuthorToMsg()
{
  replyCommand<KMReplyAuthorCommand>();
}

void MessageActions::slotReplyListToMsg()
{
  replyCommand<KMReplyListCommand>();
}

void MessageActions::slotReplyAllToMsg()
{
  replyCommand<KMReplyToAllCommand>();
}

void MessageActions::slotNoQuoteReplyToMsg()
{
  if ( !mCurrentItem.isValid() )
    return;
#ifdef OLD_COMMAND
  KMCommand *command = new KMNoQuoteReplyToCommand( mParent, mCurrentMessage );
  command->start();
#endif
}

void MessageActions::slotSetMsgStatusNew()
{
  setMessageStatus( KPIM::MessageStatus::statusNew() );
}

void MessageActions::slotSetMsgStatusUnread()
{
  setMessageStatus( KPIM::MessageStatus::statusUnread() );
}

void MessageActions::slotSetMsgStatusRead()
{
  setMessageStatus( KPIM::MessageStatus::statusRead() );
}

void MessageActions::slotSetMsgStatusFlag()
{
  setMessageStatus( KPIM::MessageStatus::statusImportant(), true );
}

void MessageActions::slotSetMsgStatusToAct()
{
  setMessageStatus( KPIM::MessageStatus::statusToAct(), true );
}

void MessageActions::setMessageStatus( KPIM::MessageStatus status, bool toggle )
{
#ifdef OLD_MESSAGEACTION
  QList<quint32> serNums = mVisibleSernums;
  if ( serNums.isEmpty() && mCurrentMessage )
    serNums.append( mCurrentMessage->getMsgSerNum() );
  if ( serNums.empty() )
    return;
  KMCommand *command = new KMSetStatusCommand( status, serNums, toggle );
  command->start();
#endif
}

void MessageActions::editCurrentMessage()
{
  if ( !mCurrentItem.isValid() )
    return;
#ifdef OLD_COMMAND
  KMCommand *command = 0;
  KMFolder *folder = mCurrentMessage->parent();
  // edit, unlike send again, removes the message from the folder
  // we only want that for templates and drafts folders
  if ( folder && ( kmkernel->folderIsDraftOrOutbox( folder ) ||
       kmkernel->folderIsTemplates( folder ) ) )
    command = new KMEditMsgCommand( mParent, mCurrentMessage );
  else
    command = new KMResendMessageCommand( mParent, mCurrentMessage );
  command->start();
#endif
}

#include "messageactions.moc"
<commit_msg>Port++<commit_after>/*
    Copyright (c) 2007 Volker Krause <vkrause@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include "messageactions.h"

#include "globalsettings.h"
#include "kmreaderwin.h"

#include <KAction>
#include <KActionMenu>
#include <KActionCollection>
#include <KToggleAction>
#include <KDebug>
#include <KLocale>
#include <KXMLGUIClient>
#include <KStandardDirs>

#include <qwidget.h>
#include <akonadi/collection.h>

using namespace KMail;

MessageActions::MessageActions( KActionCollection *ac, QWidget* parent ) :
    QObject( parent ),
    mParent( parent ),
    mActionCollection( ac ),
    mMessageView( 0 ),
    mRedirectAction( 0 )
{
  mReplyActionMenu = new KActionMenu( KIcon("mail-reply-sender"), i18nc("Message->","&Reply"), this );
  mActionCollection->addAction( "message_reply_menu", mReplyActionMenu );
  connect( mReplyActionMenu, SIGNAL(triggered(bool)),
           this, SLOT(slotReplyToMsg()) );

  mReplyAction = new KAction( KIcon("mail-reply-sender"), i18n("&Reply..."), this );
  mActionCollection->addAction( "reply", mReplyAction );
  mReplyAction->setShortcut(Qt::Key_R);
  connect( mReplyAction, SIGNAL(triggered(bool)),
           this, SLOT(slotReplyToMsg()) );
  mReplyActionMenu->addAction( mReplyAction );

  mReplyAuthorAction = new KAction( KIcon("mail-reply-sender"), i18n("Reply to A&uthor..."), this );
  mActionCollection->addAction( "reply_author", mReplyAuthorAction );
  mReplyAuthorAction->setShortcut(Qt::SHIFT+Qt::Key_A);
  connect( mReplyAuthorAction, SIGNAL(triggered(bool)),
           this, SLOT(slotReplyAuthorToMsg()) );
  mReplyActionMenu->addAction( mReplyAuthorAction );

  mReplyAllAction = new KAction( KIcon("mail-reply-all"), i18n("Reply to &All..."), this );
  mActionCollection->addAction( "reply_all", mReplyAllAction );
  mReplyAllAction->setShortcut( Qt::Key_A );
  connect( mReplyAllAction, SIGNAL(triggered(bool)),
           this, SLOT(slotReplyAllToMsg()) );
  mReplyActionMenu->addAction( mReplyAllAction );

  mReplyListAction = new KAction( KIcon("mail-reply-list"), i18n("Reply to Mailing-&List..."), this );
  mActionCollection->addAction( "reply_list", mReplyListAction );
  mReplyListAction->setShortcut( Qt::Key_L );
  connect( mReplyListAction, SIGNAL(triggered(bool)),
           this, SLOT(slotReplyListToMsg()) );
  mReplyActionMenu->addAction( mReplyListAction );

  mNoQuoteReplyAction = new KAction( i18n("Reply Without &Quote..."), this );
  mActionCollection->addAction( "noquotereply", mNoQuoteReplyAction );
  mNoQuoteReplyAction->setShortcut( Qt::SHIFT+Qt::Key_R );
  connect( mNoQuoteReplyAction, SIGNAL(triggered(bool)),
           this, SLOT(slotNoQuoteReplyToMsg()) );

  mCreateTodoAction = new KAction( KIcon( "task-new" ), i18n( "Create To-do/Reminder..." ), this );
  mCreateTodoAction->setIconText( i18n( "Create To-do" ) );
  mCreateTodoAction->setHelpText( i18n( "Allows you to create a calendar to-do or reminder from this message" ) );
  mCreateTodoAction->setWhatsThis( i18n( "This option starts the KOrganizer to-do editor with initial values taken from the currently selected message. Then you can edit the to-do to your liking before saving it to your calendar." ) );
  mActionCollection->addAction( "create_todo", mCreateTodoAction );
  connect( mCreateTodoAction, SIGNAL(triggered(bool)),
           this, SLOT(slotCreateTodo()) );
  mKorganizerIsOnSystem = !KStandardDirs::findExe("korganizer").isEmpty();
  mCreateTodoAction->setEnabled( mKorganizerIsOnSystem );

  mStatusMenu = new KActionMenu ( i18n( "Mar&k Message" ), this );
  mActionCollection->addAction( "set_status", mStatusMenu );

  KAction *action;

  action = new KAction( KIcon("mail-mark-read"), i18n("Mark Message as &Read"), this );
  action->setHelpText( i18n("Mark selected messages as read") );
  connect( action, SIGNAL(triggered(bool)),
           this, SLOT(slotSetMsgStatusRead()) );
  mActionCollection->addAction( "status_read", action );
  mStatusMenu->addAction( action );

  action = new KAction( KIcon("mail-mark-unread-new"), i18n("Mark Message as &New"), this );
  action->setHelpText( i18n("Mark selected messages as new") );
  connect( action, SIGNAL(triggered(bool)),
           this, SLOT(slotSetMsgStatusNew()) );
  mActionCollection->addAction( "status_new", action );
  mStatusMenu->addAction( action );

  action = new KAction( KIcon("mail-mark-unread"), i18n("Mark Message as &Unread"), this );
  action->setHelpText( i18n("Mark selected messages as unread") );
  connect( action, SIGNAL(triggered(bool)),
           this, SLOT(slotSetMsgStatusUnread()) );
  mActionCollection->addAction( "status_unread", action );
  action->setShortcut( Qt::CTRL+Qt::Key_U );
  mStatusMenu->addAction( action );

  mStatusMenu->addSeparator();

  mToggleFlagAction = new KToggleAction( KIcon("mail-mark-important"),
                                         i18n("Mark Message as &Important"), this );
  mToggleFlagAction->setShortcut( Qt::CTRL + Qt::Key_I );
  connect( mToggleFlagAction, SIGNAL(triggered(bool)),
           this, SLOT(slotSetMsgStatusFlag()) );
  mToggleFlagAction->setCheckedState( KGuiItem(i18n("Remove &Important Message Mark")) );
  mActionCollection->addAction( "status_flag", mToggleFlagAction );
  mStatusMenu->addAction( mToggleFlagAction );

  mToggleToActAction = new KToggleAction( KIcon("mail-mark-task"),
                                          i18n("Mark Message as &Action Item"), this );
  connect( mToggleToActAction, SIGNAL(triggered(bool)),
           this, SLOT(slotSetMsgStatusToAct()) );
  mToggleToActAction->setCheckedState( KGuiItem(i18n("Remove &Action Item Message Mark")) );
  mActionCollection->addAction( "status_toact", mToggleToActAction );
  mStatusMenu->addAction( mToggleToActAction );

  mEditAction = new KAction( KIcon("accessories-text-editor"), i18n("&Edit Message"), this );
  mActionCollection->addAction( "edit", mEditAction );
  connect( mEditAction, SIGNAL(triggered(bool)),
           this, SLOT(editCurrentMessage()) );
  mEditAction->setShortcut( Qt::Key_T );

  mForwardActionMenu  = new KActionMenu(KIcon("mail-forward"), i18nc("Message->","&Forward"), this);
  mActionCollection->addAction("message_forward", mForwardActionMenu );

  mForwardAttachedAction = new KAction( KIcon("mail-forward"),
                                        i18nc( "@action:inmenu Message->Forward->",
                                               "As &Attachment..." ),
                                        this );
  connect( mForwardAttachedAction, SIGNAL( triggered( bool ) ),
           parent, SLOT( slotForwardAttachedMsg() ) );
  mActionCollection->addAction( "message_forward_as_attachment", mForwardAttachedAction );

  mForwardInlineAction = new KAction( KIcon( "mail-forward" ),
                                       i18nc( "@action:inmenu Message->Forward->",
                                              "&Inline..." ),
                                       this );
  connect( mForwardInlineAction, SIGNAL( triggered( bool ) ),
           parent, SLOT( slotForwardInlineMsg() ) );
  mActionCollection->addAction( "message_forward_inline", mForwardInlineAction );

  setupForwardActions();

  mRedirectAction  = new KAction(i18nc("Message->Forward->", "&Redirect..."), this );
  mActionCollection->addAction( "message_forward_redirect", mRedirectAction );
  connect( mRedirectAction, SIGNAL( triggered( bool ) ),
           parent, SLOT( slotRedirectMsg() ) );
  mRedirectAction->setShortcut( QKeySequence( Qt::Key_E ) );
  mForwardActionMenu->addAction( mRedirectAction );

  updateActions();
}

void MessageActions::setCurrentMessage( const Akonadi::Item &msg )
{
  mCurrentItem = msg;
  if ( !msg.isValid() ) {
    mSelectedSernums.clear();
    mVisibleSernums.clear();
  }
  updateActions();
}

void MessageActions::setSelectedSernums(const QList< quint32 > & sernums)
{
  mSelectedSernums = sernums;
  updateActions();
}

void MessageActions::setSelectedVisibleSernums(const QList< quint32 > & sernums)
{
  mVisibleSernums = sernums;
  updateActions();
}

void MessageActions::updateActions()
{
  bool singleMsg = mCurrentItem.isValid();
  Akonadi::Collection parent;
  if ( singleMsg ) //=> valid
    parent = mCurrentItem.parentCollection();
  if ( parent.isValid() ) {
#ifdef OLD_MESSAGEACTION
    if ( mCurrentMessage->parent()->isTemplates() )
      singleMsg = false;
#endif
  }

  const bool multiVisible = mVisibleSernums.count() > 0 || mCurrentItem.isValid();
  const bool flagsAvailable = GlobalSettings::self()->allowLocalFlags()
                              || !(parent.isValid() ? parent.rights() & Akonadi::Collection::ReadOnly : true);

  mCreateTodoAction->setEnabled( singleMsg && mKorganizerIsOnSystem);
  mReplyActionMenu->setEnabled( singleMsg );
  mReplyAction->setEnabled( singleMsg );
  mNoQuoteReplyAction->setEnabled( singleMsg );
  mReplyAuthorAction->setEnabled( singleMsg );
  mReplyAllAction->setEnabled( singleMsg );
  mReplyListAction->setEnabled( singleMsg );
  mNoQuoteReplyAction->setEnabled( singleMsg );

  mStatusMenu->setEnabled( multiVisible );
  mToggleFlagAction->setEnabled( flagsAvailable );
  mToggleToActAction->setEnabled( flagsAvailable );

  if ( mCurrentItem.isValid() ) {
    KPIM::MessageStatus status;
    status.setStatusFromFlags( mCurrentItem.flags() );
    mToggleToActAction->setChecked( status.isToAct() );
    mToggleFlagAction->setChecked( status.isImportant() );
  }

  mEditAction->setEnabled( singleMsg );
}

void MessageActions::slotCreateTodo()
{
  if ( !mCurrentItem.isValid() )
    return;
#ifdef OLD_COMMAND
  KMCommand *command = new CreateTodoCommand( mParent, mCurrentMessage );
  command->start();
#endif
}

void MessageActions::setMessageView(KMReaderWin * msgView)
{
  mMessageView = msgView;
}

void MessageActions::setupForwardActions()
{
  disconnect( mForwardActionMenu, SIGNAL( triggered(bool) ), 0, 0 );
  mForwardActionMenu->removeAction( mForwardInlineAction );
  mForwardActionMenu->removeAction( mForwardAttachedAction );

  if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
    mForwardActionMenu->insertAction( mRedirectAction, mForwardInlineAction );
    mForwardActionMenu->insertAction( mRedirectAction, mForwardAttachedAction );
    mForwardInlineAction->setShortcut(QKeySequence(Qt::Key_F));
    mForwardAttachedAction->setShortcut(QKeySequence(Qt::SHIFT+Qt::Key_F));
    QObject::connect( mForwardActionMenu, SIGNAL(triggered(bool)),
                      mParent, SLOT(slotForwardInlineMsg()) );
  }
  else {
    mForwardActionMenu->insertAction( mRedirectAction, mForwardAttachedAction );
    mForwardActionMenu->insertAction( mRedirectAction, mForwardInlineAction );
    mForwardInlineAction->setShortcut(QKeySequence(Qt::SHIFT+Qt::Key_F));
    mForwardAttachedAction->setShortcut(QKeySequence(Qt::Key_F));
    QObject::connect( mForwardActionMenu, SIGNAL(triggered(bool)),
                      mParent, SLOT(slotForwardAttachedMsg()) );
  }
}

void MessageActions::setupForwardingActionsList( KXMLGUIClient *guiClient )
{
  QList<QAction*> forwardActionList;
  guiClient->unplugActionList( "forward_action_list" );
  if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
    forwardActionList.append( mForwardInlineAction );
    forwardActionList.append( mForwardAttachedAction );
  }
  else {
    forwardActionList.append( mForwardAttachedAction );
    forwardActionList.append( mForwardInlineAction );
  }
  forwardActionList.append( mRedirectAction );
  guiClient->plugActionList( "forward_action_list", forwardActionList );
}

void MessageActions::slotReplyToMsg()
{
  replyCommand<KMReplyToCommand>();
}

void MessageActions::slotReplyAuthorToMsg()
{
  replyCommand<KMReplyAuthorCommand>();
}

void MessageActions::slotReplyListToMsg()
{
  replyCommand<KMReplyListCommand>();
}

void MessageActions::slotReplyAllToMsg()
{
  replyCommand<KMReplyToAllCommand>();
}

void MessageActions::slotNoQuoteReplyToMsg()
{
  if ( !mCurrentItem.isValid() )
    return;
#ifdef OLD_COMMAND
  KMCommand *command = new KMNoQuoteReplyToCommand( mParent, mCurrentMessage );
  command->start();
#endif
}

void MessageActions::slotSetMsgStatusNew()
{
  setMessageStatus( KPIM::MessageStatus::statusNew() );
}

void MessageActions::slotSetMsgStatusUnread()
{
  setMessageStatus( KPIM::MessageStatus::statusUnread() );
}

void MessageActions::slotSetMsgStatusRead()
{
  setMessageStatus( KPIM::MessageStatus::statusRead() );
}

void MessageActions::slotSetMsgStatusFlag()
{
  setMessageStatus( KPIM::MessageStatus::statusImportant(), true );
}

void MessageActions::slotSetMsgStatusToAct()
{
  setMessageStatus( KPIM::MessageStatus::statusToAct(), true );
}

void MessageActions::setMessageStatus( KPIM::MessageStatus status, bool toggle )
{
  QList<quint32> serNums = mVisibleSernums;
  if ( serNums.isEmpty() && mCurrentItem.isValid() )
    serNums.append( mCurrentItem.id() );
  if ( serNums.empty() )
    return;
#ifdef OLD_MESSAGEACTION
  KMCommand *command = new KMSetStatusCommand( status, serNums, toggle );
  command->start();
#endif
}

void MessageActions::editCurrentMessage()
{
  if ( !mCurrentItem.isValid() )
    return;
#ifdef OLD_COMMAND
  KMCommand *command = 0;
  KMFolder *folder = mCurrentMessage->parent();
  // edit, unlike send again, removes the message from the folder
  // we only want that for templates and drafts folders
  if ( folder && ( kmkernel->folderIsDraftOrOutbox( folder ) ||
       kmkernel->folderIsTemplates( folder ) ) )
    command = new KMEditMsgCommand( mParent, mCurrentMessage );
  else
    command = new KMResendMessageCommand( mParent, mCurrentMessage );
  command->start();
#endif
}

#include "messageactions.moc"
<|endoftext|>


<commit_before>/*******************************************************************
 KNotes -- Notes for the KDE project

 Copyright (c) 2005, Michael Brade <brade@kde.org>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

 In addition, as a special exception, the copyright holders give
 permission to link the code of this program with any edition of
 the Qt library by Trolltech AS, Norway (or with modified versions
 of Qt that use the same license as Qt), and distribute linked
 combinations including the two.  You must obey the GNU General
 Public License in all respects for all of the code used other than
 Qt.  If you modify this file, you may extend this exception to
 your version of the file, but you are not obligated to do so.  If
 you do not wish to do so, delete this exception statement from
 your version.
*******************************************************************/

#include <QLabel>
#include <QRadioButton>
#include <q3buttongroup.h>

#include <klocale.h>
#include <kvbox.h>

#include <libkdepim/kdateedit.h>
#include <libkdepim/ktimeedit.h>

#include <kcal/journal.h>
#include <kcal/alarm.h>

#include "knotealarmdlg.h"

KNoteAlarmDlg::KNoteAlarmDlg( const QString& caption, QWidget *parent )
    : KDialog( parent)
{
    setCaption( caption );
    setButtons( Ok|Cancel );
    KVBox *page = new KVBox( this );
    setMainWidget( page );
    Q3GroupBox *group = new Q3GroupBox( 3, Qt::Vertical, i18n("Scheduled Alarm"), page );
    m_buttons = new Q3ButtonGroup( page );
    m_buttons->hide();

    QRadioButton *none = new QRadioButton( i18n("&No alarm"), group );
    m_buttons->insert( none );

    KHBox *at = new KHBox( group );
    QRadioButton *label_at = new QRadioButton( i18n("Alarm &at:"), at );
    m_buttons->insert( label_at );
    m_atDate = new KDateEdit( at );
    m_atTime = new KTimeEdit( at );
    at->setStretchFactor( m_atDate, 1 );

    KHBox *in = new KHBox( group );
    QRadioButton *label_in = new QRadioButton( i18n("Alarm &in:"), in );
    m_buttons->insert( label_in );
    m_inTime = new KTimeEdit( in );
    QLabel *in_min = new QLabel( i18n("hours/minutes"), in );

    label_in->setEnabled( false ); // TODO

    connect( m_buttons, SIGNAL(clicked( int )), SLOT(slotButtonChanged( int )) );
    connect( this, SIGNAL( okClicked() ), SLOT( slotOk() ) );
}

void KNoteAlarmDlg::setIncidence( KCal::Journal *journal )
{
    m_journal = journal;

    if ( !m_journal->alarms().isEmpty() )
    {
        KCal::Alarm *alarm = m_journal->alarms().first();
        if ( alarm->hasTime() )
        {
            m_buttons->setButton( 1 );
            m_atDate->setDate( alarm->time().date() );
            m_atTime->setTime( alarm->time().time() );
        }
        else if ( alarm->hasStartOffset() )
            m_buttons->setButton( 2 );
        else
            m_buttons->setButton( 0 );
    }
    else
        m_buttons->setButton( 0 );

    slotButtonChanged( m_buttons->selectedId() );
}

void KNoteAlarmDlg::slotButtonChanged( int id )
{
    switch ( id )
    {
    case 0:
        m_atDate->setEnabled( false );
        m_atTime->setEnabled( false );
        m_inTime->setEnabled( false );
        break;
    case 1:
        m_atDate->setEnabled( true );
        m_atTime->setEnabled( true );
        m_inTime->setEnabled( false );
        break;
    case 2:
        m_atDate->setEnabled( false );
        m_atTime->setEnabled( false );
        m_inTime->setEnabled( true );
    }
}

void KNoteAlarmDlg::slotOk()
{
    if ( m_buttons->selectedId() == 0 )
    {
        m_journal->clearAlarms();
        return;
    }

    KCal::Alarm *alarm;
    if ( m_journal->alarms().isEmpty() )
    {
        alarm = m_journal->newAlarm();
        alarm->setEnabled( true );
        alarm->setType( KCal::Alarm::Display );
    }
    else
        alarm = m_journal->alarms().first();

    if ( m_buttons->selectedId() == 1 )
        alarm->setTime( QDateTime( m_atDate->date(), m_atTime->getTime() ) );
    else
    {
        // TODO
    }
}

#include "knotealarmdlg.moc"
<commit_msg>Remove deprecated method<commit_after>/*******************************************************************
 KNotes -- Notes for the KDE project

 Copyright (c) 2005, Michael Brade <brade@kde.org>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

 In addition, as a special exception, the copyright holders give
 permission to link the code of this program with any edition of
 the Qt library by Trolltech AS, Norway (or with modified versions
 of Qt that use the same license as Qt), and distribute linked
 combinations including the two.  You must obey the GNU General
 Public License in all respects for all of the code used other than
 Qt.  If you modify this file, you may extend this exception to
 your version of the file, but you are not obligated to do so.  If
 you do not wish to do so, delete this exception statement from
 your version.
*******************************************************************/

#include <QLabel>
#include <QRadioButton>
#include <q3buttongroup.h>

#include <klocale.h>
#include <kvbox.h>

#include <libkdepim/kdateedit.h>
#include <libkdepim/ktimeedit.h>

#include <kcal/journal.h>
#include <kcal/alarm.h>

#include "knotealarmdlg.h"

KNoteAlarmDlg::KNoteAlarmDlg( const QString& caption, QWidget *parent )
    : KDialog( parent)
{
    setCaption( caption );
    setButtons( Ok|Cancel );
    KVBox *page = new KVBox( this );
    setMainWidget( page );
    Q3GroupBox *group = new Q3GroupBox( 3, Qt::Vertical, i18n("Scheduled Alarm"), page );
    m_buttons = new Q3ButtonGroup( page );
    m_buttons->hide();

    QRadioButton *none = new QRadioButton( i18n("&No alarm"), group );
    m_buttons->insert( none );

    KHBox *at = new KHBox( group );
    QRadioButton *label_at = new QRadioButton( i18n("Alarm &at:"), at );
    m_buttons->insert( label_at );
    m_atDate = new KDateEdit( at );
    m_atTime = new KTimeEdit( at );
    at->setStretchFactor( m_atDate, 1 );

    KHBox *in = new KHBox( group );
    QRadioButton *label_in = new QRadioButton( i18n("Alarm &in:"), in );
    m_buttons->insert( label_in );
    m_inTime = new KTimeEdit( in );
    QLabel *in_min = new QLabel( i18n("hours/minutes"), in );

    label_in->setEnabled( false ); // TODO

    connect( m_buttons, SIGNAL(clicked( int )), SLOT(slotButtonChanged( int )) );
    connect( this, SIGNAL( okClicked() ), SLOT( slotOk() ) );
}

void KNoteAlarmDlg::setIncidence( KCal::Journal *journal )
{
    m_journal = journal;

    if ( !m_journal->alarms().isEmpty() )
    {
        KCal::Alarm *alarm = m_journal->alarms().first();
        if ( alarm->hasTime() )
        {
            m_buttons->setButton( 1 );
            m_atDate->setDate( alarm->time().date() );
            m_atTime->setTime( alarm->time().time() );
        }
        else if ( alarm->hasStartOffset() )
            m_buttons->setButton( 2 );
        else
            m_buttons->setButton( 0 );
    }
    else
        m_buttons->setButton( 0 );

    slotButtonChanged( m_buttons->selectedId() );
}

void KNoteAlarmDlg::slotButtonChanged( int id )
{
    switch ( id )
    {
    case 0:
        m_atDate->setEnabled( false );
        m_atTime->setEnabled( false );
        m_inTime->setEnabled( false );
        break;
    case 1:
        m_atDate->setEnabled( true );
        m_atTime->setEnabled( true );
        m_inTime->setEnabled( false );
        break;
    case 2:
        m_atDate->setEnabled( false );
        m_atTime->setEnabled( false );
        m_inTime->setEnabled( true );
    }
}

void KNoteAlarmDlg::slotOk()
{
    if ( m_buttons->selectedId() == 0 )
    {
        m_journal->clearAlarms();
        return;
    }

    KCal::Alarm *alarm;
    if ( m_journal->alarms().isEmpty() )
    {
        alarm = m_journal->newAlarm();
        alarm->setEnabled( true );
        alarm->setType( KCal::Alarm::Display );
    }
    else
        alarm = m_journal->alarms().first();

    if ( m_buttons->selectedId() == 1 )
        alarm->setTime( KDateTime( m_atDate->date(), m_atTime->getTime(), KDateTime::LocalZone ) );
    else
    {
        // TODO
    }
}

#include "knotealarmdlg.moc"
<|endoftext|>


<commit_before>/**
 * A thread synchronization barrier implemented using erl_nif synch facilities
 */
class Barrier {

private:
	uint N_THREADS;

	uint waiting_threads_counts[2];
	uint current_counter;

	ErlNifMutex* mtx;
	ErlNifCond* cond;

public:
	explicit Barrier(uint n_Threads) {
		N_THREADS = n_Threads;
		waiting_threads_counts[0] = waiting_threads_counts[1] = 0;
		current_counter = 0;

		mtx = enif_mutex_create((char*) "map_load_thread_cond_mtx");
		cond = enif_cond_create((char*) "map_load_thread_cond");

		//std::cerr << "Barrier("<< N_THREADS <<") CREATED"<<endl;
	}
	~Barrier() {
		enif_cond_destroy(cond);
		enif_mutex_destroy(mtx);
	}

	void await(){

		enif_mutex_lock(mtx);

		uint local_counter = current_counter;

		waiting_threads_counts[local_counter]++;
		//std::cerr << "await(): waiting_threads_counts[local_counter]++: "<< waiting_threads_counts[local_counter] <<endl;

		if(waiting_threads_counts[local_counter] < N_THREADS) {
			//std::cerr << "await(): Barrier NOT full" <<endl;

			while(waiting_threads_counts[local_counter] < N_THREADS) {
			//	std::cerr << "await(): cond_wait waiting_threads_counts[local_counter]: "<< waiting_threads_counts[local_counter] <<endl;
				enif_cond_wait(cond, mtx);
			}
		}
		else {
			//std::cerr << "await(): Barrier FULL. waiting_threads:" <<waiting_threads_counts[local_counter] << " broadcast!" <<endl;

			current_counter ^= 1;
			waiting_threads_counts[current_counter] = 0;

			enif_cond_broadcast(cond);
		}

	//	std::cerr << "await(): END" <<endl;
		enif_mutex_unlock(mtx);
	}

};

/*array must be big enough to contain list.length elements*/
uint list_to_double_arrayN(ErlNifEnv *env, ERL_NIF_TERM list, double* array, uint arrayLen, ERL_NIF_TERM* lastListCell) {

	if(array == NULL)
		return 0;

	uint len = 0;

	if(enif_is_list(env, list)) {

		ERL_NIF_TERM curr_cell = list;

		uint i = 0;
		for(i = 0; enif_is_list(env, curr_cell) && i < arrayLen; i++) {

			ERL_NIF_TERM hd, tl;
			if(!enif_get_list_cell(env, curr_cell, &hd, &tl))
				break;//list is empty

			if(!(enif_get_double(env, hd, &(array[i]) ))) {
				std::cerr << "DEBUG: list_to_double_arrayN - Error: attempt to read float from something else!" << std::endl;
			}
			curr_cell = tl;

		}

		if(lastListCell != NULL) //user requested the term denoting the last cell
			*lastListCell = curr_cell;

		return i;

	} else { //term "list" is not a list

		#ifdef DEBUG
		std::cerr << "DEBUG: list_to_double_arrayN - Error: trying to convert a non list as a list"<< std::endl ;
		#endif

		return 0;
	}
}

uint sync_list_to_double_arrayN(ErlNifEnv *env, ErlNifMutex *mtx, ERL_NIF_TERM list, double* array, uint arrayLen, ERL_NIF_TERM* lastListCell) {

	enif_mutex_lock(mtx);

	uint result = list_to_double_arrayN(env, list, array,  arrayLen, lastListCell);

	enif_mutex_unlock(mtx);

	return result;

}

void list_to_double_array(ErlNifEnv *env, ERL_NIF_TERM list, uint listLen, double* array) { //TODO scorre la lista 2 volte

	if(array == NULL)
		return;

	uint len = 0;

	if(enif_is_list(env, list)) {

		list_to_double_arrayN(env, list, array, listLen, NULL);
	}

}

ERL_NIF_TERM double_array_to_list(ErlNifEnv *env, double* array, size_t array_size) {

	if(array == NULL)
		return ATOM(error);

	ERL_NIF_TERM* floatTermArray =
			(ERL_NIF_TERM*) enif_alloc(sizeof(ERL_NIF_TERM) * array_size);

	for(uint i = 0; i < array_size; i++)
		floatTermArray[i] = enif_make_double(env, array[i]);

	ERL_NIF_TERM res = enif_make_list_from_array(env, floatTermArray, array_size);

	enif_free(floatTermArray);

	return res;
}

/*returns a string containing the content of the file at filePath
 * otherwise "NULL".*/
string readFromFileStr(char* filePath) {

	ifstream file(filePath, ios::in);
	if (!file.is_open()) {
		cerr << "Failed to open file for reading: " << filePath << endl;
		return "NULL";
	}

	ostringstream oss;
	oss << file.rdbuf();

	return oss.str();
}

/*returns a dinamically allocated string containing the content of the file at filePath
 * otherwise NULL.
 * The returned sting must be enif_free'd when not needed.
 * */
char* readFromFile(char* filePath) {

	string srcStdStr = readFromFileStr(filePath);

	char* toReturn = (char*) enif_alloc(srcStdStr.length()+1);

	return strcpy(toReturn, srcStdStr.c_str());

}

#define MIN(a, b) ((a < b) ? a : b)

int inline isPow2(unsigned int v) { return v && !(v & (v - 1));}

/*
 * Return a value that is nearest value that is power of 2.
 */
unsigned int nextPow2( unsigned int x )
{
    --x;
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    return x+1;
}

// Round Up Division function
size_t roundUp(uint group_size, uint global_size)
{
    uint r = global_size % group_size;
    if(r == 0)
        return global_size;
    else
        return global_size + group_size - r;
}

/*!
 * Compute the number of threads and blocks to use for the REDUCTION kernel.
 * We set threads / block to the minimum of maxThreads and n/2 where n is
 * problem size. We observe the maximum specified number of blocks, because
 * each kernel thread can process more than 1 elements.
 *
 * \param n Problem size.
 * \param maxBlocks Maximum number of blocks that can be used.
 * \param maxThreads Maximum number of threads that can be used.
 * \param blocks An output parameter passed by reference. Specify number of blocks to be used.
 * \param threads An output parameter passed by reference. Specify number of threads to be used.
 */
void getNumBlocksAndThreads(int n, int maxBlocks, int maxThreads, long unsigned int &blocks, long unsigned int &threads)
{
        threads = (n < maxThreads*2) ? nextPow2((n + 1)/ 2) : maxThreads;
        blocks = (n + (threads * 2 - 1)) / (threads * 2);

        if(maxBlocks > 0)
        	blocks = MIN(maxBlocks, blocks);
}

/*
 *  It finds all instances of a string in another string and replaces it with
 *  a third string.
 *
 */
void replaceTextInString(std::string& text, std::string find, std::string replace)
{
        std::string::size_type pos=0;
        while((pos = text.find(find, pos)) != std::string::npos)
        {
            text.erase(pos, find.length());
            text.insert(pos, replace);
            pos+=replace.length();
        }
}

<commit_msg>Update utils.cpp<commit_after>/**
 * A thread synchronization barrier implemented using erl_nif synch facilities
 */
class Barrier {

private:
	uint N_THREADS;

	uint waiting_threads_counts[2];
	uint current_counter;

	ErlNifMutex* mtx;
	ErlNifCond* cond;

public:
	explicit Barrier(uint n_Threads) {
		N_THREADS = n_Threads;
		waiting_threads_counts[0] = waiting_threads_counts[1] = 0;
		current_counter = 0;

		mtx = enif_mutex_create((char*) "map_load_thread_cond_mtx");
		cond = enif_cond_create((char*) "map_load_thread_cond");

		//std::cerr << "Barrier("<< N_THREADS <<") CREATED"<<endl;
	}
	~Barrier() {
		enif_cond_destroy(cond);
		enif_mutex_destroy(mtx);
	}

	void await(){

		enif_mutex_lock(mtx);

		uint local_counter = current_counter;

		waiting_threads_counts[local_counter]++;
		//std::cerr << "await(): waiting_threads_counts[local_counter]++: "<< waiting_threads_counts[local_counter] <<endl;

		if(waiting_threads_counts[local_counter] < N_THREADS) {
			//std::cerr << "await(): Barrier NOT full" <<endl;

			while(waiting_threads_counts[local_counter] < N_THREADS) {
			//	std::cerr << "await(): cond_wait waiting_threads_counts[local_counter]: "<< waiting_threads_counts[local_counter] <<endl;
				enif_cond_wait(cond, mtx);
			}
		}
		else {
			//std::cerr << "await(): Barrier FULL. waiting_threads:" <<waiting_threads_counts[local_counter] << " broadcast!" <<endl;

			current_counter ^= 1;
			waiting_threads_counts[current_counter] = 0;

			enif_cond_broadcast(cond);
		}

	//	std::cerr << "await(): END" <<endl;
		enif_mutex_unlock(mtx);
	}

};

/*array must be big enough to contain list.length elements*/
uint list_to_double_arrayN(ErlNifEnv *env, ERL_NIF_TERM list, double* array, uint arrayLen, ERL_NIF_TERM* lastListCell) {

	if(array == NULL)
		return 0;

	uint len = 0;

	if(enif_is_list(env, list)) {

		ERL_NIF_TERM curr_cell = list;

		uint i = 0;
		for(i = 0; enif_is_list(env, curr_cell) && i < arrayLen; i++) {

			ERL_NIF_TERM hd, tl;
			if(!enif_get_list_cell(env, curr_cell, &hd, &tl))
				break;//list is empty

			if(!(enif_get_double(env, hd, &(array[i]) ))) {
				std::cerr << "DEBUG: list_to_double_arrayN - Error: attempt to read float from something else!" << std::endl;
			}
			curr_cell = tl;

		}

		if(lastListCell != NULL) //user requested the term denoting the last cell
			*lastListCell = curr_cell;

		return i;

	} else { //term "list" is not a list

		#ifdef DEBUG
		std::cerr << "DEBUG: list_to_double_arrayN - Error: trying to convert a non list as a list"<< std::endl ;
		#endif

		return 0;
	}
}

uint sync_list_to_double_arrayN(ErlNifEnv *env, ErlNifMutex *mtx, ERL_NIF_TERM list, double* array, uint arrayLen, ERL_NIF_TERM* lastListCell) {

	enif_mutex_lock(mtx);

	uint result = list_to_double_arrayN(env, list, array,  arrayLen, lastListCell);

	enif_mutex_unlock(mtx);

	return result;

}

void list_to_double_array(ErlNifEnv *env, ERL_NIF_TERM list, uint listLen, double* array) {

	if(array == NULL)
		return;

	uint len = 0;

	if(enif_is_list(env, list)) {

		list_to_double_arrayN(env, list, array, listLen, NULL);
	}

}

ERL_NIF_TERM double_array_to_list(ErlNifEnv *env, double* array, size_t array_size) {

	if(array == NULL)
		return ATOM(error);

	ERL_NIF_TERM* floatTermArray =
			(ERL_NIF_TERM*) enif_alloc(sizeof(ERL_NIF_TERM) * array_size);

	for(uint i = 0; i < array_size; i++)
		floatTermArray[i] = enif_make_double(env, array[i]);

	ERL_NIF_TERM res = enif_make_list_from_array(env, floatTermArray, array_size);

	enif_free(floatTermArray);

	return res;
}

/*returns a string containing the content of the file at filePath
 * otherwise "NULL".*/
string readFromFileStr(char* filePath) {

	ifstream file(filePath, ios::in);
	if (!file.is_open()) {
		cerr << "Failed to open file for reading: " << filePath << endl;
		return "NULL";
	}

	ostringstream oss;
	oss << file.rdbuf();

	return oss.str();
}

/*returns a dinamically allocated string containing the content of the file at filePath
 * otherwise NULL.
 * The returned sting must be enif_free'd when not needed.
 * */
char* readFromFile(char* filePath) {

	string srcStdStr = readFromFileStr(filePath);

	char* toReturn = (char*) enif_alloc(srcStdStr.length()+1);

	return strcpy(toReturn, srcStdStr.c_str());

}

#define MIN(a, b) ((a < b) ? a : b)

int inline isPow2(unsigned int v) { return v && !(v & (v - 1));}

/*
 * Return a value that is nearest value that is power of 2.
 */
unsigned int nextPow2( unsigned int x )
{
    --x;
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    return x+1;
}

// Round Up Division function
size_t roundUp(uint group_size, uint global_size)
{
    uint r = global_size % group_size;
    if(r == 0)
        return global_size;
    else
        return global_size + group_size - r;
}

/*!
 * Compute the number of threads and blocks to use for the REDUCTION kernel.
 * We set threads / block to the minimum of maxThreads and n/2 where n is
 * problem size. We observe the maximum specified number of blocks, because
 * each kernel thread can process more than 1 elements.
 *
 * \param n Problem size.
 * \param maxBlocks Maximum number of blocks that can be used.
 * \param maxThreads Maximum number of threads that can be used.
 * \param blocks An output parameter passed by reference. Specify number of blocks to be used.
 * \param threads An output parameter passed by reference. Specify number of threads to be used.
 */
void getNumBlocksAndThreads(int n, int maxBlocks, int maxThreads, long unsigned int &blocks, long unsigned int &threads)
{
        threads = (n < maxThreads*2) ? nextPow2((n + 1)/ 2) : maxThreads;
        blocks = (n + (threads * 2 - 1)) / (threads * 2);

        if(maxBlocks > 0)
        	blocks = MIN(maxBlocks, blocks);
}

/*
 *  It finds all instances of a string in another string and replaces it with
 *  a third string.
 *
 */
void replaceTextInString(std::string& text, std::string find, std::string replace)
{
        std::string::size_type pos=0;
        while((pos = text.find(find, pos)) != std::string::npos)
        {
            text.erase(pos, find.length());
            text.insert(pos, replace);
            pos+=replace.length();
        }
}

<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- *
 *                          OpenSim:  testScale.cpp                           *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2012 Stanford University and the Authors                *
 * Author(s): Ayman Habib, Peter Loan                                         *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

// INCLUDES
#include <string>
#include <OpenSim/version.h>
#include <OpenSim/Common/Storage.h>
#include <OpenSim/Common/IO.h>
#include <OpenSim/Common/ScaleSet.h>
#include <OpenSim/Simulation/Model/Model.h>
#include <OpenSim/Tools/ScaleTool.h>
#include <OpenSim/Common/MarkerData.h>
#include <OpenSim/Simulation/Model/MarkerSet.h>
#include <OpenSim/Simulation/Model/ForceSet.h>
#include <OpenSim/Common/LoadOpenSimLibrary.h>
#include <OpenSim/Simulation/Model/Analysis.h>
#include <OpenSim/Auxiliary/auxiliaryTestFunctions.h>

using namespace OpenSim;
using namespace std;

void scaleGait2354();
void scaleGait2354_GUI(bool useMarkerPlacement);
void scaleModelWithLigament();

int main()
{
    try {

        scaleGait2354();
        scaleGait2354_GUI(false);
        scaleModelWithLigament();

    }
    catch (const Exception& e) {
        e.print(cerr);
        return 1;
    }
    cout << "Done" << endl;
    return 0;
}

void compareModel(const Model& resultModel, const std::string& stdFileName, double tol)
{
    // Load std model and realize it to Velocity just in case
    Model* refModel = new Model(stdFileName);
    SimTK::State& sStd = refModel->initSystem();

    const SimTK::State& s = resultModel.getWorkingState();
    resultModel.getMultibodySystem().realize(s, SimTK::Stage::Velocity);

    ASSERT(sStd.getNQ()==s.getNQ());
    // put them in same configuration
    sStd.updQ() = s.getQ();
    refModel->getMultibodySystem().realize(sStd, SimTK::Stage::Velocity);

    ASSERT(sStd.getNU()==s.getNU());
    ASSERT(sStd.getNZ()==s.getNZ());

    // Now cycle thru ModelComponents recursively

    delete refModel;
}

void scaleGait2354()
{
    // SET OUTPUT FORMATTING
    IO::SetDigitsPad(4);

    std::string setupFilePath;
    ScaleTool* subject;
    Model* model;

    // Remove old results if any
    FILE* file2Remove = IO::OpenFile(setupFilePath+"subject01_scaleSet_applied.xml", "w");
    fclose(file2Remove);
    file2Remove = IO::OpenFile(setupFilePath+"subject01_simbody.osim", "w");
    fclose(file2Remove);

    // Construct model and read parameters file
    subject = new ScaleTool("subject01_Setup_Scale.xml");

    // Keep track of the folder containing setup file, wil be used to locate results to comapre against
    setupFilePath=subject->getPathToSubject();

    model = subject->createModel();

    SimTK::State& s = model->updWorkingState();
    model->getMultibodySystem().realize(s, SimTK::Stage::Position );

    if(!model) {
        //throw Exception("scale: ERROR- No model specified.",__FILE__,__LINE__);
        cout << "scale: ERROR- No model specified.";
    }

    ASSERT(!subject->isDefaultModelScaler() && subject->getModelScaler().getApply());
    ModelScaler& scaler = subject->getModelScaler();
    ASSERT(scaler.processModel(model, subject->getPathToSubject(), subject->getSubjectMass()));

    /*
    if (!subject->isDefaultMarkerPlacer() && subject->getMarkerPlacer().getApply()) {
        MarkerPlacer& placer = subject->getMarkerPlacer();
        if( false == placer.processModel(s, model, subject->getPathToSubject())) return(false);
    }
    else {
        return(1);
    }
    */
    // Compare ScaleSet
    ScaleSet stdScaleSet = ScaleSet(setupFilePath+"std_subject01_scaleSet_applied.xml");

    const ScaleSet& computedScaleSet = ScaleSet(setupFilePath+"subject01_scaleSet_applied.xml");

    ASSERT(computedScaleSet == stdScaleSet);

    delete model;
    delete subject;
}

void scaleGait2354_GUI(bool useMarkerPlacement)
{
    // SET OUTPUT FORMATTING
    IO::SetDigitsPad(4);

    // Construct model and read parameters file
    ScaleTool* subject = new ScaleTool("subject01_Setup_Scale_GUI.xml");
    std::string setupFilePath=subject->getPathToSubject();

    // Remove old results if any
    FILE* file2Remove = IO::OpenFile(setupFilePath+"subject01_scaleSet_applied_GUI.xml", "w");
    fclose(file2Remove);
    file2Remove = IO::OpenFile(setupFilePath+"subject01_scaledOnly_GUI.osim", "w");
    fclose(file2Remove);

    Model guiModel("gait2354_simbody.osim");

    // Keep track of the folder containing setup file, wil be used to locate results to comapre against
    guiModel.initSystem();
    MarkerSet *markerSet = new MarkerSet(guiModel, setupFilePath + subject->getGenericModelMaker().getMarkerSetFileName());
    guiModel.updateMarkerSet(*markerSet);

    // processedModelContext.processModelScale(scaleTool.getModelScaler(), processedModel, "", scaleTool.getSubjectMass())
    guiModel.getMultibodySystem().realizeTopology();
    SimTK::State* configState=&guiModel.updWorkingState();
    bool retValue= subject->getModelScaler().processModel(&guiModel, setupFilePath, subject->getSubjectMass());
    // Model has changed need to recreate a valid state
    guiModel.getMultibodySystem().realizeTopology();
    configState=&guiModel.updWorkingState();
    guiModel.getMultibodySystem().realize(*configState, SimTK::Stage::Position);

    if (!subject->isDefaultMarkerPlacer() && subject->getMarkerPlacer().getApply()) {
        MarkerPlacer& placer = subject->getMarkerPlacer();
        if( false == placer.processModel(&guiModel, subject->getPathToSubject()))
            throw Exception("testScale failed to place markers");
    }

    // Compare ScaleSet
    ScaleSet stdScaleSet = ScaleSet(setupFilePath+"std_subject01_scaleSet_applied.xml");

    const ScaleSet& computedScaleSet = ScaleSet(setupFilePath+"subject01_scaleSet_applied_GUI.xml");

    ASSERT(computedScaleSet == stdScaleSet);

    delete subject;
}

void scaleModelWithLigament()
{
    // SET OUTPUT FORMATTING
    IO::SetDigitsPad(4);

    std::string setupFilePath("");
    ScaleTool* subject;
    Model* model;

    // Remove old model if any
    FILE* file2Remove = IO::OpenFile(setupFilePath + "toyLigamentModelScaled.osim", "w");
    fclose(file2Remove);

    // Construct model and read parameters file
    subject = new ScaleTool("toyLigamentModel_Setup_Scale.xml");

    // Keep track of the folder containing setup file, wil be used to locate results to comapre against
    setupFilePath = subject->getPathToSubject();

    model = subject->createModel();

    SimTK::State& s = model->updWorkingState();
    model->getMultibodySystem().realize(s, SimTK::Stage::Position);

    if (!model) {
        //throw Exception("scale: ERROR- No model specified.",__FILE__,__LINE__);
        cout << "scale: ERROR- No model specified.";
    }

    ASSERT(!subject->isDefaultModelScaler() && subject->getModelScaler().getApply());
    ModelScaler& scaler = subject->getModelScaler();
    ASSERT(scaler.processModel(model, setupFilePath, subject->getSubjectMass()));

    const std::string& scaledModelFile = scaler.getOutputModelFileName();
    const std::string& std_scaledModelFile = "std_toyLigamentModelScaled.osim";

    ASSERT(Model(scaledModelFile) == Model(std_scaledModelFile));

    delete model;
    delete subject;
}
<commit_msg>Rename local variable and move a check per feedback on PR. Also merge in latest from master<commit_after>/* -------------------------------------------------------------------------- *
 *                          OpenSim:  testScale.cpp                           *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2012 Stanford University and the Authors                *
 * Author(s): Ayman Habib, Peter Loan                                         *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

// INCLUDES
#include <string>
#include <OpenSim/version.h>
#include <OpenSim/Common/Storage.h>
#include <OpenSim/Common/IO.h>
#include <OpenSim/Common/ScaleSet.h>
#include <OpenSim/Simulation/Model/Model.h>
#include <OpenSim/Tools/ScaleTool.h>
#include <OpenSim/Common/MarkerData.h>
#include <OpenSim/Simulation/Model/MarkerSet.h>
#include <OpenSim/Simulation/Model/ForceSet.h>
#include <OpenSim/Common/LoadOpenSimLibrary.h>
#include <OpenSim/Simulation/Model/Analysis.h>
#include <OpenSim/Auxiliary/auxiliaryTestFunctions.h>

using namespace OpenSim;
using namespace std;

void scaleGait2354();
void scaleGait2354_GUI(bool useMarkerPlacement);
void scaleModelWithLigament();

int main()
{
    try {

        scaleGait2354();
        scaleGait2354_GUI(false);
        scaleModelWithLigament();

    }
    catch (const Exception& e) {
        e.print(cerr);
        return 1;
    }
    cout << "Done" << endl;
    return 0;
}

void compareModel(const Model& resultModel, const std::string& stdFileName, double tol)
{
    // Load std model and realize it to Velocity just in case
    Model* refModel = new Model(stdFileName);
    SimTK::State& sStd = refModel->initSystem();

    const SimTK::State& s = resultModel.getWorkingState();
    resultModel.getMultibodySystem().realize(s, SimTK::Stage::Velocity);

    ASSERT(sStd.getNQ()==s.getNQ());
    // put them in same configuration
    sStd.updQ() = s.getQ();
    refModel->getMultibodySystem().realize(sStd, SimTK::Stage::Velocity);

    ASSERT(sStd.getNU()==s.getNU());
    ASSERT(sStd.getNZ()==s.getNZ());

    // Now cycle thru ModelComponents recursively

    delete refModel;
}

void scaleGait2354()
{
    // SET OUTPUT FORMATTING
    IO::SetDigitsPad(4);

    std::string setupFilePath;
    ScaleTool* subject;
    Model* model;

    // Remove old results if any
    FILE* file2Remove = IO::OpenFile(setupFilePath+"subject01_scaleSet_applied.xml", "w");
    fclose(file2Remove);
    file2Remove = IO::OpenFile(setupFilePath+"subject01_simbody.osim", "w");
    fclose(file2Remove);

    // Construct model and read parameters file
    subject = new ScaleTool("subject01_Setup_Scale.xml");

    // Keep track of the folder containing setup file, wil be used to locate results to comapre against
    setupFilePath=subject->getPathToSubject();

    model = subject->createModel();

    SimTK::State& s = model->updWorkingState();
    model->getMultibodySystem().realize(s, SimTK::Stage::Position );

    if(!model) {
        //throw Exception("scale: ERROR- No model specified.",__FILE__,__LINE__);
        cout << "scale: ERROR- No model specified.";
    }

    ASSERT(!subject->isDefaultModelScaler() && subject->getModelScaler().getApply());
    ModelScaler& scaler = subject->getModelScaler();
    ASSERT(scaler.processModel(model, subject->getPathToSubject(), subject->getSubjectMass()));

    /*
    if (!subject->isDefaultMarkerPlacer() && subject->getMarkerPlacer().getApply()) {
        MarkerPlacer& placer = subject->getMarkerPlacer();
        if( false == placer.processModel(s, model, subject->getPathToSubject())) return(false);
    }
    else {
        return(1);
    }
    */
    // Compare ScaleSet
    ScaleSet stdScaleSet = ScaleSet(setupFilePath+"std_subject01_scaleSet_applied.xml");

    const ScaleSet& computedScaleSet = ScaleSet(setupFilePath+"subject01_scaleSet_applied.xml");

    ASSERT(computedScaleSet == stdScaleSet);

    delete model;
    delete subject;
}

void scaleGait2354_GUI(bool useMarkerPlacement)
{
    // SET OUTPUT FORMATTING
    IO::SetDigitsPad(4);

    // Construct model and read parameters file
    ScaleTool* subject = new ScaleTool("subject01_Setup_Scale_GUI.xml");
    std::string setupFilePath=subject->getPathToSubject();

    // Remove old results if any
    FILE* file2Remove = IO::OpenFile(setupFilePath+"subject01_scaleSet_applied_GUI.xml", "w");
    fclose(file2Remove);
    file2Remove = IO::OpenFile(setupFilePath+"subject01_scaledOnly_GUI.osim", "w");
    fclose(file2Remove);

    Model guiModel("gait2354_simbody.osim");

    // Keep track of the folder containing setup file, wil be used to locate results to comapre against
    guiModel.initSystem();
    MarkerSet *markerSet = new MarkerSet(guiModel, setupFilePath + subject->getGenericModelMaker().getMarkerSetFileName());
    guiModel.updateMarkerSet(*markerSet);

    // processedModelContext.processModelScale(scaleTool.getModelScaler(), processedModel, "", scaleTool.getSubjectMass())
    guiModel.getMultibodySystem().realizeTopology();
    SimTK::State* configState=&guiModel.updWorkingState();
    bool retValue= subject->getModelScaler().processModel(&guiModel, setupFilePath, subject->getSubjectMass());
    // Model has changed need to recreate a valid state
    guiModel.getMultibodySystem().realizeTopology();
    configState=&guiModel.updWorkingState();
    guiModel.getMultibodySystem().realize(*configState, SimTK::Stage::Position);

    if (!subject->isDefaultMarkerPlacer() && subject->getMarkerPlacer().getApply()) {
        MarkerPlacer& placer = subject->getMarkerPlacer();
        if( false == placer.processModel(&guiModel, subject->getPathToSubject()))
            throw Exception("testScale failed to place markers");
    }

    // Compare ScaleSet
    ScaleSet stdScaleSet = ScaleSet(setupFilePath+"std_subject01_scaleSet_applied.xml");

    const ScaleSet& computedScaleSet = ScaleSet(setupFilePath+"subject01_scaleSet_applied_GUI.xml");

    ASSERT(computedScaleSet == stdScaleSet);

    delete subject;
}

void scaleModelWithLigament()
{
    // SET OUTPUT FORMATTING
    IO::SetDigitsPad(4);

    std::string setupFilePath("");
    ScaleTool* scaleTool;
    Model* model;

    // Remove old model if any
    FILE* file2Remove = IO::OpenFile(setupFilePath + "toyLigamentModelScaled.osim", "w");
    fclose(file2Remove);

    // Construct model and read parameters file
    scaleTool = new ScaleTool("toyLigamentModel_Setup_Scale.xml");

    // Keep track of the folder containing setup file, wil be used to locate results to comapre against
    setupFilePath = scaleTool->getPathToSubject();

    model = scaleTool->createModel();

    if (!model) {
        throw Exception("scale: ERROR- No model specified.",__FILE__,__LINE__);
        //cout << "scale: ERROR- No model specified.";
    }

    SimTK::State& s = model->updWorkingState();
    model->getMultibodySystem().realize(s, SimTK::Stage::Position);

    ASSERT(!scaleTool->isDefaultModelScaler() && scaleTool->getModelScaler().getApply());
    ModelScaler& scaler = scaleTool->getModelScaler();
    ASSERT(scaler.processModel(model, setupFilePath, scaleTool->getSubjectMass()));

    const std::string& scaledModelFile = scaler.getOutputModelFileName();
    const std::string& std_scaledModelFile = "std_toyLigamentModelScaled.osim";

    ASSERT(Model(scaledModelFile) == Model(std_scaledModelFile));

    delete model;
    delete scaleTool;
}
<|endoftext|>


<commit_before>#pragma once

#include <stdexcept>
#include <string>
#include <vector>
#include <initializer_list>
#include <memory>
#include <variant>
#include <typeinfo>

// ----------------------------------------------------------------------

class argc_argv
{
 public:
    class unrecognized_option : public std::runtime_error { public: inline unrecognized_option(std::string opt) : std::runtime_error("unrecognized command line option: " + opt) {} };
    class option_not_found : public std::runtime_error { public: inline option_not_found(std::string opt) : std::runtime_error("internal: option_not_found: " + opt) {} };
    class option_requires_argument : public std::runtime_error { public: inline option_requires_argument(std::string opt) : std::runtime_error("command line option " + opt + " requires argument") {} };
    class argument_not_found : public std::runtime_error { public: using std::runtime_error::runtime_error; };
    class option_value_conversion_failed : public std::runtime_error { public: using std::runtime_error::runtime_error; };

    using string = const char*;
    using strings = std::vector<string>;

    // using mandatory = std::variant<std::string, int, size_t, double, bool>;
    using option_default_base = std::variant<bool, string, strings, long, double>;

    class option_default : public option_default_base
    {
     public:
        inline option_default(bool b) : option_default_base(b) {}
        inline option_default(string s) : option_default_base(s) {}
        inline option_default(strings ss) : option_default_base(ss) {}
        inline option_default(long i) : option_default_base(i) {}
        inline option_default(unsigned long i) : option_default_base(static_cast<long>(i)) {}
        inline option_default(int i) : option_default_base(static_cast<long>(i)) {}
        inline option_default(unsigned int i) : option_default_base(static_cast<long>(i)) {}
        inline option_default(double d) : option_default_base(d) {}

    }; // class option_default

    struct option_setting
    {
        inline option_setting(const char* aOption, option_default&& aDefault) : option_(aOption), default_(std::move(aDefault)) {}
        inline option_setting(std::string aOption, option_default&& aDefault) : option_(aOption), default_(std::move(aDefault)) {}
        inline option_setting(std::string aOption, const option_default& aDefault) : option_(aOption), default_(aDefault) {}
        inline option_setting(const char* aOption, option_default&& aDefault, const char* aDescription) : option_(aOption), default_(std::move(aDefault)), description_(aDescription) {}

        std::string option_;
        option_default default_;
        const char* description_ = nullptr;

    }; // struct option_setting

    class option : public option_setting
    {
     private:
        template <typename T> inline T get() const
            {
                using namespace std::string_literals;
                try {
                    return std::get<T>(default_);
                }
                catch (std::bad_variant_access&) {
                    throw option_value_conversion_failed{"cannot convert value of "s + option_ + " to " + typeid(T).name()};
                }
            }

        inline bool get_bool() const
            {
                using namespace std::string_literals;
                if (auto* b = std::get_if<bool>(&default_); b)
                    return *b;
                else if (auto* s1 = std::get_if<string>(&default_); s1)
                    return *s1 != nullptr && **s1 != 0;
                else if (auto* s2 = std::get_if<strings>(&default_); s2)
                    return !s2->empty();
                else
                    throw option_value_conversion_failed{"cannot convert value of "s + option_ + " to bool"};
            }

     public:
        using option_setting::option_setting;
        inline option(const option_setting& src) : option_setting(src) {}

        inline operator bool() const { return get_bool(); }
        inline operator std::string() const { return get<string>(); }
        inline operator std::string_view() const { return get<string>(); }
        inline operator strings() const { return get<strings>(); }
        inline operator double() const { return get<double>(); }
        inline operator long() const { return get<long>(); }
        inline operator int() const { return static_cast<int>(get<long>()); }
        inline operator unsigned int() const { return static_cast<unsigned int>(get<long>()); }
        inline operator unsigned long() const { return static_cast<unsigned long>(get<long>()); }

    }; // class option

    argc_argv(int argc, const char* const argv[], std::initializer_list<option_setting> options, bool split_single_dash = true);

    const option& operator[](std::string aName) const;

      // returns number of arguments in the command line that are neither options nor option values
    inline size_t number_of_arguments() const { return mArguments.size(); }

      // returns argument (neither option nor option value) by index, throws argument_not_found if aIndex >= number_of_arguments()
    inline const char* operator[](size_t aIndex) const
        {
            if (aIndex >= mArguments.size())
                throw argument_not_found{"invalid argument index: " + std::to_string(aIndex) + ", total arguments in the command line: " + std::to_string(mArguments.size())};
            return mArguments[aIndex];
        }

      // returns argv[0]
    inline const char* program() const { return mProgram; }

    std::string usage_options(size_t aIndent = 2) const;

 private:
    const char* mProgram;
    std::vector<const char*> mArguments;
    mutable std::vector<option> mOptions;

    // const option& get(std::string aName) const;

}; // class argc_argv

inline bool operator == (const argc_argv::option& aOpt, const char* aStr) { return static_cast<std::string_view>(aOpt) == aStr; }
inline bool operator == (const char* aStr, const argc_argv::option& aOpt) { return static_cast<std::string_view>(aOpt) == aStr; }
inline bool operator != (const argc_argv::option& aOpt, const char* aStr) { return !operator==(aOpt, aStr); }
inline bool operator != (const char* aStr, const argc_argv::option& aOpt) { return !operator==(aStr, aOpt); }

// ----------------------------------------------------------------------

// class argc_argv_simple
// {
//  public:
//     class option_not_found : public std::runtime_error { public: using std::runtime_error::runtime_error; };
//     class argument_not_found : public std::runtime_error { public: using std::runtime_error::runtime_error; };
//     class option_has_no_value : public std::runtime_error { public: using std::runtime_error::runtime_error; };
//     class option_value_conversion_failed : public std::runtime_error { public: using std::runtime_error::runtime_error; };

//     class option
//     {
//      public:
//         virtual ~option();

//           // if option was present in the command line
//         virtual operator bool() const;

//           // argument extraction, throws option_not_found, option_has_no_value, option_value_conversion_failed
//         virtual operator const char*() const;
//         inline operator std::string() const { return operator const char*(); }
//         virtual operator double() const;
//         virtual operator int() const;

//      protected:
//         inline option(std::string name, const char* value = nullptr) : mName{name}, mValue{value} {}
//         friend class argc_argv_simple;

//         inline std::string name() const { return mName; }
//         inline void set_value(const char* aValue) { mValue = aValue; }
//         virtual bool really_present() const;

//      private:
//         std::string mName;
//         const char* mValue;

//     }; // class option

//       // options_with_value: list of option names that have values, e.g. {"-o", "--output"}
//       // may throw option_has_no_value if last value in argv is option from options_with_value
//     argc_argv_simple(int argc, const char* const argv[], std::initializer_list<const char*> options_with_value, bool split_single_dash = true);

//       // returns option by name, if option was not in argv, returns ref to special option object
//     const option& operator[](std::string aName) const;

//       // returns option by name, if option was not in argv, returns ref to an option object having aDefault as a value
//     const option& get(std::string aName, std::string aDefault) const;
//     const option& get(std::string aName, double aDefault) const;
//     const option& get(std::string aName, int aDefault) const;

//       // returns number of arguments in the command line that are neither options nor option values
//     inline size_t number_of_arguments() const { return mArguments.size(); }

//       // returns argument (neither option nor option value) by index, throws argument_not_found if aIndex >= number_of_arguments()
//     const char* operator[](size_t aIndex) const;

//       // returns argv[0]
//     inline const char* program() const { return mProgram; }

//  private:
//     const std::vector<const char*> mOptionsWithValue;
//     const char* mProgram;
//     std::vector<const char*> mArguments;
//     mutable std::vector<std::unique_ptr<option>> mOptions;

//     const option& get(std::string aName) const;

// }; // class argc_argv_simple

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>argc_argv: option.present()<commit_after>#pragma once

#include <stdexcept>
#include <string>
#include <vector>
#include <initializer_list>
#include <memory>
#include <variant>
#include <typeinfo>

// ----------------------------------------------------------------------

class argc_argv
{
 public:
    class unrecognized_option : public std::runtime_error { public: inline unrecognized_option(std::string opt) : std::runtime_error("unrecognized command line option: " + opt) {} };
    class option_not_found : public std::runtime_error { public: inline option_not_found(std::string opt) : std::runtime_error("internal: option_not_found: " + opt) {} };
    class option_requires_argument : public std::runtime_error { public: inline option_requires_argument(std::string opt) : std::runtime_error("command line option " + opt + " requires argument") {} };
    class argument_not_found : public std::runtime_error { public: using std::runtime_error::runtime_error; };
    class option_value_conversion_failed : public std::runtime_error { public: using std::runtime_error::runtime_error; };

    using string = const char*;
    using strings = std::vector<string>;

    // using mandatory = std::variant<std::string, int, size_t, double, bool>;
    using option_default_base = std::variant<bool, string, strings, long, double>;

    class option_default : public option_default_base
    {
     public:
        inline option_default(bool b) : option_default_base(b) {}
        inline option_default(string s) : option_default_base(s) {}
        inline option_default(strings ss) : option_default_base(ss) {}
        inline option_default(long i) : option_default_base(i) {}
        inline option_default(unsigned long i) : option_default_base(static_cast<long>(i)) {}
        inline option_default(int i) : option_default_base(static_cast<long>(i)) {}
        inline option_default(unsigned int i) : option_default_base(static_cast<long>(i)) {}
        inline option_default(double d) : option_default_base(d) {}

    }; // class option_default

    struct option_setting
    {
        inline option_setting(const char* aOption, option_default&& aDefault) : option_(aOption), default_(std::move(aDefault)) {}
        inline option_setting(std::string aOption, option_default&& aDefault) : option_(aOption), default_(std::move(aDefault)) {}
        inline option_setting(std::string aOption, const option_default& aDefault) : option_(aOption), default_(aDefault) {}
        inline option_setting(const char* aOption, option_default&& aDefault, const char* aDescription) : option_(aOption), default_(std::move(aDefault)), description_(aDescription) {}

        std::string option_;
        option_default default_;
        const char* description_ = nullptr;

    }; // struct option_setting

    class option : public option_setting
    {
     private:
        bool present_ = false;

        template <typename T> inline T get() const
            {
                using namespace std::string_literals;
                try {
                    return std::get<T>(default_);
                }
                catch (std::bad_variant_access&) {
                    throw option_value_conversion_failed{"cannot convert value of "s + option_ + " to " + typeid(T).name()};
                }
            }

        inline bool get_bool() const
            {
                using namespace std::string_literals;
                if (auto* b = std::get_if<bool>(&default_); b)
                    return *b;
                else if (auto* s1 = std::get_if<string>(&default_); s1)
                    return *s1 != nullptr && **s1 != 0;
                else if (auto* s2 = std::get_if<strings>(&default_); s2)
                    return !s2->empty();
                else
                    throw option_value_conversion_failed{"cannot convert value of "s + option_ + " to bool"};
            }

     public:
        inline option(std::string aOption, option_default&& aDefault) : option_setting(aOption, std::move(aDefault)), present_{true} {}
        inline option(const option_setting& src) : option_setting(src) {}

        constexpr inline bool present() const { return present_; }

        inline operator bool() const { return get_bool(); }
        inline operator std::string() const { return get<string>(); }
        inline operator std::string_view() const { return get<string>(); }
        inline operator strings() const { return get<strings>(); }
        inline operator double() const { return get<double>(); }
        inline operator long() const { return get<long>(); }
        inline operator int() const { return static_cast<int>(get<long>()); }
        inline operator unsigned int() const { return static_cast<unsigned int>(get<long>()); }
        inline operator unsigned long() const { return static_cast<unsigned long>(get<long>()); }

    }; // class option

    argc_argv(int argc, const char* const argv[], std::initializer_list<option_setting> options, bool split_single_dash = true);

    const option& operator[](std::string aName) const;

      // returns number of arguments in the command line that are neither options nor option values
    inline size_t number_of_arguments() const { return mArguments.size(); }

      // returns argument (neither option nor option value) by index, throws argument_not_found if aIndex >= number_of_arguments()
    inline const char* operator[](size_t aIndex) const
        {
            if (aIndex >= mArguments.size())
                throw argument_not_found{"invalid argument index: " + std::to_string(aIndex) + ", total arguments in the command line: " + std::to_string(mArguments.size())};
            return mArguments[aIndex];
        }

      // returns argv[0]
    inline const char* program() const { return mProgram; }

    std::string usage_options(size_t aIndent = 2) const;

 private:
    const char* mProgram;
    std::vector<const char*> mArguments;
    mutable std::vector<option> mOptions;

    // const option& get(std::string aName) const;

}; // class argc_argv

inline bool operator == (const argc_argv::option& aOpt, const char* aStr) { return static_cast<std::string_view>(aOpt) == aStr; }
inline bool operator == (const char* aStr, const argc_argv::option& aOpt) { return static_cast<std::string_view>(aOpt) == aStr; }
inline bool operator != (const argc_argv::option& aOpt, const char* aStr) { return !operator==(aOpt, aStr); }
inline bool operator != (const char* aStr, const argc_argv::option& aOpt) { return !operator==(aStr, aOpt); }

// ----------------------------------------------------------------------

// class argc_argv_simple
// {
//  public:
//     class option_not_found : public std::runtime_error { public: using std::runtime_error::runtime_error; };
//     class argument_not_found : public std::runtime_error { public: using std::runtime_error::runtime_error; };
//     class option_has_no_value : public std::runtime_error { public: using std::runtime_error::runtime_error; };
//     class option_value_conversion_failed : public std::runtime_error { public: using std::runtime_error::runtime_error; };

//     class option
//     {
//      public:
//         virtual ~option();

//           // if option was present in the command line
//         virtual operator bool() const;

//           // argument extraction, throws option_not_found, option_has_no_value, option_value_conversion_failed
//         virtual operator const char*() const;
//         inline operator std::string() const { return operator const char*(); }
//         virtual operator double() const;
//         virtual operator int() const;

//      protected:
//         inline option(std::string name, const char* value = nullptr) : mName{name}, mValue{value} {}
//         friend class argc_argv_simple;

//         inline std::string name() const { return mName; }
//         inline void set_value(const char* aValue) { mValue = aValue; }
//         virtual bool really_present() const;

//      private:
//         std::string mName;
//         const char* mValue;

//     }; // class option

//       // options_with_value: list of option names that have values, e.g. {"-o", "--output"}
//       // may throw option_has_no_value if last value in argv is option from options_with_value
//     argc_argv_simple(int argc, const char* const argv[], std::initializer_list<const char*> options_with_value, bool split_single_dash = true);

//       // returns option by name, if option was not in argv, returns ref to special option object
//     const option& operator[](std::string aName) const;

//       // returns option by name, if option was not in argv, returns ref to an option object having aDefault as a value
//     const option& get(std::string aName, std::string aDefault) const;
//     const option& get(std::string aName, double aDefault) const;
//     const option& get(std::string aName, int aDefault) const;

//       // returns number of arguments in the command line that are neither options nor option values
//     inline size_t number_of_arguments() const { return mArguments.size(); }

//       // returns argument (neither option nor option value) by index, throws argument_not_found if aIndex >= number_of_arguments()
//     const char* operator[](size_t aIndex) const;

//       // returns argv[0]
//     inline const char* program() const { return mProgram; }

//  private:
//     const std::vector<const char*> mOptionsWithValue;
//     const char* mProgram;
//     std::vector<const char*> mArguments;
//     mutable std::vector<std::unique_ptr<option>> mOptions;

//     const option& get(std::string aName) const;

// }; // class argc_argv_simple

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>