<commit_before>/*
* Copyright (C) 2008-2013 The Communi Project
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser 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 Lesser General Public
* License for more details.
*/

#include "ircusermodel.h"
#include "ircchannel_p.h"
#include "ircuser.h"
#include <qpointer.h>

/*!
    \file ircusermodel.h
    \brief #include <IrcUserModel>
 */

/*!
    \class IrcUserModel ircusermodel.h <IrcUserModel>
    \ingroup models
    \brief Keeps track of channel users.

    In order to keep track of channel users, create an instance of IrcUserModel.
    It will notify via signals when users are added and/or removed. IrcUserModel
    can be used directly as a data model for Qt's item views - both in C++ and QML.

    \code
    void ChatView::setChannel(IrcChannel* channel)
    {
        IrcUserModel* model = new IrcUserModel(channel);
        connect(model, SIGNAL(added(IrcUser*)), this, SLOT(onUserAdded(IrcUser*)));
        connect(model, SIGNAL(removed(IrcUser*)), this, SLOT(onUserRemoved(IrcUser*)));
        nickCompleter->setModel(model);
        userListView->setModel(model);
    }
    \endcode

    \section sorting Sorting

    The order of \ref users is kept as sent from the server. Furthermore,
    an alphabetical list of \ref names is provided for convenience.

    Whilst these available options cater basic use cases, for more fine-
    grained sorting it is recommended to implement a proxy model. The
    following example illustrates how to sort users by prefix and name.

    \code
    class IrcUserProxyModel : public QSortFilterProxyModel
    {
    public:
        IrcUserProxyModel(IrcUserModel* userModel) : QSortFilterProxyModel(userModel)
        {
            setSourceModel(userModel);
        }

        // IrcSessionInfo::prefixes()
        void sortByPrefixes(const QStringList& prefixes)
        {
            m_prefixes = prefixes;
            sort(0, Qt::AscendingOrder);
            setDynamicSortFilter(true);
        }

    protected:
        bool lessThan(const QModelIndex& left, const QModelIndex& right) const
        {
            const QString p1 = left.data(Irc::PrefixRole).toString();
            const QString p2 = right.data(Irc::PrefixRole).toString();

            const int i1 = !p1.isEmpty() ? m_prefixes.indexOf(p1.at(0)) : -1;
            const int i2 = !p2.isEmpty() ? m_prefixes.indexOf(p2.at(0)) : -1;

            if (i1 >= 0 && i2 < 0)
                return true;
            if (i1 < 0 && i2 >= 0)
                return false;
            if (i1 >= 0 && i2 >= 0 && i1 != i2)
                return i1 < i2;

            const QString n1 = left.data(Irc::NameRole).toString();
            const QString n2 = right.data(Irc::NameRole).toString();
            return n1.compare(n2, Qt::CaseInsensitive) < 0;
        }

    private:
        QStringList m_prefixes;
    };
    \endcode

    \sa models
*/

/*!
    \fn void IrcUserModel::added(IrcUser* user)

    This signal is emitted when a \a user is added to the list of users.
 */

/*!
    \fn void IrcUserModel::removed(IrcUser* user)

    This signal is emitted when a \a user is removed from the list of users.
 */

class IrcUserModelPrivate
{
public:
    inline IrcUser* userAt(int index) const
    {
        return channel ? IrcChannelPrivate::get(channel)->userList.value(index) : 0;
    }

    Irc::ItemDataRole role;
    QPointer<IrcChannel> channel;
};

/*!
    Constructs a new model with \a parent.

    \note If \a parent is an instance of IrcChannel, it will be
    automatically assigned to \ref IrcUserModel::channel "channel".
 */
IrcUserModel::IrcUserModel(QObject* parent)
    : QAbstractListModel(parent), d_ptr(new IrcUserModelPrivate)
{
    Q_D(IrcUserModel);
    d->role = Irc::TitleRole;
    setChannel(qobject_cast<IrcChannel*>(parent));

    qRegisterMetaType<IrcUser*>();
    qRegisterMetaType<QList<IrcUser*> >();
}

/*!
    Destructs the model.
 */
IrcUserModel::~IrcUserModel()
{
    Q_D(IrcUserModel);
    if (d->channel)
        IrcChannelPrivate::get(d->channel)->userModels.removeOne(this);
}

/*!
    This property holds the channel.

    \par Access functions:
    \li \ref IrcChannel* channel() const
    \li void setChannel(\ref IrcChannel* channel)
 */
IrcChannel* IrcUserModel::channel() const
{
    Q_D(const IrcUserModel);
    return d->channel;
}

void IrcUserModel::setChannel(IrcChannel* channel)
{
    Q_D(IrcUserModel);
    if (d->channel != channel) {
        beginResetModel();
        if (d->channel)
            IrcChannelPrivate::get(d->channel)->userModels.removeOne(this);

        d->channel = channel;

        if (d->channel)
            IrcChannelPrivate::get(d->channel)->userModels.append(this);
        endResetModel();

        emit channelChanged(channel);
    }
}

/*!
    This property holds the number of users on the channel.

    \par Access function:
    \li int count() const

    \par Notifier signal:
    \li void countChanged(int count)
 */
int IrcUserModel::count() const
{
    return rowCount();
}

/*!
    This property holds the list of names in alphabetical order.

    \par Access function:
    \li QStringList names() const

    \par Notifier signal:
    \li void namesChanged(const QStringList& names)
 */
QStringList IrcUserModel::names() const
{
    Q_D(const IrcUserModel);
    if (d->channel)
        return IrcChannelPrivate::get(d->channel)->userMap.keys();
    return QStringList();
}

/*!
    This property holds the list of users.

    The order of users is kept as sent from the server.

    \par Access function:
    \li QList<\ref IrcUser*> users() const

    \par Notifier signal:
    \li void usersChanged(const QList<\ref IrcUser*>& users)
 */
QList<IrcUser*> IrcUserModel::users() const
{
    Q_D(const IrcUserModel);
    if (d->channel)
        return IrcChannelPrivate::get(d->channel)->userList;
    return QList<IrcUser*>();
}

/*!
    Returns the user object at \a index.
 */
IrcUser* IrcUserModel::get(int index) const
{
    Q_D(const IrcUserModel);
    return d->userAt(index);
}

/*!
    Returns the user object for \a name.
 */
IrcUser* IrcUserModel::user(const QString& name) const
{
    Q_D(const IrcUserModel);
    if (d->channel)
        return IrcChannelPrivate::get(d->channel)->userMap.value(name);
    return 0;
}

/*!
    Returns \c true if the model contains \a name.
 */
bool IrcUserModel::contains(const QString& name) const
{
    Q_D(const IrcUserModel);
    if (d->channel)
        return IrcChannelPrivate::get(d->channel)->userMap.contains(name);
    return false;
}

/*!
    This property holds the display role.

    The specified data role is returned for Qt::DisplayRole.

    The default value is \ref Irc::TitleRole.

    \par Access functions:
    \li \ref Irc::ItemDataRole displayRole() const
    \li void setDisplayRole(\ref Irc::ItemDataRole role)
 */
Irc::ItemDataRole IrcUserModel::displayRole() const
{
    Q_D(const IrcUserModel);
    return d->role;
}

void IrcUserModel::setDisplayRole(Irc::ItemDataRole role)
{
    Q_D(IrcUserModel);
    d->role = role;
}

/*!
    Returns the model index for \a user.
 */
QModelIndex IrcUserModel::index(IrcUser* user) const
{
    Q_D(const IrcUserModel);
    if (d->channel)
        return index(IrcChannelPrivate::get(d->channel)->userList.indexOf(user));
    return QModelIndex();
}

/*!
    Returns the user for model \a index.
 */
IrcUser* IrcUserModel::user(const QModelIndex& index) const
{
    if (!hasIndex(index.row(), index.column()))
        return 0;

    return static_cast<IrcUser*>(index.internalPointer());
}

/*!
    The following role names are provided by default:

    Role            | Name      | Type     | Example
    --------------- | ----------|----------|--------
    Qt::DisplayRole | "display" | 1)       | -
    Irc::UserRole   | "user"    | IrcUser* | <object>
    Irc::NameRole   | "name"    | QString  | "jpnurmi"
    Irc::PrefixRole | "prefix"  | QString  | "@"
    Irc::ModeRole   | "mode"    | QString  | "o"
    Irc::TitleRole  | "title"   | QString  | "@jpnurmi"

    1) The type depends on \ref displayRole.
 */
QHash<int, QByteArray> IrcUserModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[Qt::DisplayRole] = "display";
    roles[Irc::UserRole] = "user";
    roles[Irc::NameRole] = "name";
    roles[Irc::PrefixRole] = "prefix";
    roles[Irc::ModeRole] = "mode";
    roles[Irc::TitleRole] = "title";
    return roles;
}

/*!
    Returns the number of users on the channel.
 */
int IrcUserModel::rowCount(const QModelIndex& parent) const
{
    Q_D(const IrcUserModel);
    if (parent.isValid() || !d->channel)
        return 0;

    return IrcChannelPrivate::get(d->channel)->userList.count();
}

/*!
    Returns the data for specified \a role referred to by the \a index.

    \sa Irc::ItemDataRole, roleNames()
 */
QVariant IrcUserModel::data(const QModelIndex& index, int role) const
{
    Q_D(const IrcUserModel);
    if (!d->channel || !hasIndex(index.row(), index.column()))
        return QVariant();

    IrcUser* user = static_cast<IrcUser*>(index.internalPointer());

    switch (role) {
    case Qt::DisplayRole:
        return data(index, d->role);
    case Irc::UserRole:
        return QVariant::fromValue(user);
    case Irc::NameRole:
        if (user)
            return user->name();
        break;
    case Irc::PrefixRole:
        if (user)
            return user->prefix();
        break;
    case Irc::ModeRole:
        if (user)
            return user->mode();
        break;
    case Irc::TitleRole:
        if (user)
            return user->prefix() + user->name();
        break;
    }

    return QVariant();
}

/*!
    Returns the index of the item in the model specified by the given \a row, \a column and \a parent index.
 */
QModelIndex IrcUserModel::index(int row, int column, const QModelIndex& parent) const
{
    Q_D(const IrcUserModel);
    if (!d->channel || !hasIndex(row, column, parent))
        return QModelIndex();

    return createIndex(row, column, d->userAt(row));
}
<commit_msg>IrcUserModel: present only the highest prefix/mode<commit_after>/*
* Copyright (C) 2008-2013 The Communi Project
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser 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 Lesser General Public
* License for more details.
*/

