<commit_before>#include <IOKit/IOLib.h>

#include "Config.hpp"
#include "DependingPressingPeriodKeyToKey.hpp"
#include "EventWatcher.hpp"
#include "IOLogWrapper.hpp"
#include "KeyboardRepeat.hpp"

namespace org_pqrs_KeyRemap4MacBook {
  namespace RemapFunc {
    TimerWrapper DependingPressingPeriodKeyToKey::fire_timer_;
    DependingPressingPeriodKeyToKey* DependingPressingPeriodKeyToKey::target_ = NULL;

    DependingPressingPeriodKeyToKey::PeriodMS::PeriodMS(void) : mode_(Mode::NONE)
    {
      for (size_t m = 0; m < Mode::__END__; ++m) {
        for (size_t t = 0; t < Type::__END__; ++t) {
          overwritten_value_[m][t] = -1;
        }
      }
    }

    void
    DependingPressingPeriodKeyToKey::PeriodMS::set(PeriodMS::Mode::Value newval)
    {
      mode_ = newval;
    }

    unsigned int
    DependingPressingPeriodKeyToKey::PeriodMS::get(PeriodMS::Type::Value type)
    {
      if (overwritten_value_[mode_][type] >= 0) {
        return overwritten_value_[mode_][type];
      }

      switch (mode_) {
        case Mode::HOLDING_KEY_TO_KEY:
          switch (type) {
            case Type::SHORT_PERIOD:             return Config::get_holdingkeytokey_wait();
            case Type::LONG_LONG_PERIOD:         return 0;
            case Type::PRESSING_TARGET_KEY_ONLY: return 0;
            case Type::__END__:                  return 0;
          }

        case Mode::KEY_OVERLAID_MODIFIER:
          switch (type) {
            case Type::SHORT_PERIOD:             return Config::get_keyoverlaidmodifier_initial_modifier_wait();
            case Type::LONG_LONG_PERIOD:         return 0;
            case Type::PRESSING_TARGET_KEY_ONLY: return Config::get_keyoverlaidmodifier_timeout();
            case Type::__END__:                  return 0;
          }

        case Mode::KEY_OVERLAID_MODIFIER_WITH_REPEAT:
          switch (type) {
            case Type::SHORT_PERIOD:             return Config::get_keyoverlaidmodifier_initial_modifier_wait();
            case Type::LONG_LONG_PERIOD:         return Config::get_keyoverlaidmodifier_initial_wait();
            case Type::PRESSING_TARGET_KEY_ONLY: return Config::get_keyoverlaidmodifier_timeout();
            case Type::__END__:                  return 0;
          }

        case Mode::NONE:
        case Mode::__END__:
          IOLOG_ERROR("Invalid DependingPressingPeriodKeyToKey::PeriodMS::get\n");
          return 0;
      }

      return 0;
    }

    bool
    DependingPressingPeriodKeyToKey::PeriodMS::enabled(PeriodMS::Type::Value type)
    {
      switch (mode_) {
        case Mode::HOLDING_KEY_TO_KEY:
          switch (type) {
            case Type::SHORT_PERIOD:             return true;
            case Type::LONG_LONG_PERIOD:         return false;
            case Type::PRESSING_TARGET_KEY_ONLY: return false;
            case Type::__END__:                  return false;
          }

        case Mode::KEY_OVERLAID_MODIFIER:
          switch (type) {
            case Type::SHORT_PERIOD:             return true;
            case Type::LONG_LONG_PERIOD:         return false;
            case Type::PRESSING_TARGET_KEY_ONLY: return true;
            case Type::__END__:                  return false;
          }

        case Mode::KEY_OVERLAID_MODIFIER_WITH_REPEAT:
          switch (type) {
            case Type::SHORT_PERIOD:             return true;
            case Type::LONG_LONG_PERIOD:         return true;
            case Type::PRESSING_TARGET_KEY_ONLY: return true;
            case Type::__END__:                  return false;
          }

        case Mode::NONE:
        case Mode::__END__:
          IOLOG_ERROR("Invalid DependingPressingPeriodKeyToKey::PeriodMS::enabled\n");
          return false;
      }

      return false;
    }

    // ======================================================================
    void
    DependingPressingPeriodKeyToKey::static_initialize(IOWorkLoop& workloop)
    {
      fire_timer_.initialize(&workloop, NULL, DependingPressingPeriodKeyToKey::fire_timer_callback);
    }

    void
    DependingPressingPeriodKeyToKey::static_terminate(void)
    {
      fire_timer_.terminate();
    }

    DependingPressingPeriodKeyToKey::DependingPressingPeriodKeyToKey(void) :
      active_(false),
      periodtype_(PeriodType::NONE),
      isAnyEventHappen_(false),
      keyboardRepeatID_(0),
      interruptibleByScrollWheel_(true)
    {}

    DependingPressingPeriodKeyToKey::~DependingPressingPeriodKeyToKey(void)
    {
      if (target_ == this) {
        fire_timer_.cancelTimeout();
        target_ = NULL;
      }
    }

    void
    DependingPressingPeriodKeyToKey::add(KeyToKeyType::Value type, AddDataType datatype, AddValue newval)
    {
      if (type == KeyToKeyType::END_) return;

      if (datatype == BRIDGE_DATATYPE_OPTION && Option::UNINTERRUPTIBLE_BY_SCROLL_WHEEL == Option(newval)) {
        interruptibleByScrollWheel_ = false;
      } else {
        keytokey_[type].add(datatype, newval);
      }
    }

    bool
    DependingPressingPeriodKeyToKey::remap(RemapParams& remapParams)
    {
      // Params_ScrollWheelEventCallback
      {
        Params_ScrollWheelEventCallback* params = remapParams.paramsUnion.get_Params_ScrollWheelEventCallback();
        if (params) {
          if (interruptibleByScrollWheel_) {
            dokeydown();
          }
          return false;
        }
      }

      // Params_KeyboardEventCallBack, Params_KeyboardSpecialEventCallback, Params_RelativePointerEventCallback
      {
        bool iskeydown = false;
        if (remapParams.paramsUnion.iskeydown(iskeydown)) {
          bool result = keytokey_[KeyToKeyType::FROM].remap(remapParams);

          if (! result) {
            if (iskeydown) {
              // another key is pressed.
              dokeydown();
            }
            return false;
          }

          if (iskeydown) {
            target_ = this;
            active_ = true;
            periodtype_ = PeriodType::NONE;

            // clear temporary_flags (KeyToKeyType::FROM's flags)
            FlagStatus::globalFlagStatus().set();
            savedflags_ = FlagStatus::globalFlagStatus().makeFlags();

            fire_timer_.setTimeoutMS(periodMS_.get(PeriodMS::Type::SHORT_PERIOD));

          } else {
            dokeydown();
            dokeyup();
          }
          return true;
        }
      }

      return false;
    }

    void
    DependingPressingPeriodKeyToKey::dokeydown(void)
    {
      if (! active_) return;
      active_ = false;

      if (target_ == this) {
        fire_timer_.cancelTimeout();
      }

      switch (periodtype_) {
        case PeriodType::NONE:
        {
          periodtype_ = PeriodType::SHORT_PERIOD;

          FlagStatus::ScopedTemporaryFlagsChanger stfc(FlagStatus::globalFlagStatus(), savedflags_);
          keytokey_[KeyToKeyType::SHORT_PERIOD].call_remap_with_VK_PSEUDO_KEY(EventType::DOWN);

          break;
        }

        case PeriodType::SHORT_PERIOD:
        case PeriodType::LONG_PERIOD:
        case PeriodType::LONG_LONG_PERIOD:
          // do nothing
          break;
      }
    }

    void
    DependingPressingPeriodKeyToKey::dokeyup(void)
    {
      switch (periodtype_) {
        case PeriodType::SHORT_PERIOD:
        {
          periodtype_ = PeriodType::NONE;
          keytokey_[KeyToKeyType::SHORT_PERIOD].call_remap_with_VK_PSEUDO_KEY(EventType::UP);
          break;
        }

        case PeriodType::LONG_PERIOD:
        {
          periodtype_ = PeriodType::NONE;
          keytokey_[KeyToKeyType::LONG_PERIOD].call_remap_with_VK_PSEUDO_KEY(EventType::UP);

          // ----------------------------------------
          // handle PRESSING_TARGET_KEY_ONLY
          if (periodMS_.enabled(PeriodMS::Type::PRESSING_TARGET_KEY_ONLY)) {
            if (! isAnyEventHappen_ &&
                ic_.getmillisec() < periodMS_.get(PeriodMS::Type::PRESSING_TARGET_KEY_ONLY)) {
              FlagStatus::ScopedTemporaryFlagsChanger stfc(FlagStatus::globalFlagStatus(), savedflags_);
              keytokey_[KeyToKeyType::PRESSING_TARGET_KEY_ONLY].call_remap_with_VK_PSEUDO_KEY(EventType::DOWN);
              keytokey_[KeyToKeyType::PRESSING_TARGET_KEY_ONLY].call_remap_with_VK_PSEUDO_KEY(EventType::UP);
            }
          }

          break;
        }

        case PeriodType::LONG_LONG_PERIOD:
        {
          periodtype_ = PeriodType::NONE;
          keytokey_[KeyToKeyType::LONG_LONG_PERIOD].call_remap_with_VK_PSEUDO_KEY(EventType::UP);
          break;
        }

        case PeriodType::NONE:
          // do nothing
          break;
      }

      EventWatcher::unset(isAnyEventHappen_);
    }

    void
    DependingPressingPeriodKeyToKey::fire_timer_callback(OSObject* owner, IOTimerEventSource* sender)
    {
      if (! target_) return;

      switch (target_->periodtype_) {
        case PeriodType::NONE:
        {
          target_->periodtype_ = PeriodType::LONG_PERIOD;

          FlagStatus::ScopedTemporaryFlagsChanger stfc(FlagStatus::globalFlagStatus(), target_->savedflags_);
          (target_->keytokey_[KeyToKeyType::LONG_PERIOD]).call_remap_with_VK_PSEUDO_KEY(EventType::DOWN);
          target_->keyboardRepeatID_ = KeyboardRepeat::getID();

          EventWatcher::set(target_->isAnyEventHappen_);
          (target_->ic_).begin();

          if (target_->periodMS_.enabled(PeriodMS::Type::LONG_LONG_PERIOD)) {
            fire_timer_.setTimeoutMS(target_->periodMS_.get(PeriodMS::Type::LONG_LONG_PERIOD));
          }

          break;
        }

        case PeriodType::LONG_PERIOD:
        {
          // If keyboard repeat is canceled while pressing LONG_PERIOD key,
          // we cancel LONG_LONG_PERIOD event.
          bool isKeyboardRepeatCanceled = (target_->keyboardRepeatID_ != KeyboardRepeat::getID());

          (target_->keytokey_[KeyToKeyType::LONG_PERIOD]).call_remap_with_VK_PSEUDO_KEY(EventType::UP);

          if (isKeyboardRepeatCanceled) {
            target_->periodtype_ = PeriodType::NONE;

          } else {
            target_->periodtype_ = PeriodType::LONG_LONG_PERIOD;

            FlagStatus::ScopedTemporaryFlagsChanger stfc(FlagStatus::globalFlagStatus(), target_->savedflags_);
            (target_->keytokey_[KeyToKeyType::LONG_LONG_PERIOD]).call_remap_with_VK_PSEUDO_KEY(EventType::DOWN);
          }

          break;
        }

        case PeriodType::SHORT_PERIOD:
        case PeriodType::LONG_LONG_PERIOD:
          // do nothing
          break;
      }
    }
  }
}
<commit_msg>improved LONG_LONG_PERIOD behavior @ DependingPressingPeriodKeyToKey<commit_after>#include <IOKit/IOLib.h>

