<commit_before>#include "updatebutton.h"
#include "dcpspaceritem.h"
#include "datetimetranslation.h"

#include <duilayout.h>
#include <duilinearlayoutpolicy.h>
#include <duigridlayoutpolicy.h>
#include <duilabel.h>
#include <duibutton.h>
#include <duiseparator.h>
#include <duiscenemanager.h>

int height = 88;

UpdateButton::UpdateButton(DuiWidget *parent)
             :DuiWidget(parent)
{
    initWidget();
}

UpdateButton::~UpdateButton()
{
}

void UpdateButton::paint(QPainter *painter,
                         const QStyleOptionGraphicsItem *option,
                         QWidget *widget)
{
    Q_UNUSED(painter);
    Q_UNUSED(option);
    Q_UNUSED(widget);
}

void UpdateButton::initWidget()
{
    // mainLayout
    DuiLayout *mainLayout = new DuiLayout(this);
    mainLayout->setAnimator(0);
    mainLayout->setContentsMargins(0.0, 0.0, 0.0, 0.0);
    this->setLayout(mainLayout);
    DuiLinearLayoutPolicy *mainLayoutPolicy =
        new DuiLinearLayoutPolicy(mainLayout, Qt::Vertical);
    mainLayout->setPolicy(mainLayoutPolicy);
    mainLayoutPolicy->setSpacing(5);

    // lineLayout
    DuiLayout *lineLayout = new DuiLayout(0);
    lineLayout->setAnimator(0);
    lineLayout->setContentsMargins(20.0, 0.0, 20.0, 0.0);
    DuiGridLayoutPolicy *lineLayoutPolicy = new DuiGridLayoutPolicy(lineLayout);
    lineLayout->setPolicy(lineLayoutPolicy);
    lineLayoutPolicy->setSpacing(3);

    // automaticLabel
    DuiLabel *automaticLabel = new DuiLabel(DcpDateTime::AutomaticUpdateText, this);
    automaticLabel->setObjectName("AutomaticLabel");
    automaticLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    automaticLabel->setAcceptedMouseButtons(0);
    automaticLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    // toggleButton
    DuiButton *toggleButton = new DuiButton(this);
    toggleButton->setObjectName("ToggleButton");
    toggleButton->setMinimumSize(QSize(48, 48));
    toggleButton->setMaximumSize(QSize(48, 48));
    toggleButton->setCheckable(true);
    toggleButton->setTextVisible(false);

    // add items to lineLayoutPolicy
    lineLayoutPolicy->addItemAtPosition(automaticLabel, 0, 0);
    lineLayoutPolicy->addItemAtPosition(
            new DcpSpacerItem(this, 10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding),
            0, 1);
    lineLayoutPolicy->addItemAtPosition(toggleButton, 0, 2);

    // graySeparator
    DuiSeparator *graySeparator = new DuiSeparator(this);
    graySeparator->setObjectName("GraySeparator");

    // add items to mainLayoutPolicy
    mainLayoutPolicy->addItemAtPosition(
            new DcpSpacerItem(this, 5, 5, QSizePolicy::Fixed, QSizePolicy::Expanding),
            0, Qt::AlignCenter);
    mainLayoutPolicy->addItemAtPosition(lineLayout, 1, Qt::AlignCenter);
    mainLayoutPolicy->addItemAtPosition(
            new DcpSpacerItem(this, 5, 5, QSizePolicy::Fixed, QSizePolicy::Expanding),
            2, Qt::AlignCenter);
    mainLayoutPolicy->addItemAtPosition(graySeparator, 3, Qt::AlignCenter);

    // set fixed height
    this->setMinimumHeight(height);
    this->setMaximumHeight(height);

    connect(DuiSceneManager::instance(), SIGNAL(orientationChanged(const Dui::Orientation &)),
            this, SLOT(onOrientationChanged()));
    onOrientationChanged();
}

void UpdateButton::onOrientationChanged()
{
    switch (DuiSceneManager::instance()->orientation()) {
        case Dui::Landscape:
            this->setMinimumWidth(DuiSceneManager::instance()->visibleSceneRect().width() - 30);
            this->setMaximumWidth(DuiSceneManager::instance()->visibleSceneRect().width() - 30);
            break;
        case Dui::Portrait:
            this->setMinimumWidth(DuiSceneManager::instance()->visibleSceneRect().width() / 2 - 30);
            this->setMaximumWidth(DuiSceneManager::instance()->visibleSceneRect().width() / 2 - 30);
            break;
        default:
            break;
    }
}
<commit_msg>Changed: updatebutton in DateTimeApplet.<commit_after>#include "updatebutton.h"
#include "dcpspaceritem.h"
#include "datetimetranslation.h"

#include <duilayout.h>
#include <duilinearlayoutpolicy.h>
#include <duigridlayoutpolicy.h>
#include <duilabel.h>
#include <duibutton.h>
#include <duiseparator.h>
#include <duiscenemanager.h>

int height = 88;

UpdateButton::UpdateButton(DuiWidget *parent)
             :DuiWidget(parent)
{
    initWidget();
}

UpdateButton::~UpdateButton()
{
}

void UpdateButton::paint(QPainter *painter,
                         const QStyleOptionGraphicsItem *option,
                         QWidget *widget)
{
    Q_UNUSED(painter);
    Q_UNUSED(option);
    Q_UNUSED(widget);
}

void UpdateButton::initWidget()
{
    // mainLayout
    DuiLayout *mainLayout = new DuiLayout(this);
    mainLayout->setAnimator(0);
    mainLayout->setContentsMargins(0.0, 0.0, 0.0, 0.0);
    this->setLayout(mainLayout);
    DuiLinearLayoutPolicy *mainLayoutPolicy =
        new DuiLinearLayoutPolicy(mainLayout, Qt::Vertical);
    mainLayout->setPolicy(mainLayoutPolicy);
    mainLayoutPolicy->setSpacing(5);

    // lineLayout
    DuiLayout *lineLayout = new DuiLayout(0);
    lineLayout->setAnimator(0);
    lineLayout->setContentsMargins(20.0, 0.0, 20.0, 0.0);
    DuiGridLayoutPolicy *lineLayoutPolicy = new DuiGridLayoutPolicy(lineLayout);
    lineLayout->setPolicy(lineLayoutPolicy);
    lineLayoutPolicy->setSpacing(3);

    // automaticLabel
    DuiLabel *automaticLabel = new DuiLabel(DcpDateTime::AutomaticUpdateText, this);
    automaticLabel->setObjectName("AutomaticLabel");
    automaticLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    automaticLabel->setAcceptedMouseButtons(0);
    automaticLabel->setMinimumWidth(
            DuiSceneManager::instance()->visibleSceneRect().width() - 130);

    // toggleButton
    DuiButton *toggleButton = new DuiButton(this);
    toggleButton->setObjectName("ToggleButton");
    toggleButton->setMinimumSize(QSize(48, 48));
    toggleButton->setMaximumSize(QSize(48, 48));
    toggleButton->setCheckable(true);
    toggleButton->setTextVisible(false);

    // add items to lineLayoutPolicy
    lineLayoutPolicy->addItemAtPosition(automaticLabel, 0, 0);
    lineLayoutPolicy->addItemAtPosition(
            new DcpSpacerItem(this, 10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding),
            0, 1);
    lineLayoutPolicy->addItemAtPosition(toggleButton, 0, 2);

    // graySeparator
    DuiSeparator *graySeparator = new DuiSeparator(this);
    graySeparator->setObjectName("GraySeparator");

    // add items to mainLayoutPolicy
    mainLayoutPolicy->addItemAtPosition(
            new DcpSpacerItem(this, 5, 5, QSizePolicy::Fixed, QSizePolicy::Expanding),
            0, Qt::AlignCenter);
    mainLayoutPolicy->addItemAtPosition(lineLayout, 1, Qt::AlignCenter);
    mainLayoutPolicy->addItemAtPosition(
            new DcpSpacerItem(this, 5, 5, QSizePolicy::Fixed, QSizePolicy::Expanding),
            2, Qt::AlignCenter);
    mainLayoutPolicy->addItemAtPosition(graySeparator, 3, Qt::AlignCenter);

    // set fixed height
    this->setMinimumHeight(height);
    this->setMaximumHeight(height);

    connect(DuiSceneManager::instance(), SIGNAL(orientationChanged(const Dui::Orientation &)),
            this, SLOT(onOrientationChanged()));
    onOrientationChanged();
}

void UpdateButton::onOrientationChanged()
{
    switch (DuiSceneManager::instance()->orientation()) {
        case Dui::Landscape:
            this->setMinimumWidth(DuiSceneManager::instance()->visibleSceneRect().width() - 30);
            this->setMaximumWidth(DuiSceneManager::instance()->visibleSceneRect().width() - 30);
            break;
        case Dui::Portrait:
            this->setMinimumWidth(DuiSceneManager::instance()->visibleSceneRect().width() / 2 - 30);
            this->setMaximumWidth(DuiSceneManager::instance()->visibleSceneRect().width() / 2 - 30);
            break;
        default:
            break;
    }
}
<|endoftext|>