#include "ircusermodel.h"
#include "ircchannel_p.h"
#include "ircuser.h"
#include <qpointer.h>

/*!
    \file ircusermodel.h
    \brief #include <IrcUserModel>
 */

/*!
    \class IrcUserModel ircusermodel.h <IrcUserModel>
    \ingroup models
    \brief Keeps track of channel users.

    In order to keep track of channel users, create an instance of IrcUserModel.
    It will notify via signals when users are added and/or removed. IrcUserModel
    can be used directly as a data model for Qt's item views - both in C++ and QML.

    \code
    void ChatView::setChannel(IrcChannel* channel)
    {
        IrcUserModel* model = new IrcUserModel(channel);
        connect(model, SIGNAL(added(IrcUser*)), this, SLOT(onUserAdded(IrcUser*)));
        connect(model, SIGNAL(removed(IrcUser*)), this, SLOT(onUserRemoved(IrcUser*)));
        nickCompleter->setModel(model);
        userListView->setModel(model);
    }
    \endcode

    \section sorting Sorting

    The order of \ref users is kept as sent from the server. Furthermore,
    an alphabetical list of \ref names is provided for convenience.

    Whilst these available options cater basic use cases, for more fine-
    grained sorting it is recommended to implement a proxy model. The
    following example illustrates how to sort users by prefix and name.

    \code
    class IrcUserProxyModel : public QSortFilterProxyModel
    {
    public:
        IrcUserProxyModel(IrcUserModel* userModel) : QSortFilterProxyModel(userModel)
        {
            setSourceModel(userModel);
        }

        // IrcSessionInfo::prefixes()
        void sortByPrefixes(const QStringList& prefixes)
        {
            m_prefixes = prefixes;
            sort(0, Qt::AscendingOrder);
            setDynamicSortFilter(true);
        }

    protected:
        bool lessThan(const QModelIndex& left, const QModelIndex& right) const
        {
            const QString p1 = left.data(Irc::PrefixRole).toString();
            const QString p2 = right.data(Irc::PrefixRole).toString();

            const int i1 = !p1.isEmpty() ? m_prefixes.indexOf(p1.at(0)) : -1;
            const int i2 = !p2.isEmpty() ? m_prefixes.indexOf(p2.at(0)) : -1;

            if (i1 >= 0 && i2 < 0)
                return true;
            if (i1 < 0 && i2 >= 0)
                return false;
            if (i1 >= 0 && i2 >= 0 && i1 != i2)
                return i1 < i2;

            const QString n1 = left.data(Irc::NameRole).toString();
            const QString n2 = right.data(Irc::NameRole).toString();
            return n1.compare(n2, Qt::CaseInsensitive) < 0;
        }

    private:
        QStringList m_prefixes;
    };
    \endcode

    \sa models
*/

/*!
    \fn void IrcUserModel::added(IrcUser* user)

    This signal is emitted when a \a user is added to the list of users.
 */

/*!
    \fn void IrcUserModel::removed(IrcUser* user)

    This signal is emitted when a \a user is removed from the list of users.
 */

class IrcUserModelPrivate
{
public:
    inline IrcUser* userAt(int index) const
    {
        return channel ? IrcChannelPrivate::get(channel)->userList.value(index) : 0;
    }

    Irc::ItemDataRole role;
    QPointer<IrcChannel> channel;
};

/*!
    Constructs a new model with \a parent.

    \note If \a parent is an instance of IrcChannel, it will be
    automatically assigned to \ref IrcUserModel::channel "channel".
 */
IrcUserModel::IrcUserModel(QObject* parent)
    : QAbstractListModel(parent), d_ptr(new IrcUserModelPrivate)
{
    Q_D(IrcUserModel);
    d->role = Irc::TitleRole;
    setChannel(qobject_cast<IrcChannel*>(parent));

    qRegisterMetaType<IrcUser*>();
    qRegisterMetaType<QList<IrcUser*> >();
}

/*!
    Destructs the model.
 */
IrcUserModel::~IrcUserModel()
{
    Q_D(IrcUserModel);
    if (d->channel)
        IrcChannelPrivate::get(d->channel)->userModels.removeOne(this);
}

/*!
    This property holds the channel.

    \par Access functions:
    \li \ref IrcChannel* channel() const
    \li void setChannel(\ref IrcChannel* channel)
 */
IrcChannel* IrcUserModel::channel() const
{
    Q_D(const IrcUserModel);
    return d->channel;
}

void IrcUserModel::setChannel(IrcChannel* channel)
{
    Q_D(IrcUserModel);
    if (d->channel != channel) {
        beginResetModel();
        if (d->channel)
            IrcChannelPrivate::get(d->channel)->userModels.removeOne(this);

        d->channel = channel;

        if (d->channel)
            IrcChannelPrivate::get(d->channel)->userModels.append(this);
        endResetModel();

        emit channelChanged(channel);
    }
}

/*!
    This property holds the number of users on the channel.

    \par Access function:
    \li int count() const

    \par Notifier signal:
    \li void countChanged(int count)
 */
int IrcUserModel::count() const
{
    return rowCount();
}

/*!
    This property holds the list of names in alphabetical order.

    \par Access function:
    \li QStringList names() const

    \par Notifier signal:
    \li void namesChanged(const QStringList& names)
 */
QStringList IrcUserModel::names() const
{
    Q_D(const IrcUserModel);
    if (d->channel)
        return IrcChannelPrivate::get(d->channel)->userMap.keys();
    return QStringList();
}

/*!
    This property holds the list of users.

    The order of users is kept as sent from the server.

    \par Access function:
    \li QList<\ref IrcUser*> users() const

    \par Notifier signal:
    \li void usersChanged(const QList<\ref IrcUser*>& users)
 */
QList<IrcUser*> IrcUserModel::users() const
{
    Q_D(const IrcUserModel);
    if (d->channel)
        return IrcChannelPrivate::get(d->channel)->userList;
    return QList<IrcUser*>();
}

/*!
    Returns the user object at \a index.
 */
IrcUser* IrcUserModel::get(int index) const
{
    Q_D(const IrcUserModel);
    return d->userAt(index);
}

/*!
    Returns the user object for \a name.
 */
IrcUser* IrcUserModel::user(const QString& name) const
{
    Q_D(const IrcUserModel);
    if (d->channel)
        return IrcChannelPrivate::get(d->channel)->userMap.value(name);
    return 0;
}

/*!
    Returns \c true if the model contains \a name.
 */
bool IrcUserModel::contains(const QString& name) const
{
    Q_D(const IrcUserModel);
    if (d->channel)
        return IrcChannelPrivate::get(d->channel)->userMap.contains(name);
    return false;
}

/*!
    This property holds the display role.

    The specified data role is returned for Qt::DisplayRole.

    The default value is \ref Irc::TitleRole.

    \par Access functions:
    \li \ref Irc::ItemDataRole displayRole() const
    \li void setDisplayRole(\ref Irc::ItemDataRole role)
 */
Irc::ItemDataRole IrcUserModel::displayRole() const
{
    Q_D(const IrcUserModel);
    return d->role;
}

void IrcUserModel::setDisplayRole(Irc::ItemDataRole role)
{
    Q_D(IrcUserModel);
    d->role = role;
}

/*!
    Returns the model index for \a user.
 */
QModelIndex IrcUserModel::index(IrcUser* user) const
{
    Q_D(const IrcUserModel);
    if (d->channel)
        return index(IrcChannelPrivate::get(d->channel)->userList.indexOf(user));
    return QModelIndex();
}

/*!
    Returns the user for model \a index.
 */
IrcUser* IrcUserModel::user(const QModelIndex& index) const
{
    if (!hasIndex(index.row(), index.column()))
        return 0;

    return static_cast<IrcUser*>(index.internalPointer());
}

/*!
    The following role names are provided by default:

    Role            | Name      | Type     | Example
    --------------- | ----------|----------|--------
    Qt::DisplayRole | "display" | 1)       | -
    Irc::UserRole   | "user"    | IrcUser* | <object>
    Irc::NameRole   | "name"    | QString  | "jpnurmi"
    Irc::PrefixRole | "prefix"  | QString  | "@"
    Irc::ModeRole   | "mode"    | QString  | "o"
    Irc::TitleRole  | "title"   | QString  | "@jpnurmi"

    1) The type depends on \ref displayRole.
 */
QHash<int, QByteArray> IrcUserModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[Qt::DisplayRole] = "display";
    roles[Irc::UserRole] = "user";
    roles[Irc::NameRole] = "name";
    roles[Irc::PrefixRole] = "prefix";
    roles[Irc::ModeRole] = "mode";
    roles[Irc::TitleRole] = "title";
    return roles;
}

/*!
    Returns the number of users on the channel.
 */
int IrcUserModel::rowCount(const QModelIndex& parent) const
{
    Q_D(const IrcUserModel);
    if (parent.isValid() || !d->channel)
        return 0;

    return IrcChannelPrivate::get(d->channel)->userList.count();
}

/*!
    Returns the data for specified \a role referred to by the \a index.

    \sa Irc::ItemDataRole, roleNames()
 */
QVariant IrcUserModel::data(const QModelIndex& index, int role) const
{
    Q_D(const IrcUserModel);
    if (!d->channel || !hasIndex(index.row(), index.column()))
        return QVariant();

    IrcUser* user = static_cast<IrcUser*>(index.internalPointer());

    switch (role) {
    case Qt::DisplayRole:
        return data(index, d->role);
    case Irc::UserRole:
        return QVariant::fromValue(user);
    case Irc::NameRole:
        if (user)
            return user->name();
        break;
    case Irc::PrefixRole:
        if (user)
            return user->prefix().left(1);
        break;
    case Irc::ModeRole:
        if (user)
            return user->mode().left(1);
        break;
    case Irc::TitleRole:
        if (user)
            return user->prefix().left(1) + user->name();
        break;
    }

    return QVariant();
}

/*!
    Returns the index of the item in the model specified by the given \a row, \a column and \a parent index.
 */
QModelIndex IrcUserModel::index(int row, int column, const QModelIndex& parent) const
{
    Q_D(const IrcUserModel);
    if (!d->channel || !hasIndex(row, column, parent))
        return QModelIndex();

    return createIndex(row, column, d->userAt(row));
}
<|endoftext|>


<commit_before><commit_msg>Fix GCC compile errors. Use a c-style string for strftime<commit_after><|endoftext|>


<commit_before>// Copyright 2015 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <rclcpp/rclcpp.hpp>