#include "Config.hpp"
#include "DependingPressingPeriodKeyToKey.hpp"
#include "EventWatcher.hpp"
#include "IOLogWrapper.hpp"
#include "KeyboardRepeat.hpp"

namespace org_pqrs_KeyRemap4MacBook {
  namespace RemapFunc {
    TimerWrapper DependingPressingPeriodKeyToKey::fire_timer_;
    DependingPressingPeriodKeyToKey* DependingPressingPeriodKeyToKey::target_ = NULL;

    DependingPressingPeriodKeyToKey::PeriodMS::PeriodMS(void) : mode_(Mode::NONE)
    {
      for (size_t m = 0; m < Mode::__END__; ++m) {
        for (size_t t = 0; t < Type::__END__; ++t) {
          overwritten_value_[m][t] = -1;
        }
      }
    }

    void
    DependingPressingPeriodKeyToKey::PeriodMS::set(PeriodMS::Mode::Value newval)
    {
      mode_ = newval;
    }

    unsigned int
    DependingPressingPeriodKeyToKey::PeriodMS::get(PeriodMS::Type::Value type)
    {
      if (overwritten_value_[mode_][type] >= 0) {
        return overwritten_value_[mode_][type];
      }

      switch (mode_) {
        case Mode::HOLDING_KEY_TO_KEY:
          switch (type) {
            case Type::SHORT_PERIOD:             return Config::get_holdingkeytokey_wait();
            case Type::LONG_LONG_PERIOD:         return 0;
            case Type::PRESSING_TARGET_KEY_ONLY: return 0;
            case Type::__END__:                  return 0;
          }

        case Mode::KEY_OVERLAID_MODIFIER:
          switch (type) {
            case Type::SHORT_PERIOD:             return Config::get_keyoverlaidmodifier_initial_modifier_wait();
            case Type::LONG_LONG_PERIOD:         return 0;
            case Type::PRESSING_TARGET_KEY_ONLY: return Config::get_keyoverlaidmodifier_timeout();
            case Type::__END__:                  return 0;
          }

        case Mode::KEY_OVERLAID_MODIFIER_WITH_REPEAT:
          switch (type) {
            case Type::SHORT_PERIOD:             return Config::get_keyoverlaidmodifier_initial_modifier_wait();
            case Type::LONG_LONG_PERIOD:         return Config::get_keyoverlaidmodifier_initial_wait();
            case Type::PRESSING_TARGET_KEY_ONLY: return Config::get_keyoverlaidmodifier_timeout();
            case Type::__END__:                  return 0;
          }

        case Mode::NONE:
        case Mode::__END__:
          IOLOG_ERROR("Invalid DependingPressingPeriodKeyToKey::PeriodMS::get\n");
          return 0;
      }

      return 0;
    }

    bool
    DependingPressingPeriodKeyToKey::PeriodMS::enabled(PeriodMS::Type::Value type)
    {
      switch (mode_) {
        case Mode::HOLDING_KEY_TO_KEY:
          switch (type) {
            case Type::SHORT_PERIOD:             return true;
            case Type::LONG_LONG_PERIOD:         return false;
            case Type::PRESSING_TARGET_KEY_ONLY: return false;
            case Type::__END__:                  return false;
          }

        case Mode::KEY_OVERLAID_MODIFIER:
          switch (type) {
            case Type::SHORT_PERIOD:             return true;
            case Type::LONG_LONG_PERIOD:         return false;
            case Type::PRESSING_TARGET_KEY_ONLY: return true;
            case Type::__END__:                  return false;
          }

        case Mode::KEY_OVERLAID_MODIFIER_WITH_REPEAT:
          switch (type) {
            case Type::SHORT_PERIOD:             return true;
            case Type::LONG_LONG_PERIOD:         return true;
            case Type::PRESSING_TARGET_KEY_ONLY: return true;
            case Type::__END__:                  return false;
          }

        case Mode::NONE:
        case Mode::__END__:
          IOLOG_ERROR("Invalid DependingPressingPeriodKeyToKey::PeriodMS::enabled\n");
          return false;
      }

      return false;
    }

    // ======================================================================
    void
    DependingPressingPeriodKeyToKey::static_initialize(IOWorkLoop& workloop)
    {
      fire_timer_.initialize(&workloop, NULL, DependingPressingPeriodKeyToKey::fire_timer_callback);
    }

    void
    DependingPressingPeriodKeyToKey::static_terminate(void)
    {
      fire_timer_.terminate();
    }

    DependingPressingPeriodKeyToKey::DependingPressingPeriodKeyToKey(void) :
      active_(false),
      periodtype_(PeriodType::NONE),
      isAnyEventHappen_(false),
      keyboardRepeatID_(0),
      interruptibleByScrollWheel_(true)
    {}

    DependingPressingPeriodKeyToKey::~DependingPressingPeriodKeyToKey(void)
    {
      if (target_ == this) {
        fire_timer_.cancelTimeout();
        target_ = NULL;
      }
    }

    void
    DependingPressingPeriodKeyToKey::add(KeyToKeyType::Value type, AddDataType datatype, AddValue newval)
    {
      if (type == KeyToKeyType::END_) return;

      if (datatype == BRIDGE_DATATYPE_OPTION && Option::UNINTERRUPTIBLE_BY_SCROLL_WHEEL == Option(newval)) {
        interruptibleByScrollWheel_ = false;
      } else {
        keytokey_[type].add(datatype, newval);
      }
    }

    bool
    DependingPressingPeriodKeyToKey::remap(RemapParams& remapParams)
    {
      // Params_ScrollWheelEventCallback
      {
        Params_ScrollWheelEventCallback* params = remapParams.paramsUnion.get_Params_ScrollWheelEventCallback();
        if (params) {
          if (interruptibleByScrollWheel_) {
            dokeydown();
          }
          return false;
        }
      }

      // Params_KeyboardEventCallBack, Params_KeyboardSpecialEventCallback, Params_RelativePointerEventCallback
      {
        bool iskeydown = false;
        if (remapParams.paramsUnion.iskeydown(iskeydown)) {
          bool result = keytokey_[KeyToKeyType::FROM].remap(remapParams);

          if (! result) {
            if (iskeydown) {
              // another key is pressed.
              dokeydown();
            }
            return false;
          }

          if (iskeydown) {
            target_ = this;
            active_ = true;
            periodtype_ = PeriodType::NONE;

            // clear temporary_flags (KeyToKeyType::FROM's flags)
            FlagStatus::globalFlagStatus().set();
            savedflags_ = FlagStatus::globalFlagStatus().makeFlags();

            fire_timer_.setTimeoutMS(periodMS_.get(PeriodMS::Type::SHORT_PERIOD));

          } else {
            dokeydown();
            dokeyup();
          }
          return true;
        }
      }

      return false;
    }

    void
    DependingPressingPeriodKeyToKey::dokeydown(void)
    {
      if (! active_) return;
      active_ = false;

      if (target_ == this) {
        fire_timer_.cancelTimeout();
      }

      switch (periodtype_) {
        case PeriodType::NONE:
        {
          periodtype_ = PeriodType::SHORT_PERIOD;

          FlagStatus::ScopedTemporaryFlagsChanger stfc(FlagStatus::globalFlagStatus(), savedflags_);
          keytokey_[KeyToKeyType::SHORT_PERIOD].call_remap_with_VK_PSEUDO_KEY(EventType::DOWN);

          break;
        }

        case PeriodType::SHORT_PERIOD:
        case PeriodType::LONG_PERIOD:
        case PeriodType::LONG_LONG_PERIOD:
          // do nothing
          break;
      }
    }

    void
    DependingPressingPeriodKeyToKey::dokeyup(void)
    {
      switch (periodtype_) {
        case PeriodType::SHORT_PERIOD:
        {
          periodtype_ = PeriodType::NONE;
          keytokey_[KeyToKeyType::SHORT_PERIOD].call_remap_with_VK_PSEUDO_KEY(EventType::UP);
          break;
        }

        case PeriodType::LONG_PERIOD:
        {
          periodtype_ = PeriodType::NONE;
          keytokey_[KeyToKeyType::LONG_PERIOD].call_remap_with_VK_PSEUDO_KEY(EventType::UP);

          // ----------------------------------------
          // handle PRESSING_TARGET_KEY_ONLY
          if (periodMS_.enabled(PeriodMS::Type::PRESSING_TARGET_KEY_ONLY)) {
            if (! isAnyEventHappen_ &&
                ic_.getmillisec() < periodMS_.get(PeriodMS::Type::PRESSING_TARGET_KEY_ONLY)) {
              FlagStatus::ScopedTemporaryFlagsChanger stfc(FlagStatus::globalFlagStatus(), savedflags_);
              keytokey_[KeyToKeyType::PRESSING_TARGET_KEY_ONLY].call_remap_with_VK_PSEUDO_KEY(EventType::DOWN);
              keytokey_[KeyToKeyType::PRESSING_TARGET_KEY_ONLY].call_remap_with_VK_PSEUDO_KEY(EventType::UP);
            }
          }

          break;
        }

        case PeriodType::LONG_LONG_PERIOD:
        {
          periodtype_ = PeriodType::NONE;
          keytokey_[KeyToKeyType::LONG_LONG_PERIOD].call_remap_with_VK_PSEUDO_KEY(EventType::UP);
          break;
        }

        case PeriodType::NONE:
          // do nothing
          break;
      }

      EventWatcher::unset(isAnyEventHappen_);
    }