<commit_before>/*
    This file is part of libakonadi.

    Copyright (c) 2006 Till Adam <adam@kde.org>

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

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

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

#include <QtCore/QCoreApplication>
#include <QtCore/QTimer>

#include "resourcebase.h"
#include "resourceadaptor.h"

#include "tracerinterface.h"

using namespace PIM;

class ResourceBase::Private
{
  public:
    Private()
      : mStatusCode( Ready ),
        mProgress( 0 )
    {
      mStatusMessage = defaultReadyMessage();
    }

    QString defaultReadyMessage() const;
    QString defaultSyncingMessage() const;
    QString defaultErrorMessage() const;

    org::kde::Akonadi::Tracer *mTracer;
    QString mId;

    int mStatusCode;
    QString mStatusMessage;

    uint mProgress;
    QString mProgressMessage;
};

QString ResourceBase::Private::defaultReadyMessage() const
{
  return tr( "Ready" );
}

QString ResourceBase::Private::defaultSyncingMessage() const
{
  return tr( "Syncing..." );
}

QString ResourceBase::Private::defaultErrorMessage() const
{
  return tr( "Error!" );
}

ResourceBase::ResourceBase( const QString & id )
  : d( new Private )
{
  d->mTracer = new org::kde::Akonadi::Tracer( "org.kde.Akonadi", "/tracing", QDBusConnection::sessionBus(), this );

  if ( !QDBusConnection::sessionBus().registerService( "org.kde.Akonadi.Resource." + id ) )
    error( QString( "Unable to register service at dbus: %1" ).arg( QDBusConnection::sessionBus().lastError().message() ) );

  new ResourceAdaptor( this );
  if ( !QDBusConnection::sessionBus().registerObject( "/", this, QDBusConnection::ExportAdaptors ) )
    error( QString( "Unable to register object at dbus: %1" ).arg( QDBusConnection::sessionBus().lastError().message() ) );

  d->mId = id;
}

ResourceBase::~ResourceBase()
{
  delete d;
}

int ResourceBase::status() const
{
  return d->mStatusCode;
}

QString ResourceBase::statusMessage() const
{
  return d->mStatusMessage;
}

uint ResourceBase::progress() const
{
  return d->mProgress;
}

QString ResourceBase::progressMessage() const
{
  return d->mProgressMessage;
}

void ResourceBase::warning( const QString& message )
{
  d->mTracer->warning( QString( "ResourceBase(%1)" ).arg( d->mId ), message );
}

void ResourceBase::error( const QString& message )
{
  d->mTracer->error( QString( "ResourceBase(%1)" ).arg( d->mId ), message );
}

void ResourceBase::changeStatus( Status status, const QString &message )
{
  d->mStatusMessage = message;
  d->mStatusCode = 0;

  switch ( status ) {
    case Ready:
      if ( d->mStatusMessage.isEmpty() )
        d->mStatusMessage = d->defaultReadyMessage();

      d->mStatusCode = 0;
      break;
    case Syncing:
      if ( d->mStatusMessage.isEmpty() )
        d->mStatusMessage = d->defaultSyncingMessage();

      d->mStatusCode = 1;
      break;
    case Error:
      if ( d->mStatusMessage.isEmpty() )
        d->mStatusMessage = d->defaultErrorMessage();

      d->mStatusCode = 2;
      break;
    default:
      Q_ASSERT( !"Unknown status passed" );
      break;
  }

  emit statusChanged( d->mStatusCode, d->mStatusMessage );
}

void ResourceBase::changeProgress( uint progress, const QString &message )
{
  d->mProgress = progress;
  d->mProgressMessage = message;

  emit progressChanged( d->mProgress, d->mProgressMessage );
}

void ResourceBase::configure()
{
  emit configurationChanged( QString() );
}

bool ResourceBase::setConfiguration( const QString &data )
{
  // TODO: add template method
  emit configurationChanged( data );

  return true;
}

QString ResourceBase::configuration() const
{
  return QString();
}

void ResourceBase::synchronize()
{
}

QString ResourceBase::parseArguments( int argc, char **argv )
{
  if ( argc < 3 ) {
    qDebug( "ResourceBase::parseArguments: Not enough arguments passed..." );
    QCoreApplication::exit( 1 );
  }

  QString identifier;
  for ( int i = 1; i < argc - 1; ++i ) {
    if ( QString( argv[ i ] ) == "--identifier" )
      identifier = QString( argv[ i + 1 ] );
  }

  if ( identifier.isEmpty() ) {
    qDebug( "ResourceBase::parseArguments: Identifier argument missing" );
    QCoreApplication::exit( 1 );
  }

  return identifier;
}

void ResourceBase::quit()
{
  aboutToQuit();

  QTimer::singleShot( 0, QCoreApplication::instance(), SLOT( quit() ) );
}

void ResourceBase::aboutToQuit()
{
  qDebug( "about to quit called" );
}

QString PIM::ResourceBase::identifier() const
{
  return d->mId;
}

<commit_msg>Use 'exit(3)' instead of QApplication::exit(), because the latter has no effect if QApplication::exec() isn't called yet ;) Furthermore disabling the CloseOnLastWindowQuit to not terminate the resource if the config dialog is closed...<commit_after>/*
    This file is part of libakonadi.

    Copyright (c) 2006 Till Adam <adam@kde.org>

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

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

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

#include <QtCore/QTimer>
#include <QtGui/QApplication>

#include <stdlib.h>

#include "resourcebase.h"
#include "resourceadaptor.h"

#include "tracerinterface.h"

using namespace PIM;

class ResourceBase::Private
{
  public:
    Private()
      : mStatusCode( Ready ),
        mProgress( 0 )
    {
      mStatusMessage = defaultReadyMessage();
    }

    QString defaultReadyMessage() const;
    QString defaultSyncingMessage() const;
    QString defaultErrorMessage() const;

    org::kde::Akonadi::Tracer *mTracer;
    QString mId;

    int mStatusCode;
    QString mStatusMessage;

    uint mProgress;
    QString mProgressMessage;
};

QString ResourceBase::Private::defaultReadyMessage() const
{
  return tr( "Ready" );
}

QString ResourceBase::Private::defaultSyncingMessage() const
{
  return tr( "Syncing..." );
}

QString ResourceBase::Private::defaultErrorMessage() const
{
  return tr( "Error!" );
}

ResourceBase::ResourceBase( const QString & id )
  : d( new Private )
{
  d->mTracer = new org::kde::Akonadi::Tracer( "org.kde.Akonadi", "/tracing", QDBusConnection::sessionBus(), this );

  if ( !QDBusConnection::sessionBus().registerService( "org.kde.Akonadi.Resource." + id ) )
    error( QString( "Unable to register service at dbus: %1" ).arg( QDBusConnection::sessionBus().lastError().message() ) );

  new ResourceAdaptor( this );
  if ( !QDBusConnection::sessionBus().registerObject( "/", this, QDBusConnection::ExportAdaptors ) )
    error( QString( "Unable to register object at dbus: %1" ).arg( QDBusConnection::sessionBus().lastError().message() ) );

  d->mId = id;
}

ResourceBase::~ResourceBase()
{
  delete d;
}

int ResourceBase::status() const
{
  return d->mStatusCode;
}

QString ResourceBase::statusMessage() const
{
  return d->mStatusMessage;
}

uint ResourceBase::progress() const
{
  return d->mProgress;
}

QString ResourceBase::progressMessage() const
{
  return d->mProgressMessage;
}

void ResourceBase::warning( const QString& message )
{
  d->mTracer->warning( QString( "ResourceBase(%1)" ).arg( d->mId ), message );
}

void ResourceBase::error( const QString& message )
{
  d->mTracer->error( QString( "ResourceBase(%1)" ).arg( d->mId ), message );
}

void ResourceBase::changeStatus( Status status, const QString &message )
{
  d->mStatusMessage = message;
  d->mStatusCode = 0;

  switch ( status ) {
    case Ready:
      if ( d->mStatusMessage.isEmpty() )
        d->mStatusMessage = d->defaultReadyMessage();

      d->mStatusCode = 0;
      break;
    case Syncing:
      if ( d->mStatusMessage.isEmpty() )
        d->mStatusMessage = d->defaultSyncingMessage();

      d->mStatusCode = 1;
      break;
    case Error:
      if ( d->mStatusMessage.isEmpty() )
        d->mStatusMessage = d->defaultErrorMessage();

      d->mStatusCode = 2;
      break;
    default:
      Q_ASSERT( !"Unknown status passed" );
      break;
  }

  emit statusChanged( d->mStatusCode, d->mStatusMessage );
}

void ResourceBase::changeProgress( uint progress, const QString &message )
{
  d->mProgress = progress;
  d->mProgressMessage = message;

  emit progressChanged( d->mProgress, d->mProgressMessage );
}

void ResourceBase::configure()
{
  emit configurationChanged( QString() );
}

bool ResourceBase::setConfiguration( const QString &data )
{
  // TODO: add template method
  emit configurationChanged( data );

  return true;
}

QString ResourceBase::configuration() const
{
  return QString();
}

void ResourceBase::synchronize()
{
}

QString ResourceBase::parseArguments( int argc, char **argv )
{
  if ( argc < 3 ) {
    qDebug( "ResourceBase::parseArguments: Not enough arguments passed..." );
    exit( 1 );
  }

  QString identifier;
  for ( int i = 1; i < argc - 1; ++i ) {
    if ( QString( argv[ i ] ) == "--identifier" )
      identifier = QString( argv[ i + 1 ] );
  }

  if ( identifier.isEmpty() ) {
    qDebug( "ResourceBase::parseArguments: Identifier argument missing" );
    exit( 1 );
  }

  QApplication::setQuitOnLastWindowClosed( false );

  return identifier;
}

void ResourceBase::quit()
{
  aboutToQuit();

  QTimer::singleShot( 0, QCoreApplication::instance(), SLOT( quit() ) );
}

void ResourceBase::aboutToQuit()
{
  qDebug( "about to quit called" );
}

QString PIM::ResourceBase::identifier() const
{
  return d->mId;
}

<|endoftext|>


<commit_before>/*
 * This file is part of the Yildiz-Engine project, licenced under the MIT License  (MIT)
 *
 * Copyright (c) 2017 Grégory Van den Borre
 *
 * More infos available: https://www.yildiz-games.be
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without
 * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
 * OR COPYRIGHT  HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  SOFTWARE.
 */

/**
*@author Grégory Van den Borre
*/

#include "../includes/Root.hpp"
#include <physfs.h>
#include "../includes/PhysFS++.h"
#include "../includes/PhysFSOgre.h"

yz::Root* yz::Root::instance = NULL;

yz::Root::Root() {
    LOG_FUNCTION
    this->root = OGRE_NEW Ogre::Root("", "", "ogre.log");
    this->os = OGRE_NEW Ogre::OverlaySystem();
}

yz::Root::~Root() {
    LOG_FUNCTION
    OGRE_DELETE this->os;
    OGRE_DELETE this->root;
}

void yz::Root::initPhysFS() {
    LOG_FUNCTION
    PhysFS::init("");
    PhysFS::registerPhysFSToOgre();
}

void yz::Root::loadPlugin(const std::string& name) {
    LOG_FUNCTION
    //FIXME use enumeration instead of Strings.
    this->root->loadPlugin(name);
}

void yz::Root::initialise(const std::string& renderer) {
    LOG_FUNCTION
    //FIXME use enumeration instead of strings
    if(!this->initialized) {
        this->root->loadPlugin(renderer);
        Ogre::RenderSystem* rs = this->root->getAvailableRenderers().front();
        this->root->setRenderSystem(rs);
        this->root->initialise(false);
        this->initialized = true;
    }
}

yz::SceneManager* yz::Root::createSceneManager(const std::string& name) {
    LOG_FUNCTION
    Ogre::SceneManager* sm = this->root->createSceneManager(Ogre::ST_GENERIC, name);
    sm->addRenderQueueListener(this->os);
    return new yz::SceneManager(sm);
}

void yz::Root::createRenderWindow(const Ogre::Real width, const Ogre::Real height, const long handle) {
    LOG_FUNCTION
    Ogre::NameValuePairList params;
    params["externalWindowHandle"] = Ogre::StringConverter::toString((unsigned int) (handle));
    params["FSAA"] = Ogre::String("4");
    params["vsync"] = Ogre::String("true");
    Ogre::RenderWindow* rw = this->root->createRenderWindow("default", width, height, false, &params);
    yz::RenderWindow::create(rw);
}

void yz::Root::createRenderWindow(const Ogre::Real width, const Ogre::Real height) {
    LOG_FUNCTION
    Ogre::NameValuePairList params;
    params["currentGLContext"] = Ogre::String("true");
    Ogre::RenderWindow* rw = this->root->createRenderWindow("default", width, height, false, &params);
    yz::RenderWindow::create(rw);
}

void yz::Root::close() {
    LOG_FUNCTION
    this->root->shutdown();
    this->initialized = false;
}

void yz::Root::addResourcePath(const std::string& name, const std::string& path, const int type) {
    LOG_FUNCTION
    switch (type) {
        case 0:
            this->root->addResourceLocation(path, "FileSystem", name, false);
            break;
        case 1:
            this->root->addResourceLocation(path, "Zip", name, false);
            break;
        case 2:
            PhysFS::addToSearchPath(path);
            this->root->addResourceLocation("", "Package", name, false);
            break;
        case 3:
            this->root->addResourceLocation(path, "FileSystem", name, false);
            break;
        default:
            throw std::exception();
            break;
    }
    Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup(name);
}
<commit_msg>[NO-JIRA] Log the version in native code.<commit_after>/*
 * This file is part of the Yildiz-Engine project, licenced under the MIT License  (MIT)
 *
 * Copyright (c) 2017 Grégory Van den Borre
 *
 * More infos available: https://www.yildiz-games.be
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without
 * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
 * OR COPYRIGHT  HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  SOFTWARE.
 */