int main(int argc, char ** argv)
{
  rclcpp::init(argc, argv);

  auto node = rclcpp::Node::make_shared("parameters");

  auto parameters_client = std::make_shared<rclcpp::parameter::AsyncParametersClient>(node);

  auto parameters = {
    rclcpp::parameter::ParameterVariant("foo", 2),
    rclcpp::parameter::ParameterVariant("bar", "hello"),
    rclcpp::parameter::ParameterVariant("baz", 1.45),
    rclcpp::parameter::ParameterVariant("foobar", true),
  };

  auto f1 = parameters_client->set_parameters(
    parameters, [](std::shared_future<std::vector<rcl_interfaces::ParameterSetResult>> f) {
    for (auto v : f.get()) {
      if (!v.successful) {
        std::cerr << v.reason << std::endl;
      }
    }
  });

  rclcpp::spin_until_future_complete(node, f1);

  auto f2 = parameters_client->get_parameters({{"foo", "baz"}});

  auto values_f2 = rclcpp::spin_until_future_complete(node, f2).get();

  for (auto p : values_f2) {
    std::cout << "Parameter name: " << p.get_name() << std::endl;
    std::cout << "Parameter value: ";
    switch (p.get_type()) {
      case rclcpp::parameter::ParameterType::PARAMETER_BOOL:
        std::cout << "(bool): " << p.get_value<bool>() ? "true" : "false";
        break;
      case rclcpp::parameter::ParameterType::PARAMETER_INTEGER:
        std::cout << "(integer): " << p.get_value<int64_t>();
        break;
      case rclcpp::parameter::ParameterType::PARAMETER_DOUBLE:
        std::cout << "(double): " << p.get_value<double>();
        break;
      case rclcpp::parameter::ParameterType::PARAMETER_STRING:
        std::cout << "(string): " << p.get_value<std::string>();
        break;
      case rclcpp::parameter::ParameterType::PARAMETER_BYTES:
        std::cout << "(bytes)";
        break;
      case rclcpp::parameter::ParameterType::PARAMETER_NOT_SET:
      default:
        std::cout << "INVALID";
    }
    std::cout << std::endl;
  }

  auto f3 = parameters_client->list_parameters({{"foo", "bar"}}, 10);

  auto result_f3 = rclcpp::spin_until_future_complete(node, f3).get();
  for (auto parameter_name : result_f3.parameter_names) {
    std::cout << "Parameter name: " << parameter_name << std::endl;
  }
  for (auto parameter_prefix : result_f3.parameter_prefixes) {
    std::cout << "Parameter prefix: " << parameter_prefix << std::endl;
  }

  rclcpp::spin(node);

  return 0;
}
<commit_msg>Use SetParametersResult<commit_after>// Copyright 2015 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <rclcpp/rclcpp.hpp>

int main(int argc, char ** argv)
{
  rclcpp::init(argc, argv);

  auto node = rclcpp::Node::make_shared("parameters");

  auto parameters_client = std::make_shared<rclcpp::parameter::AsyncParametersClient>(node);

  auto parameters = {
    rclcpp::parameter::ParameterVariant("foo", 2),
    rclcpp::parameter::ParameterVariant("bar", "hello"),
    rclcpp::parameter::ParameterVariant("baz", 1.45),
    rclcpp::parameter::ParameterVariant("foobar", true),
  };

  auto f1 = parameters_client->set_parameters(
    parameters, [](std::shared_future<std::vector<rcl_interfaces::SetParametersResult>> f) {
    for (auto v : f.get()) {
      if (!v.successful) {
        std::cerr << v.reason << std::endl;
      }
    }
  });

  rclcpp::spin_until_future_complete(node, f1);

  auto f2 = parameters_client->get_parameters({{"foo", "baz"}});

  auto values_f2 = rclcpp::spin_until_future_complete(node, f2).get();

  for (auto p : values_f2) {
    std::cout << "Parameter name: " << p.get_name() << std::endl;
    std::cout << "Parameter value: ";
    switch (p.get_type()) {
      case rclcpp::parameter::ParameterType::PARAMETER_BOOL:
        std::cout << "(bool): " << p.get_value<bool>() ? "true" : "false";
        break;
      case rclcpp::parameter::ParameterType::PARAMETER_INTEGER:
        std::cout << "(integer): " << p.get_value<int64_t>();
        break;
      case rclcpp::parameter::ParameterType::PARAMETER_DOUBLE:
        std::cout << "(double): " << p.get_value<double>();
        break;
      case rclcpp::parameter::ParameterType::PARAMETER_STRING:
        std::cout << "(string): " << p.get_value<std::string>();
        break;
      case rclcpp::parameter::ParameterType::PARAMETER_BYTES:
        std::cout << "(bytes)";
        break;
      case rclcpp::parameter::ParameterType::PARAMETER_NOT_SET:
      default:
        std::cout << "INVALID";
    }
    std::cout << std::endl;
  }

  auto f3 = parameters_client->list_parameters({{"foo", "bar"}}, 10);

  auto result_f3 = rclcpp::spin_until_future_complete(node, f3).get();
  for (auto parameter_name : result_f3.parameter_names) {
    std::cout << "Parameter name: " << parameter_name << std::endl;
  }
  for (auto parameter_prefix : result_f3.parameter_prefixes) {
    std::cout << "Parameter prefix: " << parameter_prefix << std::endl;
  }

  rclcpp::spin(node);

  return 0;
}
<|endoftext|>