    void
    DependingPressingPeriodKeyToKey::fire_timer_callback(OSObject* owner, IOTimerEventSource* sender)
    {
      if (! target_) return;

      switch (target_->periodtype_) {
        case PeriodType::NONE:
        {
          target_->periodtype_ = PeriodType::LONG_PERIOD;

          FlagStatus::ScopedTemporaryFlagsChanger stfc(FlagStatus::globalFlagStatus(), target_->savedflags_);
          (target_->keytokey_[KeyToKeyType::LONG_PERIOD]).call_remap_with_VK_PSEUDO_KEY(EventType::DOWN);

          EventWatcher::set(target_->isAnyEventHappen_);
          (target_->ic_).begin();

          if (target_->periodMS_.enabled(PeriodMS::Type::LONG_LONG_PERIOD)) {
            KeyboardRepeat::cancel();
            target_->keyboardRepeatID_ = KeyboardRepeat::getID();
            fire_timer_.setTimeoutMS(target_->periodMS_.get(PeriodMS::Type::LONG_LONG_PERIOD));
          }

          break;
        }

        case PeriodType::LONG_PERIOD:
        {
          // If keyboard repeat cancellation occured while pressing LONG_PERIOD key,
          // we cancel LONG_LONG_PERIOD event.
          bool isKeyboardRepeatCanceled = (target_->keyboardRepeatID_ != KeyboardRepeat::getID());

          (target_->keytokey_[KeyToKeyType::LONG_PERIOD]).call_remap_with_VK_PSEUDO_KEY(EventType::UP);

          if (isKeyboardRepeatCanceled) {
            target_->periodtype_ = PeriodType::NONE;

          } else {
            target_->periodtype_ = PeriodType::LONG_LONG_PERIOD;

            FlagStatus::ScopedTemporaryFlagsChanger stfc(FlagStatus::globalFlagStatus(), target_->savedflags_);
            (target_->keytokey_[KeyToKeyType::LONG_LONG_PERIOD]).call_remap_with_VK_PSEUDO_KEY(EventType::DOWN);
          }

          break;
        }

        case PeriodType::SHORT_PERIOD:
        case PeriodType::LONG_LONG_PERIOD:
          // do nothing
          break;
      }
    }
  }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: connector.cxx,v $
 *
 *  $Revision: 1.18 $
 *
 *  last change: $Author: obo $ $Date: 2006-01-19 18:21:59 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#include <osl/mutex.hxx>
#include "osl/security.hxx"

#include <uno/mapping.hxx>

#include <cppuhelper/factory.hxx>
#include <cppuhelper/implbase2.hxx>
#include <cppuhelper/implementationentry.hxx>
#include "cppuhelper/unourl.hxx"
#include "rtl/malformeduriexception.hxx"

#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/connection/XConnector.hpp>

#include "connector.hxx"

#define IMPLEMENTATION_NAME "com.sun.star.comp.io.Connector"
#define SERVICE_NAME "com.sun.star.connection.Connector"

using namespace ::osl;
using namespace ::rtl;
using namespace ::cppu;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::registry;
using namespace ::com::sun::star::connection;

namespace stoc_connector
{
    rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;

    class OConnector : public WeakImplHelper2< XConnector, XServiceInfo >
    {
        Reference< XMultiComponentFactory > _xSMgr;
        Reference< XComponentContext > _xCtx;
    public:
        OConnector(const Reference< XComponentContext > &xCtx);
        ~OConnector();
        // Methods
        virtual Reference< XConnection > SAL_CALL connect(
            const OUString& sConnectionDescription )
            throw( NoConnectException, ConnectionSetupException, RuntimeException);

    public: // XServiceInfo
                virtual OUString              SAL_CALL getImplementationName() throw();
                virtual Sequence< OUString >  SAL_CALL getSupportedServiceNames(void) throw();
                virtual sal_Bool              SAL_CALL supportsService(const OUString& ServiceName) throw();
    };

    OConnector::OConnector(const Reference< XComponentContext > &xCtx)
        : _xCtx( xCtx )
        , _xSMgr( xCtx->getServiceManager() )
    {
        g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
    }

    OConnector::~OConnector()
    {
        g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
    }

    Reference< XConnection > SAL_CALL OConnector::connect( const OUString& sConnectionDescription )
        throw( NoConnectException, ConnectionSetupException, RuntimeException)
    {
#if OSL_DEBUG_LEVEL > 1
        OString tmp = OUStringToOString(sConnectionDescription, RTL_TEXTENCODING_ASCII_US);
        OSL_TRACE("connector %s\n", tmp.getStr());
#endif

        // split string into tokens
        try
        {
            cppu::UnoUrlDescriptor aDesc(sConnectionDescription);

            Reference< XConnection > r;
            if (aDesc.getName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
                                                 "pipe")))
            {
                rtl::OUString aName(
                    aDesc.getParameter(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("name"))));

                PipeConnection *pConn = new PipeConnection( aName, sConnectionDescription );

                if( pConn->m_pipe.create( aName.pData, osl_Pipe_OPEN, osl::Security() ) )
                {
                    r = Reference < XConnection > ( (XConnection * ) pConn );
                }
                else
                {
                    OUString sMessage = OUString::createFromAscii( "Connector : couldn't connect to pipe " );
                    sMessage += aName;
                    sMessage += OUString::createFromAscii( "(" );
                    sMessage += OUString::valueOf( (sal_Int32 ) pConn->m_pipe.getError() );
                    sMessage += OUString::createFromAscii( ")" );
                    delete pConn;
                    throw NoConnectException( sMessage ,Reference< XInterface > () );
                }
            }
            else if (aDesc.getName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
                                                      "socket")))
            {
                rtl::OUString aHost;
                if (aDesc.hasParameter(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("host"))))
                    aHost = aDesc.getParameter(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("host")));
                else
                    aHost = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
                                              "localhost"));
                sal_uInt16 nPort = static_cast< sal_uInt16 >(
                    aDesc.getParameter(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("port"))).
                    toInt32());
                bool bTcpNoDelay
                    = aDesc.getParameter(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
                                          "tcpnodelay"))).toInt32() != 0;

                SocketConnection *pConn = new SocketConnection( aHost,
                                                                nPort,
                                                                sConnectionDescription);

                SocketAddr AddrTarget( aHost.pData, nPort );
                if(pConn->m_socket.connect(AddrTarget) != osl_Socket_Ok)
                {
                    OUString sMessage = OUString::createFromAscii( "Connector : couldn't connect to socket (" );
                    OUString sError = pConn->m_socket.getErrorAsString();
                    sMessage += sError;
                    sMessage += OUString::createFromAscii( ")" );
                    delete pConn;
                    throw NoConnectException( sMessage, Reference < XInterface > () );
                }
                if( bTcpNoDelay )
                {
                    sal_Int32 nTcpNoDelay = sal_True;
                    pConn->m_socket.setOption( osl_Socket_OptionTcpNoDelay , &nTcpNoDelay,
                                               sizeof( nTcpNoDelay ) , osl_Socket_LevelTcp );
                }
                pConn->completeConnectionString();
                r = Reference< XConnection > ( (XConnection * ) pConn );
            }
            else
            {
                OUString delegatee = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector."));
                delegatee += aDesc.getName();

#if OSL_DEBUG_LEVEL > 1
                OString tmp = OUStringToOString(delegatee, RTL_TEXTENCODING_ASCII_US);
                OSL_TRACE("connector: trying to get service %s\n", tmp.getStr());
#endif
                Reference<XConnector> xConnector(
                    _xSMgr->createInstanceWithContext(delegatee, _xCtx), UNO_QUERY );

                if(!xConnector.is())
                {
                    OUString message(RTL_CONSTASCII_USTRINGPARAM("Connector: unknown delegatee "));
                    message += delegatee;

                    throw ConnectionSetupException(message, Reference<XInterface>());
                }

                sal_Int32 index = sConnectionDescription.indexOf((sal_Unicode) ',');

                r = xConnector->connect(sConnectionDescription.copy(index + 1).trim());
            }
            return r;
        }
        catch (rtl::MalformedUriException & rEx)
        {
            throw ConnectionSetupException(rEx.getMessage(),
                                           Reference< XInterface > ());
        }
    }

    Sequence< OUString > connector_getSupportedServiceNames()
    {
        static Sequence < OUString > *pNames = 0;
        if( ! pNames )
        {
            MutexGuard guard( Mutex::getGlobalMutex() );
            if( !pNames )
            {
                static Sequence< OUString > seqNames(1);
                seqNames.getArray()[0] = OUString::createFromAscii( SERVICE_NAME );
                pNames = &seqNames;
            }
        }
        return *pNames;
    }

    OUString connector_getImplementationName()
    {
        return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
    }

        OUString OConnector::getImplementationName() throw()
    {
        return connector_getImplementationName();
    }

        sal_Bool OConnector::supportsService(const OUString& ServiceName) throw()
    {
        Sequence< OUString > aSNL = getSupportedServiceNames();
        const OUString * pArray = aSNL.getConstArray();

        for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
            if( pArray[i] == ServiceName )
                return sal_True;

        return sal_False;
    }

        Sequence< OUString > OConnector::getSupportedServiceNames(void) throw()
    {
        return connector_getSupportedServiceNames();
    }

    Reference< XInterface > SAL_CALL connector_CreateInstance( const Reference< XComponentContext > & xCtx)
    {
        return Reference < XInterface >( ( OWeakObject * ) new OConnector(xCtx) );
    }

}
using namespace stoc_connector;

static struct ImplementationEntry g_entries[] =
{
    {
        connector_CreateInstance, connector_getImplementationName ,
        connector_getSupportedServiceNames, createSingleComponentFactory ,
        &g_moduleCount.modCnt , 0
    },
    { 0, 0, 0, 0, 0, 0 }
};