/**
*@author Grégory Van den Borre
*/

#include "../includes/Root.hpp"
#include <physfs.h>
#include "../includes/PhysFS++.h"
#include "../includes/PhysFSOgre.h"

yz::Root* yz::Root::instance = NULL;

yz::Root::Root() {
    LOG_FUNCTION
    this->root = OGRE_NEW Ogre::Root("", "", "ogre.log");
    this->os = OGRE_NEW Ogre::OverlaySystem();
    Ogre::LogManager::getSingleton().logMessage("Initializing Ogre native version 1.1.6");
}

yz::Root::~Root() {
    LOG_FUNCTION
    OGRE_DELETE this->os;
    OGRE_DELETE this->root;
}

void yz::Root::initPhysFS() {
    LOG_FUNCTION
    PhysFS::init("");
    PhysFS::registerPhysFSToOgre();
}

void yz::Root::loadPlugin(const std::string& name) {
    LOG_FUNCTION
    //FIXME use enumeration instead of Strings.
    this->root->loadPlugin(name);
}

void yz::Root::initialise(const std::string& renderer) {
    LOG_FUNCTION
    //FIXME use enumeration instead of strings
    if(!this->initialized) {
        this->root->loadPlugin(renderer);
        Ogre::RenderSystem* rs = this->root->getAvailableRenderers().front();
        this->root->setRenderSystem(rs);
        this->root->initialise(false);
        this->initialized = true;
    }
}

yz::SceneManager* yz::Root::createSceneManager(const std::string& name) {
    LOG_FUNCTION
    Ogre::SceneManager* sm = this->root->createSceneManager(Ogre::ST_GENERIC, name);
    sm->addRenderQueueListener(this->os);
    return new yz::SceneManager(sm);
}

void yz::Root::createRenderWindow(const Ogre::Real width, const Ogre::Real height, const long handle) {
    LOG_FUNCTION
    Ogre::NameValuePairList params;
    params["externalWindowHandle"] = Ogre::StringConverter::toString((unsigned int) (handle));
    params["FSAA"] = Ogre::String("4");
    params["vsync"] = Ogre::String("true");
    Ogre::RenderWindow* rw = this->root->createRenderWindow("default", width, height, false, &params);
    yz::RenderWindow::create(rw);
}

void yz::Root::createRenderWindow(const Ogre::Real width, const Ogre::Real height) {
    LOG_FUNCTION
    Ogre::NameValuePairList params;
    params["currentGLContext"] = Ogre::String("true");
    Ogre::RenderWindow* rw = this->root->createRenderWindow("default", width, height, false, &params);
    yz::RenderWindow::create(rw);
}

void yz::Root::close() {
    LOG_FUNCTION
    this->root->shutdown();
    this->initialized = false;
}

void yz::Root::addResourcePath(const std::string& name, const std::string& path, const int type) {
    LOG_FUNCTION
    switch (type) {
        case 0:
            this->root->addResourceLocation(path, "FileSystem", name, false);
            break;
        case 1:
            this->root->addResourceLocation(path, "Zip", name, false);
            break;
        case 2:
            PhysFS::addToSearchPath(path);
            this->root->addResourceLocation("", "Package", name, false);
            break;
        case 3:
            this->root->addResourceLocation(path, "FileSystem", name, false);
            break;
        default:
            throw std::exception();
            break;
    }
    Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup(name);
}
<|endoftext|>


<commit_before>#include "messagedialog.h"

#include "qommunicate.h"
#include "messenger.h"
#include "constants.h"
#include "filehandler.h"

MessageDialog::MessageDialog(Member* receiver, QWidget *parent) : QDialog(parent)
{
    receivers << receiver;

    ui.setupUi(this);
    messageTimer = NULL;
    setWindowTitle(tr("Conversation: %1").arg(receiver->name()));
    connect(messenger(), SIGNAL(msg_recvMsg(Message)), this, SLOT(incomingMessage(Message)));
    connect(messenger(), SIGNAL(msg_recvConfirmMsg(Message)), this, SLOT(messageRecvConfirm()));

    ((Qommunicate*)parent)->dialogOpened(receiver);

}

MessageDialog::MessageDialog(QList<Member*> receivers, QWidget *parent) : QDialog(parent)
{
    this->receivers = receivers;

    ui.setupUi(this);

    QStringList titleRecvs;
    Member* t;
    foreach(t, receivers)
        titleRecvs << t->name();
    setWindowTitle(tr("Conversation: %1").arg(titleRecvs.join(",")));
}

MessageDialog::MessageDialog(QWidget *parent) : QDialog(parent)
{
    ui.setupUi(this);
    setWindowTitle(tr("Multicast message"));
}

void MessageDialog::closeEvent(QCloseEvent *evt)
{
    if(receivers.size() == 1)
        ((Qommunicate*) parent())->dialogClosed(receivers[0]);
    evt->accept();
}

void MessageDialog::incomingMessage(Message msg)
{
    ui.messageEdit->append(QString("<%1> ").arg(receivers[0]->name()));
    ui.messageEdit->append(msg.payload().replace('\a', "").trimmed());

    if(msg.command() & QOM_SENDCHECKOPT)
        messenger()->sendMessage(QOM_RECVMSG, QByteArray::number(msg.packetNo()), receivers[0]);
}

void MessageDialog::on_sendButton_clicked()
{
    if(ui.messageInput->text().trimmed().isEmpty())
        return;

    if(receivers.isEmpty())
    {
        messenger()->multicast(QOM_SENDMSG|QOM_BROADCASTOPT, ui.messageInput->text().toAscii());
        QTimer::singleShot(500, this, SLOT(accept()));
        return;
    }

    foreach(Member* m, receivers)
    {
        messenger()->sendMessage(
            QOM_SENDMSG|QOM_SENDCHECKOPT |
            ( ui.notifyReadCB->isChecked() ? QOM_SECRETOPT | QOM_READCHECKOPT : 0 ),
            //( ui.sealCB->isChecked() ? QOM_SECRETOPT : 0 ) ,
            ui.messageInput->text().toAscii(), m);
    }
    if(receivers.size() == 1)
    {
        if(messageTimer != NULL)
            delete messageTimer;
        messageTimer = new QTimer(this);
        messageTimer->setSingleShot(true);
        connect(messageTimer, SIGNAL(timeout()), this, SLOT(messageTimeout()));

        ui.messageInput->setEnabled(false);
        messageTimer->start(5000);
    }
    else
    {
        messageRecvConfirm();
        QTimer::singleShot(500, this, SLOT(accept()));
    }

}