<commit_before>#pragma once
//=========================================================================//
/*! @file
    @brief  UDP/TCP 共通クラス @n
			Copyright 2017 Kunihito Hiramatsu
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=========================================================================//
#include "common/fixed_block.hpp"
#include "net2/net_st.hpp"
#include "net2/memory.hpp"

#define UDP_TCP_DEBUG

namespace net {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  UDP/TCP 共通テンプレート
		@param[in]	CTX	コンテキスト
		@param[in]	NMAX	管理最大数
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template<class CTX, uint32_t NMAX>
	class udp_tcp_common {

#ifndef UDP_TCP_DEBUG
		typedef utils::null_format debug_format;
#else
		typedef utils::format debug_format;
#endif

		typedef utils::fixed_block<CTX, NMAX> BLOCKS;
		BLOCKS	blocks_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		udp_tcp_common() noexcept : blocks_() { }

		//-----------------------------------------------------------------//
		/*!
			@brief  MAC アドレス取得の検査
			@param[in]	ctx		コンテキスト
			@param[in]	info	ネット情報
			@return MAC アドレス取得済みなら「true」
		*/
		//-----------------------------------------------------------------//
		bool check_mac(CTX& ctx, net_info& info) noexcept
		{
			const auto& cash = info.get_cash();
			auto idx = cash.lookup(ctx.adrs_);
			if(cash.is_valid(idx)) {
				std::memcpy(ctx.mac_, cash[idx].mac, 6);
				debug_format("UDP/TCP MAC lookup: %s at %s\n")
					% ctx.adrs_.c_str()
					% tools::mac_str(cash[idx].mac);
				return true;
			}
			return false;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  コンテキスト・ブロックの参照
			@return コンテキスト・ブロック
		*/
		//-----------------------------------------------------------------//
		inline BLOCKS& at_blocks() noexcept
		{
			return blocks_;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  送信
			@param[in]	desc	ディスクリプタ
			@param[in]	src		ソース
			@param[in]	len		送信バイト数
			@return 送信バイト（負の値はエラー）
		*/
		//-----------------------------------------------------------------//
		int send(int desc, const void* src, uint16_t len) noexcept
		{
			uint32_t idx = static_cast<uint32_t>(desc);
			if(!blocks_.is_alloc(idx)) return -1;
			if(blocks_.is_lock(idx)) return -1;

			CTX& ctx = blocks_.at(idx);
			uint16_t spc = ctx.send_.size() - ctx.send_.length() - 1;
			if(spc < len) {
				len = spc;
			}
			ctx.send_.put(src, len);

			return len;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  送信バッファの残量取得
			@param[in]	desc	ディスクリプタ
			@return 送信バッファの残量（負の値はエラー）
		*/
		//-----------------------------------------------------------------//
		int get_send_length(int desc) const noexcept
		{
			uint32_t idx = static_cast<uint32_t>(desc);
			if(!blocks_.is_alloc(idx)) return -1;
			if(blocks_.is_lock(idx)) return -1;

			const CTX& ctx = blocks_.get(idx);
			return ctx.send_.length();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  受信
			@param[in]	desc	ディスクリプタ
			@param[in]	dst		ソース
			@param[in]	len		受信バイト数
			@return 受信バイト（負の値はエラー）
		*/
		//-----------------------------------------------------------------//
		int recv(int desc, void* dst, uint16_t len) noexcept
		{
			uint32_t idx = static_cast<uint32_t>(desc);
			if(!blocks_.is_alloc(idx)) return -1;
			if(blocks_.is_lock(idx)) return -1;

			CTX& ctx = blocks_.at(idx);
			int rlen = ctx.recv_.length();
			if(rlen == 0) {  // 読み込むデータが無い
				return rlen;
			}

			if(rlen > len) {
				rlen = len;
			}
			ctx.recv_.get(dst, rlen);
			return rlen;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  受信バッファの残量取得
			@param[in]	desc	ディスクリプタ
			@return 受信バッファの残量（負の値はエラー）
		*/
		//-----------------------------------------------------------------//
		int get_recv_length(int desc) const noexcept
		{
			uint32_t idx = static_cast<uint32_t>(desc);
			if(!blocks_.is_alloc(idx)) return -1;
			if(blocks_.is_lock(idx)) return -1;

			const CTX& ctx = blocks_.get(idx);
			return ctx.recv_.length();
		}
	};
}
<commit_msg>add const access API<commit_after>#pragma once
//=========================================================================//
/*! @file
    @brief  UDP/TCP 共通クラス @n
			Copyright 2017 Kunihito Hiramatsu
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=========================================================================//
#include "common/fixed_block.hpp"
#include "net2/net_st.hpp"
#include "net2/memory.hpp"

#define UDP_TCP_DEBUG

namespace net {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  UDP/TCP 共通テンプレート
		@param[in]	CTX	コンテキスト
		@param[in]	NMAX	管理最大数
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template<class CTX, uint32_t NMAX>
	class udp_tcp_common {

#ifndef UDP_TCP_DEBUG
		typedef utils::null_format debug_format;
#else
		typedef utils::format debug_format;
#endif

		typedef utils::fixed_block<CTX, NMAX> BLOCKS;
		BLOCKS	blocks_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		udp_tcp_common() noexcept : blocks_() { }

		//-----------------------------------------------------------------//
		/*!
			@brief  MAC アドレス取得の検査
			@param[in]	ctx		コンテキスト
			@param[in]	info	ネット情報
			@return MAC アドレス取得済みなら「true」
		*/
		//-----------------------------------------------------------------//
		bool check_mac(CTX& ctx, net_info& info) noexcept
		{
			const auto& cash = info.get_cash();
			auto idx = cash.lookup(ctx.adrs_);
			if(cash.is_valid(idx)) {
				std::memcpy(ctx.mac_, cash[idx].mac, 6);
				debug_format("UDP/TCP MAC lookup: %s at %s\n")
					% ctx.adrs_.c_str()
					% tools::mac_str(cash[idx].mac);
				return true;
			}
			return false;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  コンテキスト・ブロックの参照
			@return コンテキスト・ブロック
		*/
		//-----------------------------------------------------------------//
		inline BLOCKS& at_blocks() noexcept
		{
			return blocks_;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  コンテキスト・ブロックの参照（const）
			@return コンテキスト・ブロック
		*/
		//-----------------------------------------------------------------//
		inline const BLOCKS& get_blocks() const noexcept
		{
			return blocks_;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  送信
			@param[in]	desc	ディスクリプタ
			@param[in]	src		ソース
			@param[in]	len		送信バイト数
			@return 送信バイト（負の値はエラー）
		*/
		//-----------------------------------------------------------------//
		int send(int desc, const void* src, uint16_t len) noexcept
		{
			uint32_t idx = static_cast<uint32_t>(desc);
			if(!blocks_.is_alloc(idx)) return -1;
			if(blocks_.is_lock(idx)) return -1;

			CTX& ctx = blocks_.at(idx);
			uint16_t spc = ctx.send_.size() - ctx.send_.length() - 1;
			if(spc < len) {
				len = spc;
			}
			ctx.send_.put(src, len);

			return len;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  送信バッファの残量取得
			@param[in]	desc	ディスクリプタ
			@return 送信バッファの残量（負の値はエラー）
		*/
		//-----------------------------------------------------------------//
		int get_send_length(int desc) const noexcept
		{
			uint32_t idx = static_cast<uint32_t>(desc);
			if(!blocks_.is_alloc(idx)) return -1;
			if(blocks_.is_lock(idx)) return -1;

			const CTX& ctx = blocks_.get(idx);
			return ctx.send_.length();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  受信
			@param[in]	desc	ディスクリプタ
			@param[in]	dst		ソース
			@param[in]	len		受信バイト数
			@return 受信バイト（負の値はエラー）
		*/
		//-----------------------------------------------------------------//
		int recv(int desc, void* dst, uint16_t len) noexcept
		{
			uint32_t idx = static_cast<uint32_t>(desc);
			if(!blocks_.is_alloc(idx)) return -1;
			if(blocks_.is_lock(idx)) return -1;

			CTX& ctx = blocks_.at(idx);
			int rlen = ctx.recv_.length();
			if(rlen == 0) {  // 読み込むデータが無い
				return rlen;
			}

			if(rlen > len) {
				rlen = len;
			}
			ctx.recv_.get(dst, rlen);
			return rlen;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  受信バッファの残量取得
			@param[in]	desc	ディスクリプタ
			@return 受信バッファの残量（負の値はエラー）
		*/
		//-----------------------------------------------------------------//
		int get_recv_length(int desc) const noexcept
		{
			uint32_t idx = static_cast<uint32_t>(desc);
			if(!blocks_.is_alloc(idx)) return -1;
			if(blocks_.is_lock(idx)) return -1;

			const CTX& ctx = blocks_.get(idx);
			return ctx.recv_.length();
		}
	};
}
<|endoftext|>


<commit_before>/*
 *  This file is part of Poedit (http://www.poedit.net)
 *
 *  Copyright (C) 2013 Vaclav Slavik
 *
 *  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.
 *
 */

#include "languagectrl.h"

#include <wx/config.h>
#include <wx/sizer.h>
#include <wx/stattext.h>

IMPLEMENT_DYNAMIC_CLASS(LanguageCtrl, wxComboBox)

LanguageCtrl::LanguageCtrl(wxWindow *parent, wxWindowID winid)
    : wxComboBox(parent, winid)
{
    Init();
}

void LanguageCtrl::Init()
{
    SetHint(_("Language Code or Name (e.g. en_GB)"));

    for (auto x: Language::AllFormattedNames())
        Append(x);

    m_inited = true;
}

void LanguageCtrl::SetLang(const Language& lang)
{
    if (!m_inited)
        Init();

    SetValue(lang.FormatForRoundtrip());
}

Language LanguageCtrl::GetLang() const
{
    return Language::TryParse(GetValue());
}

#ifdef __WXMSW__
wxSize LanguageCtrl::DoGetBestSize() const
{
    // wxComboBox's implementation is insanely slow, at least on MSW.
    // Hardcode a value instead, it doesn't matter for Poedit's use anyway,
    // this control's best size is not the determining factor.
    return GetSizeFromTextSize(100);
}
#endif

LanguageDialog::LanguageDialog(wxWindow *parent)
    : wxDialog(parent, wxID_ANY, _("Translation Language")),
      m_validatedLang(-1)
{
    auto sizer = new wxBoxSizer(wxVERTICAL);

    auto label = new wxStaticText(this, wxID_ANY, _("Language of the translation:"));
    m_language = new LanguageCtrl(this);
    m_language->SetMinSize(wxSize(300,-1));
    auto buttons = CreateButtonSizer(wxOK | wxCANCEL);

#ifdef __WXOSX__
    sizer->AddSpacer(10);
    sizer->Add(label, wxSizerFlags().Border());
    sizer->Add(m_language, wxSizerFlags().Expand().DoubleBorder(wxLEFT|wxRIGHT));
    sizer->Add(buttons, wxSizerFlags().Expand());
#else
    sizer->AddSpacer(10);
    sizer->Add(label, wxSizerFlags().DoubleBorder(wxLEFT|wxRIGHT));
    sizer->Add(m_language, wxSizerFlags().Expand().DoubleBorder(wxLEFT|wxRIGHT));
    sizer->Add(buttons, wxSizerFlags().Expand().Border());
#endif

    m_language->Bind(wxEVT_TEXT,     [=](wxCommandEvent&){ m_validatedLang = -1; });
    m_language->Bind(wxEVT_COMBOBOX, [=](wxCommandEvent&){ m_validatedLang = -1; });

    wxString lang = wxConfigBase::Get()->Read("/last_translation_lang", "");
    if (!lang.empty())
        SetLang(Language::TryParse(lang));

    Bind(wxEVT_UPDATE_UI,
        [=](wxUpdateUIEvent& e){ e.Enable(Validate()); },
        wxID_OK);

    SetSizerAndFit(sizer);
    CenterOnParent();
}

bool LanguageDialog::Validate()
{
    if (m_validatedLang == -1)
    {
        m_validatedLang = m_language->IsValid() ? 1 : 0;
    }

    return m_validatedLang == 1;
}

void LanguageDialog::EndModal(int retval)
{
    if (retval == wxID_OK)
    {
        wxConfigBase::Get()->Write("/last_translation_lang", GetLang().Code().c_str());
    }
    wxDialog::EndModal(retval);
}

void LanguageDialog::SetLang(const Language& lang)
{
    m_validatedLang = -1;
    m_language->SetLang(lang);
}
<commit_msg>Set focus in language dialog.<commit_after>/*
 *  This file is part of Poedit (http://www.poedit.net)
 *
 *  Copyright (C) 2013 Vaclav Slavik
 *
 *  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.
 *
 */

#include "languagectrl.h"

#include <wx/config.h>
#include <wx/sizer.h>
#include <wx/stattext.h>

IMPLEMENT_DYNAMIC_CLASS(LanguageCtrl, wxComboBox)

LanguageCtrl::LanguageCtrl(wxWindow *parent, wxWindowID winid)
    : wxComboBox(parent, winid)
{
    Init();
}

void LanguageCtrl::Init()
{
    SetHint(_("Language Code or Name (e.g. en_GB)"));

    for (auto x: Language::AllFormattedNames())
        Append(x);

    m_inited = true;
}

void LanguageCtrl::SetLang(const Language& lang)
{
    if (!m_inited)
        Init();

    SetValue(lang.FormatForRoundtrip());
}

Language LanguageCtrl::GetLang() const
{
    return Language::TryParse(GetValue());
}

#ifdef __WXMSW__
wxSize LanguageCtrl::DoGetBestSize() const
{
    // wxComboBox's implementation is insanely slow, at least on MSW.
    // Hardcode a value instead, it doesn't matter for Poedit's use anyway,
    // this control's best size is not the determining factor.
    return GetSizeFromTextSize(100);
}
#endif

LanguageDialog::LanguageDialog(wxWindow *parent)
    : wxDialog(parent, wxID_ANY, _("Translation Language")),
      m_validatedLang(-1)
{
    auto sizer = new wxBoxSizer(wxVERTICAL);

    auto label = new wxStaticText(this, wxID_ANY, _("Language of the translation:"));
    m_language = new LanguageCtrl(this);
    m_language->SetMinSize(wxSize(300,-1));
    auto buttons = CreateButtonSizer(wxOK | wxCANCEL);

#ifdef __WXOSX__
    sizer->AddSpacer(10);
    sizer->Add(label, wxSizerFlags().Border());
    sizer->Add(m_language, wxSizerFlags().Expand().DoubleBorder(wxLEFT|wxRIGHT));
    sizer->Add(buttons, wxSizerFlags().Expand());
#else
    sizer->AddSpacer(10);
    sizer->Add(label, wxSizerFlags().DoubleBorder(wxLEFT|wxRIGHT));
    sizer->Add(m_language, wxSizerFlags().Expand().DoubleBorder(wxLEFT|wxRIGHT));
    sizer->Add(buttons, wxSizerFlags().Expand().Border());
#endif

    m_language->Bind(wxEVT_TEXT,     [=](wxCommandEvent&){ m_validatedLang = -1; });
    m_language->Bind(wxEVT_COMBOBOX, [=](wxCommandEvent&){ m_validatedLang = -1; });

    wxString lang = wxConfigBase::Get()->Read("/last_translation_lang", "");
    if (!lang.empty())
        SetLang(Language::TryParse(lang));

    Bind(wxEVT_UPDATE_UI,
        [=](wxUpdateUIEvent& e){ e.Enable(Validate()); },
        wxID_OK);

    SetSizerAndFit(sizer);
    CenterOnParent();

    m_language->SetFocus();
#ifdef __WXOSX__
    // Workaround wx bug: http://trac.wxwidgets.org/ticket/9521
    m_language->SelectAll();
#endif
}

bool LanguageDialog::Validate()
{
    if (m_validatedLang == -1)
    {
        m_validatedLang = m_language->IsValid() ? 1 : 0;
    }

    return m_validatedLang == 1;
}

void LanguageDialog::EndModal(int retval)
{
    if (retval == wxID_OK)
    {
        wxConfigBase::Get()->Write("/last_translation_lang", GetLang().Code().c_str());
    }
    wxDialog::EndModal(retval);
}

void LanguageDialog::SetLang(const Language& lang)
{
    m_validatedLang = -1;
    m_language->SetLang(lang);
}
<|endoftext|>


<commit_before>#ifndef WINDOWS_CONNECTION_HPP
#define WINDOWS_CONNECTION_HPP

// adapted from https://msdn.microsoft.com/en-us/library/ms738545(v=vs.85).aspx

#include <string>
#include <array>
#include <winsock2.h>
#include <ws2tcpip.h>

namespace cpp_client
{

class Connection_internal
{
public:
   Connection_internal() :
      sock_(INVALID_SOCKET),
      buffer_()
   {
      WSADATA wsa_data;
      const auto res = WSAStartup(MAKEWORD(2, 2), &wsa_data);
      if(res != 0)
      {
         throw Communication_error("Initialization error - could not connect to server.");
      }
   }

   void connect(const char* host, unsigned port)
   {
      struct Free_addr
      {
         addrinfo* info;
         ~Free_addr()
         {
            freeaddrinfo(info);
         }
      };
      // can have temporary name resolution failure so specify a number of tries
      constexpr auto num_tries = 3;
      // set up structures needed
      addrinfo* result;
      addrinfo hints;
      ZeroMemory(&hints, sizeof(hints));
      hints.ai_family = AF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_protocol = IPPROTO_IP;
      const auto port_str = std::to_string(port);
      // now try to connect
      for(auto i = 0; i < num_tries; ++i)
      {
         const auto resaddr = getaddrinfo(host, port_str.c_str(), &hints, &result);
         // free the memory allocated if going out of scope
         Free_addr dummy{result};
         using ce = Communication_error;
         if(resaddr != 0)
         {
            switch(resaddr)
            {
            case WSATRY_AGAIN:          continue;
            case WSANO_RECOVERY:        throw ce("Could not resolve host name - Unrecoverable error.");
            case WSA_NOT_ENOUGH_MEMORY: throw ce("Could not resolve host name - Out of memory.");
            case WSAHOST_NOT_FOUND:     throw ce("Could not resolve host name - Host not found.");
            default:                    throw ce("Could not resolve host name - Unknown error.");
            }
         }
         // now create the socket by trying to connect to all possible addresses
         for(auto ptr = result; ptr; ptr = ptr->ai_next)
         {
            sock_ = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
            if(sock_ == INVALID_SOCKET)
            {
               continue;
            }
            const auto res = ::connect(sock_, ptr->ai_addr, static_cast<int>(ptr->ai_addrlen));
            if(res == SOCKET_ERROR)
            {
               closesocket(sock_);
               sock_ = INVALID_SOCKET;
            }
         }
      }
      // if sock_ is invalid some sort of error occured
      if(sock_ == INVALID_SOCKET)
      {
         throw Communication_error("Could not connect to server.");
      }
   }

   void send(const std::string& msg)
   {
      // need to fragment messages if it gets too large
      static const auto max_size = [this](){
         unsigned size;
         auto size_val = static_cast<int>(sizeof(size));
         getsockopt(sock_,
                    SOL_SOCKET,
                    SO_MAX_MSG_SIZE,
                    reinterpret_cast<char*>(&size),
                    &size_val);
         return static_cast<decltype(msg.size())>(size);
      }();
      // error checking
      const auto check_err = [](int err) {
         if(err != SOCKET_ERROR)
         {
            throw Communication_error("Sending data failed.");
         }
      };
      const char* loc = msg.c_str();
      auto left = msg.size();
      // send the message in max_size chunks
      while(left > 0)
      {
         // std::min in parentheses because min is a Windows macro
         const auto to_send = (std::min)(max_size, left);
         check_err(::send(sock_, loc, to_send, 0));
         left -= to_send;
         loc += to_send;
      }
   }

   std::string recieve()
   {
      std::array<char, 2048> read_buffer;
      std::string to_return;
      to_return.reserve(read_buffer.size());
      //put anything left over into the message to start
      to_return += buffer_;
      auto split_point = to_return.find('\x04');
      while(split_point == std::string::npos)
      {
         const auto received = recv(sock_, read_buffer.data(), read_buffer.size(), 0);
         if(received == SOCKET_ERROR)
         {
            throw Communication_error("Receiving data failed.");
         }
         to_return.append(read_buffer.data(), received);
         split_point = to_return.find('\x04');
      }
      //now split by the 0x04
      buffer_ = to_return.substr(split_point + 1);
      to_return = to_return.substr(0, split_point);
      return to_return;
   }

   ~Connection_internal()
   {
      if(sock_ != INVALID_SOCKET)
      {
         closesocket(sock_);
      }
      WSACleanup();
   }

private:
   SOCKET sock_;
   std::string buffer_;
};

} // cpp_client

#endif // WINDOWS_CONNECTION_HPP
<commit_msg>Added more detailed errors for Windows.<commit_after>#ifndef WINDOWS_CONNECTION_HPP
#define WINDOWS_CONNECTION_HPP

// adapted from https://msdn.microsoft.com/en-us/library/ms738545(v=vs.85).aspx

#include <string>
#include <array>
#include <winsock2.h>
#include <ws2tcpip.h>

namespace cpp_client
{

class Connection_internal
{
public:
   Connection_internal() :
      sock_(INVALID_SOCKET),
      buffer_()
   {
      WSADATA wsa_data;
      const auto res = WSAStartup(MAKEWORD(2, 2), &wsa_data);
      if(res != 0)
      {
         throw Communication_error{"Initialization error - could not connect to server."};
      }
   }

   // translates and throws a communication error on send or recieve
   [[noreturn]] void throw_comm_error()
   {
      using ce = Communication_error;
      switch(WSAGetLastError())
      {
      case WSANOTINITIALISED: throw ce{"WSA wasn't initalized??"};
      case WSAENETDOWN:       throw ce{"Network subsystem failed."};
      case WSAEACCES:         throw ce{"Address is a broadcast address."};
      case WSAEFAULT:         throw ce{"Buffer out of user address space??"};
      case WSAENOBUFS:        throw ce{"No buffers available."};
      case WSAENOTCONN:       throw ce{"Socket not connected??"};
      case WSAENOTSOCK:       throw ce{"Socket isn't a socket??"};
      case WSAEMSGSIZE:       throw ce{"Message size too big."};
      case WSAEHOSTUNREACH:   throw ce{"Host could not be reached."};
      case WSAETIMEDOUT:      throw ce{"Connection timed out."};
      default:                throw ce{"Uknown error."};
      }
   }

   void connect(const char* host, unsigned port)
   {
      struct Free_addr
      {
         addrinfo* info;
         ~Free_addr()
         {
            freeaddrinfo(info);
         }
      };
      // can have temporary name resolution failure so specify a number of tries
      constexpr auto num_tries = 3;
      // set up structures needed
      addrinfo* result;
      addrinfo hints;
      ZeroMemory(&hints, sizeof(hints));
      hints.ai_family = AF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_protocol = IPPROTO_IP;
      const auto port_str = std::to_string(port);
      // now try to connect
      for(auto i = 0; i < num_tries; ++i)
      {
         const auto resaddr = getaddrinfo(host, port_str.c_str(), &hints, &result);
         // free the memory allocated if going out of scope
         Free_addr dummy{result};
         using ce = Communication_error;
         if(resaddr != 0)
         {
            switch(resaddr)
            {
            case WSATRY_AGAIN:          continue;
            case WSANO_RECOVERY:        throw ce{"Could not resolve host name - Unrecoverable error."};
            case WSA_NOT_ENOUGH_MEMORY: throw ce{"Could not resolve host name - Out of memory."};
            case WSAHOST_NOT_FOUND:     throw ce{"Could not resolve host name - Host not found."};
            default:                    throw ce{"Could not resolve host name - Unknown error."};
            }
         }
         // now create the socket by trying to connect to all possible addresses
         for(auto ptr = result; ptr; ptr = ptr->ai_next)
         {
            sock_ = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
            if(sock_ == INVALID_SOCKET)
            {
               continue;
            }
            const auto res = ::connect(sock_, ptr->ai_addr, static_cast<int>(ptr->ai_addrlen));
            if(res == SOCKET_ERROR)
            {
               closesocket(sock_);
               sock_ = INVALID_SOCKET;
            }
         }
      }
      // if sock_ is invalid some sort of error occured
      if(sock_ == INVALID_SOCKET)
      {
         throw Communication_error("Could not connect to server.");
      }
   }

   void send(const std::string& msg)
   {
      // need to fragment messages if it gets too large
      static const auto max_size = [this](){
         unsigned size;
         auto size_val = static_cast<int>(sizeof(size));
         getsockopt(sock_,
                    SOL_SOCKET,
                    SO_MAX_MSG_SIZE,
                    reinterpret_cast<char*>(&size),
                    &size_val);
         return static_cast<decltype(msg.size())>(size);
      }();
      const char* loc = msg.c_str();
      auto left = msg.size();
      // send the message in max_size chunks
      while(left > 0)
      {
         // std::min in parentheses because min is a Windows macro
         const auto to_send = (std::min)(max_size, left);
         if(::send(sock_, loc, to_send, 0) == SOCKET_ERROR)
         {
            throw_comm_error();
         }
         left -= to_send;
         loc += to_send;
      }
   }

   std::string recieve()
   {
      std::array<char, 2048> read_buffer;
      std::string to_return;
      to_return.reserve(read_buffer.size());
      //put anything left over into the message to start
      to_return += buffer_;
      auto split_point = to_return.find('\x04');
      while(split_point == std::string::npos)
      {
         const auto received = recv(sock_, read_buffer.data(), read_buffer.size(), 0);
         if(received == SOCKET_ERROR)
         {
            throw_comm_error();
         }
         to_return.append(read_buffer.data(), received);
         split_point = to_return.find('\x04');
      }
      //now split by the 0x04
      buffer_ = to_return.substr(split_point + 1);
      to_return = to_return.substr(0, split_point);
      return to_return;
   }

   ~Connection_internal()
   {
      if(sock_ != INVALID_SOCKET)
      {
         closesocket(sock_);
      }
      WSACleanup();
   }

private:
   SOCKET sock_;
   std::string buffer_;
};

} // cpp_client

#endif // WINDOWS_CONNECTION_HPP
<|endoftext|>


<commit_before>/* idmapping.cc			KPilot
**
** Copyright (C) 2007 by Bertjan Broeksema <b.broeksema@kdemail.net>
** Copyright (C) 2007 by Jason "vanRijn" Kasper <vr@movingparts.net>
*/
/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/
#include "idmapping.h"

#include "options.h"

IDMapping::IDMapping( const QString &userName, const QString &conduit )
	: fSource( userName, conduit )
{
	FUNCTIONSETUP;

	fSource.loadMapping();
}

bool IDMapping::isValid( const QList<QString> &ids ) const
{
	FUNCTIONSETUP;

	const QMap<QString, QString>* mappings = fSource.constMappings();
	int idsSize = ids.size();

	// should be a 1..1 mapping between keys and values
	bool equalSize = (mappings->uniqueKeys().size() == idsSize);

	if(equalSize)
	{
		bool idsInMapping = true;

		QList<QString>::const_iterator i;
		QList<QString> mIds;

		// now, check for validity of mappings.  *note* we can stop
		// looking if we find at least one problem.
		if( fSource.constMappings()->contains( *ids.constBegin() ) )
		{
			// The ids are hanhdeld ids.
			mIds = fSource.constMappings()->keys();
			for( i = mIds.constBegin(); i != mIds.constEnd(); ++i )
			{
				QString id = *i;
				idsInMapping = idsInMapping && ids.contains( id );

				if (!idsInMapping) break;
			}
		}
		else
		{
			// The ids are pc ids.
			mIds = fSource.constMappings()->values();
			for( i = mIds.constBegin(); i != mIds.constEnd(); ++i )
			{
				QString id = *i;
				idsInMapping = idsInMapping && ids.contains( id );

				if (!idsInMapping) break;
			}
		}

		// if we're otherwise valid, double-check and make sure that
		// we also have only unique values in our mapping...
		if (idsInMapping)
		{
			// build a reverse map and check the count at the end...
			QMap<QString, int> revMap;

			QMapIterator<QString, QString> it( *mappings );
			while (it.hasNext()) {
				it.next();
				revMap.insert(it.value(), 1);
			}
			idsInMapping = (revMap.uniqueKeys().size() == idsSize);
			DEBUGKPILOT << "Reverse map integrity: ["
				<< idsInMapping << "]";
		}

		DEBUGKPILOT << "Returning: [" << idsInMapping << "]";

		return idsInMapping;
	}

	return false;
}

void IDMapping::map( const QString &hhRecordId, const QString &pcId )
{
	FUNCTIONSETUP;

	// check to see if we already have a key with this value
	QString existingHhRecordId = fSource.constMappings()->key(pcId);

	// if we already have a key for this one and it isn't the hhRecordId
	// that is being passed in, it's an error
	if ( ! existingHhRecordId.isEmpty() )
	{
		WARNINGKPILOT << "Error.  pcId:[" << pcId
			<< "] already mapped to hhRecordId: [" << existingHhRecordId
			<< "].  Shouldn't have same pcId mapped also to incoming: ["
			<< hhRecordId << "].  Removing it.";

		fSource.mappings()->remove( existingHhRecordId );
	}

	fSource.mappings()->insert( hhRecordId, pcId );
}

QString IDMapping::pcRecordId( const QString &id ) const
{
	FUNCTIONSETUP;

	return fSource.constMappings()->value( id );
}

QString IDMapping::hhRecordId( const QString &id ) const
{
	FUNCTIONSETUP;

	return fSource.constMappings()->key( id );
}

void IDMapping::removeHHId( const QString &recordId )
{
	FUNCTIONSETUP;

	fSource.mappings()->remove( recordId );
}

void IDMapping::removePCId( const QString &recordId )
{
	FUNCTIONSETUP;

	// The recordId is one of a pc record.
	QString hhId = fSource.mappings()->key( recordId );
	if( !hhId.isEmpty() )
	{
		fSource.mappings()->remove( hhId );
	}
}

bool IDMapping::containsHHId( const QString &recordId ) const
{
	FUNCTIONSETUP;

	return fSource.constMappings()->contains( recordId );
}

bool IDMapping::containsPCId( const QString &recordId ) const
{
	FUNCTIONSETUP;

	return fSource.constMappings()->values().contains( recordId );
}

void IDMapping::changeHHId( const QString &from, const QString &to )
{
	FUNCTIONSETUP;

	QString pcId = pcRecordId( from );
	fSource.mappings()->remove( from );
	fSource.mappings()->insert( to, pcId );
}

void IDMapping::changePCId( const QString &from, const QString &to )
{
	FUNCTIONSETUP;

	QString hhId = hhRecordId( from );
	fSource.mappings()->insert( hhId, to );
}

bool IDMapping::isArchivedRecord( const QString &pcRecordId ) const
{
	FUNCTIONSETUP;

	return fSource.constArchivedRecords()->contains( pcRecordId );
}

void IDMapping::archiveRecord( const QString &hhRecordId )
{
	FUNCTIONSETUP;

	if( containsHHId( hhRecordId ) )
	{
		QString pcRecordId = this->pcRecordId( hhRecordId );
		fSource.archivedRecords()->append( pcRecordId );
	}
}

void IDMapping::setLastSyncedDate( const QDateTime &dateTime )
{
	FUNCTIONSETUP;

	fSource.setLastSyncedDate( dateTime );
}

void IDMapping::setLastSyncedPC( const QString &pc )
{
	FUNCTIONSETUP;

	fSource.setLastSyncedPC( pc );
}

bool IDMapping::commit()
{
	FUNCTIONSETUP;

	return fSource.saveMapping();
}

bool IDMapping::rollback()
{
	FUNCTIONSETUP;

	return fSource.rollback();
}
<commit_msg>- using QSet to validate unique QMap values for performance<commit_after>/* idmapping.cc			KPilot
**
** Copyright (C) 2007 by Bertjan Broeksema <b.broeksema@kdemail.net>
** Copyright (C) 2007 by Jason "vanRijn" Kasper <vr@movingparts.net>
*/
/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/
#include "idmapping.h"

#include "options.h"

IDMapping::IDMapping( const QString &userName, const QString &conduit )
	: fSource( userName, conduit )
{
	FUNCTIONSETUP;

	fSource.loadMapping();
}

bool IDMapping::isValid( const QList<QString> &ids ) const
{
	FUNCTIONSETUP;

	const QMap<QString, QString>* mappings = fSource.constMappings();
	int idsSize = ids.size();

	// should be a 1..1 mapping between keys and values
	bool equalSize = (mappings->uniqueKeys().size() == idsSize);

	if(equalSize)
	{
		bool idsInMapping = true;

		QList<QString>::const_iterator i;
		QList<QString> mIds;

		// now, check for validity of mappings.  *note* we can stop
		// looking if we find at least one problem.
		if( fSource.constMappings()->contains( *ids.constBegin() ) )
		{
			// The ids are hanhdeld ids.
			mIds = fSource.constMappings()->keys();
			for( i = mIds.constBegin(); i != mIds.constEnd(); ++i )
			{
				QString id = *i;
				idsInMapping = idsInMapping && ids.contains( id );

				if (!idsInMapping) break;
			}
		}
		else
		{
			// The ids are pc ids.
			mIds = fSource.constMappings()->values();
			for( i = mIds.constBegin(); i != mIds.constEnd(); ++i )
			{
				QString id = *i;
				idsInMapping = idsInMapping && ids.contains( id );

				if (!idsInMapping) break;
			}
		}

		// if we're otherwise valid, double-check and make sure that
		// we also have only unique values in our mapping...
		if (idsInMapping)
		{
			// build a unique list (set) of values and make sure we
			// have a 1..1 mapping
			QSet<QString> values = mappings->values().toSet();
			idsInMapping = (values.size() == idsSize);
			DEBUGKPILOT << "Reverse map integrity: ["
				<< idsInMapping << "]";
		}

		DEBUGKPILOT << "Returning: [" << idsInMapping << "]";

		return idsInMapping;
	}

	return false;
}

void IDMapping::map( const QString &hhRecordId, const QString &pcId )
{
	FUNCTIONSETUP;

	// check to see if we already have a key with this value
	QString existingHhRecordId = fSource.constMappings()->key(pcId);

	// if we already have a key for this one and it isn't the hhRecordId
	// that is being passed in, it's an error
	if ( ! existingHhRecordId.isEmpty() )
	{
		WARNINGKPILOT << "Error.  pcId:[" << pcId
			<< "] already mapped to hhRecordId: [" << existingHhRecordId
			<< "].  Shouldn't have same pcId mapped also to incoming: ["
			<< hhRecordId << "].  Removing it.";

		fSource.mappings()->remove( existingHhRecordId );
	}

	fSource.mappings()->insert( hhRecordId, pcId );
}

QString IDMapping::pcRecordId( const QString &id ) const
{
	FUNCTIONSETUP;

	return fSource.constMappings()->value( id );
}

QString IDMapping::hhRecordId( const QString &id ) const
{
	FUNCTIONSETUP;

	return fSource.constMappings()->key( id );
}

void IDMapping::removeHHId( const QString &recordId )
{
	FUNCTIONSETUP;

	fSource.mappings()->remove( recordId );
}

void IDMapping::removePCId( const QString &recordId )
{
	FUNCTIONSETUP;

	// The recordId is one of a pc record.
	QString hhId = fSource.mappings()->key( recordId );
	if( !hhId.isEmpty() )
	{
		fSource.mappings()->remove( hhId );
	}
}

bool IDMapping::containsHHId( const QString &recordId ) const
{
	FUNCTIONSETUP;

	return fSource.constMappings()->contains( recordId );
}

bool IDMapping::containsPCId( const QString &recordId ) const
{
	FUNCTIONSETUP;

	return fSource.constMappings()->values().contains( recordId );
}

void IDMapping::changeHHId( const QString &from, const QString &to )
{
	FUNCTIONSETUP;

	QString pcId = pcRecordId( from );
	fSource.mappings()->remove( from );
	fSource.mappings()->insert( to, pcId );
}

void IDMapping::changePCId( const QString &from, const QString &to )
{
	FUNCTIONSETUP;

	QString hhId = hhRecordId( from );
	fSource.mappings()->insert( hhId, to );
}

bool IDMapping::isArchivedRecord( const QString &pcRecordId ) const
{
	FUNCTIONSETUP;

	return fSource.constArchivedRecords()->contains( pcRecordId );
}

void IDMapping::archiveRecord( const QString &hhRecordId )
{
	FUNCTIONSETUP;

	if( containsHHId( hhRecordId ) )
	{
		QString pcRecordId = this->pcRecordId( hhRecordId );
		fSource.archivedRecords()->append( pcRecordId );
	}
}

void IDMapping::setLastSyncedDate( const QDateTime &dateTime )
{
	FUNCTIONSETUP;

	fSource.setLastSyncedDate( dateTime );
}

void IDMapping::setLastSyncedPC( const QString &pc )
{
	FUNCTIONSETUP;

	fSource.setLastSyncedPC( pc );
}

bool IDMapping::commit()
{
	FUNCTIONSETUP;

	return fSource.saveMapping();
}

bool IDMapping::rollback()
{
	FUNCTIONSETUP;

	return fSource.rollback();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: display.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 20:04:02 $
 *
 *  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_vcl.hxx"

#ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
#include <com/sun/star/container/XIndexAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_RECTANGLE_HPP_
#include <com/sun/star/awt/Rectangle.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif

#include <vcl/svapp.hxx>

#include <cppuhelper/implbase3.hxx>
#include <cppuhelper/implbase4.hxx>

#include <vector>
#include <tools/debug.hxx>

using ::rtl::OUString;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::beans;

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

namespace vcl
{

class DisplayInfo : public ::cppu::WeakAggImplHelper3< XPropertySet, XPropertySetInfo, XServiceInfo >
{
public:
    DisplayInfo( sal_uInt32 nDisplay );

    // XPropertySet
    virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw (RuntimeException);
    virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException);
    virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);

    // XPropertySetInfo
    virtual Sequence< Property > SAL_CALL getProperties(  ) throw (RuntimeException);
    virtual Property SAL_CALL getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException);
    virtual ::sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) throw (RuntimeException);

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

private:
    sal_uInt32 mnDisplay;
};

static const char* pScreenAreaName = "ScreenArea";
static const char* pWorkAreaName = "WorkArea";
static const char* pScreenName = "ScreenName";

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

DisplayInfo::DisplayInfo( sal_uInt32 nDisplay )
: mnDisplay( nDisplay )
{
}

// XPropertySet
Reference< XPropertySetInfo > SAL_CALL DisplayInfo::getPropertySetInfo(  ) throw (RuntimeException)
{
    return this;
}

void SAL_CALL DisplayInfo::setPropertyValue( const OUString& /*aPropertyName* */, const Any& /*aValue*/ ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
{
    throw PropertyVetoException();
}

Any SAL_CALL DisplayInfo::getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
{
    Rectangle aRect;
    if( PropertyName.equalsAscii( pScreenAreaName ) )
    {
        aRect = Application::GetScreenPosSizePixel( mnDisplay );
    }
    else if( PropertyName.equalsAscii( pWorkAreaName ) )
    {
        aRect = Application::GetWorkAreaPosSizePixel( mnDisplay );
    }
    else if( PropertyName.equalsAscii( pScreenName ) )
    {
        return Any( Application::GetScreenName( mnDisplay ) );
    }
    else
        throw UnknownPropertyException();

    return Any( com::sun::star::awt::Rectangle( aRect.Left(), aRect.Top(), aRect.getWidth(), aRect.getHeight() ) );
}

void SAL_CALL DisplayInfo::addPropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
void SAL_CALL DisplayInfo::removePropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
void SAL_CALL DisplayInfo::addVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
void SAL_CALL DisplayInfo::removeVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}

// XPropertySetInfo
Sequence< Property > SAL_CALL DisplayInfo::getProperties(  ) throw (RuntimeException)
{
    Sequence< Property > aProps(2);
    aProps[0] = getPropertyByName( OUString::createFromAscii( pScreenAreaName ) );
    aProps[1] = getPropertyByName( OUString::createFromAscii( pWorkAreaName ) );
    return aProps;
}

Property SAL_CALL DisplayInfo::getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException)
{
    if( aName.equalsAscii( pScreenAreaName ) ||
        aName.equalsAscii( pWorkAreaName ) )
        return Property( aName, 0, ::getCppuType( (::com::sun::star::awt::Rectangle const *)0 ), PropertyAttribute::READONLY );
    throw UnknownPropertyException();
}

::sal_Bool SAL_CALL DisplayInfo::hasPropertyByName( const OUString& Name ) throw (RuntimeException)
{
    return Name.equalsAscii( pScreenAreaName ) ||
           Name.equalsAscii( pWorkAreaName );
}

// XServiceInfo
OUString SAL_CALL DisplayInfo::getImplementationName(  ) throw (RuntimeException)
{
    static OUString aImplementationName( RTL_CONSTASCII_USTRINGPARAM( "vcl::DisplayInfo" ) );
    return aImplementationName;
}

::sal_Bool SAL_CALL DisplayInfo::supportsService( const OUString& ServiceName ) throw (RuntimeException)
{
    Sequence< OUString > aSN( getSupportedServiceNames() );
    for( sal_Int32 nService = 0; nService < aSN.getLength(); nService++ )
    {
        if( aSN[nService] == ServiceName )
            return sal_True;
    }
    return sal_False;
}

Sequence< OUString > SAL_CALL DisplayInfo::getSupportedServiceNames(  ) throw (RuntimeException)
{
    static OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DisplayInfo" ) );
    static Sequence< OUString > aServiceNames( &aServiceName, 1  );
    return aServiceNames;
}

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

class DisplayAccess : public ::cppu::WeakAggImplHelper4< XPropertySet, XPropertySetInfo, XIndexAccess, XServiceInfo >
{
public:
    DisplayAccess ();

    // XPropertySet
    virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw (RuntimeException);
    virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException);
    virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);

    // XPropertySetInfo
    virtual Sequence< Property > SAL_CALL getProperties(  ) throw (RuntimeException);
    virtual Property SAL_CALL getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException);
    virtual ::sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) throw (RuntimeException);

    // XIndexAccess
    virtual ::sal_Int32 SAL_CALL getCount() throw (RuntimeException);
    virtual Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException);

    // XElementAccess
    virtual Type SAL_CALL getElementType(  ) throw (RuntimeException);
    virtual ::sal_Bool SAL_CALL hasElements(  ) throw (RuntimeException);

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