extern "C"
{

sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
{
    return g_moduleCount.canUnload( &g_moduleCount , pTime );
}

//==================================================================================================
void SAL_CALL component_getImplementationEnvironment(
    const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
//==================================================================================================
sal_Bool SAL_CALL component_writeInfo(
    void * pServiceManager, void * pRegistryKey )
{
    return component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries );
}
//==================================================================================================
void * SAL_CALL component_getFactory(
    const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
{
    return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
}

}

<commit_msg>INTEGRATION: CWS warnings01 (1.16.22); FILE MERGED 2006/01/25 20:30:41 sb 1.16.22.4: RESYNC: (1.17-1.18); FILE MERGED 2005/09/22 20:27:48 sb 1.16.22.3: RESYNC: (1.16-1.17); FILE MERGED 2005/09/07 14:14:52 sb 1.16.22.2: #i53898# Made code warning-free. 2005/09/01 08:14:27 sb 1.16.22.1: #i53898# Made code warning-free.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: connector.cxx,v $
 *
 *  $Revision: 1.19 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 00:16:41 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#include <osl/mutex.hxx>
#include "osl/security.hxx"

#include <uno/mapping.hxx>

#include <cppuhelper/factory.hxx>
#include <cppuhelper/implbase2.hxx>
#include <cppuhelper/implementationentry.hxx>
#include "cppuhelper/unourl.hxx"
#include "rtl/malformeduriexception.hxx"

#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/connection/XConnector.hpp>

#include "connector.hxx"

#define IMPLEMENTATION_NAME "com.sun.star.comp.io.Connector"
#define SERVICE_NAME "com.sun.star.connection.Connector"

using namespace ::osl;
using namespace ::rtl;
using namespace ::cppu;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::registry;
using namespace ::com::sun::star::connection;

namespace stoc_connector
{
    rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;

    class OConnector : public WeakImplHelper2< XConnector, XServiceInfo >
    {
        Reference< XMultiComponentFactory > _xSMgr;
        Reference< XComponentContext > _xCtx;
    public:
        OConnector(const Reference< XComponentContext > &xCtx);
        ~OConnector();
        // Methods
        virtual Reference< XConnection > SAL_CALL connect(
            const OUString& sConnectionDescription )
            throw( NoConnectException, ConnectionSetupException, RuntimeException);

    public: // XServiceInfo
                virtual OUString              SAL_CALL getImplementationName() throw();
                virtual Sequence< OUString >  SAL_CALL getSupportedServiceNames(void) throw();
                virtual sal_Bool              SAL_CALL supportsService(const OUString& ServiceName) throw();
    };

    OConnector::OConnector(const Reference< XComponentContext > &xCtx)
        : _xSMgr( xCtx->getServiceManager() )
        , _xCtx( xCtx )
    {
        g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
    }

    OConnector::~OConnector()
    {
        g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
    }

    Reference< XConnection > SAL_CALL OConnector::connect( const OUString& sConnectionDescription )
        throw( NoConnectException, ConnectionSetupException, RuntimeException)
    {
#if OSL_DEBUG_LEVEL > 1
        OString tmp = OUStringToOString(sConnectionDescription, RTL_TEXTENCODING_ASCII_US);
        OSL_TRACE("connector %s\n", tmp.getStr());
#endif

        // split string into tokens
        try
        {
            cppu::UnoUrlDescriptor aDesc(sConnectionDescription);

            Reference< XConnection > r;
            if (aDesc.getName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
                                                 "pipe")))
            {
                rtl::OUString aName(
                    aDesc.getParameter(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("name"))));

                PipeConnection *pConn = new PipeConnection( sConnectionDescription );

                if( pConn->m_pipe.create( aName.pData, osl_Pipe_OPEN, osl::Security() ) )
                {
                    r = Reference < XConnection > ( (XConnection * ) pConn );
                }
                else
                {
                    OUString sMessage = OUString::createFromAscii( "Connector : couldn't connect to pipe " );
                    sMessage += aName;
                    sMessage += OUString::createFromAscii( "(" );
                    sMessage += OUString::valueOf( (sal_Int32 ) pConn->m_pipe.getError() );
                    sMessage += OUString::createFromAscii( ")" );
                    delete pConn;
                    throw NoConnectException( sMessage ,Reference< XInterface > () );
                }
            }
            else if (aDesc.getName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
                                                      "socket")))
            {
                rtl::OUString aHost;
                if (aDesc.hasParameter(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("host"))))
                    aHost = aDesc.getParameter(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("host")));
                else
                    aHost = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
                                              "localhost"));
                sal_uInt16 nPort = static_cast< sal_uInt16 >(
                    aDesc.getParameter(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("port"))).
                    toInt32());
                bool bTcpNoDelay
                    = aDesc.getParameter(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
                                          "tcpnodelay"))).toInt32() != 0;

                SocketConnection *pConn = new SocketConnection( sConnectionDescription);

                SocketAddr AddrTarget( aHost.pData, nPort );
                if(pConn->m_socket.connect(AddrTarget) != osl_Socket_Ok)
                {
                    OUString sMessage = OUString::createFromAscii( "Connector : couldn't connect to socket (" );
                    OUString sError = pConn->m_socket.getErrorAsString();
                    sMessage += sError;
                    sMessage += OUString::createFromAscii( ")" );
                    delete pConn;
                    throw NoConnectException( sMessage, Reference < XInterface > () );
                }
                if( bTcpNoDelay )
                {
                    sal_Int32 nTcpNoDelay = sal_True;
                    pConn->m_socket.setOption( osl_Socket_OptionTcpNoDelay , &nTcpNoDelay,
                                               sizeof( nTcpNoDelay ) , osl_Socket_LevelTcp );
                }
                pConn->completeConnectionString();
                r = Reference< XConnection > ( (XConnection * ) pConn );
            }
            else
            {
                OUString delegatee = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector."));
                delegatee += aDesc.getName();

#if OSL_DEBUG_LEVEL > 1
                OString tmp = OUStringToOString(delegatee, RTL_TEXTENCODING_ASCII_US);
                OSL_TRACE("connector: trying to get service %s\n", tmp.getStr());
#endif
                Reference<XConnector> xConnector(
                    _xSMgr->createInstanceWithContext(delegatee, _xCtx), UNO_QUERY );

                if(!xConnector.is())
                {
                    OUString message(RTL_CONSTASCII_USTRINGPARAM("Connector: unknown delegatee "));
                    message += delegatee;

                    throw ConnectionSetupException(message, Reference<XInterface>());
                }

                sal_Int32 index = sConnectionDescription.indexOf((sal_Unicode) ',');

                r = xConnector->connect(sConnectionDescription.copy(index + 1).trim());
            }
            return r;
        }
        catch (rtl::MalformedUriException & rEx)
        {
            throw ConnectionSetupException(rEx.getMessage(),
                                           Reference< XInterface > ());
        }
    }

    Sequence< OUString > connector_getSupportedServiceNames()
    {
        static Sequence < OUString > *pNames = 0;
        if( ! pNames )
        {
            MutexGuard guard( Mutex::getGlobalMutex() );
            if( !pNames )
            {
                static Sequence< OUString > seqNames(1);
                seqNames.getArray()[0] = OUString::createFromAscii( SERVICE_NAME );
                pNames = &seqNames;
            }
        }
        return *pNames;
    }

    OUString connector_getImplementationName()
    {
        return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
    }

        OUString OConnector::getImplementationName() throw()
    {
        return connector_getImplementationName();
    }

        sal_Bool OConnector::supportsService(const OUString& ServiceName) throw()
    {
        Sequence< OUString > aSNL = getSupportedServiceNames();
        const OUString * pArray = aSNL.getConstArray();

        for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
            if( pArray[i] == ServiceName )
                return sal_True;

        return sal_False;
    }

        Sequence< OUString > OConnector::getSupportedServiceNames(void) throw()
    {
        return connector_getSupportedServiceNames();
    }

    Reference< XInterface > SAL_CALL connector_CreateInstance( const Reference< XComponentContext > & xCtx)
    {
        return Reference < XInterface >( ( OWeakObject * ) new OConnector(xCtx) );
    }

}
using namespace stoc_connector;

static struct ImplementationEntry g_entries[] =
{
    {
        connector_CreateInstance, connector_getImplementationName ,
        connector_getSupportedServiceNames, createSingleComponentFactory ,
        &g_moduleCount.modCnt , 0
    },
    { 0, 0, 0, 0, 0, 0 }
};

extern "C"
{

sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
{
    return g_moduleCount.canUnload( &g_moduleCount , pTime );
}

//==================================================================================================
void SAL_CALL component_getImplementationEnvironment(
    const sal_Char ** ppEnvTypeName, uno_Environment ** )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
//==================================================================================================
sal_Bool SAL_CALL component_writeInfo(
    void * pServiceManager, void * pRegistryKey )
{
    return component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries );
}
//==================================================================================================
void * SAL_CALL component_getFactory(
    const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
{
    return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
}

}

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qtest.h>

#include <QDeclarativeEngine>
#include <private/qdeclarativeengine_p.h>
#include <QAbstractAnimation>
#include <private/qabstractanimation_p.h>

// We have copied the header which is used in the qmljsdebugger (part of QtCreator)
// to catch BC changes. Don't update it unless you know what you are doing!
#include "private_headers/qdeclarativedebughelper_p.h"

class tst_qdeclarativedebughelper : public QObject {
    Q_OBJECT
private slots:
    void setAnimationSlowDownFactor();
    void enableDebugging();
};

class TestAnimation : public QAbstractAnimation {
public:
    int updateCalled;

    TestAnimation() : updateCalled(0) {}

    virtual void updateCurrentTime(int /*currentTime*/) {
        updateCalled++;
    }
    virtual int duration() const {
        return 100;
    }
};

void tst_qdeclarativedebughelper::setAnimationSlowDownFactor()
{
    TestAnimation animation;

    // first check whether setup works
    QCOMPARE(animation.updateCalled, 0);
    animation.start();
    QTest::qWait(animation.totalDuration() + 50);
#ifdef Q_OS_WIN
    if (animation.state() != QAbstractAnimation::Stopped)
        QEXPECT_FAIL("", "On windows, consistent timing is not working properly due to bad timer resolution", Abort);
#endif
    QCOMPARE(animation.state(), QAbstractAnimation::Stopped);
    QVERIFY(animation.updateCalled > 1);

    // check if we can pause all animations
    animation.updateCalled = 0;
    QDeclarativeDebugHelper::setAnimationSlowDownFactor(0.0);
    animation.start();
    QTest::qWait(animation.totalDuration() + 50);
    QVERIFY(animation.updateCalled <= 1); // updateCurrentTime seems to be called at  least once

    // now run them again
    animation.updateCalled = 0;
    QDeclarativeDebugHelper::setAnimationSlowDownFactor(2.0);
    animation.start();
    QTest::qWait(animation.totalDuration() + 50);
    QVERIFY(animation.updateCalled > 1);
}

void tst_qdeclarativedebughelper::enableDebugging()
{
    QTest::ignoreMessage(QtWarningMsg, "Qml debugging is enabled. Only use this in a safe environment!");
    QDeclarativeDebugHelper::enableDebugging();
}

QTEST_MAIN(tst_qdeclarativedebughelper)

#include "tst_qdeclarativedebughelper.moc"

<commit_msg>Make test more reliable<commit_after>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qtest.h>

#include <QDeclarativeEngine>
#include <private/qdeclarativeengine_p.h>
#include <QAbstractAnimation>
#include <private/qabstractanimation_p.h>

// We have copied the header which is used in the qmljsdebugger (part of QtCreator)
// to catch BC changes. Don't update it unless you know what you are doing!
#include "private_headers/qdeclarativedebughelper_p.h"

class tst_qdeclarativedebughelper : public QObject {
    Q_OBJECT
private slots:
    void setAnimationSlowDownFactor();
    void enableDebugging();
};

class TestAnimation : public QAbstractAnimation {
public:
    int updateCalled;

    TestAnimation() : updateCalled(0) {}

    virtual void updateCurrentTime(int /*currentTime*/) {
        updateCalled++;
    }
    virtual int duration() const {
        return 100;
    }
};

void tst_qdeclarativedebughelper::setAnimationSlowDownFactor()
{
    TestAnimation animation;

    // first check whether setup works
    QCOMPARE(animation.updateCalled, 0);
    animation.start();
    QTest::qWait(animation.totalDuration() + 150);
#ifdef Q_OS_WIN
    if (animation.state() != QAbstractAnimation::Stopped)
        QEXPECT_FAIL("", "On windows, consistent timing is not working properly due to bad timer resolution", Abort);
#endif
    QCOMPARE(animation.state(), QAbstractAnimation::Stopped);
    QVERIFY(animation.updateCalled > 1);

    // check if we can pause all animations
    animation.updateCalled = 0;
    QDeclarativeDebugHelper::setAnimationSlowDownFactor(0.0);
    animation.start();
    QTest::qWait(animation.totalDuration() + 150);
    QVERIFY(animation.updateCalled <= 1); // updateCurrentTime seems to be called at  least once

    // now run them again
    animation.updateCalled = 0;
    QDeclarativeDebugHelper::setAnimationSlowDownFactor(2.0);
    animation.start();
    QTest::qWait(animation.totalDuration() + 150);
    QVERIFY(animation.updateCalled > 1);
}