void MessageDialog::messageTimeout()
{
    if(QMessageBox::warning(this,
            tr("Sending Failed"),
            tr("Failed to send message. To retry click Ok"),
            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok)
    {
        on_sendButton_clicked();
    }
    else
        ui.messageInput->setEnabled(true);
}

void MessageDialog::messageRecvConfirm()
{
    if(! ui.messageInput->text().trimmed().isEmpty())
        ui.messageEdit->append(QString("<%1> %2").arg(me().name()).arg(ui.messageInput->text()));

    ui.messageInput->clear();
    ui.messageInput->setFocus();
    ui.messageInput->setEnabled(true);

    if(receivers.size() == 1 && messageTimer != NULL)
        messageTimer->stop();
}

void MessageDialog::dropEvent(QDropEvent *evt)
{
    QStringList files;
    foreach(QUrl url, evt->mimeData()->urls())
    {
        files << url.toLocalFile();
    }

    foreach(Member* to, receivers)
    {
        fileHandler()->sendFilesRequest(files, to, ui.messageInput->text());
    }
}
<commit_msg>Fixed problem of new paragraph being inserted when appending<commit_after>#include "messagedialog.h"

#include "qommunicate.h"
#include "messenger.h"
#include "constants.h"
#include "filehandler.h"

MessageDialog::MessageDialog(Member* receiver, QWidget *parent) : QDialog(parent)
{
    receivers << receiver;

    ui.setupUi(this);
    messageTimer = NULL;
    setWindowTitle(tr("Conversation: %1").arg(receiver->name()));
    connect(messenger(), SIGNAL(msg_recvMsg(Message)), this, SLOT(incomingMessage(Message)));
    connect(messenger(), SIGNAL(msg_recvConfirmMsg(Message)), this, SLOT(messageRecvConfirm()));

    ((Qommunicate*)parent)->dialogOpened(receiver);

}

MessageDialog::MessageDialog(QList<Member*> receivers, QWidget *parent) : QDialog(parent)
{
    this->receivers = receivers;

    ui.setupUi(this);

    QStringList titleRecvs;
    Member* t;
    foreach(t, receivers)
        titleRecvs << t->name();
    setWindowTitle(tr("Conversation: %1").arg(titleRecvs.join(",")));
}

MessageDialog::MessageDialog(QWidget *parent) : QDialog(parent)
{
    ui.setupUi(this);
    setWindowTitle(tr("Multicast message"));
}

void MessageDialog::closeEvent(QCloseEvent *evt)
{
    if(receivers.size() == 1)
        ((Qommunicate*) parent())->dialogClosed(receivers[0]);
    evt->accept();
}

void MessageDialog::incomingMessage(Message msg)
{
    QString text = QString("<%1> ").arg(receivers[0]->name());
    text += msg.payload().replace('\a', "").trimmed();
    ui.messageEdit->append(text);

    if(msg.command() & QOM_SENDCHECKOPT)
        messenger()->sendMessage(QOM_RECVMSG, QByteArray::number(msg.packetNo()), receivers[0]);
}

void MessageDialog::on_sendButton_clicked()
{
    if(ui.messageInput->text().trimmed().isEmpty())
        return;

    if(receivers.isEmpty())
    {
        messenger()->multicast(QOM_SENDMSG|QOM_BROADCASTOPT, ui.messageInput->text().toAscii());
        QTimer::singleShot(500, this, SLOT(accept()));
        return;
    }

    foreach(Member* m, receivers)
    {
        messenger()->sendMessage(
            QOM_SENDMSG|QOM_SENDCHECKOPT |
            ( ui.notifyReadCB->isChecked() ? QOM_SECRETOPT | QOM_READCHECKOPT : 0 ),
            //( ui.sealCB->isChecked() ? QOM_SECRETOPT : 0 ) ,
            ui.messageInput->text().toAscii(), m);
    }
    if(receivers.size() == 1)
    {
        if(messageTimer != NULL)
            delete messageTimer;
        messageTimer = new QTimer(this);
        messageTimer->setSingleShot(true);
        connect(messageTimer, SIGNAL(timeout()), this, SLOT(messageTimeout()));

        ui.messageInput->setEnabled(false);
        messageTimer->start(5000);
    }
    else
    {
        messageRecvConfirm();
        QTimer::singleShot(500, this, SLOT(accept()));
    }

}

void MessageDialog::messageTimeout()
{
    if(QMessageBox::warning(this,
            tr("Sending Failed"),
            tr("Failed to send message. To retry click Ok"),
            QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok)
    {
        on_sendButton_clicked();
    }
    else
        ui.messageInput->setEnabled(true);
}

void MessageDialog::messageRecvConfirm()
{
    if(! ui.messageInput->text().trimmed().isEmpty())
        ui.messageEdit->append(QString("<%1> %2").arg(me().name()).arg(ui.messageInput->text()));

    ui.messageInput->clear();
    ui.messageInput->setFocus();
    ui.messageInput->setEnabled(true);

    if(receivers.size() == 1 && messageTimer != NULL)
        messageTimer->stop();
}

void MessageDialog::dropEvent(QDropEvent *evt)
{
    QStringList files;
    foreach(QUrl url, evt->mimeData()->urls())
    {
        files << url.toLocalFile();
    }

    foreach(Member* to, receivers)
    {
        fileHandler()->sendFilesRequest(files, to, ui.messageInput->text());
    }
}
<|endoftext|>


<commit_before>/**
Copyright (c) 2016, Ubiquity Robotics
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of ubiquity_motor nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN AiiiiiiiiiiiNY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include <boost/assign.hpp>
#include <ubiquity_motor/motor_hardware.h>
#include <ubiquity_motor/motor_message.h>

#include <boost/math/special_functions/round.hpp>

//#define SENSOR_DISTANCE 0.002478

// 60 tics per revolution of the motor (pre gearbox)
//17.2328767123
// gear ratio of 4.29411764706:1
#define TICS_PER_RADIAN (41.0058030317/2)
#define SECONDS_PER_VELOCITY_READ 10.0 //read = ticks / (100 ms), so we have scale of 10 for ticks/second
#define CURRENT_FIRMWARE_VERSION 18

MotorHardware::MotorHardware(ros::NodeHandle nh){
	ros::V_string joint_names = boost::assign::list_of("left_wheel_joint")("right_wheel_joint");

	for (unsigned int i = 0; i < joint_names.size(); i++) {
		hardware_interface::JointStateHandle joint_state_handle(joint_names[i],
		    &joints_[i].position, &joints_[i].velocity, &joints_[i].effort);
		joint_state_interface_.registerHandle(joint_state_handle);

		hardware_interface::JointHandle joint_handle(
		    joint_state_handle, &joints_[i].velocity_command);
		velocity_joint_interface_.registerHandle(joint_handle);
	}
	registerInterface(&joint_state_interface_);
	registerInterface(&velocity_joint_interface_);

	std::string sPort;
	int sBaud;

	double sLoopRate;

	if (!nh.getParam("ubiquity_motor/serial_port", sPort))
	{
		sPort.assign("/dev/ttyS0");
		nh.setParam("ubiquity_motor/serial_port", sPort);
	}

	if (!nh.getParam("ubiquity_motor/serial_baud", sBaud))
	{
		sBaud = 9600;
		nh.setParam("ubiquity_motor/serial_baud", sBaud);
	}

	if (!nh.getParam("ubiquity_motor/serial_loop_rate", sLoopRate))
	{
		sLoopRate = 100;
		nh.setParam("ubiquity_motor/serial_loop_rate", sLoopRate);
	}

	motor_serial_ = new MotorSerial(sPort,sBaud,sLoopRate);
}

MotorHardware::~MotorHardware(){
	delete motor_serial_;
}

void MotorHardware::readInputs(){
	while(motor_serial_->commandAvailable()){
		MotorMessage mm;
		mm = motor_serial_-> receiveCommand();
		if(mm.getType() == MotorMessage::TYPE_RESPONSE){
			switch(mm.getRegister()){
			        case MotorMessage::REG_FIRMWARE_VERSION:
						if (mm.getData() != CURRENT_FIRMWARE_VERSION) {
							ROS_FATAL("Firmware version %d, expect %d",
								mm.getData(), CURRENT_FIRMWARE_VERSION);
						}
						else {
							ROS_WARN("Firmware version %d", mm.getData());
						}
					break;
				case MotorMessage::REG_LEFT_ODOM:
				  //ROS_ERROR("TICK: %d", mm.getData());
				        joints_[0].position += mm.getData()/TICS_PER_RADIAN;
					break;
				case MotorMessage::REG_RIGHT_ODOM:
					joints_[1].position += mm.getData()/TICS_PER_RADIAN;
					break;
			        case MotorMessage::REG_LEFT_SPEED_MEASURED:
   				        joints_[0].velocity = mm.getData()*SECONDS_PER_VELOCITY_READ/TICS_PER_RADIAN;
					break;
			        case MotorMessage::REG_RIGHT_SPEED_MEASURED:
				        joints_[1].velocity = mm.getData()*SECONDS_PER_VELOCITY_READ/TICS_PER_RADIAN;
					break;
			}
		}
	}
}

void MotorHardware::writeSpeeds(){
	std::vector<MotorMessage> commands;
	//requestOdometry();
	//requestVelocity();
	//requestVersion();

	MotorMessage left_odom;
	left_odom.setRegister(MotorMessage::REG_LEFT_ODOM);
	left_odom.setType(MotorMessage::TYPE_READ);
	left_odom.setData(0);
	commands.push_back(left_odom);

	MotorMessage right_odom;
	right_odom.setRegister(MotorMessage::REG_RIGHT_ODOM);
	right_odom.setType(MotorMessage::TYPE_READ);
	right_odom.setData(0);
	commands.push_back(right_odom);

	MotorMessage left_vel;
	left_vel.setRegister(MotorMessage::REG_LEFT_SPEED_MEASURED);
	left_vel.setType(MotorMessage::TYPE_READ);
	left_vel.setData(0);
	commands.push_back(left_vel);

	MotorMessage right_vel;
	right_vel.setRegister(MotorMessage::REG_RIGHT_SPEED_MEASURED);
	right_vel.setType(MotorMessage::TYPE_READ);
	right_vel.setData(0);
	commands.push_back(right_vel);

	MotorMessage left;
	left.setRegister(MotorMessage::REG_LEFT_SPEED_SET);
	left.setType(MotorMessage::TYPE_WRITE);
	left.setData(boost::math::lround(joints_[0].velocity_command*TICS_PER_RADIAN/SECONDS_PER_VELOCITY_READ));
	commands.push_back(left);

	MotorMessage right;
	right.setRegister(MotorMessage::REG_RIGHT_SPEED_SET);
	right.setType(MotorMessage::TYPE_WRITE);
	right.setData(boost::math::lround(joints_[1].velocity_command*TICS_PER_RADIAN/SECONDS_PER_VELOCITY_READ));
	commands.push_back(right);

	//Send all commands to serial thread in one go to reduce locking
	motor_serial_->transmitCommands(commands);

	//ROS_ERROR("velocity_command %f rad/s %f rad/s", joints_[0].velocity_command, joints_[1].velocity_command);
	// ROS_ERROR("SPEEDS %d %d", left.getData(), right.getData());
}

void MotorHardware::requestVersion(){
    MotorMessage version;
	version.setRegister(MotorMessage::REG_FIRMWARE_VERSION);
	version.setType(MotorMessage::TYPE_READ);
	version.setData(0);
	motor_serial_->transmitCommand(version);

}

void MotorHardware::requestOdometry(){
	//ROS_ERROR("TICKR");
	std::vector<MotorMessage> commands;

	MotorMessage left_odom;
	left_odom.setRegister(MotorMessage::REG_LEFT_ODOM);
	left_odom.setType(MotorMessage::TYPE_READ);
	left_odom.setData(0);
	commands.push_back(left_odom);

	MotorMessage right_odom;
	right_odom.setRegister(MotorMessage::REG_RIGHT_ODOM);
	right_odom.setType(MotorMessage::TYPE_READ);
	right_odom.setData(0);
	commands.push_back(right_odom);

	motor_serial_->transmitCommands(commands);
}

void MotorHardware::requestVelocity(){
	std::vector<MotorMessage> commands;

	MotorMessage left_vel;
	left_vel.setRegister(MotorMessage::REG_LEFT_SPEED_MEASURED);
	left_vel.setType(MotorMessage::TYPE_READ);
	left_vel.setData(0);
	commands.push_back(left_vel);

	MotorMessage right_vel;
	right_vel.setRegister(MotorMessage::REG_RIGHT_SPEED_MEASURED);
	right_vel.setType(MotorMessage::TYPE_READ);
	right_vel.setData(0);
	commands.push_back(right_vel);

	motor_serial_->transmitCommands(commands);
}

void MotorHardware::setPid(int32_t p_set, int32_t i_set, int32_t d_set, int32_t denominator_set){
        p_value = p_set;
        i_value = i_set;
        d_value = d_set;
        denominator_value = denominator_set;
}

void MotorHardware::sendPid() {
	std::vector<MotorMessage> commands;

	MotorMessage p;
	p.setRegister(MotorMessage::REG_PARAM_P);
	p.setType(MotorMessage::TYPE_WRITE);
	p.setData(p_value);
	commands.push_back(p);

	MotorMessage i;
	i.setRegister(MotorMessage::REG_PARAM_I);
	i.setType(MotorMessage::TYPE_WRITE);
	i.setData(i_value);
	commands.push_back(i);

	MotorMessage d;
	d.setRegister(MotorMessage::REG_PARAM_D);
	d.setType(MotorMessage::TYPE_WRITE);
	d.setData(d_value);
	commands.push_back(d);

	MotorMessage denominator;
	denominator.setRegister(MotorMessage::REG_PARAM_C);
	denominator.setType(MotorMessage::TYPE_WRITE);
	denominator.setData(denominator_value);
	commands.push_back(denominator);

	motor_serial_->transmitCommands(commands);
}
<commit_msg>cleanup some formating<commit_after>/**
Copyright (c) 2016, Ubiquity Robotics
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of ubiquity_motor nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN AiiiiiiiiiiiNY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include <boost/assign.hpp>
#include <ubiquity_motor/motor_hardware.h>
#include <ubiquity_motor/motor_message.h>

#include <boost/math/special_functions/round.hpp>

//#define SENSOR_DISTANCE 0.002478

// 60 tics per revolution of the motor (pre gearbox)
//17.2328767123
// gear ratio of 4.29411764706:1
#define TICS_PER_RADIAN (41.0058030317/2)
#define SECONDS_PER_VELOCITY_READ 10.0 //read = ticks / (100 ms), so we have scale of 10 for ticks/second
#define CURRENT_FIRMWARE_VERSION 18

MotorHardware::MotorHardware(ros::NodeHandle nh){
	ros::V_string joint_names = boost::assign::list_of("left_wheel_joint")("right_wheel_joint");

	for (unsigned int i = 0; i < joint_names.size(); i++) {
		hardware_interface::JointStateHandle joint_state_handle(joint_names[i],
		    &joints_[i].position, &joints_[i].velocity, &joints_[i].effort);
		joint_state_interface_.registerHandle(joint_state_handle);

		hardware_interface::JointHandle joint_handle(
		joint_state_handle, &joints_[i].velocity_command);
		velocity_joint_interface_.registerHandle(joint_handle);
	}
	registerInterface(&joint_state_interface_);
	registerInterface(&velocity_joint_interface_);

	std::string sPort;
	int sBaud;

	double sLoopRate;

	if (!nh.getParam("ubiquity_motor/serial_port", sPort))
	{
		sPort.assign("/dev/ttyS0");
		nh.setParam("ubiquity_motor/serial_port", sPort);
	}

	if (!nh.getParam("ubiquity_motor/serial_baud", sBaud))
	{
		sBaud = 9600;
		nh.setParam("ubiquity_motor/serial_baud", sBaud);
	}

	if (!nh.getParam("ubiquity_motor/serial_loop_rate", sLoopRate))
	{
		sLoopRate = 100;
		nh.setParam("ubiquity_motor/serial_loop_rate", sLoopRate);
	}

	motor_serial_ = new MotorSerial(sPort,sBaud,sLoopRate);
}

MotorHardware::~MotorHardware(){
	delete motor_serial_;
}

void MotorHardware::readInputs(){
	while(motor_serial_->commandAvailable()){
		MotorMessage mm;
		mm = motor_serial_-> receiveCommand();
		if(mm.getType() == MotorMessage::TYPE_RESPONSE){
			switch(mm.getRegister()){
				case MotorMessage::REG_FIRMWARE_VERSION:
					if (mm.getData() != CURRENT_FIRMWARE_VERSION) {
						ROS_FATAL("Firmware version %d, expect %d",
							mm.getData(), CURRENT_FIRMWARE_VERSION);
					}
					else {
						ROS_INFO("Firmware version %d", mm.getData());
					}
					break;
				case MotorMessage::REG_LEFT_ODOM:
					joints_[0].position += mm.getData()/TICS_PER_RADIAN;
					break;
				case MotorMessage::REG_RIGHT_ODOM:
					joints_[1].position += mm.getData()/TICS_PER_RADIAN;
					break;
				case MotorMessage::REG_LEFT_SPEED_MEASURED:
					joints_[0].velocity = mm.getData()*SECONDS_PER_VELOCITY_READ/TICS_PER_RADIAN;
					break;
				case MotorMessage::REG_RIGHT_SPEED_MEASURED:
					joints_[1].velocity = mm.getData()*SECONDS_PER_VELOCITY_READ/TICS_PER_RADIAN;
					break;
			}
		}
	}
}

void MotorHardware::writeSpeeds(){
	std::vector<MotorMessage> commands;
	//requestOdometry();
	//requestVelocity();
	//requestVersion();

	MotorMessage left_odom;
	left_odom.setRegister(MotorMessage::REG_LEFT_ODOM);
	left_odom.setType(MotorMessage::TYPE_READ);
	left_odom.setData(0);
	commands.push_back(left_odom);

	MotorMessage right_odom;
	right_odom.setRegister(MotorMessage::REG_RIGHT_ODOM);
	right_odom.setType(MotorMessage::TYPE_READ);
	right_odom.setData(0);
	commands.push_back(right_odom);

	MotorMessage left_vel;
	left_vel.setRegister(MotorMessage::REG_LEFT_SPEED_MEASURED);
	left_vel.setType(MotorMessage::TYPE_READ);
	left_vel.setData(0);
	commands.push_back(left_vel);

	MotorMessage right_vel;
	right_vel.setRegister(MotorMessage::REG_RIGHT_SPEED_MEASURED);
	right_vel.setType(MotorMessage::TYPE_READ);
	right_vel.setData(0);
	commands.push_back(right_vel);

	MotorMessage left;
	left.setRegister(MotorMessage::REG_LEFT_SPEED_SET);
	left.setType(MotorMessage::TYPE_WRITE);
	left.setData(boost::math::lround(joints_[0].velocity_command*TICS_PER_RADIAN/SECONDS_PER_VELOCITY_READ));
	commands.push_back(left);

	MotorMessage right;
	right.setRegister(MotorMessage::REG_RIGHT_SPEED_SET);
	right.setType(MotorMessage::TYPE_WRITE);
	right.setData(boost::math::lround(joints_[1].velocity_command*TICS_PER_RADIAN/SECONDS_PER_VELOCITY_READ));
	commands.push_back(right);

	//Send all commands to serial thread in one go to reduce locking
	motor_serial_->transmitCommands(commands);

	//ROS_ERROR("velocity_command %f rad/s %f rad/s", joints_[0].velocity_command, joints_[1].velocity_command);
	// ROS_ERROR("SPEEDS %d %d", left.getData(), right.getData());
}

void MotorHardware::requestVersion(){
    MotorMessage version;
	version.setRegister(MotorMessage::REG_FIRMWARE_VERSION);
	version.setType(MotorMessage::TYPE_READ);
	version.setData(0);
	motor_serial_->transmitCommand(version);

}

void MotorHardware::requestOdometry(){
	//ROS_ERROR("TICKR");
	std::vector<MotorMessage> commands;

	MotorMessage left_odom;
	left_odom.setRegister(MotorMessage::REG_LEFT_ODOM);
	left_odom.setType(MotorMessage::TYPE_READ);
	left_odom.setData(0);
	commands.push_back(left_odom);

	MotorMessage right_odom;
	right_odom.setRegister(MotorMessage::REG_RIGHT_ODOM);
	right_odom.setType(MotorMessage::TYPE_READ);
	right_odom.setData(0);
	commands.push_back(right_odom);

	motor_serial_->transmitCommands(commands);
}

void MotorHardware::requestVelocity(){
	std::vector<MotorMessage> commands;

	MotorMessage left_vel;
	left_vel.setRegister(MotorMessage::REG_LEFT_SPEED_MEASURED);
	left_vel.setType(MotorMessage::TYPE_READ);
	left_vel.setData(0);
	commands.push_back(left_vel);

	MotorMessage right_vel;
	right_vel.setRegister(MotorMessage::REG_RIGHT_SPEED_MEASURED);
	right_vel.setType(MotorMessage::TYPE_READ);
	right_vel.setData(0);
	commands.push_back(right_vel);

	motor_serial_->transmitCommands(commands);
}

void MotorHardware::setPid(int32_t p_set, int32_t i_set, int32_t d_set, int32_t denominator_set){
	p_value = p_set;
	i_value = i_set;
	d_value = d_set;
	denominator_value = denominator_set;
}

void MotorHardware::sendPid() {
	std::vector<MotorMessage> commands;

	MotorMessage p;
	p.setRegister(MotorMessage::REG_PARAM_P);
	p.setType(MotorMessage::TYPE_WRITE);
	p.setData(p_value);
	commands.push_back(p);

	MotorMessage i;
	i.setRegister(MotorMessage::REG_PARAM_I);
	i.setType(MotorMessage::TYPE_WRITE);
	i.setData(i_value);
	commands.push_back(i);

	MotorMessage d;
	d.setRegister(MotorMessage::REG_PARAM_D);
	d.setType(MotorMessage::TYPE_WRITE);
	d.setData(d_value);
	commands.push_back(d);

	MotorMessage denominator;
	denominator.setRegister(MotorMessage::REG_PARAM_C);
	denominator.setType(MotorMessage::TYPE_WRITE);
	denominator.setData(denominator_value);
	commands.push_back(denominator);

	motor_serial_->transmitCommands(commands);
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#endif

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <vector>
#include <string>
#include "common.h"
#include "multicast.h"
#include "ErrorHandler.h"

int			openBroadcast(int port, const char* service,
					struct sockaddr_in* addr)
{
#if defined(_WIN32)
  const BOOL optOn = TRUE;
#else
  const int optOn = 1;
#endif
  int fd;

  /* check parameters */
  if (!addr) {
    printError("openBroadcast: Must supply a return address structure!");
    return -1;
  }
  memset(addr, 0, sizeof(*addr));

  /* lookup service and check port */
  if (service) {
    struct servent *sp = getservbyname(service, "udp");
    if (!sp) {
      if (port <= 0) {
	std::vector<std::string> args;
	args.push_back(service);

	printError("openBroadcast: No udp service {1}", &args);
	return -1;
      }
    }
    else {
      port = sp->s_port;
    }
  }
  if (port <= 0) {
    std::vector<std::string> args;
    char buf[10];
    sprintf(buf,"%d", port);
    args.push_back(buf);
    printError("openBroadcast: Invalid port {1}", &args);
    return -1;
  }

  /* open socket */
  fd = socket(AF_INET, SOCK_DGRAM, 0);
  if (fd < 0) {
    nerror("openBroadcast: socket");
    return -1;
  }

  /* set address info */
  addr->sin_family = AF_INET;
  addr->sin_addr.s_addr = htonl(INADDR_ANY);

#if defined(SO_REUSEPORT)
  /* set reuse port */
  if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT,
				(SSOType)&optOn, sizeof(optOn)) < 0) {
    nerror("openBroadcast: setsockopt SO_REUSEPORT");
    close(fd);
    return -1;
  }