Sequence< OUString > DisplayAccess_getSupportedServiceNames()
{
    static OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DisplayAccess" ) );
    static Sequence< OUString > aServiceNames( &aServiceName, 1 );
    return aServiceNames;
}

OUString DisplayAccess_getImplementationName()
{
    return OUString( RTL_CONSTASCII_USTRINGPARAM( "vcl::DisplayAccess" ) );
}

Reference< XInterface > SAL_CALL DisplayAccess_createInstance( const Reference< XMultiServiceFactory >&  )
{
    return static_cast< ::cppu::OWeakObject * >( new DisplayAccess );
}

DisplayAccess::DisplayAccess()
{
}

static const char* pMultiDisplayName = "MultiDisplay";
static const char* pDefaultDisplayName = "DefaultDisplay";

// XPropertySet
Reference< XPropertySetInfo > SAL_CALL DisplayAccess::getPropertySetInfo(  ) throw (RuntimeException)
{
    return this;
}

void SAL_CALL DisplayAccess::setPropertyValue( const OUString& /*aPropertyName* */, const Any& /*aValue*/ ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
{
    throw PropertyVetoException();
}

Any SAL_CALL DisplayAccess::getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
{
    Any aRet;
    if( PropertyName.equalsAscii( pMultiDisplayName ) )
    {
        aRet <<= sal_Bool( Application::IsMultiDisplay() );
    }
    else if( PropertyName.equalsAscii( pDefaultDisplayName ) )
    {
        aRet <<= sal_Int32( Application::GetDefaultDisplayNumber() );
    }
    else
        throw UnknownPropertyException();

    return aRet;
}

void SAL_CALL DisplayAccess::addPropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
void SAL_CALL DisplayAccess::removePropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
void SAL_CALL DisplayAccess::addVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
void SAL_CALL DisplayAccess::removeVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}