void tst_qdeclarativedebughelper::enableDebugging()
{
    QTest::ignoreMessage(QtWarningMsg, "Qml debugging is enabled. Only use this in a safe environment!");
    QDeclarativeDebugHelper::enableDebugging();
}

QTEST_MAIN(tst_qdeclarativedebughelper)

#include "tst_qdeclarativedebughelper.moc"

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkPlotLine.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkPlotLine.h"

#include "vtkContext2D.h"
#include "vtkPen.h"
#include "vtkContextDevice2D.h"
#include "vtkContextMapper2D.h"
#include "vtkPoints2D.h"
#include "vtkTable.h"
#include "vtkDataArray.h"
#include "vtkIdTypeArray.h"
#include "vtkExecutive.h"
#include "vtkTimeStamp.h"
#include "vtkInformation.h"

#include "vtkObjectFactory.h"

vtkCxxRevisionMacro(vtkPlotLine, "1.12");

//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkPlotLine);

//-----------------------------------------------------------------------------
vtkPlotLine::vtkPlotLine()
{
  this->Points = 0;
  this->Label = 0;
}

//-----------------------------------------------------------------------------
vtkPlotLine::~vtkPlotLine()
{
  this->SetLabel(NULL);
  if (this->Points)
    {
    this->Points->Delete();
    this->Points = NULL;
    }
}

//-----------------------------------------------------------------------------
bool vtkPlotLine::Paint(vtkContext2D *painter)
{
  // This is where everything should be drawn, or dispatched to other methods.
  vtkDebugMacro(<< "Paint event called in vtkPlotLine.");

  if (!this->Visible)
    {
    return false;
    }

  // First check if we have an input
  vtkTable *table = this->Data->GetInput();
  if (!table)
    {
    vtkDebugMacro(<< "Paint event called with no input table set.");
    return false;
    }
  else if(this->Data->GetMTime() > this->BuildTime ||
          table->GetMTime() > this->BuildTime ||
          this->MTime > this->BuildTime)
    {
    vtkDebugMacro(<< "Paint event called with outdated table cache. Updating.");
    this->UpdateTableCache(table);
    }

  // Now add some decorations for our selected points...
  if (this->Selection)
    {
    vtkDebugMacro(<<"Selection set " << this->Selection->GetNumberOfTuples());
    for (int i = 0; i < this->Selection->GetNumberOfTuples(); ++i)
      {
      painter->ApplyPen(this->Pen);
      painter->GetPen()->SetWidth(this->Pen->GetWidth()*15.0);
      vtkIdType id = 0;
      this->Selection->GetTupleValue(i, &id);
      if (id < this->Points->GetNumberOfPoints())
        {
        double *point = this->Points->GetPoint(id);
        painter->DrawPoint(point[0], point[1]);
        }
      }
    }
  else
    {
    vtkDebugMacro("No selection set.");
    }

  // Now to plot the points
  if (this->Points)
    {
    painter->ApplyPen(this->Pen);
    painter->DrawPoly(this->Points);
    painter->GetPen()->SetLineType(vtkPen::SOLID_LINE);
    }

  return true;
}

//-----------------------------------------------------------------------------
bool vtkPlotLine::PaintLegend(vtkContext2D *painter, float rect[4])
{
  painter->ApplyPen(this->Pen);
  painter->DrawLine(rect[0], rect[1]+0.5*rect[3],
                    rect[0]+rect[2], rect[1]+0.5*rect[3]);
  return true;
}

//-----------------------------------------------------------------------------
void vtkPlotLine::GetBounds(double bounds[4])
{
  // Get the x and y arrays (index 0 and 1 respectively)
  vtkTable *table = this->Data->GetInput();
  vtkDataArray *x = this->Data->GetInputArrayToProcess(0, table);
  vtkDataArray *y = this->Data->GetInputArrayToProcess(1, table);

  if (this->UseIndexForXSeries && y)
    {
    bounds[0] = 0;
    bounds[1] = y->GetSize();
    y->GetRange(&bounds[2]);
    }
  else if (x && y)
    {
    x->GetRange(&bounds[0]);
    y->GetRange(&bounds[2]);
    }
  vtkDebugMacro(<< "Bounds: " << bounds[0] << "\t" << bounds[1] << "\t"
                << bounds[2] << "\t" << bounds[3]);
}

//-----------------------------------------------------------------------------
namespace {

// Copy the two arrays into the points array
template<class A>
void CopyToPointsSwitch(vtkPoints2D *points, A *a, vtkDataArray *b, int n)
{
  switch(b->GetDataType())
    {
    vtkTemplateMacro(
        CopyToPoints(points, a, static_cast<VTK_TT*>(b->GetVoidPointer(0)), n));
    }
}

// Copy the two arrays into the points array
template<class A, class B>
void CopyToPoints(vtkPoints2D *points, A *a, B *b, int n)
{
  points->SetNumberOfPoints(n);
  for (int i = 0; i < n; ++i)
    {
    points->SetPoint(i, a[i], b[i]);
    }
}

// Copy one array into the points array, use the index of that array as x
template<class A>
void CopyToPoints(vtkPoints2D *points, A *a, int n)
{
  points->SetNumberOfPoints(n);
  for (int i = 0; i < n; ++i)
    {
    points->SetPoint(i, i, a[i]);
    }
}

}

//-----------------------------------------------------------------------------
bool vtkPlotLine::UpdateTableCache(vtkTable *table)
{
  // Get the x and y arrays (index 0 and 1 respectively)
  vtkDataArray* x = this->Data->GetInputArrayToProcess(0, table);
  vtkDataArray* y = this->Data->GetInputArrayToProcess(1, table);
  if (!x && !this->UseIndexForXSeries)
    {
    vtkErrorMacro(<< "No X column is set (index 0).");
    return false;
    }
  else if (!y)
    {
    vtkErrorMacro(<< "No Y column is set (index 1).");
    return false;
    }
  else if (x->GetSize() != y->GetSize() && !this->UseIndexForXSeries)
    {
    vtkErrorMacro("The x and y columns must have the same number of elements.");
    return false;
    }

  if (!this->Points)
    {
    this->Points = vtkPoints2D::New();
    }

  // Now copy the components into their new columns
  if (this->UseIndexForXSeries)
    {
    switch(y->GetDataType())
      {
        vtkTemplateMacro(
            CopyToPoints(this->Points,
                         static_cast<VTK_TT*>(y->GetVoidPointer(0)),
                         y->GetSize()));
      }
    }
  else
    {
    switch(x->GetDataType())
      {
      vtkTemplateMacro(
          CopyToPointsSwitch(this->Points,
                             static_cast<VTK_TT*>(x->GetVoidPointer(0)),
                             y, x->GetSize()));
      }
    }
  this->SetLabel(y->GetName());
  this->BuildTime.Modified();
  return true;
}

//-----------------------------------------------------------------------------
void vtkPlotLine::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}
<commit_msg>BUG: Label cleared by vtkPlot, remove set in update.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkPlotLine.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkPlotLine.h"

#include "vtkContext2D.h"
#include "vtkPen.h"
#include "vtkContextDevice2D.h"
#include "vtkContextMapper2D.h"
#include "vtkPoints2D.h"
#include "vtkTable.h"
#include "vtkDataArray.h"
#include "vtkIdTypeArray.h"
#include "vtkExecutive.h"
#include "vtkTimeStamp.h"
#include "vtkInformation.h"

#include "vtkObjectFactory.h"

vtkCxxRevisionMacro(vtkPlotLine, "1.13");

//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkPlotLine);

//-----------------------------------------------------------------------------
vtkPlotLine::vtkPlotLine()
{
  this->Points = 0;
  this->Label = 0;
}

//-----------------------------------------------------------------------------
vtkPlotLine::~vtkPlotLine()
{
  if (this->Points)
    {
    this->Points->Delete();
    this->Points = NULL;
    }
}

//-----------------------------------------------------------------------------
bool vtkPlotLine::Paint(vtkContext2D *painter)
{
  // This is where everything should be drawn, or dispatched to other methods.
  vtkDebugMacro(<< "Paint event called in vtkPlotLine.");

  if (!this->Visible)
    {
    return false;
    }

  // First check if we have an input
  vtkTable *table = this->Data->GetInput();
  if (!table)
    {
    vtkDebugMacro(<< "Paint event called with no input table set.");
    return false;
    }
  else if(this->Data->GetMTime() > this->BuildTime ||
          table->GetMTime() > this->BuildTime ||
          this->MTime > this->BuildTime)
    {
    vtkDebugMacro(<< "Paint event called with outdated table cache. Updating.");
    this->UpdateTableCache(table);
    }

  // Now add some decorations for our selected points...
  if (this->Selection)
    {
    vtkDebugMacro(<<"Selection set " << this->Selection->GetNumberOfTuples());
    for (int i = 0; i < this->Selection->GetNumberOfTuples(); ++i)
      {
      painter->ApplyPen(this->Pen);
      painter->GetPen()->SetWidth(this->Pen->GetWidth()*15.0);
      vtkIdType id = 0;
      this->Selection->GetTupleValue(i, &id);
      if (id < this->Points->GetNumberOfPoints())
        {
        double *point = this->Points->GetPoint(id);
        painter->DrawPoint(point[0], point[1]);
        }
      }
    }
  else
    {
    vtkDebugMacro("No selection set.");
    }

  // Now to plot the points
  if (this->Points)
    {
    painter->ApplyPen(this->Pen);
    painter->DrawPoly(this->Points);
    painter->GetPen()->SetLineType(vtkPen::SOLID_LINE);
    }

  return true;
}

//-----------------------------------------------------------------------------
bool vtkPlotLine::PaintLegend(vtkContext2D *painter, float rect[4])
{
  painter->ApplyPen(this->Pen);
  painter->DrawLine(rect[0], rect[1]+0.5*rect[3],
                    rect[0]+rect[2], rect[1]+0.5*rect[3]);
  return true;
}

//-----------------------------------------------------------------------------
void vtkPlotLine::GetBounds(double bounds[4])
{
  // Get the x and y arrays (index 0 and 1 respectively)
  vtkTable *table = this->Data->GetInput();
  vtkDataArray *x = this->Data->GetInputArrayToProcess(0, table);
  vtkDataArray *y = this->Data->GetInputArrayToProcess(1, table);

  if (this->UseIndexForXSeries && y)
    {
    bounds[0] = 0;
    bounds[1] = y->GetSize();
    y->GetRange(&bounds[2]);
    }
  else if (x && y)
    {
    x->GetRange(&bounds[0]);
    y->GetRange(&bounds[2]);
    }
  vtkDebugMacro(<< "Bounds: " << bounds[0] << "\t" << bounds[1] << "\t"
                << bounds[2] << "\t" << bounds[3]);
}