#elif defined(SO_REUSEADDR)
  /* set reuse address */
  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
				(SSOType)&optOn, sizeof(optOn)) < 0) {
    nerror("openBroadcast: setsockopt SO_REUSEADDR");
    close(fd);
    return -1;
  }
#endif

  /* bind address */
  if (bind(fd, (const struct sockaddr*)addr, sizeof(*addr)) < 0) {
    nerror("openBroadcast: bind");
    close(fd);
    return -1;
  }

  /* make broadcast */
  if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
				(SSOType)&optOn, sizeof(optOn)) < 0) {
    nerror("openBroadcast: setsockopt SO_BROADCAST");
    close(fd);
    return -1;
  }

  // address to send to is the broadcast address
  addr->sin_addr.s_addr = INADDR_BROADCAST;
  addr->sin_port = htons(port);

#if defined(__linux__)
  // linux doesn't seem to like INADDR_BROADCAST, but it's okay
  // with the broadcast address on the local network.  get the
  // broadcast address on the first interface that's not the
  // loopback interface.  (check the first numInterfaces
  // interfaces.)
  const int numInterfaces = 5;
  int i;
  struct ifconf conf;
  struct ifreq req[numInterfaces];

  // get the list of interface names
  conf.ifc_len = sizeof(req);
  conf.ifc_ifcu.ifcu_req = req;
  for (i = 0; i < numInterfaces; ++i)
    req[i].ifr_ifrn.ifrn_name[0] = 0;
  if (ioctl(fd, SIOCGIFCONF, &conf) < 0) {
    nerror("openBroadcast: getting interface list");
    close(fd);
    return(-1);
  }

  // get the broadcast address on each interface
  for (i = 0; i < numInterfaces; ++i) {
    // if no name then we're done
    if (req[i].ifr_ifrn.ifrn_name[0] == 0)
      break;

    // if we can't get the address then skip this interface
    if (ioctl(fd, SIOCGIFBRDADDR, req + i) < 0)
      continue;

    // if the address is the loopback broadcast address then skip it
    const sockaddr_in* ifbaddr = (const sockaddr_in*)
					&req[i].ifr_ifru.ifru_broadaddr;
    if (ntohl(ifbaddr->sin_addr.s_addr) == 0x7ffffffflu)
      continue;

    // got the broadcast address on the interface
    addr->sin_addr.s_addr = ifbaddr->sin_addr.s_addr;
    break;
  }

  // failed if no broadcast addresses found
  if (i == numInterfaces) {
    nerror("openBroadcast: getting broadcast address");
    close(fd);
    return(-1);
  }
#endif

  /* turn on non-blocking io */
  if (BzfNetwork::setNonBlocking(fd) < 0) {
    nerror("openBroadcast: setNonBlocking");
    close(fd);
    return(-1);
  }

  return fd;
}

int			closeBroadcast(int fd)
{
  if (fd == -1) return 0;
  return close(fd);
}

int			sendBroadcast(int fd, const void* buffer,
					int bufferLength,
					const struct sockaddr_in* addr)
{
  return sendto(fd, (const char*)buffer, bufferLength, 0,
				(const struct sockaddr*)addr, sizeof(*addr));
}