// XPropertySetInfo
Sequence< Property > SAL_CALL DisplayAccess::getProperties(  ) throw (RuntimeException)
{
    Sequence< Property > aProps(2);
    aProps[0] = getPropertyByName( OUString::createFromAscii( pMultiDisplayName ) );
    aProps[1] = getPropertyByName( OUString::createFromAscii( pDefaultDisplayName ) );
    return aProps;
}

Property SAL_CALL DisplayAccess::getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException)
{
    if( aName.equalsAscii( pMultiDisplayName ) )
        return Property( aName, 0, ::getCppuType( (sal_Bool const *)0 ), PropertyAttribute::READONLY );

    if( aName.equalsAscii( pDefaultDisplayName ) )
        return Property( aName, 0, ::getCppuType( (sal_Int32 const *)0 ), PropertyAttribute::READONLY );
    throw UnknownPropertyException();
}

::sal_Bool SAL_CALL DisplayAccess::hasPropertyByName( const OUString& Name ) throw (RuntimeException)
{
    return Name.equalsAscii( pMultiDisplayName ) ||
           Name.equalsAscii( pDefaultDisplayName );
}

// XIndexAccess
::sal_Int32 SAL_CALL DisplayAccess::getCount() throw (RuntimeException)
{
    return Application::GetScreenCount();
}