//-----------------------------------------------------------------------------
namespace {

// Copy the two arrays into the points array
template<class A>
void CopyToPointsSwitch(vtkPoints2D *points, A *a, vtkDataArray *b, int n)
{
  switch(b->GetDataType())
    {
    vtkTemplateMacro(
        CopyToPoints(points, a, static_cast<VTK_TT*>(b->GetVoidPointer(0)), n));
    }
}

// Copy the two arrays into the points array
template<class A, class B>
void CopyToPoints(vtkPoints2D *points, A *a, B *b, int n)
{
  points->SetNumberOfPoints(n);
  for (int i = 0; i < n; ++i)
    {
    points->SetPoint(i, a[i], b[i]);
    }
}

// Copy one array into the points array, use the index of that array as x
template<class A>
void CopyToPoints(vtkPoints2D *points, A *a, int n)
{
  points->SetNumberOfPoints(n);
  for (int i = 0; i < n; ++i)
    {
    points->SetPoint(i, i, a[i]);
    }
}

}

//-----------------------------------------------------------------------------
bool vtkPlotLine::UpdateTableCache(vtkTable *table)
{
  // Get the x and y arrays (index 0 and 1 respectively)
  vtkDataArray* x = this->Data->GetInputArrayToProcess(0, table);
  vtkDataArray* y = this->Data->GetInputArrayToProcess(1, table);
  if (!x && !this->UseIndexForXSeries)
    {
    vtkErrorMacro(<< "No X column is set (index 0).");
    return false;
    }
  else if (!y)
    {
    vtkErrorMacro(<< "No Y column is set (index 1).");
    return false;
    }
  else if (x->GetSize() != y->GetSize() && !this->UseIndexForXSeries)
    {
    vtkErrorMacro("The x and y columns must have the same number of elements.");
    return false;
    }

  if (!this->Points)
    {
    this->Points = vtkPoints2D::New();
    }

  // Now copy the components into their new columns
  if (this->UseIndexForXSeries)
    {
    switch(y->GetDataType())
      {
        vtkTemplateMacro(
            CopyToPoints(this->Points,
                         static_cast<VTK_TT*>(y->GetVoidPointer(0)),
                         y->GetSize()));
      }
    }
  else
    {
    switch(x->GetDataType())
      {
      vtkTemplateMacro(
          CopyToPointsSwitch(this->Points,
                             static_cast<VTK_TT*>(x->GetVoidPointer(0)),
                             y, x->GetSize()));
      }
    }
  this->BuildTime.Modified();
  return true;
}

//-----------------------------------------------------------------------------
void vtkPlotLine::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}
<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/optimization/COptProblem.cpp,v $
   $Revision: 1.26 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/01/20 20:54:29 $
   End CVS Header */

/**
 *  File name: COptProblem.cpp
 *
 *  Programmer: Yongqun He
 *  Contact email: yohe@vt.edu
 *  Purpose: This is the source file of the COptProblem class.
 *           It specifies the optimization problem with its own members and
 *           functions. It's used by COptAlgorithm class and COptimization class
 */
#include <float.h>

#include "copasi.h"
#include "COptProblem.h"
#include "COptItem.h"

#include "steadystate/CSteadyStateTask.h"
#include "trajectory/CTrajectoryTask.h"
#include "steadystate/CSteadyStateProblem.h"
#include "trajectory/CTrajectoryProblem.h"

#include "model/CModel.h"
#include "model/CCompartment.h"

//  Default constructor
COptProblem::COptProblem(const CCopasiContainer * pParent):
    CCopasiProblem(CCopasiTask::optimization, pParent),
    mCalculateVariablesMin(),
    mCalculateVariablesMax(),
    mpSteadyState(NULL),
    mpTrajectory(NULL)
{
  addGroup("OptimizationItemList");
  addGroup("OptimizationConstraintList");

  addParameter("SteadyState", CCopasiParameter::STRING, (std::string) "");
  addParameter("Trajectory", CCopasiParameter::STRING, (std::string) "");
  addParameter("ObjectiveFunction", CCopasiParameter::STRING, (std::string) "");
  addParameter("Maximize", CCopasiParameter::BOOL, (bool) false);
}

// copy constructor
COptProblem::COptProblem(const COptProblem& src,
                         const CCopasiContainer * pParent):
    CCopasiProblem(src, pParent),
    mCalculateVariablesMin(src.mCalculateVariablesMin),
    mCalculateVariablesMax(src.mCalculateVariablesMax),
    mpSteadyState(src.mpSteadyState),
    mpTrajectory(src.mpTrajectory)
{}

// Destructor
COptProblem::~COptProblem()
{}

// check constraints : unimplemented - always returns true
bool COptProblem::checkParametricConstraints()
{
  return true;
}

bool COptProblem::checkFunctionalConstraints()
{
  return true;
}

/**
 * calculate() decides whether the problem is a steady state problem or a
 * trajectory problem based on whether the pointer to that type of problem
 * is null or not.  It then calls the process() method for that type of
 * problem.  Currently process takes ofstream& as a parameter but it will
 * change so that process() takes no parameters.
 */
bool COptProblem::calculate()
{
  if (mpSteadyState != NULL)
    {
      ((CSteadyStateProblem *) mpSteadyState->getProblem())->
      setInitialState(mpSteadyState->getProblem()->getModel()->getInitialState());
      mpSteadyState->process();
    }

  if (mpTrajectory != NULL)
    {
      ((CTrajectoryProblem *) mpTrajectory->getProblem())->
      setInitialState(mpTrajectory->getProblem()->getModel()->getInitialState());
      mpTrajectory->process();
    }
  return true;
}

void COptProblem::setSolutionValue(const C_FLOAT64 & value)
{
  getSolutionResults()[0] = value;
}

// get the minimum value of parameters
CVector< C_FLOAT64 > & COptProblem::getParameterMin()
{
  return mCalculateVariablesMin;
}

// get the maximum value of the parameters
CVector< C_FLOAT64 > & COptProblem::getParameterMax()
{
  return mCalculateVariablesMax;
}

// set the type of problem : Steady State OR Trajectory
void COptProblem::setProblemType(ProblemType type)
{
  if (type == SteadyState)
    mpSteadyState = new CSteadyStateTask(/*this*/NULL);
  if (type == Trajectory)
    mpTrajectory = new CTrajectoryTask(/*this*/NULL);
}

COptItem COptProblem::getOptItem(const unsigned C_INT32 & index)
{
  CCopasiParameterGroup * pOptimizationItemList
  = (CCopasiParameterGroup *) getValue("OptimizationItemList");

  CCopasiParameterGroup * pOptItem
  = (CCopasiParameterGroup *) pOptimizationItemList->getValue(index);

  if (!pOptItem || !COptItem::isValid(*pOptItem)) fatalError();

  COptItem Item(*pOptItem);
  return Item;
}

const unsigned C_INT32 COptProblem::getOptItemSize() const
{return ((CCopasiParameterGroup *) getValue("OptimizationItemList"))->size();}

COptItem COptProblem::addOptItem(const CCopasiObjectName & objectCN)
{
  unsigned C_INT32 index = getOptItemSize();
  CCopasiParameterGroup * pOptimizationItemList
  = (CCopasiParameterGroup *) getValue("OptimizationItemList");
  pOptimizationItemList->addGroup("OptimizationItem");

  CCopasiParameterGroup * pOptItem = (CCopasiParameterGroup *) pOptimizationItemList->getValue(index);
  pOptItem->addParameter("ObjectCN", CCopasiParameter::STRING, (std::string) objectCN);
  pOptItem->addParameter("LowerBound", CCopasiParameter::STRING, (std::string) "-inf");
  pOptItem->addParameter("LowerRelation", CCopasiParameter::STRING, (std::string) "<=");
  pOptItem->addParameter("UpperBound", CCopasiParameter::STRING, (std::string) "inf");
  pOptItem->addParameter("UpperRelation", CCopasiParameter::STRING, (std::string) "<=");

  if (!pOptItem || !COptItem::isValid(*pOptItem)) fatalError();

  COptItem Item(*pOptItem);
  return Item;
}

bool COptProblem::swapOptItem(const unsigned C_INT32 & iFrom,
                              const unsigned C_INT32 & iTo)
{return ((CCopasiParameterGroup *) getValue("OptimizationItemList"))->swap(iFrom, iTo);}
<commit_msg>The addOptItem method utilizes COptItem::initialize instead of creating the parameter itsef.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/optimization/COptProblem.cpp,v $
   $Revision: 1.27 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/01/21 18:54:02 $
   End CVS Header */

/**
 *  File name: COptProblem.cpp
 *
 *  Programmer: Yongqun He
 *  Contact email: yohe@vt.edu
 *  Purpose: This is the source file of the COptProblem class.
 *           It specifies the optimization problem with its own members and
 *           functions. It's used by COptAlgorithm class and COptimization class
 */
#include <float.h>

#include "copasi.h"
#include "COptProblem.h"
#include "COptItem.h"

#include "steadystate/CSteadyStateTask.h"
#include "trajectory/CTrajectoryTask.h"
#include "steadystate/CSteadyStateProblem.h"
#include "trajectory/CTrajectoryProblem.h"

#include "model/CModel.h"
#include "model/CCompartment.h"

//  Default constructor
COptProblem::COptProblem(const CCopasiContainer * pParent):
    CCopasiProblem(CCopasiTask::optimization, pParent),
    mCalculateVariablesMin(),
    mCalculateVariablesMax(),
    mpSteadyState(NULL),
    mpTrajectory(NULL)
{
  addGroup("OptimizationItemList");
  addGroup("OptimizationConstraintList");

  addParameter("SteadyState", CCopasiParameter::STRING, (std::string) "");
  addParameter("Trajectory", CCopasiParameter::STRING, (std::string) "");
  addParameter("ObjectiveFunction", CCopasiParameter::STRING, (std::string) "");
  addParameter("Maximize", CCopasiParameter::BOOL, (bool) false);
}

// copy constructor
COptProblem::COptProblem(const COptProblem& src,
                         const CCopasiContainer * pParent):
    CCopasiProblem(src, pParent),
    mCalculateVariablesMin(src.mCalculateVariablesMin),
    mCalculateVariablesMax(src.mCalculateVariablesMax),
    mpSteadyState(src.mpSteadyState),
    mpTrajectory(src.mpTrajectory)
{}

// Destructor
COptProblem::~COptProblem()
{}

// check constraints : unimplemented - always returns true
bool COptProblem::checkParametricConstraints()
{
  return true;
}

bool COptProblem::checkFunctionalConstraints()
{
  return true;
}

/**
 * calculate() decides whether the problem is a steady state problem or a
 * trajectory problem based on whether the pointer to that type of problem
 * is null or not.  It then calls the process() method for that type of
 * problem.  Currently process takes ofstream& as a parameter but it will
 * change so that process() takes no parameters.
 */
bool COptProblem::calculate()
{
  if (mpSteadyState != NULL)
    {
      ((CSteadyStateProblem *) mpSteadyState->getProblem())->
      setInitialState(mpSteadyState->getProblem()->getModel()->getInitialState());
      mpSteadyState->process();
    }

  if (mpTrajectory != NULL)
    {
      ((CTrajectoryProblem *) mpTrajectory->getProblem())->
      setInitialState(mpTrajectory->getProblem()->getModel()->getInitialState());
      mpTrajectory->process();
    }
  return true;
}