#if !defined(AddrLen)
#define AddrLen		int
#endif

#ifdef WIN32
/* This is a really really fugly hack to get around winsock sillyness
 * The newer versions of winsock have a socken_t typedef, and there
 * doesn't seem to be any way to tell the versions apart. However,
 * VC++ helps us out here by treating typedef as #define
 * If we've got a socklen_t typedefed, define HAVE_SOCKLEN_T to
 * avoid #define'ing it in common.h */

#ifndef socklen_t
	#define socklen_t int
#endif
#endif //WIN32

int			recvBroadcast(int fd, void* buffer, int bufferLength,
					 struct sockaddr_in* addr)
{
  struct sockaddr_in from;
  AddrLen fromLength = sizeof(from);

  int byteCount = recvfrom(fd, (char*)buffer, bufferLength, 0,
				(struct sockaddr*)&from, (socklen_t*) &fromLength);
  if (byteCount < 0) {
    if (getErrno() == EWOULDBLOCK) {
      return 0;
    }
    else {
      nerror("recvBroadcast");
      return -1;
    }
  }
  if (addr) *addr = from;
  return byteCount;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>On some system, loopback broadcast is not set<commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#endif

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <vector>
#include <string>
#include "common.h"
#include "multicast.h"
#include "ErrorHandler.h"

int			openBroadcast(int port, const char* service,
					struct sockaddr_in* addr)
{
#if defined(_WIN32)
  const BOOL optOn = TRUE;
#else
  const int optOn = 1;
#endif
  int fd;

  /* check parameters */
  if (!addr) {
    printError("openBroadcast: Must supply a return address structure!");
    return -1;
  }
  memset(addr, 0, sizeof(*addr));

  /* lookup service and check port */
  if (service) {
    struct servent *sp = getservbyname(service, "udp");
    if (!sp) {
      if (port <= 0) {
	std::vector<std::string> args;
	args.push_back(service);

	printError("openBroadcast: No udp service {1}", &args);
	return -1;
      }
    }
    else {
      port = sp->s_port;
    }
  }
  if (port <= 0) {
    std::vector<std::string> args;
    char buf[10];
    sprintf(buf,"%d", port);
    args.push_back(buf);
    printError("openBroadcast: Invalid port {1}", &args);
    return -1;
  }

  /* open socket */
  fd = socket(AF_INET, SOCK_DGRAM, 0);
  if (fd < 0) {
    nerror("openBroadcast: socket");
    return -1;
  }

  /* set address info */
  addr->sin_family = AF_INET;
  addr->sin_addr.s_addr = htonl(INADDR_ANY);

#if defined(SO_REUSEPORT)
  /* set reuse port */
  if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT,
				(SSOType)&optOn, sizeof(optOn)) < 0) {
    nerror("openBroadcast: setsockopt SO_REUSEPORT");
    close(fd);
    return -1;
  }
#elif defined(SO_REUSEADDR)
  /* set reuse address */
  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
				(SSOType)&optOn, sizeof(optOn)) < 0) {
    nerror("openBroadcast: setsockopt SO_REUSEADDR");
    close(fd);
    return -1;
  }
#endif

  /* bind address */
  if (bind(fd, (const struct sockaddr*)addr, sizeof(*addr)) < 0) {
    nerror("openBroadcast: bind");
    close(fd);
    return -1;
  }

  /* make broadcast */
  if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
				(SSOType)&optOn, sizeof(optOn)) < 0) {
    nerror("openBroadcast: setsockopt SO_BROADCAST");
    close(fd);
    return -1;
  }

  // address to send to is the broadcast address
  addr->sin_addr.s_addr = INADDR_BROADCAST;
  addr->sin_port = htons(port);

#if defined(__linux__)
  // linux doesn't seem to like INADDR_BROADCAST, but it's okay
  // with the broadcast address on the local network.  get the
  // broadcast address on the first interface that's not the
  // loopback interface.  (check the first numInterfaces
  // interfaces.)
  const int numInterfaces = 5;
  int i;
  struct ifconf conf;
  struct ifreq req[numInterfaces];

  // get the list of interface names
  conf.ifc_len = sizeof(req);
  conf.ifc_ifcu.ifcu_req = req;
  for (i = 0; i < numInterfaces; ++i)
    req[i].ifr_ifrn.ifrn_name[0] = 0;
  if (ioctl(fd, SIOCGIFCONF, &conf) < 0) {
    nerror("openBroadcast: getting interface list");
    close(fd);
    return(-1);
  }

  // get the broadcast address on each interface
  for (i = 0; i < numInterfaces; ++i) {
    // if no name then we're done
    if (req[i].ifr_ifrn.ifrn_name[0] == 0)
      break;

    // if we can't get the address then skip this interface
    if (ioctl(fd, SIOCGIFBRDADDR, req + i) < 0)
      continue;

    // if the address is the loopback broadcast address then skip it
    const sockaddr_in* ifbaddr = (const sockaddr_in*)
					&req[i].ifr_ifru.ifru_broadaddr;
    if (ntohl(ifbaddr->sin_addr.s_addr) == 0x7ffffffflu)
      continue;
    if (ifbaddr->sin_addr.s_addr == 0)
      continue;

    // got the broadcast address on the interface
    addr->sin_addr.s_addr = ifbaddr->sin_addr.s_addr;
    break;
  }

  // failed if no broadcast addresses found
  if (i == numInterfaces) {
    nerror("openBroadcast: getting broadcast address");
    close(fd);
    return(-1);
  }
#endif

  /* turn on non-blocking io */
  if (BzfNetwork::setNonBlocking(fd) < 0) {
    nerror("openBroadcast: setNonBlocking");
    close(fd);
    return(-1);
  }

  return fd;
}

int			closeBroadcast(int fd)
{
  if (fd == -1) return 0;
  return close(fd);
}

int			sendBroadcast(int fd, const void* buffer,
					int bufferLength,
					const struct sockaddr_in* addr)
{
  return sendto(fd, (const char*)buffer, bufferLength, 0,
				(const struct sockaddr*)addr, sizeof(*addr));
}

#if !defined(AddrLen)
#define AddrLen		int
#endif

#ifdef WIN32
/* This is a really really fugly hack to get around winsock sillyness
 * The newer versions of winsock have a socken_t typedef, and there
 * doesn't seem to be any way to tell the versions apart. However,
 * VC++ helps us out here by treating typedef as #define
 * If we've got a socklen_t typedefed, define HAVE_SOCKLEN_T to
 * avoid #define'ing it in common.h */

#ifndef socklen_t
	#define socklen_t int
#endif
#endif //WIN32

int			recvBroadcast(int fd, void* buffer, int bufferLength,
					 struct sockaddr_in* addr)
{
  struct sockaddr_in from;
  AddrLen fromLength = sizeof(from);

  int byteCount = recvfrom(fd, (char*)buffer, bufferLength, 0,
				(struct sockaddr*)&from, (socklen_t*) &fromLength);
  if (byteCount < 0) {
    if (getErrno() == EWOULDBLOCK) {
      return 0;
    }
    else {
      nerror("recvBroadcast");
      return -1;
    }
  }
  if (addr) *addr = from;
  return byteCount;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dbinteraction.cxx,v $
 *
 *  $Revision: 1.17 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-06 18:30:56 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef _DBAUI_INTERACTION_HXX_
#include "dbinteraction.hxx"
#endif
#ifndef _DBU_REGHELPER_HXX_
#include "dbu_reghelper.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef TOOLS_DIAGNOSE_EX_H
#include <tools/diagnose_ex.h>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _DBHELPER_DBEXCEPTION_HXX_
#include <connectivity/dbexception.hxx>
#endif
#ifndef _DBAUI_SQLMESSAGE_HXX_
#include "sqlmessage.hxx"
#endif
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONAPPROVE_HPP_
#include <com/sun/star/task/XInteractionApprove.hpp>
#endif
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONDISAPPROVE_HPP_
#include <com/sun/star/task/XInteractionDisapprove.hpp>
#endif
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONRETRY_HPP_
#include <com/sun/star/task/XInteractionRetry.hpp>
#endif
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONABORT_HPP_
#include <com/sun/star/task/XInteractionAbort.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XINTERACTIONSUPPLYPARAMETERS_HPP_
#include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XINTERACTIONDOCUMENTSAVE_HPP_
#include <com/sun/star/sdb/XInteractionDocumentSave.hpp>
#endif
#ifndef _SVTOOLS_LOGINDLG_HXX_
#include <svtools/logindlg.hxx>
#endif
#ifndef SFX_QUERYSAVEDOCUMENT_HXX
#include <sfx2/QuerySaveDocument.hxx>
#endif
#ifndef _DBU_UNO_HRC_
#include "dbu_uno.hrc"
#endif
#ifndef _DBAUI_PARAMDIALOG_HXX_
#include "paramdialog.hxx"
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef DBAUI_COLLECTIONVIEW_HXX
#include "CollectionView.hxx"
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif

//==========================================================================

extern "C" void SAL_CALL createRegistryInfo_OInteractionHandler()
{
    static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::OInteractionHandler > aOInteractionHandler_AutoRegistration;
}

//.........................................................................
namespace dbaui
{
//.........................................................................
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::ucb;
    using namespace ::com::sun::star::sdb;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::task;
    using namespace ::com::sun::star::beans;
    using namespace ::dbtools;

    //=========================================================================
    //= OInteractionHandler
    //=========================================================================
    //-------------------------------------------------------------------------
    OInteractionHandler::OInteractionHandler(const Reference< XMultiServiceFactory >& _rxORB)
        :m_xORB(_rxORB)
    {
    }

    //-------------------------------------------------------------------------
    IMPLEMENT_SERVICE_INFO1_STATIC(OInteractionHandler, "com.sun.star.comp.dbu.OInteractionHandler", "com.sun.star.sdb.InteractionHandler");

    //-------------------------------------------------------------------------
    void SAL_CALL OInteractionHandler::handle(const Reference< XInteractionRequest >& _rxRequest) throw(RuntimeException)
    {
        Any aRequest;
        if (_rxRequest.is())
        {
            try { aRequest = _rxRequest->getRequest(); }
            catch(RuntimeException&) { }
        }
        DBG_ASSERT(aRequest.hasValue(), "OInteractionHandler::handle: invalid request!");
        if (!aRequest.hasValue())
            // no request -> no handling
            return;

        Sequence< Reference< XInteractionContinuation > > aContinuations;
        try { aContinuations = _rxRequest->getContinuations(); }
        catch(RuntimeException&) { }

        // try to extract an SQLException (or one of it's derived members
        SQLExceptionInfo aInfo(aRequest);
        if (aInfo.isValid())
        {
            implHandle(aInfo, aContinuations);
            return;
        }

        ParametersRequest aParamRequest;
        if (aRequest >>= aParamRequest)
        {   // it's an authentication request
            implHandle(aParamRequest, aContinuations);
            return;
        }

        DocumentSaveRequest aDocuRequest;
        if (aRequest >>= aDocuRequest)
        {   // it's an document request
            implHandle(aDocuRequest, aContinuations);
            return;
        }

        OSL_VERIFY( implHandleUnknown( _rxRequest ) );
    }