Any SAL_CALL DisplayAccess::getByIndex( ::sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
{
    if( (Index < 0) || (Index >= getCount()) )
        throw IndexOutOfBoundsException();

    return makeAny( Reference< XPropertySet >( new DisplayInfo( Index ) ) );
}

// XElementAccess
Type SAL_CALL DisplayAccess::getElementType(  ) throw (RuntimeException)
{
    return XPropertySet::static_type();
}

::sal_Bool SAL_CALL DisplayAccess::hasElements() throw (RuntimeException)
{
    return true;
}

// XServiceInfo
OUString SAL_CALL DisplayAccess::getImplementationName(  ) throw (RuntimeException)
{
    return DisplayAccess_getImplementationName();
}

::sal_Bool SAL_CALL DisplayAccess::supportsService( const OUString& ServiceName ) throw (RuntimeException)
{
    Sequence< OUString > aSN( DisplayAccess_getSupportedServiceNames() );
    for( sal_Int32 nService = 0; nService < aSN.getLength(); nService++ )
    {
        if( aSN[nService] == ServiceName )
            return sal_True;
    }
    return sal_False;
}

Sequence< OUString > SAL_CALL DisplayAccess::getSupportedServiceNames(  ) throw (RuntimeException)
{
    return DisplayAccess_getSupportedServiceNames();
}

} // namespace vcl
<commit_msg>INTEGRATION: CWS changefileheader (1.5.248); FILE MERGED 2008/04/01 13:01:33 thb 1.5.248.2: #i85898# Stripping all external header guards 2008/03/28 15:44:39 rt 1.5.248.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: display.cxx,v $
 * $Revision: 1.6 $
 *
 * 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_vcl.hxx"
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/awt/Rectangle.hpp>
#include <com/sun/star/lang/DisposedException.hpp>