void COptProblem::setSolutionValue(const C_FLOAT64 & value)
{
  getSolutionResults()[0] = value;
}

// get the minimum value of parameters
CVector< C_FLOAT64 > & COptProblem::getParameterMin()
{
  return mCalculateVariablesMin;
}

// get the maximum value of the parameters
CVector< C_FLOAT64 > & COptProblem::getParameterMax()
{
  return mCalculateVariablesMax;
}

// set the type of problem : Steady State OR Trajectory
void COptProblem::setProblemType(ProblemType type)
{
  if (type == SteadyState)
    mpSteadyState = new CSteadyStateTask(/*this*/NULL);
  if (type == Trajectory)
    mpTrajectory = new CTrajectoryTask(/*this*/NULL);
}

COptItem COptProblem::getOptItem(const unsigned C_INT32 & index)
{
  CCopasiParameterGroup * pOptimizationItemList
  = (CCopasiParameterGroup *) getValue("OptimizationItemList");

  CCopasiParameterGroup * pOptItem
  = (CCopasiParameterGroup *) pOptimizationItemList->getValue(index);

  if (!pOptItem || !COptItem::isValid(*pOptItem)) fatalError();

  COptItem Item(*pOptItem);
  return Item;
}

const unsigned C_INT32 COptProblem::getOptItemSize() const
{return ((CCopasiParameterGroup *) getValue("OptimizationItemList"))->size();}

COptItem COptProblem::addOptItem(const CCopasiObjectName & objectCN)
{
  unsigned C_INT32 index = getOptItemSize();
  CCopasiParameterGroup * pOptimizationItemList
  = (CCopasiParameterGroup *) getValue("OptimizationItemList");
  pOptimizationItemList->addGroup("OptimizationItem");

  CCopasiParameterGroup * pOptItem =
    (CCopasiParameterGroup *) pOptimizationItemList->getValue(index);

  assert(pOptItem != NULL);

  COptItem OptItem(*pOptItem);
  if (!OptItem.initialize(objectCN)) fatalError();

  return OptItem;
}

bool COptProblem::swapOptItem(const unsigned C_INT32 & iFrom,
                              const unsigned C_INT32 & iTo)
{return ((CCopasiParameterGroup *) getValue("OptimizationItemList"))->swap(iFrom, iTo);}
<|endoftext|>


<commit_before><commit_msg>Prevent buffer overflow in QuicSimpleServerSession::HandleRstOnValidNonexistentStream<commit_after><|endoftext|>


<commit_before>#include <QDebug>
#include <QDir>
#include <QTemporaryFile>
#include <iostream>
#include "kernel.h"
#include "geometries.h"
#include "ilwiscontext.h"
#include "grid.h"

using namespace Ilwis;
GridBlockInternal::GridBlockInternal(quint32 lines , quint32 width) :  _size(Size(lines,width,1)),_initialized(false), _loaded(false)

{
    _undef = undef<double>();
    _id = ++_blockid;
    _blockSize = _size.xsize()* _size.ysize();
}

GridBlockInternal::~GridBlockInternal() {

}

Size GridBlockInternal::size() const {
    return _size;
}

GridBlockInternal *GridBlockInternal::clone()
{
    GridBlockInternal *block = new GridBlockInternal(_size.xsize(), _size.ysize());
    block->prepare();
    block->_undef = _undef;
    block->_index = 0;
    block->_blockSize = _blockSize;
    if(!isLoaded())
        load();
    std::copy(_data.begin(), _data.end(), block->_data.begin());

    return block;

}

char *GridBlockInternal::blockAsMemory() {
    prepare();
    return (char *)&_data[0];
}

void GridBlockInternal::fill(const std::vector<double>& values) {

    if ( values.size() != _data.size())
        prepare();
    copy(values.begin(), values.end(), _data.begin());

}

quint32 GridBlockInternal::blockSize() {
    return _blockSize;
}

bool GridBlockInternal::isLoaded() const {
    return _loaded;
}

inline bool GridBlockInternal::unload() {
    if ( _tempName == sUNDEF) {
        QString name = QString("gridblock_%1").arg(_id);
        QDir localDir(context()->temporaryWorkLocation().toLocalFile());
        if ( !localDir.exists()) {
            localDir.mkpath(localDir.absolutePath());
        }
        _tempName = localDir.absolutePath() + "/" + name;
    }
    if ( _swapFile.isNull()) {
        _swapFile.reset(new QTemporaryFile(_tempName));

    }
    if(!_swapFile->open() ){
        return ERROR1(ERR_COULD_NOT_OPEN_WRITING_1,_tempName);
    }
    quint64 bytesNeeded = _data.size() * sizeof(double);
    quint64 total =_swapFile->write((char *)&_data[0], bytesNeeded);
    _swapFile->close();
    if ( total != bytesNeeded) {
        return ERROR1(ERR_COULD_NOT_OPEN_WRITING_1,_tempName);
    }
    _loaded = false;
    _initialized = false;
    _data.clear();

    return true;

}

bool GridBlockInternal::load() {
     _loaded = true;
    prepare();
    if ( _tempName == sUNDEF) {
        return true; // totaly new block; never been swapped so no load needed
    }
    quint64 bytesNeeded = _data.size() * sizeof(double);
    if(!_swapFile->open() ){
        return ERROR1(ERR_COULD_NOT_OPEN_READING_1,_tempName);
    }
    quint64 total =_swapFile->read((char *)&_data[0], bytesNeeded);

    _swapFile->close();
    if ( total != bytesNeeded) {
        _loaded = false;
        return ERROR1(ERR_COULD_NOT_OPEN_READING_1,_tempName);
    }
    return true;

}

//----------------------------------------------------------------------
Grid::Grid(const Size& sz, int maxLines) : _maxLines(maxLines){
    //Locker lock(_mutex);

    setSize(sz);
    quint64 bytesNeeded = _size.totalSize() * sizeof(double);
    quint64 mleft = context()->memoryLeft();
    _memUsed = std::min(bytesNeeded, mleft/2);
    context()->changeMemoryLeft(-_memUsed);
    int n = numberOfBlocks();
    _inMemoryIndex = std::max(1ULL, n * _memUsed / bytesNeeded);
    _blocksPerBand = n / sz.zsize();

}

quint32 Grid::blockSize(quint32 index) const {
    if ( index < _blockSizes.size() )
        return _blockSizes[index];
    return iUNDEF;
}

Grid::~Grid() {
    clear();
    context()->changeMemoryLeft(_memUsed);
}

Size Grid::size() const {
    return _size;
}

int Grid::maxLines() const
{
    return _maxLines;
}

Grid *Grid::clone(quint32 index1, quint32 index2)
{
    if ( index2 < index1){
        ERROR2(ERR_INVALID_INIT_FOR_2,TR("grid limits"),TR("clone grid"));
        return 0;
    }
    quint32 start = index1 == iUNDEF ? 0 : index1;
    quint32 end = index2 == iUNDEF ? _blocks.size() : index2 + 1;

    Grid *grid = new Grid(Size(_size.xsize(), _size.ysize(), end - start), _maxLines);
    grid->prepare();

    for(int i=start; i < end; ++i) {
        grid->_blocks[i] = _blocks[i]->clone();
    }
    grid->_inMemoryIndex = 1;
    grid->_memUsed = _memUsed;
    return grid;

}

void Grid::clear() {
    _size = Size();
    _blockSizes.clear();
    for(quint32 i = 0; i < _blocks.size(); ++i) {
        delete _blocks[i];
    }
    _blocks.clear();
}

double Grid::value(const Voxel& vox) {
    if ( vox.x() <0 || vox.y() < 0 || vox.z() < 0)
        return rUNDEF;
    quint32 yoff = (qint32)vox.y() % _maxLines;
    quint32 block = vox.y() / _maxLines;
    quint32 bandBlocks = _blocksPerBand * vox.z();
    quint32 offset = _offsets[yoff][vox.x()];
    return value(bandBlocks + block, offset);
}

inline double &Grid::value(quint32 block, int offset )  {
    if ( _blocks.size() <= _inMemoryIndex) // no cache case
        return _blocks[block]->at(offset);

    update(block);

    return _blocks[_cacheHead]->at(offset);
}

inline void Grid::setValue(quint32 block, int offset, double v ) {
    if ( _blocks.size() <= _inMemoryIndex) {
        _blocks[block]->at(offset) = v;
        return ;
    }

    if(!update(block))
        return ;

    _blocks[_cacheHead]->at(offset) = v;
}

quint32 Grid::blocks() const {
    return _blocks.size();
}

quint32 Grid::blocksPerBand() const {
    return _blocksPerBand;
}

void Grid::setBlock(quint32 block, const std::vector<double>& data, bool creation) {
    if ( _blocks.size() <= _inMemoryIndex) { // no cache case
        _blocks[block]->fill(data);
        return ;
    }
    if(!update(block, creation))
        return ;
    _blocks[_cache[block]]->fill(data);
}

char *Grid::blockAsMemory(quint32 block, bool creation) {
    if ( _blocks.size() <= _inMemoryIndex) { // no cache case
        GridBlockInternal *du = _blocks[block];
        char * p = du->blockAsMemory();
        return p;
    }

    if(!update(block, creation))
        return 0;
    GridBlockInternal *du = _blocks[_cache[block]];
    char * p = du->blockAsMemory();
    return p;

}

void Grid::setSize(const Size& sz) {
    if ( _blocks.size() != 0)
        clear();
    _size = sz;
    if ( _size.zsize() == 0)
        _size.zsize(1); // 1 grid at least in the grid;

}

bool Grid::prepare() {
    Locker lock(_mutex);
    if ( _size.isNull()|| !_size.isValid() || _maxLines == 0) {
        return ERROR0("Grid size not properly initialized");
    }

    int nblocks = numberOfBlocks();
    qint32 totalLines = _size.ysize();
    _blocks.resize(nblocks);
    _blockSizes.resize(nblocks);
    _blockOffsets.resize(nblocks);

    for(quint32 i = 0; i < _blocks.size(); ++i) {
        int linesPerBlock = std::min((qint32)_maxLines, totalLines);
        _blocks[i] = new GridBlockInternal(linesPerBlock, _size.xsize());
        _blockSizes[i] = linesPerBlock * _size.xsize();
        _blockOffsets[i] = i == 0 ? 0 : _blockOffsets[i-1] +  _blockSizes[i];
        totalLines -= _maxLines;
        if ( totalLines <= 0) // to next band
            totalLines = _size.ysize();
    }
    _offsets.resize(_maxLines);
    for(quint32 y=0; y < _maxLines; ++y) {
        _offsets[y].resize(_size.xsize());
        for(quint32 x=0; x < _size.xsize(); ++x) {
            quint64 linearPos = y * size().xsize() + x;
            _offsets[y][x] = linearPos;
        }
    }
    return true;
}

int Grid::numberOfBlocks() {
    double rblocks = (double)_size.ysize() / _maxLines;
    int nblocks = (int)rblocks;
    double rest = rblocks - nblocks;
    if ( rest >= (1.0 / ( _maxLines + 1))) {
        nblocks++;
    }
    return nblocks * _size.zsize();
}