    //-------------------------------------------------------------------------
    void OInteractionHandler::implHandle(const ParametersRequest& _rParamRequest, const Sequence< Reference< XInteractionContinuation > >& _rContinuations)
    {
        ::vos::OGuard aGuard(Application::GetSolarMutex());
            // want to open a dialog ....

        sal_Int32 nAbortPos = getContinuation(ABORT, _rContinuations);
        sal_Int32 nParamPos = getContinuation(SUPPLY_PARAMETERS, _rContinuations);

        Reference< XInteractionSupplyParameters > xParamCallback;
        if (-1 != nParamPos)
            xParamCallback = Reference< XInteractionSupplyParameters >(_rContinuations[nParamPos], UNO_QUERY);
        DBG_ASSERT(xParamCallback.is(), "OInteractionHandler::implHandle(ParametersRequest): can't set the parameters without an appropriate interaction handler!s");

        // determine the style of the dialog, dependent on the present continuation types
        WinBits nDialogStyle = WB_OK | WB_DEF_OK;
        if (-1 != nAbortPos)
            nDialogStyle = WB_OK_CANCEL;

        OParameterDialog aDlg(NULL, _rParamRequest.Parameters, _rParamRequest.Connection, m_xORB);
        sal_Int16 nResult = aDlg.Execute();
        try
        {
            switch (nResult)
            {
                case RET_OK:
                    if (xParamCallback.is())
                    {
                        xParamCallback->setParameters(aDlg.getValues());
                        xParamCallback->select();
                    }
                    break;
                default:
                    if (-1 != nAbortPos)
                        _rContinuations[nAbortPos]->select();
                    break;
            }
        }
        catch(RuntimeException&)
        {
            DBG_ERROR("OInteractionHandler::implHandle(ParametersRequest): caught a RuntimeException while calling the continuation callback!");
        }
    }

    //-------------------------------------------------------------------------
    void OInteractionHandler::implHandle(const SQLExceptionInfo& _rSqlInfo, const Sequence< Reference< XInteractionContinuation > >& _rContinuations)
    {
        ::vos::OGuard aGuard(Application::GetSolarMutex());
            // want to open a dialog ....

        sal_Int32 nApprovePos = getContinuation(APPROVE, _rContinuations);
        sal_Int32 nDisapprovePos = getContinuation(DISAPPROVE, _rContinuations);
        sal_Int32 nAbortPos = getContinuation(ABORT, _rContinuations);
        sal_Int32 nRetryPos = getContinuation(RETRY, _rContinuations);

        // determine the style of the dialog, dependent on the present continuation types
        WinBits nDialogStyle = 0;
        bool bHaveCancel = nAbortPos != -1;
        // "approve" means "Yes", "disapprove" means "No"
        // VCL only supports having both (which makes sense ...)
        if ( ( nApprovePos != -1 ) || ( nDisapprovePos != -1 ) )
            nDialogStyle = ( bHaveCancel ? WB_YES_NO_CANCEL : WB_YES_NO ) | WB_DEF_YES;
        else
        {
            // if there's no yes/no, then use a default OK button
            nDialogStyle = ( bHaveCancel ? WB_OK_CANCEL : WB_OK ) | WB_DEF_OK;
        }

        // If there's a "Retry" continuation, have a "Retry" button
        if ( nRetryPos != -1 )
        {
            nDialogStyle = WB_RETRY_CANCEL | WB_DEF_RETRY;
        }

        // excute the dialog
        OSQLMessageBox aDialog(NULL, _rSqlInfo, nDialogStyle);
            // TODO: need a way to specify the parent window
        sal_Int16 nResult = aDialog.Execute();
        try
        {
            switch (nResult)
            {
                case RET_YES:
                case RET_OK:
                    if ( nApprovePos != -1 )
                        _rContinuations[ nApprovePos ]->select();
                    else
                        OSL_ENSURE( nResult != RET_YES, "OInteractionHandler::implHandle: no handler for YES!" );
                    break;

                case RET_NO:
                    if ( nDisapprovePos != -1 )
                        _rContinuations[ nDisapprovePos ]->select();
                    else
                        OSL_ENSURE( false, "OInteractionHandler::implHandle: no handler for NO!" );
                    break;

                case RET_CANCEL:
                    if ( nAbortPos != -1 )
                        _rContinuations[ nAbortPos ]->select();
                    else if ( nDisapprovePos != -1 )
                        _rContinuations[ nDisapprovePos ]->select();
                    else
                        OSL_ENSURE( false, "OInteractionHandler::implHandle: no handler for CANCEL!" );
                    break;
                case RET_RETRY:
                    if ( nRetryPos != -1 )
                        _rContinuations[ nRetryPos ]->select();
                    else
                        OSL_ENSURE( false, "OInteractionHandler::implHandle: where does the RETRY come from?" );
                    break;
            }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }
    //-------------------------------------------------------------------------
    void OInteractionHandler::implHandle(const DocumentSaveRequest& _rDocuRequest, const Sequence< Reference< XInteractionContinuation > >& _rContinuations)
    {
        ::vos::OGuard aGuard(Application::GetSolarMutex());
            // want to open a dialog ....

        sal_Int32 nApprovePos = getContinuation(APPROVE, _rContinuations);
        sal_Int32 nDisApprovePos = getContinuation(DISAPPROVE, _rContinuations);
        sal_Int32 nAbortPos = getContinuation(ABORT, _rContinuations);

        short nRet = RET_YES;
        if ( -1 != nApprovePos )
        {
            // fragen, ob gespeichert werden soll
            nRet = ExecuteQuerySaveDocument(NULL,_rDocuRequest.Name);
        }

        if ( RET_CANCEL == nRet )
        {
            if (-1 != nAbortPos)
                _rContinuations[nAbortPos]->select();
            return;
        }
        else if ( RET_YES == nRet )
        {
            sal_Int32 nDocuPos = getContinuation(SUPPLY_DOCUMENTSAVE, _rContinuations);

            if (-1 != nDocuPos)
            {
                Reference< XInteractionDocumentSave > xCallback(_rContinuations[nDocuPos], UNO_QUERY);
                DBG_ASSERT(xCallback.is(), "OInteractionHandler::implHandle(DocumentSaveRequest): can't save document without an appropriate interaction handler!s");

                // determine the style of the dialog, dependent on the present continuation types
                WinBits nDialogStyle = WB_OK | WB_DEF_OK;
                if (-1 != nAbortPos)
                    nDialogStyle = WB_OK_CANCEL;

                OCollectionView aDlg(NULL,_rDocuRequest.Content,_rDocuRequest.Name,m_xORB);
                sal_Int16 nResult = aDlg.Execute();
                try
                {
                    switch (nResult)
                    {
                        case RET_OK:
                            if (xCallback.is())
                            {
                                xCallback->setName(aDlg.getName(),aDlg.getSelectedFolder());
                                xCallback->select();
                            }
                            break;
                        default:
                            if (-1 != nAbortPos)
                                _rContinuations[nAbortPos]->select();
                            break;
                    }
                }
                catch(RuntimeException&)
                {
                    DBG_ERROR("OInteractionHandler::implHandle(DocumentSaveRequest): caught a RuntimeException while calling the continuation callback!");
                }
            }
            else if ( -1 != nApprovePos )
                _rContinuations[nApprovePos]->select();
        }
        else if ( -1 != nDisApprovePos )
                _rContinuations[nDisApprovePos]->select();
    }

    //-------------------------------------------------------------------------
    bool OInteractionHandler::implHandleUnknown( const Reference< XInteractionRequest >& _rxRequest )
    {
        Reference< XInteractionHandler > xFallbackHandler;
        if ( m_xORB.is() )
            xFallbackHandler = xFallbackHandler.query( m_xORB->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ) );
        if ( xFallbackHandler.is() )
        {
            xFallbackHandler->handle( _rxRequest );
            return true;
        }
        return false;
    }

    //-------------------------------------------------------------------------
    sal_Int32 OInteractionHandler::getContinuation(Continuation _eCont, const Sequence< Reference< XInteractionContinuation > >& _rContinuations)
    {
        const Reference< XInteractionContinuation >* pContinuations = _rContinuations.getConstArray();
        for (sal_Int32 i=0; i<_rContinuations.getLength(); ++i, ++pContinuations)
        {
            switch (_eCont)
            {
                case APPROVE:
                    if (Reference< XInteractionApprove >(*pContinuations, UNO_QUERY).is())
                        return i;
                    break;
                case DISAPPROVE:
                    if (Reference< XInteractionDisapprove >(*pContinuations, UNO_QUERY).is())
                        return i;
                    break;
                case RETRY:
                    if (Reference< XInteractionRetry >(*pContinuations, UNO_QUERY).is())
                        return i;
                    break;
                case ABORT:
                    if (Reference< XInteractionAbort >(*pContinuations, UNO_QUERY).is())
                        return i;
                    break;
                case SUPPLY_PARAMETERS:
                    if (Reference< XInteractionSupplyParameters >(*pContinuations, UNO_QUERY).is())
                        return i;
                    break;
                case SUPPLY_DOCUMENTSAVE:
                    if (Reference< XInteractionDocumentSave >(*pContinuations, UNO_QUERY).is())
                        return i;
                    break;
            }
        }

        return -1;
    }

//.........................................................................
}   // namespace dbaui
//.........................................................................

<commit_msg>INTEGRATION: CWS changefileheader (1.17.12); FILE MERGED 2008/03/31 13:28:10 rt 1.17.12.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: dbinteraction.cxx,v $
 * $Revision: 1.18 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"

#ifndef _DBAUI_INTERACTION_HXX_
#include "dbinteraction.hxx"
#endif
#ifndef _DBU_REGHELPER_HXX_
#include "dbu_reghelper.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef TOOLS_DIAGNOSE_EX_H
#include <tools/diagnose_ex.h>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _DBHELPER_DBEXCEPTION_HXX_
#include <connectivity/dbexception.hxx>
#endif
#ifndef _DBAUI_SQLMESSAGE_HXX_
#include "sqlmessage.hxx"
#endif
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONAPPROVE_HPP_
#include <com/sun/star/task/XInteractionApprove.hpp>
#endif
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONDISAPPROVE_HPP_
#include <com/sun/star/task/XInteractionDisapprove.hpp>
#endif
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONRETRY_HPP_
#include <com/sun/star/task/XInteractionRetry.hpp>
#endif
#ifndef _COM_SUN_STAR_TASK_XINTERACTIONABORT_HPP_
#include <com/sun/star/task/XInteractionAbort.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XINTERACTIONSUPPLYPARAMETERS_HPP_
#include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XINTERACTIONDOCUMENTSAVE_HPP_
#include <com/sun/star/sdb/XInteractionDocumentSave.hpp>
#endif
#ifndef _SVTOOLS_LOGINDLG_HXX_
#include <svtools/logindlg.hxx>
#endif
#ifndef SFX_QUERYSAVEDOCUMENT_HXX
#include <sfx2/QuerySaveDocument.hxx>
#endif
#ifndef _DBU_UNO_HRC_
#include "dbu_uno.hrc"
#endif
#ifndef _DBAUI_PARAMDIALOG_HXX_
#include "paramdialog.hxx"
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef DBAUI_COLLECTIONVIEW_HXX
#include "CollectionView.hxx"
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif

//==========================================================================

extern "C" void SAL_CALL createRegistryInfo_OInteractionHandler()
{
    static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::OInteractionHandler > aOInteractionHandler_AutoRegistration;
}

//.........................................................................
namespace dbaui
{
//.........................................................................
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::ucb;
    using namespace ::com::sun::star::sdb;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::task;
    using namespace ::com::sun::star::beans;
    using namespace ::dbtools;