#include <vcl/svapp.hxx>

#include <cppuhelper/implbase3.hxx>
#include <cppuhelper/implbase4.hxx>

#include <vector>
#include <tools/debug.hxx>

using ::rtl::OUString;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::beans;

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

namespace vcl
{

class DisplayInfo : public ::cppu::WeakAggImplHelper3< XPropertySet, XPropertySetInfo, XServiceInfo >
{
public:
    DisplayInfo( sal_uInt32 nDisplay );

    // XPropertySet
    virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw (RuntimeException);
    virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException);
    virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);

    // XPropertySetInfo
    virtual Sequence< Property > SAL_CALL getProperties(  ) throw (RuntimeException);
    virtual Property SAL_CALL getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException);
    virtual ::sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) throw (RuntimeException);

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

private:
    sal_uInt32 mnDisplay;
};

static const char* pScreenAreaName = "ScreenArea";
static const char* pWorkAreaName = "WorkArea";
static const char* pScreenName = "ScreenName";

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

DisplayInfo::DisplayInfo( sal_uInt32 nDisplay )
: mnDisplay( nDisplay )
{
}

// XPropertySet
Reference< XPropertySetInfo > SAL_CALL DisplayInfo::getPropertySetInfo(  ) throw (RuntimeException)
{
    return this;
}

void SAL_CALL DisplayInfo::setPropertyValue( const OUString& /*aPropertyName* */, const Any& /*aValue*/ ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
{
    throw PropertyVetoException();
}

Any SAL_CALL DisplayInfo::getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
{
    Rectangle aRect;
    if( PropertyName.equalsAscii( pScreenAreaName ) )
    {
        aRect = Application::GetScreenPosSizePixel( mnDisplay );
    }
    else if( PropertyName.equalsAscii( pWorkAreaName ) )
    {
        aRect = Application::GetWorkAreaPosSizePixel( mnDisplay );
    }
    else if( PropertyName.equalsAscii( pScreenName ) )
    {
        return Any( Application::GetScreenName( mnDisplay ) );
    }
    else
        throw UnknownPropertyException();

    return Any( com::sun::star::awt::Rectangle( aRect.Left(), aRect.Top(), aRect.getWidth(), aRect.getHeight() ) );
}

void SAL_CALL DisplayInfo::addPropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
void SAL_CALL DisplayInfo::removePropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
void SAL_CALL DisplayInfo::addVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
void SAL_CALL DisplayInfo::removeVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}

// XPropertySetInfo
Sequence< Property > SAL_CALL DisplayInfo::getProperties(  ) throw (RuntimeException)
{
    Sequence< Property > aProps(2);
    aProps[0] = getPropertyByName( OUString::createFromAscii( pScreenAreaName ) );
    aProps[1] = getPropertyByName( OUString::createFromAscii( pWorkAreaName ) );
    return aProps;
}

Property SAL_CALL DisplayInfo::getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException)
{
    if( aName.equalsAscii( pScreenAreaName ) ||
        aName.equalsAscii( pWorkAreaName ) )
        return Property( aName, 0, ::getCppuType( (::com::sun::star::awt::Rectangle const *)0 ), PropertyAttribute::READONLY );
    throw UnknownPropertyException();
}

::sal_Bool SAL_CALL DisplayInfo::hasPropertyByName( const OUString& Name ) throw (RuntimeException)
{
    return Name.equalsAscii( pScreenAreaName ) ||
           Name.equalsAscii( pWorkAreaName );
}

// XServiceInfo
OUString SAL_CALL DisplayInfo::getImplementationName(  ) throw (RuntimeException)
{
    static OUString aImplementationName( RTL_CONSTASCII_USTRINGPARAM( "vcl::DisplayInfo" ) );
    return aImplementationName;
}

::sal_Bool SAL_CALL DisplayInfo::supportsService( const OUString& ServiceName ) throw (RuntimeException)
{
    Sequence< OUString > aSN( getSupportedServiceNames() );
    for( sal_Int32 nService = 0; nService < aSN.getLength(); nService++ )
    {
        if( aSN[nService] == ServiceName )
            return sal_True;
    }
    return sal_False;
}

Sequence< OUString > SAL_CALL DisplayInfo::getSupportedServiceNames(  ) throw (RuntimeException)
{
    static OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DisplayInfo" ) );
    static Sequence< OUString > aServiceNames( &aServiceName, 1  );
    return aServiceNames;
}

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

class DisplayAccess : public ::cppu::WeakAggImplHelper4< XPropertySet, XPropertySetInfo, XIndexAccess, XServiceInfo >
{
public:
    DisplayAccess ();

    // XPropertySet
    virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw (RuntimeException);
    virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException);
    virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);
    virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException);

    // XPropertySetInfo
    virtual Sequence< Property > SAL_CALL getProperties(  ) throw (RuntimeException);
    virtual Property SAL_CALL getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException);
    virtual ::sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) throw (RuntimeException);

    // XIndexAccess
    virtual ::sal_Int32 SAL_CALL getCount() throw (RuntimeException);
    virtual Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException);

    // XElementAccess
    virtual Type SAL_CALL getElementType(  ) throw (RuntimeException);
    virtual ::sal_Bool SAL_CALL hasElements(  ) throw (RuntimeException);

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

Sequence< OUString > DisplayAccess_getSupportedServiceNames()
{
    static OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DisplayAccess" ) );
    static Sequence< OUString > aServiceNames( &aServiceName, 1 );
    return aServiceNames;
}

OUString DisplayAccess_getImplementationName()
{
    return OUString( RTL_CONSTASCII_USTRINGPARAM( "vcl::DisplayAccess" ) );
}

Reference< XInterface > SAL_CALL DisplayAccess_createInstance( const Reference< XMultiServiceFactory >&  )
{
    return static_cast< ::cppu::OWeakObject * >( new DisplayAccess );
}

DisplayAccess::DisplayAccess()
{
}

static const char* pMultiDisplayName = "MultiDisplay";
static const char* pDefaultDisplayName = "DefaultDisplay";

// XPropertySet
Reference< XPropertySetInfo > SAL_CALL DisplayAccess::getPropertySetInfo(  ) throw (RuntimeException)
{
    return this;
}

void SAL_CALL DisplayAccess::setPropertyValue( const OUString& /*aPropertyName* */, const Any& /*aValue*/ ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
{
    throw PropertyVetoException();
}

Any SAL_CALL DisplayAccess::getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
{
    Any aRet;
    if( PropertyName.equalsAscii( pMultiDisplayName ) )
    {
        aRet <<= sal_Bool( Application::IsMultiDisplay() );
    }
    else if( PropertyName.equalsAscii( pDefaultDisplayName ) )
    {
        aRet <<= sal_Int32( Application::GetDefaultDisplayNumber() );
    }
    else
        throw UnknownPropertyException();

    return aRet;
}

void SAL_CALL DisplayAccess::addPropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
void SAL_CALL DisplayAccess::removePropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
void SAL_CALL DisplayAccess::addVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}
void SAL_CALL DisplayAccess::removeVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException) {}

// XPropertySetInfo
Sequence< Property > SAL_CALL DisplayAccess::getProperties(  ) throw (RuntimeException)
{
    Sequence< Property > aProps(2);
    aProps[0] = getPropertyByName( OUString::createFromAscii( pMultiDisplayName ) );
    aProps[1] = getPropertyByName( OUString::createFromAscii( pDefaultDisplayName ) );
    return aProps;
}

Property SAL_CALL DisplayAccess::getPropertyByName( const OUString& aName ) throw (UnknownPropertyException, RuntimeException)
{
    if( aName.equalsAscii( pMultiDisplayName ) )
        return Property( aName, 0, ::getCppuType( (sal_Bool const *)0 ), PropertyAttribute::READONLY );

    if( aName.equalsAscii( pDefaultDisplayName ) )
        return Property( aName, 0, ::getCppuType( (sal_Int32 const *)0 ), PropertyAttribute::READONLY );
    throw UnknownPropertyException();
}

::sal_Bool SAL_CALL DisplayAccess::hasPropertyByName( const OUString& Name ) throw (RuntimeException)
{
    return Name.equalsAscii( pMultiDisplayName ) ||
           Name.equalsAscii( pDefaultDisplayName );
}

// XIndexAccess
::sal_Int32 SAL_CALL DisplayAccess::getCount() throw (RuntimeException)
{
    return Application::GetScreenCount();
}

Any SAL_CALL DisplayAccess::getByIndex( ::sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
{
    if( (Index < 0) || (Index >= getCount()) )
        throw IndexOutOfBoundsException();

    return makeAny( Reference< XPropertySet >( new DisplayInfo( Index ) ) );
}

// XElementAccess
Type SAL_CALL DisplayAccess::getElementType(  ) throw (RuntimeException)
{
    return XPropertySet::static_type();
}

::sal_Bool SAL_CALL DisplayAccess::hasElements() throw (RuntimeException)
{
    return true;
}

// XServiceInfo
OUString SAL_CALL DisplayAccess::getImplementationName(  ) throw (RuntimeException)
{
    return DisplayAccess_getImplementationName();
}

::sal_Bool SAL_CALL DisplayAccess::supportsService( const OUString& ServiceName ) throw (RuntimeException)
{
    Sequence< OUString > aSN( DisplayAccess_getSupportedServiceNames() );
    for( sal_Int32 nService = 0; nService < aSN.getLength(); nService++ )
    {
        if( aSN[nService] == ServiceName )
            return sal_True;
    }
    return sal_False;
}

Sequence< OUString > SAL_CALL DisplayAccess::getSupportedServiceNames(  ) throw (RuntimeException)
{
    return DisplayAccess_getSupportedServiceNames();
}

} // namespace vcl
<|endoftext|>