inline bool Grid::update(quint32 block, bool creation) {
    Locker lock(_mutex);
    if ( block >= _blocks.size() )
        return false;
    if ( !_blocks[block]->isLoaded()) {
        if(!_blocks[block]->load())
            return false;
    }
    if ( creation || _cache.size() == 0) { // at create time we want to preserver the original order in memory

        if ( block > _inMemoryIndex )
            _blocks[_cache.back()]->unload();
        _cache.push_back(block);
    }
    else if ( _cache.front() != block) {
        int index = _cache.indexOf(block);
        if (index >=0) {
            _cache.removeOne(index);
        }
        _cache.push_front(block);
        _cacheHead = block; // for efficiency, no lookup what the head is
        if ( index > (int)_inMemoryIndex) {
            return _blocks[_cache[_inMemoryIndex]]->unload();
        }

    }
    return true;
}

void Grid::unload() {
    Locker lock(_mutex);
    _cache.clear();
    for(GridBlockInternal *block : _blocks) {
        block->unload();
    }
    _inMemoryIndex = 0;
}

<commit_msg>better calculation for begin and end when cloning<commit_after>#include <QDebug>
#include <QDir>
#include <QTemporaryFile>
#include <iostream>
#include "kernel.h"
#include "geometries.h"
#include "ilwiscontext.h"
#include "grid.h"

using namespace Ilwis;
GridBlockInternal::GridBlockInternal(quint32 lines , quint32 width) :  _size(Size(lines,width,1)),_initialized(false), _loaded(false)

{
    _undef = undef<double>();
    _id = ++_blockid;
    _blockSize = _size.xsize()* _size.ysize();
}

GridBlockInternal::~GridBlockInternal() {

}

Size GridBlockInternal::size() const {
    return _size;
}

GridBlockInternal *GridBlockInternal::clone()
{
    GridBlockInternal *block = new GridBlockInternal(_size.xsize(), _size.ysize());
    block->prepare();
    block->_undef = _undef;
    block->_index = 0;
    block->_blockSize = _blockSize;
    if(!isLoaded())
        load();
    std::copy(_data.begin(), _data.end(), block->_data.begin());

    return block;

}

char *GridBlockInternal::blockAsMemory() {
    prepare();
    return (char *)&_data[0];
}

void GridBlockInternal::fill(const std::vector<double>& values) {

    if ( values.size() != _data.size())
        prepare();
    copy(values.begin(), values.end(), _data.begin());

}

quint32 GridBlockInternal::blockSize() {
    return _blockSize;
}

bool GridBlockInternal::isLoaded() const {
    return _loaded;
}

inline bool GridBlockInternal::unload() {
    if ( _tempName == sUNDEF) {
        QString name = QString("gridblock_%1").arg(_id);
        QDir localDir(context()->temporaryWorkLocation().toLocalFile());
        if ( !localDir.exists()) {
            localDir.mkpath(localDir.absolutePath());
        }
        _tempName = localDir.absolutePath() + "/" + name;
    }
    if ( _swapFile.isNull()) {
        _swapFile.reset(new QTemporaryFile(_tempName));

    }
    if(!_swapFile->open() ){
        return ERROR1(ERR_COULD_NOT_OPEN_WRITING_1,_tempName);
    }
    quint64 bytesNeeded = _data.size() * sizeof(double);
    quint64 total =_swapFile->write((char *)&_data[0], bytesNeeded);
    _swapFile->close();
    if ( total != bytesNeeded) {
        return ERROR1(ERR_COULD_NOT_OPEN_WRITING_1,_tempName);
    }
    _loaded = false;
    _initialized = false;
    _data.clear();

    return true;

}

bool GridBlockInternal::load() {
     _loaded = true;
    prepare();
    if ( _tempName == sUNDEF) {
        return true; // totaly new block; never been swapped so no load needed
    }
    quint64 bytesNeeded = _data.size() * sizeof(double);
    if(!_swapFile->open() ){
        return ERROR1(ERR_COULD_NOT_OPEN_READING_1,_tempName);
    }
    quint64 total =_swapFile->read((char *)&_data[0], bytesNeeded);

    _swapFile->close();
    if ( total != bytesNeeded) {
        _loaded = false;
        return ERROR1(ERR_COULD_NOT_OPEN_READING_1,_tempName);
    }
    return true;

}

//----------------------------------------------------------------------
Grid::Grid(const Size& sz, int maxLines) : _maxLines(maxLines){
    //Locker lock(_mutex);

    setSize(sz);
    quint64 bytesNeeded = _size.totalSize() * sizeof(double);
    quint64 mleft = context()->memoryLeft();
    _memUsed = std::min(bytesNeeded, mleft/2);
    context()->changeMemoryLeft(-_memUsed);
    int n = numberOfBlocks();
    _inMemoryIndex = std::max(1ULL, n * _memUsed / bytesNeeded);
    _blocksPerBand = n / sz.zsize();

}

quint32 Grid::blockSize(quint32 index) const {
    if ( index < _blockSizes.size() )
        return _blockSizes[index];
    return iUNDEF;
}

Grid::~Grid() {
    clear();
    context()->changeMemoryLeft(_memUsed);
}

Size Grid::size() const {
    return _size;
}

int Grid::maxLines() const
{
    return _maxLines;
}

Grid *Grid::clone(quint32 index1, quint32 index2)
{
    if ( index2 < index1){
        ERROR2(ERR_INVALID_INIT_FOR_2,TR("grid limits"),TR("clone grid"));
        return 0;
    }
    quint32 start = index1 == iUNDEF ? 0 : index1;
    quint32 end = index2 == iUNDEF ? _blocks.size() / _blocksPerBand : index2 + 1;

    Grid *grid = new Grid(Size(_size.xsize(), _size.ysize(), end - start), _maxLines);
    grid->prepare();

    quint32 startBlock = start * _blocksPerBand;
    quint32 endBlock = std::min(end * _blocksPerBand, _blocks.size());
    for(int i=startBlock, j=0; i < endBlock; ++i, ++j) {
        grid->_blocks[j] = _blocks[i]->clone();
    }
    grid->_inMemoryIndex = 1;
    grid->_memUsed = _memUsed;
    return grid;

}

void Grid::clear() {
    _size = Size();
    _blockSizes.clear();
    for(quint32 i = 0; i < _blocks.size(); ++i) {
        delete _blocks[i];
    }
    _blocks.clear();
}

double Grid::value(const Voxel& vox) {
    if ( vox.x() <0 || vox.y() < 0 || vox.z() < 0)
        return rUNDEF;
    quint32 yoff = (qint32)vox.y() % _maxLines;
    quint32 block = vox.y() / _maxLines;
    quint32 bandBlocks = _blocksPerBand * vox.z();
    quint32 offset = _offsets[yoff][vox.x()];
    return value(bandBlocks + block, offset);
}

inline double &Grid::value(quint32 block, int offset )  {
    if ( _blocks.size() <= _inMemoryIndex) // no cache case
        return _blocks[block]->at(offset);

    update(block);

    return _blocks[_cacheHead]->at(offset);
}

inline void Grid::setValue(quint32 block, int offset, double v ) {
    if ( _blocks.size() <= _inMemoryIndex) {
        _blocks[block]->at(offset) = v;
        return ;
    }

    if(!update(block))
        return ;

    _blocks[_cacheHead]->at(offset) = v;
}

quint32 Grid::blocks() const {
    return _blocks.size();
}

quint32 Grid::blocksPerBand() const {
    return _blocksPerBand;
}

void Grid::setBlock(quint32 block, const std::vector<double>& data, bool creation) {
    if ( _blocks.size() <= _inMemoryIndex) { // no cache case
        _blocks[block]->fill(data);
        return ;
    }
    if(!update(block, creation))
        return ;
    _blocks[_cache[block]]->fill(data);
}

char *Grid::blockAsMemory(quint32 block, bool creation) {
    if ( _blocks.size() <= _inMemoryIndex) { // no cache case
        GridBlockInternal *du = _blocks[block];
        char * p = du->blockAsMemory();
        return p;
    }

    if(!update(block, creation))
        return 0;
    GridBlockInternal *du = _blocks[_cache[block]];
    char * p = du->blockAsMemory();
    return p;

}

void Grid::setSize(const Size& sz) {
    if ( _blocks.size() != 0)
        clear();
    _size = sz;
    if ( _size.zsize() == 0)
        _size.zsize(1); // 1 grid at least in the grid;

}

bool Grid::prepare() {
    Locker lock(_mutex);
    if ( _size.isNull()|| !_size.isValid() || _maxLines == 0) {
        return ERROR0("Grid size not properly initialized");
    }

    int nblocks = numberOfBlocks();
    qint32 totalLines = _size.ysize();
    _blocks.resize(nblocks);
    _blockSizes.resize(nblocks);
    _blockOffsets.resize(nblocks);

    for(quint32 i = 0; i < _blocks.size(); ++i) {
        int linesPerBlock = std::min((qint32)_maxLines, totalLines);
        _blocks[i] = new GridBlockInternal(linesPerBlock, _size.xsize());
        _blockSizes[i] = linesPerBlock * _size.xsize();
        _blockOffsets[i] = i == 0 ? 0 : _blockOffsets[i-1] +  _blockSizes[i];
        totalLines -= _maxLines;
        if ( totalLines <= 0) // to next band
            totalLines = _size.ysize();
    }
    _offsets.resize(_maxLines);
    for(quint32 y=0; y < _maxLines; ++y) {
        _offsets[y].resize(_size.xsize());
        for(quint32 x=0; x < _size.xsize(); ++x) {
            quint64 linearPos = y * size().xsize() + x;
            _offsets[y][x] = linearPos;
        }
    }
    return true;
}

int Grid::numberOfBlocks() {
    double rblocks = (double)_size.ysize() / _maxLines;
    int nblocks = (int)rblocks;
    double rest = rblocks - nblocks;
    if ( rest >= (1.0 / ( _maxLines + 1))) {
        nblocks++;
    }
    return nblocks * _size.zsize();
}

inline bool Grid::update(quint32 block, bool creation) {
    Locker lock(_mutex);
    if ( block >= _blocks.size() )
        return false;
    if ( !_blocks[block]->isLoaded()) {
        if(!_blocks[block]->load())
            return false;
    }
    if ( creation || _cache.size() == 0) { // at create time we want to preserver the original order in memory

        if ( block > _inMemoryIndex )
            _blocks[_cache.back()]->unload();
        _cache.push_back(block);
    }
    else if ( _cache.front() != block) {
        int index = _cache.indexOf(block);
        if (index >=0) {
            _cache.removeOne(index);
        }
        _cache.push_front(block);
        _cacheHead = block; // for efficiency, no lookup what the head is
        if ( index > (int)_inMemoryIndex) {
            return _blocks[_cache[_inMemoryIndex]]->unload();
        }

    }
    return true;
}

void Grid::unload() {
    Locker lock(_mutex);
    _cache.clear();
    for(GridBlockInternal *block : _blocks) {
        block->unload();
    }
    _inMemoryIndex = 0;
}

<|endoftext|>