    //=========================================================================
    //= OInteractionHandler
    //=========================================================================
    //-------------------------------------------------------------------------
    OInteractionHandler::OInteractionHandler(const Reference< XMultiServiceFactory >& _rxORB)
        :m_xORB(_rxORB)
    {
    }

    //-------------------------------------------------------------------------
    IMPLEMENT_SERVICE_INFO1_STATIC(OInteractionHandler, "com.sun.star.comp.dbu.OInteractionHandler", "com.sun.star.sdb.InteractionHandler");

    //-------------------------------------------------------------------------
    void SAL_CALL OInteractionHandler::handle(const Reference< XInteractionRequest >& _rxRequest) throw(RuntimeException)
    {
        Any aRequest;
        if (_rxRequest.is())
        {
            try { aRequest = _rxRequest->getRequest(); }
            catch(RuntimeException&) { }
        }
        DBG_ASSERT(aRequest.hasValue(), "OInteractionHandler::handle: invalid request!");
        if (!aRequest.hasValue())
            // no request -> no handling
            return;

        Sequence< Reference< XInteractionContinuation > > aContinuations;
        try { aContinuations = _rxRequest->getContinuations(); }
        catch(RuntimeException&) { }

        // try to extract an SQLException (or one of it's derived members
        SQLExceptionInfo aInfo(aRequest);
        if (aInfo.isValid())
        {
            implHandle(aInfo, aContinuations);
            return;
        }

        ParametersRequest aParamRequest;
        if (aRequest >>= aParamRequest)
        {   // it's an authentication request
            implHandle(aParamRequest, aContinuations);
            return;
        }

        DocumentSaveRequest aDocuRequest;
        if (aRequest >>= aDocuRequest)
        {   // it's an document request
            implHandle(aDocuRequest, aContinuations);
            return;
        }

        OSL_VERIFY( implHandleUnknown( _rxRequest ) );
    }

    //-------------------------------------------------------------------------
    void OInteractionHandler::implHandle(const ParametersRequest& _rParamRequest, const Sequence< Reference< XInteractionContinuation > >& _rContinuations)
    {
        ::vos::OGuard aGuard(Application::GetSolarMutex());
            // want to open a dialog ....

        sal_Int32 nAbortPos = getContinuation(ABORT, _rContinuations);
        sal_Int32 nParamPos = getContinuation(SUPPLY_PARAMETERS, _rContinuations);

        Reference< XInteractionSupplyParameters > xParamCallback;
        if (-1 != nParamPos)
            xParamCallback = Reference< XInteractionSupplyParameters >(_rContinuations[nParamPos], UNO_QUERY);
        DBG_ASSERT(xParamCallback.is(), "OInteractionHandler::implHandle(ParametersRequest): can't set the parameters without an appropriate interaction handler!s");

        // determine the style of the dialog, dependent on the present continuation types
        WinBits nDialogStyle = WB_OK | WB_DEF_OK;
        if (-1 != nAbortPos)
            nDialogStyle = WB_OK_CANCEL;

        OParameterDialog aDlg(NULL, _rParamRequest.Parameters, _rParamRequest.Connection, m_xORB);
        sal_Int16 nResult = aDlg.Execute();
        try
        {
            switch (nResult)
            {
                case RET_OK:
                    if (xParamCallback.is())
                    {
                        xParamCallback->setParameters(aDlg.getValues());
                        xParamCallback->select();
                    }
                    break;
                default:
                    if (-1 != nAbortPos)
                        _rContinuations[nAbortPos]->select();
                    break;
            }
        }
        catch(RuntimeException&)
        {
            DBG_ERROR("OInteractionHandler::implHandle(ParametersRequest): caught a RuntimeException while calling the continuation callback!");
        }
    }

    //-------------------------------------------------------------------------
    void OInteractionHandler::implHandle(const SQLExceptionInfo& _rSqlInfo, const Sequence< Reference< XInteractionContinuation > >& _rContinuations)
    {
        ::vos::OGuard aGuard(Application::GetSolarMutex());
            // want to open a dialog ....

        sal_Int32 nApprovePos = getContinuation(APPROVE, _rContinuations);
        sal_Int32 nDisapprovePos = getContinuation(DISAPPROVE, _rContinuations);
        sal_Int32 nAbortPos = getContinuation(ABORT, _rContinuations);
        sal_Int32 nRetryPos = getContinuation(RETRY, _rContinuations);

        // determine the style of the dialog, dependent on the present continuation types
        WinBits nDialogStyle = 0;
        bool bHaveCancel = nAbortPos != -1;
        // "approve" means "Yes", "disapprove" means "No"
        // VCL only supports having both (which makes sense ...)
        if ( ( nApprovePos != -1 ) || ( nDisapprovePos != -1 ) )
            nDialogStyle = ( bHaveCancel ? WB_YES_NO_CANCEL : WB_YES_NO ) | WB_DEF_YES;
        else
        {
            // if there's no yes/no, then use a default OK button
            nDialogStyle = ( bHaveCancel ? WB_OK_CANCEL : WB_OK ) | WB_DEF_OK;
        }

        // If there's a "Retry" continuation, have a "Retry" button
        if ( nRetryPos != -1 )
        {
            nDialogStyle = WB_RETRY_CANCEL | WB_DEF_RETRY;
        }

        // excute the dialog
        OSQLMessageBox aDialog(NULL, _rSqlInfo, nDialogStyle);
            // TODO: need a way to specify the parent window
        sal_Int16 nResult = aDialog.Execute();
        try
        {
            switch (nResult)
            {
                case RET_YES:
                case RET_OK:
                    if ( nApprovePos != -1 )
                        _rContinuations[ nApprovePos ]->select();
                    else
                        OSL_ENSURE( nResult != RET_YES, "OInteractionHandler::implHandle: no handler for YES!" );
                    break;

                case RET_NO:
                    if ( nDisapprovePos != -1 )
                        _rContinuations[ nDisapprovePos ]->select();
                    else
                        OSL_ENSURE( false, "OInteractionHandler::implHandle: no handler for NO!" );
                    break;

                case RET_CANCEL:
                    if ( nAbortPos != -1 )
                        _rContinuations[ nAbortPos ]->select();
                    else if ( nDisapprovePos != -1 )
                        _rContinuations[ nDisapprovePos ]->select();
                    else
                        OSL_ENSURE( false, "OInteractionHandler::implHandle: no handler for CANCEL!" );
                    break;
                case RET_RETRY:
                    if ( nRetryPos != -1 )
                        _rContinuations[ nRetryPos ]->select();
                    else
                        OSL_ENSURE( false, "OInteractionHandler::implHandle: where does the RETRY come from?" );
                    break;
            }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }
    //-------------------------------------------------------------------------
    void OInteractionHandler::implHandle(const DocumentSaveRequest& _rDocuRequest, const Sequence< Reference< XInteractionContinuation > >& _rContinuations)
    {
        ::vos::OGuard aGuard(Application::GetSolarMutex());
            // want to open a dialog ....

        sal_Int32 nApprovePos = getContinuation(APPROVE, _rContinuations);
        sal_Int32 nDisApprovePos = getContinuation(DISAPPROVE, _rContinuations);
        sal_Int32 nAbortPos = getContinuation(ABORT, _rContinuations);

        short nRet = RET_YES;
        if ( -1 != nApprovePos )
        {
            // fragen, ob gespeichert werden soll
            nRet = ExecuteQuerySaveDocument(NULL,_rDocuRequest.Name);
        }

        if ( RET_CANCEL == nRet )
        {
            if (-1 != nAbortPos)
                _rContinuations[nAbortPos]->select();
            return;
        }
        else if ( RET_YES == nRet )
        {
            sal_Int32 nDocuPos = getContinuation(SUPPLY_DOCUMENTSAVE, _rContinuations);

            if (-1 != nDocuPos)
            {
                Reference< XInteractionDocumentSave > xCallback(_rContinuations[nDocuPos], UNO_QUERY);
                DBG_ASSERT(xCallback.is(), "OInteractionHandler::implHandle(DocumentSaveRequest): can't save document without an appropriate interaction handler!s");

                // determine the style of the dialog, dependent on the present continuation types
                WinBits nDialogStyle = WB_OK | WB_DEF_OK;
                if (-1 != nAbortPos)
                    nDialogStyle = WB_OK_CANCEL;

                OCollectionView aDlg(NULL,_rDocuRequest.Content,_rDocuRequest.Name,m_xORB);
                sal_Int16 nResult = aDlg.Execute();
                try
                {
                    switch (nResult)
                    {
                        case RET_OK:
                            if (xCallback.is())
                            {
                                xCallback->setName(aDlg.getName(),aDlg.getSelectedFolder());
                                xCallback->select();
                            }
                            break;
                        default:
                            if (-1 != nAbortPos)
                                _rContinuations[nAbortPos]->select();
                            break;
                    }
                }
                catch(RuntimeException&)
                {
                    DBG_ERROR("OInteractionHandler::implHandle(DocumentSaveRequest): caught a RuntimeException while calling the continuation callback!");
                }
            }
            else if ( -1 != nApprovePos )
                _rContinuations[nApprovePos]->select();
        }
        else if ( -1 != nDisApprovePos )
                _rContinuations[nDisApprovePos]->select();
    }

    //-------------------------------------------------------------------------
    bool OInteractionHandler::implHandleUnknown( const Reference< XInteractionRequest >& _rxRequest )
    {
        Reference< XInteractionHandler > xFallbackHandler;
        if ( m_xORB.is() )
            xFallbackHandler = xFallbackHandler.query( m_xORB->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ) );
        if ( xFallbackHandler.is() )
        {
            xFallbackHandler->handle( _rxRequest );
            return true;
        }
        return false;
    }

    //-------------------------------------------------------------------------
    sal_Int32 OInteractionHandler::getContinuation(Continuation _eCont, const Sequence< Reference< XInteractionContinuation > >& _rContinuations)
    {
        const Reference< XInteractionContinuation >* pContinuations = _rContinuations.getConstArray();
        for (sal_Int32 i=0; i<_rContinuations.getLength(); ++i, ++pContinuations)
        {
            switch (_eCont)
            {
                case APPROVE:
                    if (Reference< XInteractionApprove >(*pContinuations, UNO_QUERY).is())
                        return i;
                    break;
                case DISAPPROVE:
                    if (Reference< XInteractionDisapprove >(*pContinuations, UNO_QUERY).is())
                        return i;
                    break;
                case RETRY:
                    if (Reference< XInteractionRetry >(*pContinuations, UNO_QUERY).is())
                        return i;
                    break;
                case ABORT:
                    if (Reference< XInteractionAbort >(*pContinuations, UNO_QUERY).is())
                        return i;
                    break;
                case SUPPLY_PARAMETERS:
                    if (Reference< XInteractionSupplyParameters >(*pContinuations, UNO_QUERY).is())
                        return i;
                    break;
                case SUPPLY_DOCUMENTSAVE:
                    if (Reference< XInteractionDocumentSave >(*pContinuations, UNO_QUERY).is())
                        return i;
                    break;
            }
        }

        return -1;
    }

//.........................................................................
}   // namespace dbaui
//.........................................................................

<|endoftext|>