<commit_before>#include "QPubNub.h"

#include <QNetworkRequest>
#include <QDebug>
#include <QMetaMethod>

static const QString defaultOrigin("qt.pubnub.com");

QPubNub::QPubNub(QNetworkAccessManager* networkAccessManager, QObject* parent) :
  QObject(parent),
  m_trace(0),
  m_networkAccessManager(networkAccessManager),
  m_origin(defaultOrigin),
  m_ssl(true),
  m_timeToken("0"),
  m_resumeOnReconnect(false) {
}

QNetworkReply* QPubNub::sendRequest(const QString& path) {
  QNetworkRequest request(baseUrl() + path);
#ifndef _DEBUG
  static bool originChecked = false;
  if (!originChecked) {
    originChecked = true;
    if (request.url().host() == defaultOrigin) {
      qWarning() << "Before running in production, please contact support@pubnub.com for your custom origin."
        << "\nPlease set the origin from qt.pubnub.com to <your custom origin>.pubnub.com to remove this warning.";
    }
  }
#endif
  request.setHeader(QNetworkRequest::UserAgentHeader, "Qt/1.0");
  request.setRawHeader("V", "3.4");

  // Only emit signal if there are connections currently.
  if (m_trace) {
    emit trace(request.url().toString());
  }
  return m_networkAccessManager->get(request);
}

bool QPubNub::handleResponse(QNetworkReply* reply, QJsonArray& response) const {
  reply->deleteLater();
  if (reply->error() != QNetworkReply::NoError) {
    return true;
  }

  const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
  if (statusCode / 100 != 2) {
    emit error(reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(), statusCode);
    return true;
  }

  auto data(reply->readAll());
  if (m_trace) {
    emit trace(QString("Response for %1:\n%2").arg(reply->request().url().toString()).arg(data.constData()));
  }
  const QJsonDocument doc(QJsonDocument::fromJson(data));
  // Response must be an array and first element must also be an array
  if (doc.isArray()) {
    response = doc.array();
  } else {
    emit error("Response is not an JSON array", 0);
    return true;
  }
  return false;
}

void QPubNub::time() {
  if (m_origin.isEmpty()) {
    return emit error("Origin not set", 0);
  }
  auto reply = sendRequest("/time/0");
  connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
  connect(reply, &QNetworkReply::finished, this, &QPubNub::onTimeFinished);
}

void QPubNub::onError(QNetworkReply::NetworkError) {
  auto reply = qobject_cast<QNetworkReply*>(sender());
  reply->deleteLater();
  emit error(reply->errorString(), 0);
}

void QPubNub::onTimeFinished() {
  auto reply = qobject_cast<QNetworkReply*>(sender());
  QJsonArray result;
  if (handleResponse(reply, result)) {
    return;
  }
  emit timeResponse(result[0].toDouble());
}

void QPubNub::resetOrigin() {
  m_origin = defaultOrigin;
}

QByteArray QPubNub::signature(const QByteArray& message, const QString& channel) const {
  QCryptographicHash hash(QCryptographicHash::Md5);
  hash.addData(m_publishKey);
  hash.addData("/", 1);
  hash.addData(m_subscribeKey);
  hash.addData("/", 1);
  hash.addData(m_secretKey);
  hash.addData("/", 1);
  hash.addData(channel.toLatin1());
  hash.addData("/", 1);
  hash.addData(message);
  hash.addData("", 1);
  return hash.result().toHex();
}

QString QPubNub::baseUrl() const {
  return QString("http%1://%2").arg(m_ssl ? "s" : "").arg(m_origin);
}

QString QPubNub::publishUrl(const QByteArray& message, const QString& channel) const {
  return QString("/publish/%1/%2/%3/%4/0/%5")
    .arg(m_publishKey.constData())
    .arg(m_subscribeKey.constData())
    .arg(m_secretKey.isEmpty() ? "0" : signature(message, channel).constData())
    .arg(channel)
    .arg(message.constData());
}

void QPubNub::publish(const QString& channel, const QJsonValue& value) {
  if (m_publishKey.isEmpty()) {
    return emit error("No publish key set", 0);
  }

  QByteArray message;
#ifdef Q_PUBNUB_CRYPT
  if (!m_cipherKey.isEmpty()) {
    QPubNubCrypt crypt(m_cipherKey);
    int errorCode = 0;
    message = crypt.encrypt(value, errorCode);
    if (errorCode != 0) {
      char errorString[1024+1];
      ERR_error_string_n(errorCode, errorString, 1024);
      emit error(errorString, errorCode);
      return;
    }
  } else {
#endif // Q_PUBNUB_CRYPT
    message = toByteArray(value);
  }

  auto reply = sendRequest(publishUrl("\""+message+"\"", channel));
  // This can't be connected using the new syntax, cause the signal and error property have the same name "error"
  connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
  connect(reply, &QNetworkReply::finished, this, &QPubNub::publishFinished);
}

void QPubNub::publishFinished() {
  auto reply = qobject_cast<QNetworkReply*>(sender());
  QJsonArray response;
  if (handleResponse(reply, response)) {
    return;
  }
  if (response.size() >= 2) {
    const QJsonValue statusCode(response[0]);
    if ((int)statusCode.toDouble() == 0) {
      emit error(response[1].toString(), 0);
    } else {
      emit published(response[2].toString());
    }
  } else {
    emit error("Response array is too small", 0);
  }
}

QString QPubNub::subscribeUrl(const QString& channel) const {
  return QString("/subscribe/%1/%2/0/").arg(m_subscribeKey.constData()).arg(channel);
}

void QPubNub::subscribe(const QString& channel) {
  if (m_channels.contains(channel)) {
    return;
  }
  m_channels.insert(channel);
  if (m_channelUrlPart.isEmpty()) {
    m_channelUrlPart = channel;
  } else {
    m_channelUrlPart += "," + channel;
  }

  subscribe();
}

void QPubNub::subscribe() {
  QString url(subscribeUrl(m_channelUrlPart) + m_timeToken);
  if (!m_uuid.isNull()) {
    url += "?uuid=" + m_uuid;
  }
  QNetworkReply* reply = sendRequest(url);
  connect(reply, &QNetworkReply::finished, this, &QPubNub::onSubscribeReadyRead);
  // This can't be connected using the new syntax, cause the signal and error property have the same name "error"
  connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
}

void QPubNub::onSubscribeReadyRead() {
  auto reply = qobject_cast<QNetworkReply*>(sender());
  QJsonArray response;
  if (handleResponse(reply, response)) {
    return;
  }
  auto firstElement(response.at(0));
  if (!firstElement.isArray()) {
    emit error("First element of response is not an JSON array", 0);
    subscribe();
  }

  auto timeTokenElement = response.at(1);
  if (!timeTokenElement.isString()) {
    emit error("Second element of response is not a string", 0);
    subscribe();
  }
  m_timeToken = timeTokenElement.toString();
  auto channelListString = response.at(2);
  QStringList channels;
  if (channelListString.isString()) {
    channels = channelListString.toString().split(',');
  } else {
    channels << m_channelUrlPart;
  }
  auto messages = firstElement.toArray();
  if (messages.isEmpty()) {
    emit connected();
  } else {
#ifdef Q_PUBNUB_CRYPT
    if (m_cipherKey.isEmpty()) {
      for (int i=0,len=messages.size();i<len;++i) {
        emit message(messages[i], m_timeToken, channels[i]);
      }
    } else {
      decrypt(messages, channels);
    }
  #else
    for (int i=0,len=messages.size();i<len;++i) {
      emit message(messages[i], m_timeToken, channels[i]);
    }
#endif // Q_PUBNUB_CRYPT
  }
  subscribe();
}

#ifdef Q_PUBNUB_CRYPT
bool QPubNub::decrypt(const QJsonArray& messages, const QStringList& channels) {
  QPubNubCrypt crypt(m_cipherKey);
  for (int i=0,len=messages.size();i<len;++i) {
    int errorCode = 0;
    auto value(crypt.decrypt(messages[i].toString().toLocal8Bit(), errorCode));
    if (errorCode != 0) {
      char errorString[1024+1];
      ERR_error_string_n(errorCode, errorString, 1024);
      emit error(errorString, errorCode);
    } else {
      emit message(value, m_timeToken, channels[i]);
    }
  }
  return true;
}
#endif // Q_PUBNUB_CRYPT

void QPubNub::connectNotify(const QMetaMethod& signal) {
  if (signal == QMetaMethod::fromSignal(&QPubNub::trace)) {
    ++m_trace;
  }
}

void QPubNub::disconnectNotify(const QMetaMethod& signal) {
  if (signal == QMetaMethod::fromSignal(&QPubNub::trace)) {
    --m_trace;
  }
}<commit_msg>Fix emitting of timeResponse as quint64<commit_after>#include "QPubNub.h"

#include <QNetworkRequest>
#include <QDebug>
#include <QMetaMethod>

static const QString defaultOrigin("qt.pubnub.com");

QPubNub::QPubNub(QNetworkAccessManager* networkAccessManager, QObject* parent) :
  QObject(parent),
  m_trace(0),
  m_networkAccessManager(networkAccessManager),
  m_origin(defaultOrigin),
  m_ssl(true),
  m_timeToken("0"),
  m_resumeOnReconnect(false) {
}

QNetworkReply* QPubNub::sendRequest(const QString& path) {
  QNetworkRequest request(baseUrl() + path);
#ifndef _DEBUG
  static bool originChecked = false;
  if (!originChecked) {
    originChecked = true;
    if (request.url().host() == defaultOrigin) {
      qWarning() << "Before running in production, please contact support@pubnub.com for your custom origin."
        << "\nPlease set the origin from qt.pubnub.com to <your custom origin>.pubnub.com to remove this warning.";
    }
  }
#endif
  request.setHeader(QNetworkRequest::UserAgentHeader, "Qt/1.0");
  request.setRawHeader("V", "3.4");

  // Only emit signal if there are connections currently.
  if (m_trace) {
    emit trace(request.url().toString());
  }
  return m_networkAccessManager->get(request);
}

bool QPubNub::handleResponse(QNetworkReply* reply, QJsonArray& response) const {
  reply->deleteLater();
  if (reply->error() != QNetworkReply::NoError) {
    return true;
  }

  const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
  if (statusCode / 100 != 2) {
    emit error(reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(), statusCode);
    return true;
  }

  auto data(reply->readAll());
  if (m_trace) {
    emit trace(QString("Response for %1:\n%2").arg(reply->request().url().toString()).arg(data.constData()));
  }
  const QJsonDocument doc(QJsonDocument::fromJson(data));
  // Response must be an array and first element must also be an array
  if (doc.isArray()) {
    response = doc.array();
  } else {
    emit error("Response is not an JSON array", 0);
    return true;
  }
  return false;
}

void QPubNub::time() {
  if (m_origin.isEmpty()) {
    return emit error("Origin not set", 0);
  }
  auto reply = sendRequest("/time/0");
  connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
  connect(reply, &QNetworkReply::finished, this, &QPubNub::onTimeFinished);
}

void QPubNub::onError(QNetworkReply::NetworkError) {
  auto reply = qobject_cast<QNetworkReply*>(sender());
  reply->deleteLater();
  emit error(reply->errorString(), 0);
}

void QPubNub::onTimeFinished() {
  auto reply = qobject_cast<QNetworkReply*>(sender());
  QJsonArray result;
  if (handleResponse(reply, result)) {
    return;
  }
  emit timeResponse((quint64)(result[0].toDouble()));
}

void QPubNub::resetOrigin() {
  m_origin = defaultOrigin;
}

QByteArray QPubNub::signature(const QByteArray& message, const QString& channel) const {
  QCryptographicHash hash(QCryptographicHash::Md5);
  hash.addData(m_publishKey);
  hash.addData("/", 1);
  hash.addData(m_subscribeKey);
  hash.addData("/", 1);
  hash.addData(m_secretKey);
  hash.addData("/", 1);
  hash.addData(channel.toLatin1());
  hash.addData("/", 1);
  hash.addData(message);
  hash.addData("", 1);
  return hash.result().toHex();
}

QString QPubNub::baseUrl() const {
  return QString("http%1://%2").arg(m_ssl ? "s" : "").arg(m_origin);
}

QString QPubNub::publishUrl(const QByteArray& message, const QString& channel) const {
  return QString("/publish/%1/%2/%3/%4/0/%5")
    .arg(m_publishKey.constData())
    .arg(m_subscribeKey.constData())
    .arg(m_secretKey.isEmpty() ? "0" : signature(message, channel).constData())
    .arg(channel)
    .arg(message.constData());
}

void QPubNub::publish(const QString& channel, const QJsonValue& value) {
  if (m_publishKey.isEmpty()) {
    return emit error("No publish key set", 0);
  }

  QByteArray message;
#ifdef Q_PUBNUB_CRYPT
  if (!m_cipherKey.isEmpty()) {
    QPubNubCrypt crypt(m_cipherKey);
    int errorCode = 0;
    message = crypt.encrypt(value, errorCode);
    if (errorCode != 0) {
      char errorString[1024+1];
      ERR_error_string_n(errorCode, errorString, 1024);
      emit error(errorString, errorCode);
      return;
    }
  } else {
#endif // Q_PUBNUB_CRYPT
    message = toByteArray(value);
  }

  auto reply = sendRequest(publishUrl("\""+message+"\"", channel));
  // This can't be connected using the new syntax, cause the signal and error property have the same name "error"
  connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
  connect(reply, &QNetworkReply::finished, this, &QPubNub::publishFinished);
}

void QPubNub::publishFinished() {
  auto reply = qobject_cast<QNetworkReply*>(sender());
  QJsonArray response;
  if (handleResponse(reply, response)) {
    return;
  }
  if (response.size() >= 2) {
    const QJsonValue statusCode(response[0]);
    if ((int)statusCode.toDouble() == 0) {
      emit error(response[1].toString(), 0);
    } else {
      emit published(response[2].toString());
    }
  } else {
    emit error("Response array is too small", 0);
  }
}

QString QPubNub::subscribeUrl(const QString& channel) const {
  return QString("/subscribe/%1/%2/0/").arg(m_subscribeKey.constData()).arg(channel);
}

void QPubNub::subscribe(const QString& channel) {
  if (m_channels.contains(channel)) {
    return;
  }
  m_channels.insert(channel);
  if (m_channelUrlPart.isEmpty()) {
    m_channelUrlPart = channel;
  } else {
    m_channelUrlPart += "," + channel;
  }

  subscribe();
}

void QPubNub::subscribe() {
  QString url(subscribeUrl(m_channelUrlPart) + m_timeToken);
  if (!m_uuid.isNull()) {
    url += "?uuid=" + m_uuid;
  }
  QNetworkReply* reply = sendRequest(url);
  connect(reply, &QNetworkReply::finished, this, &QPubNub::onSubscribeReadyRead);
  // This can't be connected using the new syntax, cause the signal and error property have the same name "error"
  connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
}

void QPubNub::onSubscribeReadyRead() {
  auto reply = qobject_cast<QNetworkReply*>(sender());
  QJsonArray response;
  if (handleResponse(reply, response)) {
    return;
  }
  auto firstElement(response.at(0));
  if (!firstElement.isArray()) {
    emit error("First element of response is not an JSON array", 0);
    subscribe();
  }

  auto timeTokenElement = response.at(1);
  if (!timeTokenElement.isString()) {
    emit error("Second element of response is not a string", 0);
    subscribe();
  }
  m_timeToken = timeTokenElement.toString();
  auto channelListString = response.at(2);
  QStringList channels;
  if (channelListString.isString()) {
    channels = channelListString.toString().split(',');
  } else {
    channels << m_channelUrlPart;
  }
  auto messages = firstElement.toArray();
  if (messages.isEmpty()) {
    emit connected();
  } else {
#ifdef Q_PUBNUB_CRYPT
    if (m_cipherKey.isEmpty()) {
      for (int i=0,len=messages.size();i<len;++i) {
        emit message(messages[i], m_timeToken, channels[i]);
      }
    } else {
      decrypt(messages, channels);
    }
  #else
    for (int i=0,len=messages.size();i<len;++i) {
      emit message(messages[i], m_timeToken, channels[i]);
    }
#endif // Q_PUBNUB_CRYPT
  }
  subscribe();
}

#ifdef Q_PUBNUB_CRYPT
bool QPubNub::decrypt(const QJsonArray& messages, const QStringList& channels) {
  QPubNubCrypt crypt(m_cipherKey);
  for (int i=0,len=messages.size();i<len;++i) {
    int errorCode = 0;
    auto value(crypt.decrypt(messages[i].toString().toLocal8Bit(), errorCode));
    if (errorCode != 0) {
      char errorString[1024+1];
      ERR_error_string_n(errorCode, errorString, 1024);
      emit error(errorString, errorCode);
    } else {
      emit message(value, m_timeToken, channels[i]);
    }
  }
  return true;
}
#endif // Q_PUBNUB_CRYPT

void QPubNub::connectNotify(const QMetaMethod& signal) {
  if (signal == QMetaMethod::fromSignal(&QPubNub::trace)) {
    ++m_trace;
  }
}

void QPubNub::disconnectNotify(const QMetaMethod& signal) {
  if (signal == QMetaMethod::fromSignal(&QPubNub::trace)) {
    --m_trace;
  }
}<|endoftext|>


<commit_before>/*************************************************************************
QlibVLC: a C++ wrapper of libVLC for Qt, with audio part only.
    Copyright (C) 2014 - Philippe SWARTVAGHER

    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.1 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.

    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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    *****************************************************************************/

#include "QlibVLC.h"

QlibVLC::QlibVLC()
{
    m_vlc = libvlc_new(0, NULL); // Initialize libVLC
    m_player = libvlc_media_player_new(m_vlc);

    m_issetMedia = false;
}

QlibVLC::~QlibVLC()
{
    libvlc_media_release(m_media);
    libvlc_media_player_release(m_player);
    libvlc_release(m_vlc);
}

int QlibVLC::duration()
{
    return libvlc_media_get_duration(m_media);
}

int QlibVLC::getDuration(QString path)
{
    libvlc_media_t* media = libvlc_media_new_path(m_vlc, path.replace("/", "\\\\").toStdString().c_str());

    libvlc_media_parse(media);

    int duration = libvlc_media_get_duration(media);

    libvlc_media_release(media);

    return duration;
}

void QlibVLC::setMedia(QString path)
{
    m_path = path;
    //m_media = libvlc_media_new_path(m_vlc, path.replace("/", "\\\\").toStdString().c_str());
    m_media = libvlc_media_new_path(m_vlc, m_path.toStdString().c_str());
    libvlc_media_parse(m_media);
    libvlc_media_player_set_media(m_player, m_media);
    m_eventManager = libvlc_media_player_event_manager(m_player);
    m_issetMedia = true;
}

void QlibVLC::play()
{
    libvlc_media_player_play(m_player);

    libvlc_event_attach(m_eventManager, libvlc_MediaPlayerPositionChanged, callbackTimeChanged, (void*) this);
    libvlc_event_attach(m_eventManager, libvlc_MediaPlayerEndReached, callbackEndTrack, (void*) this);
}

void QlibVLC::callbackTimeChanged(const libvlc_event_t* event, void* data)
{
    QlibVLC* vlc;
    vlc = (QlibVLC*) data;
    vlc->emitPositionChanged();
}

void QlibVLC::callbackEndTrack(const libvlc_event_t* event, void* data)
{
    QlibVLC* vlc;
    vlc = (QlibVLC*) data;
    vlc->endTrack();
}

void QlibVLC::emitPositionChanged()
{
    float positionFloat = libvlc_media_player_get_position(m_player);
    int positionInt = positionFloat * libvlc_media_get_duration(m_media);
    emit positionChanged(positionInt);
}

void QlibVLC::pause(bool pause)
{
    if(pause)
        libvlc_media_player_set_pause(m_player, 1);
    else
        libvlc_media_player_set_pause(m_player, 0);
}

bool QlibVLC::isPlaying()
{
    if(libvlc_media_player_is_playing(m_player) == 1)
        return true;
    else
        return false;
}

void QlibVLC::changePosition(float value)
{
    if(isPlaying())
        libvlc_media_player_set_position(m_player, value);
}

int QlibVLC::trackNumber()
{
    QString trackNumberString = libvlc_media_get_meta(m_media, libvlc_meta_TrackNumber);
    if(trackNumberString.isEmpty() || trackNumberString.isNull())
        return -1;
    else
        return trackNumberString.toInt();
}

QString QlibVLC::album()
{
    QString album = libvlc_media_get_meta(m_media, libvlc_meta_Album);

    return album;
}

QString QlibVLC::artist()
{
    QString artist = libvlc_media_get_meta(m_media, libvlc_meta_Artist);

    return artist;
}

int QlibVLC::year()
{
    QString yearNumberString = libvlc_media_get_meta(m_media, libvlc_meta_Date);
    if(yearNumberString.isNull())
        return 0;
    else
    {
        return yearNumberString.toInt();
    }
}

QString QlibVLC::title()
{
    QString title = libvlc_media_get_meta(m_media, libvlc_meta_Title);
    return title;
}

void QlibVLC::ejectMedia()
{
    if(m_issetMedia)
    {
        libvlc_media_player_stop(m_player);
        libvlc_media_player_retain(m_player);
        m_issetMedia = false;
    }
}

void QlibVLC::stop()
{
    libvlc_media_player_stop(m_player);
}

std::vector<QlibVLCOutput> QlibVLC::getOutputs()
{
    std::vector<QlibVLCOutput> array;

    libvlc_audio_output_t* outputs = libvlc_audio_output_list_get(m_vlc);

    while(outputs!=NULL)
    {
        QlibVLCOutput output;
        output.description = outputs->psz_description;
        output.name = outputs->psz_name;

        array.push_back(output);

        outputs = outputs->p_next;
    }

    libvlc_audio_output_list_release(outputs);

    return array;
}

void QlibVLC::setOutput(QString name)
{
    libvlc_audio_output_set(m_player, name.toStdString().c_str());
}
<commit_msg>BUG: title was sometimes given with the extension.<commit_after>/*************************************************************************
QlibVLC: a C++ wrapper of libVLC for Qt, with audio part only.
    Copyright (C) 2014 - Philippe SWARTVAGHER

    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.1 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.

    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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    *****************************************************************************/

#include "QlibVLC.h"

QlibVLC::QlibVLC()
{
    m_vlc = libvlc_new(0, NULL); // Initialize libVLC
    m_player = libvlc_media_player_new(m_vlc);

    m_issetMedia = false;
}

QlibVLC::~QlibVLC()
{
    libvlc_media_release(m_media);
    libvlc_media_player_release(m_player);
    libvlc_release(m_vlc);
}

int QlibVLC::duration()
{
    return libvlc_media_get_duration(m_media);
}

int QlibVLC::getDuration(QString path)
{
    libvlc_media_t* media = libvlc_media_new_path(m_vlc, path.replace("/", "\\\\").toStdString().c_str());

    libvlc_media_parse(media);

    int duration = libvlc_media_get_duration(media);

    libvlc_media_release(media);

    return duration;
}

void QlibVLC::setMedia(QString path)
{
    m_path = path;
    //m_media = libvlc_media_new_path(m_vlc, path.replace("/", "\\\\").toStdString().c_str());
    m_media = libvlc_media_new_path(m_vlc, m_path.toStdString().c_str());
    libvlc_media_parse(m_media);
    libvlc_media_player_set_media(m_player, m_media);
    m_eventManager = libvlc_media_player_event_manager(m_player);
    m_issetMedia = true;
}

void QlibVLC::play()
{
    libvlc_media_player_play(m_player);

    libvlc_event_attach(m_eventManager, libvlc_MediaPlayerPositionChanged, callbackTimeChanged, (void*) this);
    libvlc_event_attach(m_eventManager, libvlc_MediaPlayerEndReached, callbackEndTrack, (void*) this);
}

void QlibVLC::callbackTimeChanged(const libvlc_event_t* event, void* data)
{
    QlibVLC* vlc;
    vlc = (QlibVLC*) data;
    vlc->emitPositionChanged();
}

void QlibVLC::callbackEndTrack(const libvlc_event_t* event, void* data)
{
    QlibVLC* vlc;
    vlc = (QlibVLC*) data;
    vlc->endTrack();
}

void QlibVLC::emitPositionChanged()
{
    float positionFloat = libvlc_media_player_get_position(m_player);
    int positionInt = positionFloat * libvlc_media_get_duration(m_media);
    emit positionChanged(positionInt);
}

void QlibVLC::pause(bool pause)
{
    if(pause)
        libvlc_media_player_set_pause(m_player, 1);
    else
        libvlc_media_player_set_pause(m_player, 0);
}

bool QlibVLC::isPlaying()
{
    if(libvlc_media_player_is_playing(m_player) == 1)
        return true;
    else
        return false;
}

void QlibVLC::changePosition(float value)
{
    if(isPlaying())
        libvlc_media_player_set_position(m_player, value);
}

int QlibVLC::trackNumber()
{
    QString trackNumberString = libvlc_media_get_meta(m_media, libvlc_meta_TrackNumber);
    if(trackNumberString.isEmpty() || trackNumberString.isNull())
        return -1;
    else
        return trackNumberString.toInt();
}

QString QlibVLC::album()
{
    QString album = libvlc_media_get_meta(m_media, libvlc_meta_Album);

    return album;
}

QString QlibVLC::artist()
{
    QString artist = libvlc_media_get_meta(m_media, libvlc_meta_Artist);

    return artist;
}

int QlibVLC::year()
{
    QString yearNumberString = libvlc_media_get_meta(m_media, libvlc_meta_Date);
    if(yearNumberString.isNull())
        return 0;
    else
    {
        return yearNumberString.toInt();
    }
}

QString QlibVLC::title()
{
    QString title = libvlc_media_get_meta(m_media, libvlc_meta_Title);

    QFileInfo* fileInfo = new QFileInfo(m_path);
    if(title==fileInfo->fileName())
    {
        return fileInfo->baseName();
    }
    else
        return title;
}

void QlibVLC::ejectMedia()
{
    if(m_issetMedia)
    {
        libvlc_media_player_stop(m_player);
        libvlc_media_player_retain(m_player);
        m_issetMedia = false;
    }
}

void QlibVLC::stop()
{
    libvlc_media_player_stop(m_player);
}

std::vector<QlibVLCOutput> QlibVLC::getOutputs()
{
    std::vector<QlibVLCOutput> array;

    libvlc_audio_output_t* outputs = libvlc_audio_output_list_get(m_vlc);

    while(outputs!=NULL)
    {
        QlibVLCOutput output;
        output.description = outputs->psz_description;
        output.name = outputs->psz_name;

        array.push_back(output);

        outputs = outputs->p_next;
    }

    libvlc_audio_output_list_release(outputs);

    return array;
}

void QlibVLC::setOutput(QString name)
{
    libvlc_audio_output_set(m_player, name.toStdString().c_str());
}
<|endoftext|>


<commit_before>// Copyright (c) 2013, Mhd Adel G. Al Qodamni
// All rights reserved - under BSD 2-clause license.
// Check the LICENSE file for the full text
#include <iostream>

#include "Spinlock.h"

Spinlock::Spinlock()
{
    lock_variable.store(false);
    // Since the onwer is not valid unless the Spinlock is locked, there's
    // no point in initializing it here - what would you set it to be?
}

void Spinlock::lock()
{
    bool expected = false;
    bool desired = true;
    // if lock_variable = expected(false) then set it to desired(true)
    // else, loop again but set expected to false again since
    // compare_exchange_strong does: expected = desired when it fails
    while(!lock_variable.compare_exchange_strong(expected, desired))
        expected = false;
    owner.store(std::this_thread::get_id());
}

bool Spinlock::unlock()
{
    if(lock_variable.load())
        if(owner.load() == std::this_thread::get_id()) {
            lock_variable.store(false);
            return true;
        }
    return false;
}

Spinlock::~Spinlock()
{
    // To be safe
    lock_variable.store(false);
}
<commit_msg>Added the copyrights notice<commit_after>/*
Copyright (c) 2013, Mhd Adel G. Al Qodamni
All rights reserved.

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

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

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

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

#include <iostream>

#include "Spinlock.h"

Spinlock::Spinlock()
{
    lock_variable.store(false);
    // Since the onwer is not valid unless the Spinlock is locked, there's
    // no point in initializing it here - what would you set it to be?
}

void Spinlock::lock()
{
    bool expected = false;
    bool desired = true;
    // if lock_variable = expected(false) then set it to desired(true)
    // else, loop again but set expected to false again since
    // compare_exchange_strong does: expected = desired when it fails
    while(!lock_variable.compare_exchange_strong(expected, desired))
        expected = false;
    owner.store(std::this_thread::get_id());
}

bool Spinlock::unlock()
{
    if(lock_variable.load())
        if(owner.load() == std::this_thread::get_id()) {
            lock_variable.store(false);
            return true;
        }
    return false;
}

Spinlock::~Spinlock()
{
    // To be safe
    lock_variable.store(false);
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Utility module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Utility/Formats/STBLoader.hpp>
#include <stb/stb_image_write.h>
#include <Nazara/Utility/Image.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <map>
#include <stdexcept>
#include <Nazara/Utility/Debug.hpp>

namespace Nz
{
	namespace
	{
		using FormatHandler = bool(*)(const Image& image, const ImageParams& parameters, Stream& stream);

		std::map<String, FormatHandler> s_formatHandlers;

		int ConvertToFloatFormat(Image& image)
		{
			switch (image.GetFormat())
			{
				case PixelFormatType_R32F:
					return 1;

				case PixelFormatType_RG32F:
					return 2;

				case PixelFormatType_RGB32F:
					return 3;

				case PixelFormatType_RGBA32F:
					return 4;

				default:
				{
					if (PixelFormat::HasAlpha(image.GetFormat()))
					{
						if (!image.Convert(PixelFormatType_RGBA32F))
							break;

						return 4;
					}
					else
					{
						if (!image.Convert(PixelFormatType_RGB32F))
							break;

						return 3;
					}
				}
			}

			return 0;
		}

		int ConvertToIntegerFormat(Image& image)
		{
			switch (image.GetFormat())
			{
				case PixelFormatType_L8:
				case PixelFormatType_R8:
					return 1;

				case PixelFormatType_LA8:
				case PixelFormatType_RG8:
					return 2;

				case PixelFormatType_RGB8:
					return 3;

				case PixelFormatType_RGBA8:
					return 4;

				default:
				{
					if (PixelFormat::HasAlpha(image.GetFormat()))
					{
						if (!image.Convert(PixelFormatType_RGBA8))
							break;

						return 4;
					}
					else
					{
						if (!image.Convert(PixelFormatType_RGB8))
							break;

						return 3;
					}
				}
			}

			return 0;
		}

		void WriteToStream(void* userdata, void* data, int size)
		{
			Stream* stream = static_cast<Stream*>(userdata);
			if (stream->Write(data, size) != size)
				throw std::runtime_error("Failed to write to stream");
		}

		bool FormatQuerier(const String& extension)
		{
			return s_formatHandlers.find(extension) != s_formatHandlers.end();
		}

		bool SaveToStream(const Image& image, const String& format, Stream& stream, const ImageParams& parameters)
		{
			NazaraUnused(parameters);

			if (!image.IsValid())
			{
				NazaraError("Invalid image");
				return false;
			}

			ImageType type = image.GetType();
			if (type != ImageType_1D && type != ImageType_2D)
			{
				NazaraError("Image type 0x" + String::Number(type, 16) + " is not ");
				return false;
			}

			auto it = s_formatHandlers.find(format);
			NazaraAssert(it != s_formatHandlers.end(), "Invalid handler");

			const FormatHandler& handler = it->second;
			try
			{
				return handler(image, parameters, stream);
			}
			catch (const std::exception& e)
			{
				NazaraError(e.what());
				return false;
			}
		}

		bool SaveBMP(const Image& image, const ImageParams& parameters, Stream& stream)
		{
			Image tempImage(image); //< We're using COW here to prevent Image copy unless required

			int componentCount = ConvertToIntegerFormat(tempImage);
			if (componentCount == 0)
			{
				NazaraError("Failed to convert image to suitable format");
				return false;
			}

			if (!stbi_write_bmp_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, tempImage.GetConstPixels()))
			{
				NazaraError("Failed to write BMP to stream");
				return false;
			}

			return true;
		}

		bool SaveHDR(const Image& image, const ImageParams& parameters, Stream& stream)
		{
			Image tempImage(image); //< We're using COW here to prevent Image copy unless required

			int componentCount = ConvertToFloatFormat(tempImage);
			if (componentCount == 0)
			{
				NazaraError("Failed to convert image to suitable format");
				return false;
			}

			if (!stbi_write_hdr_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, reinterpret_cast<const float*>(tempImage.GetConstPixels())))
			{
				NazaraError("Failed to write BMP to stream");
				return false;
			}

			return true;
		}

		bool SavePNG(const Image& image, const ImageParams& parameters, Stream& stream)
		{
			Image tempImage(image); //< We're using COW here to prevent Image copy unless required

			int componentCount = ConvertToIntegerFormat(tempImage);
			if (componentCount == 0)
			{
				NazaraError("Failed to convert image to suitable format");
				return false;
			}

			if (!stbi_write_png_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, tempImage.GetConstPixels(), 0))
			{
				NazaraError("Failed to write BMP to stream");
				return false;
			}

			return true;
		}

		bool SaveTGA(const Image& image, const ImageParams& parameters, Stream& stream)
		{
			Image tempImage(image); //< We're using COW here to prevent Image copy unless required

			int componentCount = ConvertToIntegerFormat(tempImage);
			if (componentCount == 0)
			{
				NazaraError("Failed to convert image to suitable format");
				return false;
			}

			if (!stbi_write_tga_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, tempImage.GetConstPixels()))
			{
				NazaraError("Failed to write BMP to stream");
				return false;
			}

			return true;
		}
	}

	namespace Loaders
	{
		void RegisterSTBSaver()
		{
			s_formatHandlers["bmp"] = &SaveBMP;
			s_formatHandlers["hdr"] = &SaveHDR;
			s_formatHandlers["png"] = &SavePNG;
			s_formatHandlers["tga"] = &SaveTGA;

			ImageSaver::RegisterSaver(FormatQuerier, SaveToStream);
		}

		void UnregisterSTBSaver()
		{
			ImageSaver::UnregisterSaver(FormatQuerier, SaveToStream);
			s_formatHandlers.clear();
		}
	}
}
<commit_msg>Utility/STBSaver: Fix failure error message<commit_after>// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Utility module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Utility/Formats/STBLoader.hpp>
#include <stb/stb_image_write.h>
#include <Nazara/Utility/Image.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <map>
#include <stdexcept>
#include <Nazara/Utility/Debug.hpp>

namespace Nz
{
	namespace
	{
		using FormatHandler = bool(*)(const Image& image, const ImageParams& parameters, Stream& stream);

		std::map<String, FormatHandler> s_formatHandlers;

		int ConvertToFloatFormat(Image& image)
		{
			switch (image.GetFormat())
			{
				case PixelFormatType_R32F:
					return 1;

				case PixelFormatType_RG32F:
					return 2;

				case PixelFormatType_RGB32F:
					return 3;

				case PixelFormatType_RGBA32F:
					return 4;

				default:
				{
					if (PixelFormat::HasAlpha(image.GetFormat()))
					{
						if (!image.Convert(PixelFormatType_RGBA32F))
							break;

						return 4;
					}
					else
					{
						if (!image.Convert(PixelFormatType_RGB32F))
							break;

						return 3;
					}
				}
			}

			return 0;
		}

		int ConvertToIntegerFormat(Image& image)
		{
			switch (image.GetFormat())
			{
				case PixelFormatType_L8:
				case PixelFormatType_R8:
					return 1;

				case PixelFormatType_LA8:
				case PixelFormatType_RG8:
					return 2;

				case PixelFormatType_RGB8:
					return 3;

				case PixelFormatType_RGBA8:
					return 4;

				default:
				{
					if (PixelFormat::HasAlpha(image.GetFormat()))
					{
						if (!image.Convert(PixelFormatType_RGBA8))
							break;

						return 4;
					}
					else
					{
						if (!image.Convert(PixelFormatType_RGB8))
							break;

						return 3;
					}
				}
			}

			return 0;
		}

		void WriteToStream(void* userdata, void* data, int size)
		{
			Stream* stream = static_cast<Stream*>(userdata);
			if (stream->Write(data, size) != size)
				throw std::runtime_error("Failed to write to stream");
		}

		bool FormatQuerier(const String& extension)
		{
			return s_formatHandlers.find(extension) != s_formatHandlers.end();
		}

		bool SaveToStream(const Image& image, const String& format, Stream& stream, const ImageParams& parameters)
		{
			NazaraUnused(parameters);

			if (!image.IsValid())
			{
				NazaraError("Invalid image");
				return false;
			}

			ImageType type = image.GetType();
			if (type != ImageType_1D && type != ImageType_2D)
			{
				NazaraError("Image type 0x" + String::Number(type, 16) + " is not ");
				return false;
			}

			auto it = s_formatHandlers.find(format);
			NazaraAssert(it != s_formatHandlers.end(), "Invalid handler");

			const FormatHandler& handler = it->second;
			try
			{
				return handler(image, parameters, stream);
			}
			catch (const std::exception& e)
			{
				NazaraError(e.what());
				return false;
			}
		}

		bool SaveBMP(const Image& image, const ImageParams& parameters, Stream& stream)
		{
			Image tempImage(image); //< We're using COW here to prevent Image copy unless required

			int componentCount = ConvertToIntegerFormat(tempImage);
			if (componentCount == 0)
			{
				NazaraError("Failed to convert image to suitable format");
				return false;
			}

			if (!stbi_write_bmp_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, tempImage.GetConstPixels()))
			{
				NazaraError("Failed to write BMP to stream");
				return false;
			}

			return true;
		}

		bool SaveHDR(const Image& image, const ImageParams& parameters, Stream& stream)
		{
			Image tempImage(image); //< We're using COW here to prevent Image copy unless required

			int componentCount = ConvertToFloatFormat(tempImage);
			if (componentCount == 0)
			{
				NazaraError("Failed to convert image to suitable format");
				return false;
			}

			if (!stbi_write_hdr_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, reinterpret_cast<const float*>(tempImage.GetConstPixels())))
			{
				NazaraError("Failed to write HDR to stream");
				return false;
			}

			return true;
		}

		bool SavePNG(const Image& image, const ImageParams& parameters, Stream& stream)
		{
			Image tempImage(image); //< We're using COW here to prevent Image copy unless required

			int componentCount = ConvertToIntegerFormat(tempImage);
			if (componentCount == 0)
			{
				NazaraError("Failed to convert image to suitable format");
				return false;
			}

			if (!stbi_write_png_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, tempImage.GetConstPixels(), 0))
			{
				NazaraError("Failed to write PNG to stream");
				return false;
			}

			return true;
		}

		bool SaveTGA(const Image& image, const ImageParams& parameters, Stream& stream)
		{
			Image tempImage(image); //< We're using COW here to prevent Image copy unless required

			int componentCount = ConvertToIntegerFormat(tempImage);
			if (componentCount == 0)
			{
				NazaraError("Failed to convert image to suitable format");
				return false;
			}

			if (!stbi_write_tga_to_func(&WriteToStream, &stream, tempImage.GetWidth(), tempImage.GetHeight(), componentCount, tempImage.GetConstPixels()))
			{
				NazaraError("Failed to write TGA to stream");
				return false;
			}

			return true;
		}
	}

	namespace Loaders
	{
		void RegisterSTBSaver()
		{
			s_formatHandlers["bmp"] = &SaveBMP;
			s_formatHandlers["hdr"] = &SaveHDR;
			s_formatHandlers["png"] = &SavePNG;
			s_formatHandlers["tga"] = &SaveTGA;

			ImageSaver::RegisterSaver(FormatQuerier, SaveToStream);
		}

		void UnregisterSTBSaver()
		{
			ImageSaver::UnregisterSaver(FormatQuerier, SaveToStream);
			s_formatHandlers.clear();
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/tray/system_tray.h"

#include <vector>

#include "ash/system/status_area_widget.h"
#include "ash/system/tray/system_tray_item.h"
#include "ash/test/ash_test_base.h"
#include "base/utf_string_conversions.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"

namespace ash {
namespace test {

namespace {

SystemTray* GetSystemTray() {
  return Shell::GetInstance()->status_area_widget()->system_tray();
}

// Trivial item implementation that tracks its views for testing.
class TestItem : public SystemTrayItem {
 public:
  TestItem() : tray_view_(NULL) {}

  virtual views::View* CreateTrayView(user::LoginStatus status) {
    tray_view_ = new views::View;
    // Add a label so it has non-zero width.
    tray_view_->SetLayoutManager(new views::FillLayout);
    tray_view_->AddChildView(new views::Label(UTF8ToUTF16("Tray")));
    return tray_view_;
  }

  virtual views::View* CreateDefaultView(user::LoginStatus status) {
    default_view_ = new views::View;
    default_view_->SetLayoutManager(new views::FillLayout);
    default_view_->AddChildView(new views::Label(UTF8ToUTF16("Default")));
    return default_view_;
  }

  virtual views::View* CreateDetailedView(user::LoginStatus status) {
    detailed_view_ = new views::View;
    detailed_view_->SetLayoutManager(new views::FillLayout);
    detailed_view_->AddChildView(new views::Label(UTF8ToUTF16("Detailed")));
    return detailed_view_;
  }

  virtual views::View* CreateNotificationView(user::LoginStatus status) {
    notification_view_ = new views::View;
    return notification_view_;
  }

  virtual void DestroyTrayView() {
    tray_view_ = NULL;
  }

  virtual void DestroyDefaultView() {
    default_view_ = NULL;
  }

  virtual void DestroyDetailedView() {
    detailed_view_ = NULL;
  }

  virtual void DestroyNotificationView() {
    notification_view_ = NULL;
  }

  virtual void UpdateAfterLoginStatusChange(user::LoginStatus status) {
  }

  views::View* tray_view() const { return tray_view_; }
  views::View* default_view() const { return default_view_; }
  views::View* detailed_view() const { return detailed_view_; }
  views::View* notification_view() const { return notification_view_; }

 private:
  views::View* tray_view_;
  views::View* default_view_;
  views::View* detailed_view_;
  views::View* notification_view_;
};

}  // namespace

typedef AshTestBase SystemTrayTest;

TEST_F(SystemTrayTest, SystemTrayDefaultView) {
  SystemTray* tray = GetSystemTray();
  ASSERT_TRUE(tray->GetWidget());

  tray->ShowDefaultView(BUBBLE_CREATE_NEW);

  // Ensure that closing the bubble destroys it.
  ASSERT_TRUE(tray->CloseBubbleForTest());
  RunAllPendingInMessageLoop();
  ASSERT_FALSE(tray->CloseBubbleForTest());
}

TEST_F(SystemTrayTest, SystemTrayTestItems) {
  SystemTray* tray = GetSystemTray();
  ASSERT_TRUE(tray->GetWidget());

  TestItem* test_item = new TestItem;
  TestItem* detailed_item = new TestItem;
  tray->AddTrayItem(test_item);
  tray->AddTrayItem(detailed_item);

  // Ensure the tray views are created.
  ASSERT_TRUE(test_item->tray_view() != NULL);
  ASSERT_TRUE(detailed_item->tray_view() != NULL);

  // Ensure a default views are created.
  tray->ShowDefaultView(BUBBLE_CREATE_NEW);
  ASSERT_TRUE(test_item->default_view() != NULL);
  ASSERT_TRUE(detailed_item->default_view() != NULL);

  // Show the detailed view, ensure it's created and the default view destroyed.
  tray->ShowDetailedView(detailed_item, 0, false, BUBBLE_CREATE_NEW);
  RunAllPendingInMessageLoop();
  ASSERT_TRUE(test_item->default_view() == NULL);
  ASSERT_TRUE(detailed_item->detailed_view() != NULL);

  // Show the default view, ensure it's created and the detailed view destroyed.
  tray->ShowDefaultView(BUBBLE_CREATE_NEW);
  RunAllPendingInMessageLoop();
  ASSERT_TRUE(test_item->default_view() != NULL);
  ASSERT_TRUE(detailed_item->detailed_view() == NULL);
}

TEST_F(SystemTrayTest, TrayWidgetAutoResizes) {
  SystemTray* tray = GetSystemTray();
  ASSERT_TRUE(tray->GetWidget());

  gfx::Size widget_size = tray->GetWidget()->GetWindowScreenBounds().size();

  TestItem* test_item = new TestItem;
  tray->AddTrayItem(test_item);

  gfx::Size new_size = tray->GetWidget()->GetWindowScreenBounds().size();

  // Adding the new item should change the size of the tray.
  EXPECT_NE(widget_size.ToString(), new_size.ToString());

  // Hiding the tray view of the new item should also change the size of the
  // tray.
  test_item->tray_view()->SetVisible(false);
  EXPECT_EQ(widget_size.ToString(),
            tray->GetWidget()->GetWindowScreenBounds().size().ToString());

  test_item->tray_view()->SetVisible(true);
  EXPECT_EQ(new_size.ToString(),
            tray->GetWidget()->GetWindowScreenBounds().size().ToString());
}

// Disabled due to a use-after-free, see http://crbug.com/127539.
TEST_F(SystemTrayTest, DISABLED_SystemTrayNotifications) {
  SystemTray* tray = GetSystemTray();
  ASSERT_TRUE(tray->GetWidget());

  TestItem* test_item = new TestItem;
  TestItem* detailed_item = new TestItem;
  tray->AddTrayItem(test_item);
  tray->AddTrayItem(detailed_item);

  // Ensure the tray views are created.
  ASSERT_TRUE(test_item->tray_view() != NULL);
  ASSERT_TRUE(detailed_item->tray_view() != NULL);

  // Ensure a notification view is created.
  tray->ShowNotificationView(test_item);
  ASSERT_TRUE(test_item->notification_view() != NULL);

  // Show the default view, ensure the notification view is destroyed.
  tray->ShowDefaultView(BUBBLE_CREATE_NEW);
  RunAllPendingInMessageLoop();
  ASSERT_TRUE(test_item->notification_view() == NULL);

  // Show the detailed view, ensure the notificaiton view is created again.
  tray->ShowDetailedView(detailed_item, 0, false, BUBBLE_CREATE_NEW);
  RunAllPendingInMessageLoop();
  ASSERT_TRUE(detailed_item->detailed_view() != NULL);
  ASSERT_TRUE(test_item->notification_view() != NULL);

  // Hide the detailed view, ensure the notificaiton view still exists.
  ASSERT_TRUE(tray->CloseBubbleForTest());
  RunAllPendingInMessageLoop();
  ASSERT_TRUE(detailed_item->detailed_view() == NULL);
  ASSERT_TRUE(test_item->notification_view() != NULL);
}

TEST_F(SystemTrayTest, BubbleCreationTypesTest) {
  SystemTray* tray = GetSystemTray();
  ASSERT_TRUE(tray->GetWidget());

  TestItem* test_item = new TestItem;
  tray->AddTrayItem(test_item);

  // Ensure the tray views are created.
  ASSERT_TRUE(test_item->tray_view() != NULL);

  // Show the default view, ensure the notification view is destroyed.
  tray->ShowDefaultView(BUBBLE_CREATE_NEW);
  RunAllPendingInMessageLoop();

  views::Widget* widget = test_item->default_view()->GetWidget();
  gfx::Rect bubble_bounds = widget->GetWindowScreenBounds();

  tray->ShowDetailedView(test_item, 0, true, BUBBLE_USE_EXISTING);
  RunAllPendingInMessageLoop();

  EXPECT_FALSE(test_item->default_view());

  EXPECT_EQ(bubble_bounds.ToString(), test_item->detailed_view()->GetWidget()->
      GetWindowScreenBounds().ToString());
  EXPECT_EQ(widget, test_item->detailed_view()->GetWidget());

  tray->ShowDefaultView(BUBBLE_USE_EXISTING);
  RunAllPendingInMessageLoop();

  EXPECT_EQ(bubble_bounds.ToString(), test_item->default_view()->GetWidget()->
      GetWindowScreenBounds().ToString());
  EXPECT_EQ(widget, test_item->default_view()->GetWidget());
}

}  // namespace test
}  // namespace ash
<commit_msg>Disable SystemTrayTestItems on OS_WIN<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/tray/system_tray.h"

#include <vector>

#include "ash/system/status_area_widget.h"
#include "ash/system/tray/system_tray_item.h"
#include "ash/test/ash_test_base.h"
#include "base/utf_string_conversions.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"

namespace ash {
namespace test {

namespace {

SystemTray* GetSystemTray() {
  return Shell::GetInstance()->status_area_widget()->system_tray();
}

// Trivial item implementation that tracks its views for testing.
class TestItem : public SystemTrayItem {
 public:
  TestItem() : tray_view_(NULL) {}

  virtual views::View* CreateTrayView(user::LoginStatus status) {
    tray_view_ = new views::View;
    // Add a label so it has non-zero width.
    tray_view_->SetLayoutManager(new views::FillLayout);
    tray_view_->AddChildView(new views::Label(UTF8ToUTF16("Tray")));
    return tray_view_;
  }

  virtual views::View* CreateDefaultView(user::LoginStatus status) {
    default_view_ = new views::View;
    default_view_->SetLayoutManager(new views::FillLayout);
    default_view_->AddChildView(new views::Label(UTF8ToUTF16("Default")));
    return default_view_;
  }

  virtual views::View* CreateDetailedView(user::LoginStatus status) {
    detailed_view_ = new views::View;
    detailed_view_->SetLayoutManager(new views::FillLayout);
    detailed_view_->AddChildView(new views::Label(UTF8ToUTF16("Detailed")));
    return detailed_view_;
  }

  virtual views::View* CreateNotificationView(user::LoginStatus status) {
    notification_view_ = new views::View;
    return notification_view_;
  }

  virtual void DestroyTrayView() {
    tray_view_ = NULL;
  }

  virtual void DestroyDefaultView() {
    default_view_ = NULL;
  }

  virtual void DestroyDetailedView() {
    detailed_view_ = NULL;
  }

  virtual void DestroyNotificationView() {
    notification_view_ = NULL;
  }

  virtual void UpdateAfterLoginStatusChange(user::LoginStatus status) {
  }

  views::View* tray_view() const { return tray_view_; }
  views::View* default_view() const { return default_view_; }
  views::View* detailed_view() const { return detailed_view_; }
  views::View* notification_view() const { return notification_view_; }

 private:
  views::View* tray_view_;
  views::View* default_view_;
  views::View* detailed_view_;
  views::View* notification_view_;
};

}  // namespace

typedef AshTestBase SystemTrayTest;

TEST_F(SystemTrayTest, SystemTrayDefaultView) {
  SystemTray* tray = GetSystemTray();
  ASSERT_TRUE(tray->GetWidget());

  tray->ShowDefaultView(BUBBLE_CREATE_NEW);

  // Ensure that closing the bubble destroys it.
  ASSERT_TRUE(tray->CloseBubbleForTest());
  RunAllPendingInMessageLoop();
  ASSERT_FALSE(tray->CloseBubbleForTest());
}

#if defined(OS_WIN)
// This test is crashing on windows. See http://crbug.com/127539.
#define MAYBE_SystemTrayTestItems DISABLED_SystemTrayTestItems
#else
#define MAYBE_SystemTrayTestItems SystemTrayTestItems
#endif

TEST_F(SystemTrayTest, MAYBE_SystemTrayTestItems) {
  SystemTray* tray = GetSystemTray();
  ASSERT_TRUE(tray->GetWidget());

  TestItem* test_item = new TestItem;
  TestItem* detailed_item = new TestItem;
  tray->AddTrayItem(test_item);
  tray->AddTrayItem(detailed_item);

  // Ensure the tray views are created.
  ASSERT_TRUE(test_item->tray_view() != NULL);
  ASSERT_TRUE(detailed_item->tray_view() != NULL);

  // Ensure a default views are created.
  tray->ShowDefaultView(BUBBLE_CREATE_NEW);
  ASSERT_TRUE(test_item->default_view() != NULL);
  ASSERT_TRUE(detailed_item->default_view() != NULL);

  // Show the detailed view, ensure it's created and the default view destroyed.
  tray->ShowDetailedView(detailed_item, 0, false, BUBBLE_CREATE_NEW);
  RunAllPendingInMessageLoop();
  ASSERT_TRUE(test_item->default_view() == NULL);
  ASSERT_TRUE(detailed_item->detailed_view() != NULL);

  // Show the default view, ensure it's created and the detailed view destroyed.
  tray->ShowDefaultView(BUBBLE_CREATE_NEW);
  RunAllPendingInMessageLoop();
  ASSERT_TRUE(test_item->default_view() != NULL);
  ASSERT_TRUE(detailed_item->detailed_view() == NULL);
}

TEST_F(SystemTrayTest, TrayWidgetAutoResizes) {
  SystemTray* tray = GetSystemTray();
  ASSERT_TRUE(tray->GetWidget());

  gfx::Size widget_size = tray->GetWidget()->GetWindowScreenBounds().size();

  TestItem* test_item = new TestItem;
  tray->AddTrayItem(test_item);

  gfx::Size new_size = tray->GetWidget()->GetWindowScreenBounds().size();

  // Adding the new item should change the size of the tray.
  EXPECT_NE(widget_size.ToString(), new_size.ToString());

  // Hiding the tray view of the new item should also change the size of the
  // tray.
  test_item->tray_view()->SetVisible(false);
  EXPECT_EQ(widget_size.ToString(),
            tray->GetWidget()->GetWindowScreenBounds().size().ToString());

  test_item->tray_view()->SetVisible(true);
  EXPECT_EQ(new_size.ToString(),
            tray->GetWidget()->GetWindowScreenBounds().size().ToString());
}

// Disabled due to a use-after-free, see http://crbug.com/127539.
TEST_F(SystemTrayTest, DISABLED_SystemTrayNotifications) {
  SystemTray* tray = GetSystemTray();
  ASSERT_TRUE(tray->GetWidget());

  TestItem* test_item = new TestItem;
  TestItem* detailed_item = new TestItem;
  tray->AddTrayItem(test_item);
  tray->AddTrayItem(detailed_item);

  // Ensure the tray views are created.
  ASSERT_TRUE(test_item->tray_view() != NULL);
  ASSERT_TRUE(detailed_item->tray_view() != NULL);

  // Ensure a notification view is created.
  tray->ShowNotificationView(test_item);
  ASSERT_TRUE(test_item->notification_view() != NULL);

  // Show the default view, ensure the notification view is destroyed.
  tray->ShowDefaultView(BUBBLE_CREATE_NEW);
  RunAllPendingInMessageLoop();
  ASSERT_TRUE(test_item->notification_view() == NULL);

  // Show the detailed view, ensure the notificaiton view is created again.
  tray->ShowDetailedView(detailed_item, 0, false, BUBBLE_CREATE_NEW);
  RunAllPendingInMessageLoop();
  ASSERT_TRUE(detailed_item->detailed_view() != NULL);
  ASSERT_TRUE(test_item->notification_view() != NULL);

  // Hide the detailed view, ensure the notificaiton view still exists.
  ASSERT_TRUE(tray->CloseBubbleForTest());
  RunAllPendingInMessageLoop();
  ASSERT_TRUE(detailed_item->detailed_view() == NULL);
  ASSERT_TRUE(test_item->notification_view() != NULL);
}

TEST_F(SystemTrayTest, BubbleCreationTypesTest) {
  SystemTray* tray = GetSystemTray();
  ASSERT_TRUE(tray->GetWidget());

  TestItem* test_item = new TestItem;
  tray->AddTrayItem(test_item);

  // Ensure the tray views are created.
  ASSERT_TRUE(test_item->tray_view() != NULL);

  // Show the default view, ensure the notification view is destroyed.
  tray->ShowDefaultView(BUBBLE_CREATE_NEW);
  RunAllPendingInMessageLoop();

  views::Widget* widget = test_item->default_view()->GetWidget();
  gfx::Rect bubble_bounds = widget->GetWindowScreenBounds();

  tray->ShowDetailedView(test_item, 0, true, BUBBLE_USE_EXISTING);
  RunAllPendingInMessageLoop();

  EXPECT_FALSE(test_item->default_view());

  EXPECT_EQ(bubble_bounds.ToString(), test_item->detailed_view()->GetWidget()->
      GetWindowScreenBounds().ToString());
  EXPECT_EQ(widget, test_item->detailed_view()->GetWidget());

  tray->ShowDefaultView(BUBBLE_USE_EXISTING);
  RunAllPendingInMessageLoop();

  EXPECT_EQ(bubble_bounds.ToString(), test_item->default_view()->GetWidget()->
      GetWindowScreenBounds().ToString());
  EXPECT_EQ(widget, test_item->default_view()->GetWidget());
}

}  // namespace test
}  // namespace ash
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Nathan Osman
 *
 * 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 <QJsonDocument>
#include <QNetworkInterface>
#include <QSet>

#include "../util/platform.h"
#include "config.h"
#include "devicelistener.h"

DeviceListener::DeviceListener()
{
    connect(&mTimer, &QTimer::timeout, this, &DeviceListener::sendPings);
    connect(&mSocket, &QUdpSocket::readyRead, this, &DeviceListener::processPings);

    reload();
}

void DeviceListener::start()
{
    sendPings();
    mTimer.start();
}

void DeviceListener::processPings()
{
    while(mSocket.hasPendingDatagrams()) {
        QByteArray data;
        QHostAddress address;

        data.resize(mSocket.pendingDatagramSize());
        mSocket.readDatagram(data.data(), data.size(), &address);

        QJsonDocument document(QJsonDocument::fromJson(data));
        if(!document.isEmpty()) {
            emit pingReceived(document.object(), address);
        }
    }
}

void DeviceListener::sendPings()
{
    // TODO: when switching to Qt 5.4, switch to using QJsonObject's
    // initializer instead of converting a QVariantMap

    QJsonObject object(QJsonObject::fromVariantMap({
        { "version", NITROSHARE_VERSION },
        { "uuid", Settings::get<QString>(Settings::DeviceUUID) },
        { "name", Settings::get<QString>(Settings::DeviceName) },
        { "os", Platform::currentOSString() },
        { "port", Settings::get<quint16>(Settings::TransferPort) }
    }));

    QByteArray data(QJsonDocument(object).toJson(QJsonDocument::Compact));
    QSet<QHostAddress> addresses;

    foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces()) {
        if(interface.flags() & QNetworkInterface::CanBroadcast) {
            foreach(QNetworkAddressEntry entry, interface.addressEntries()) {
                if(!entry.broadcast().isNull()) {
                    addresses.insert(entry.broadcast());
                }
            }
        }
    }

    foreach(QHostAddress address, addresses) {
        mSocket.writeDatagram(data, address, mSocket.localPort());
    }
}

void DeviceListener::settingChanged(Settings::Key key)
{
    if(key == Settings::BroadcastInterval || key == Settings::BroadcastPort) {
        reload();
        start();
    }
}

void DeviceListener::reload()
{
    mTimer.stop();
    mTimer.setInterval(Settings::get<int>(Settings::BroadcastInterval));

    mSocket.close();
    mSocket.bind(Settings::get<quint16>(Settings::BroadcastPort), QUdpSocket::ShareAddress);
}
<commit_msg>Added missing connection for settingChanged() signal in DeviceListener.<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Nathan Osman
 *
 * 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 <QJsonDocument>
#include <QNetworkInterface>
#include <QSet>

#include "../util/platform.h"
#include "config.h"
#include "devicelistener.h"

DeviceListener::DeviceListener()
{
    connect(&mTimer, &QTimer::timeout, this, &DeviceListener::sendPings);
    connect(&mSocket, &QUdpSocket::readyRead, this, &DeviceListener::processPings);
    connect(Settings::instance(), &Settings::settingChanged, this, &DeviceListener::settingChanged);

    reload();
}

void DeviceListener::start()
{
    sendPings();
    mTimer.start();
}

void DeviceListener::processPings()
{
    while(mSocket.hasPendingDatagrams()) {
        QByteArray data;
        QHostAddress address;

        data.resize(mSocket.pendingDatagramSize());
        mSocket.readDatagram(data.data(), data.size(), &address);

        QJsonDocument document(QJsonDocument::fromJson(data));
        if(!document.isEmpty()) {
            emit pingReceived(document.object(), address);
        }
    }
}

void DeviceListener::sendPings()
{
    // TODO: when switching to Qt 5.4, switch to using QJsonObject's
    // initializer instead of converting a QVariantMap

    QJsonObject object(QJsonObject::fromVariantMap({
        { "version", NITROSHARE_VERSION },
        { "uuid", Settings::get<QString>(Settings::DeviceUUID) },
        { "name", Settings::get<QString>(Settings::DeviceName) },
        { "os", Platform::currentOSString() },
        { "port", Settings::get<quint16>(Settings::TransferPort) }
    }));

    QByteArray data(QJsonDocument(object).toJson(QJsonDocument::Compact));
    QSet<QHostAddress> addresses;

    foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces()) {
        if(interface.flags() & QNetworkInterface::CanBroadcast) {
            foreach(QNetworkAddressEntry entry, interface.addressEntries()) {
                if(!entry.broadcast().isNull()) {
                    addresses.insert(entry.broadcast());
                }
            }
        }
    }

    foreach(QHostAddress address, addresses) {
        mSocket.writeDatagram(data, address, mSocket.localPort());
    }
}

void DeviceListener::settingChanged(Settings::Key key)
{
    if(key == Settings::BroadcastInterval || key == Settings::BroadcastPort) {
        reload();
        start();
    }
}

void DeviceListener::reload()
{
    mTimer.stop();
    mTimer.setInterval(Settings::get<int>(Settings::BroadcastInterval));

    mSocket.close();
    mSocket.bind(Settings::get<quint16>(Settings::BroadcastPort), QUdpSocket::ShareAddress);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: hfi_enum.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-18 14:11:37 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <precomp.h>
#include "hfi_enum.hxx"

// NOT FULLY DEFINED SERVICES
#include <ary/idl/i_ce.hxx>
#include <ary/idl/ik_enum.hxx>
#include <toolkit/hf_linachain.hxx>
#include <toolkit/hf_navi_sub.hxx>
#include <toolkit/hf_title.hxx>
#include "hfi_navibar.hxx"
#include "hfi_property.hxx"
#include "hi_linkhelper.hxx"

extern const String
    C_sCePrefix_Enum("enum");

namespace
{

const String
    C_sList_Values("Values");
const String
    C_sList_Values_Label("Values");
const String
    C_sList_ValueDetails("Values' Details");
const String
    C_sList_ValueDetails_Label("ValueDetails");

enum E_SubListIndices
{
    sli_ValuesSummary = 0,
    sli_ValueDetails = 1
};

}   // anonymous namespace

HF_IdlEnum::HF_IdlEnum( Environment &       io_rEnv,
                        Xml::Element &      o_rOut )
    :   HtmlFactory_Idl(io_rEnv, &o_rOut)
{
}

HF_IdlEnum::~HF_IdlEnum()
{
}

void
HF_IdlEnum::Produce_byData( const client & i_ce ) const
{
    Dyn<HF_NaviSubRow>
        pNaviSubRow( &make_Navibar(i_ce) );

    HF_TitleTable
        aTitle(CurOut());

    HF_LinkedNameChain
        aNameChain(aTitle.Add_Row());

    aNameChain.Produce_CompleteChain(Env().CurPosition(), nameChainLinker);
    aTitle.Produce_Title( StreamLock(200)()
                          << C_sCePrefix_Enum
                          << " "
                          << i_ce.LocalName()
                          << c_str );

    write_Docu(aTitle.Add_Row(), i_ce);
    CurOut() << new Html::HorizontalLine();

    dyn_ce_list
        dpValues;
    ary::idl::ifc_enum::attr::Get_Values(dpValues, i_ce);
    if ( BOOL_OF(*dpValues) )
    {
        produce_Members( *dpValues,
                         C_sList_Values,
                         C_sList_Values_Label,
                         C_sList_ValueDetails,
                         C_sList_ValueDetails_Label );
        pNaviSubRow->SwitchOn(sli_ValuesSummary);
        pNaviSubRow->SwitchOn(sli_ValueDetails);
    }
    pNaviSubRow->Produce_Row();
}

HF_NaviSubRow &
HF_IdlEnum::make_Navibar( const client & i_ce ) const
{
    HF_IdlNavigationBar
        aNaviBar(Env(), CurOut());
    aNaviBar.Produce_CeMainRow(i_ce);

    DYN HF_NaviSubRow &
        ret = aNaviBar.Add_SubRow();
    ret.AddItem(C_sList_Values, C_sList_Values_Label, false);
    ret.AddItem(C_sList_ValueDetails, C_sList_ValueDetails_Label, false);

    CurOut() << new Html::HorizontalLine();
    return ret;
}

void
HF_IdlEnum::produce_MemberDetails( HF_SubTitleTable &  o_table,
                                   const client &      i_ce) const
{
    HF_IdlEnumValue
        aElement( Env(), o_table );
    aElement.Produce_byData(i_ce);
}
<commit_msg>INTEGRATION: CWS adc8 (1.2.66); FILE MERGED 2004/07/02 11:04:10 np 1.2.66.1: #i26261#<commit_after>/*************************************************************************
 *
 *  $RCSfile: hfi_enum.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-12 15:25:05 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <precomp.h>
#include "hfi_enum.hxx"

// NOT FULLY DEFINED SERVICES
#include <ary/idl/i_ce.hxx>
#include <ary/idl/ik_enum.hxx>
#include <toolkit/hf_linachain.hxx>
#include <toolkit/hf_navi_sub.hxx>
#include <toolkit/hf_title.hxx>
#include "hfi_navibar.hxx"
#include "hfi_property.hxx"
#include "hi_linkhelper.hxx"

extern const String
    C_sCePrefix_Enum("enum");

namespace
{

const String
    C_sList_Values("Values");
const String
    C_sList_Values_Label("Values");
const String
    C_sList_ValueDetails("Values' Details");
const String
    C_sList_ValueDetails_Label("ValueDetails");

enum E_SubListIndices
{
    sli_ValuesSummary = 0,
    sli_ValueDetails = 1
};

}   // anonymous namespace

HF_IdlEnum::HF_IdlEnum( Environment &       io_rEnv,
                        Xml::Element &      o_rOut )
    :   HtmlFactory_Idl(io_rEnv, &o_rOut)
{
}

HF_IdlEnum::~HF_IdlEnum()
{
}

void
HF_IdlEnum::Produce_byData( const client & i_ce ) const
{
    Dyn<HF_NaviSubRow>
        pNaviSubRow( &make_Navibar(i_ce) );

    HF_TitleTable
        aTitle(CurOut());

    HF_LinkedNameChain
        aNameChain(aTitle.Add_Row());

    aNameChain.Produce_CompleteChain(Env().CurPosition(), nameChainLinker);
    aTitle.Produce_Title( StreamLock(200)()
                          << C_sCePrefix_Enum
                          << " "
                          << i_ce.LocalName()
                          << c_str );

    write_Docu(aTitle.Add_Row(), i_ce);
    CurOut() << new Html::HorizontalLine();

    dyn_ce_list
        dpValues;
    ary::idl::ifc_enum::attr::Get_Values(dpValues, i_ce);
    if ( (*dpValues).operator bool() )
    {
        produce_Members( *dpValues,
                         C_sList_Values,
                         C_sList_Values_Label,
                         C_sList_ValueDetails,
                         C_sList_ValueDetails_Label );
        pNaviSubRow->SwitchOn(sli_ValuesSummary);
        pNaviSubRow->SwitchOn(sli_ValueDetails);
    }
    pNaviSubRow->Produce_Row();
}

HF_NaviSubRow &
HF_IdlEnum::make_Navibar( const client & i_ce ) const
{
    HF_IdlNavigationBar
        aNaviBar(Env(), CurOut());
    aNaviBar.Produce_CeMainRow(i_ce);

    DYN HF_NaviSubRow &
        ret = aNaviBar.Add_SubRow();
    ret.AddItem(C_sList_Values, C_sList_Values_Label, false);
    ret.AddItem(C_sList_ValueDetails, C_sList_ValueDetails_Label, false);

    CurOut() << new Html::HorizontalLine();
    return ret;
}

void
HF_IdlEnum::produce_MemberDetails( HF_SubTitleTable &  o_table,
                                   const client &      i_ce) const
{
    HF_IdlEnumValue
        aElement( Env(), o_table );
    aElement.Produce_byData(i_ce);
}
<|endoftext|>


<commit_before>/**
 * @file   RectTest.cpp
 * @brief  Rect class tester.
 * @author zer0
 * @date   2016-04-20
 */

#include <gtest/gtest.h>
#include <libtbag/geometry/Rect.hpp>

#include <atomic>

using namespace libtbag;
using namespace libtbag::geometry;

TEST(RectTest, Constructor)
{
    Rect r1;
    Rect r2 = {1, 2, 3, 4};
    Rect r3 = r2;
    Rect r4_move = Rect{5, 6, 7, 8};
    Rect r4 = std::move(r4_move);

    r1 = r2;

    ASSERT_EQ(1, r1.x);
    ASSERT_EQ(2, r1.y);
    ASSERT_EQ(3, r1.width);
    ASSERT_EQ(4, r1.height);

    ASSERT_EQ(1, r2.x);
    ASSERT_EQ(2, r2.y);
    ASSERT_EQ(3, r2.width);
    ASSERT_EQ(4, r2.height);

    ASSERT_EQ(1, r3.x);
    ASSERT_EQ(2, r3.y);
    ASSERT_EQ(3, r3.width);
    ASSERT_EQ(4, r3.height);

    ASSERT_EQ(5, r4.x);
    ASSERT_EQ(6, r4.y);
    ASSERT_EQ(7, r4.width);
    ASSERT_EQ(8, r4.height);

    ASSERT_EQ(r1, r2);
    ASSERT_EQ(r2, r3);
    ASSERT_NE(r3, r4);
}

TEST(RectTest, Operators_1)
{
    Point p = {1, 2};
    Size  s = {3, 4};
    Rect  r = {5, 6, 7, 8};

    ASSERT_EQ(Rect(6, 8,  7,  8), r + p);
    ASSERT_EQ(Rect(4, 4,  7,  8), r - p);
    ASSERT_EQ(Rect(5, 6, 10, 12), r + s);
    ASSERT_EQ(Rect(5, 6,  4,  4), r - s);

    Rect temp;
    temp = r; temp += p;
    ASSERT_EQ(Rect(6, 8,  7,  8), temp);
    temp = r; temp -= p;
    ASSERT_EQ(Rect(4, 4,  7,  8), temp);
    temp = r; temp += s;
    ASSERT_EQ(Rect(5, 6, 10, 12), temp);
    temp = r; temp -= s;
    ASSERT_EQ(Rect(5, 6,  4,  4), temp);
}

TEST(RectTest, Operators_2)
{
    /*
     * 0 |  1  2  3  4  5
     * --+--------------------
     *   |
     * 1 |  +-----+
     *   |  |     |
     * 2 |  |  +-----+
     *   |  |  |  |  |
     * 3 |  +- |--+  |
     *   |     |     |
     * 4 |     +-----+
     *   |
     * 5 |
     */
    Rect r1 = {1, 1, 2, 2};
    Rect r2 = {2, 2, 2, 2};

    ASSERT_EQ(Rect(2, 2, 1, 1), r1 & r2);
    ASSERT_EQ(Rect(1, 1, 3, 3), r1 | r2);
}

TEST(RectTest, Utility)
{
    Point p = {10, 20};
    Size  s = {30, 40};
    Rect  r = {p.x, p.y, s.width, s.height};
    int   a = s.width * s.height;

    ASSERT_EQ(p, r.point());
    ASSERT_EQ(s, r.size ());
    ASSERT_EQ(a, r.area ());
};

TEST(RectTest, Methods)
{
    /*
     *  0 |  10  20
     * ---+--------
     *    |
     * 10 |   +---+
     *    |   |   |
     * 20 |   +---+
     */
    Rect r = {20, 20, -10, -10};

    ASSERT_EQ(Point(10, 10), r.getLeftTop());
    ASSERT_EQ(Point(20, 10), r.getRightTop());
    ASSERT_EQ(Point(10, 20), r.getLeftBottom());
    ASSERT_EQ(Point(20, 20), r.getRightBottom());
}

TEST(RectTest, CheckInside)
{
    /*
     *  0 |  10  20  30
     * ---+------------
     *    |
     * 10 |
     *    |
     * 20 |       +---+
     *    |       |   |
     * 30 |       +---+
     */
    Rect r = {20, 20, 10, 10};

    Point p1 = {30, 25};
    Point p2 = {25, 25};
    ASSERT_TRUE(r.contains(p1));
    ASSERT_TRUE(r.contains(p2));
    ASSERT_TRUE(r.contains(Rect(p1, p2)));

    Point p3 = {10, 25};
    Point p4 = {40, 25};
    Point p5 = {25, 15};
    Point p6 = {25, 35};
    ASSERT_FALSE(r.contains(p3));
    ASSERT_FALSE(r.contains(p4));
    ASSERT_FALSE(r.contains(p5));
    ASSERT_FALSE(r.contains(p6));
    ASSERT_FALSE(r.contains(Rect(p1, p3)));
    ASSERT_FALSE(r.contains(Rect(p1, p4)));
    ASSERT_FALSE(r.contains(Rect(p1, p5)));
    ASSERT_FALSE(r.contains(Rect(p1, p6)));
    ASSERT_FALSE(r.contains(Rect(p2, p3)));
    ASSERT_FALSE(r.contains(Rect(p2, p4)));
    ASSERT_FALSE(r.contains(Rect(p2, p5)));
    ASSERT_FALSE(r.contains(Rect(p2, p6)));
}

TEST(RectTest, ClipRect_True)
{
    /*
     *  0 |  10  20  30  40  50
     * ---+--------------------
     *    |
     * 10 |   +-------+
     *    |   |       |
     * 20 |   |   +-------+
     *    |   |   |   |   |
     * 30 |   +---|---+   |
     *    |       |       |
     * 40 |       +-------+
     *    |
     * 50 |
     */
    Rect clip;
    ASSERT_TRUE(Rect(20, 20, 20, 20).clip(Rect(30, 30, -20, -20), &clip));

    Rect predict = {20, 20, 10, 10};
    ASSERT_EQ(predict, clip);
}

TEST(RectTest, ClipRect_False)
{
    /*
     *  0 |  10  20  30  40  50
     * ---+--------------------
     *    |
     * 10 |           +---+
     *    |           |   |
     * 20 |   +---+   +---+
     *    |   |   |
     * 30 |   +---+
     *    |
     * 40 |
     */
    ASSERT_FALSE(Rect(10, 20, 10, 10).clip(Rect(30, 10, 10, 10)));
}

TEST(RectTest, AbsoluteRect)
{
    /*
     *  0 |  10  20
     * ---+--------
     *    |
     * 10 |   +---+
     *    |   |   |
     * 20 |   +---+ <-(x,y)
     */
    Rect r = {20, 20, -10, -10};
    ASSERT_EQ(Rect(10, 10, 10, 10), r.absolute());
    ASSERT_EQ(Rect(10, 10, 10, 10), Rect(10, 10, 10, 10).absolute());
}

TEST(RectTest, StretchByCenter)
{
    /*
     *  0 |  10  20  30  40  50
     * ---+--------------------
     *    |
     * 10 |   +-----------+
     *    |   |           |
     * 20 |   |   +---+   |
     *    |   |   |   |   |
     * 30 |   |   +---+   |
     *    |   |           |
     * 40 |   +-----------+
     *    |
     * 50 |
     */
    Rect r = {20, 20, 10, 10};
    ASSERT_EQ(Rect(10, 10, 30, 30), r.stretchByCenter(10));
}

TEST(RectTest, String)
{
    Rect p = {1, 2, 3, 4};
    ASSERT_FALSE(p.toString().empty());
}

namespace __impl {

struct TestRect
{
    int x, y, w, h;
};

} // namespace __impl

TEST(RectTest, Convert)
{
    using namespace __impl;
    TestRect const TEST_RECT = Rect(1, 2, 3, 4).toOther<TestRect>();
    ASSERT_EQ(1, TEST_RECT.x);
    ASSERT_EQ(2, TEST_RECT.y);
    ASSERT_EQ(3, TEST_RECT.w);
    ASSERT_EQ(4, TEST_RECT.h);
}

<commit_msg>Create RectTest.Operators3 tester.<commit_after>/**
 * @file   RectTest.cpp
 * @brief  Rect class tester.
 * @author zer0
 * @date   2016-04-20
 */

#include <gtest/gtest.h>
#include <libtbag/geometry/Rect.hpp>

#include <atomic>

using namespace libtbag;
using namespace libtbag::geometry;

TEST(RectTest, Constructor)
{
    Rect r1;
    Rect r2 = {1, 2, 3, 4};
    Rect r3 = r2;
    Rect r4_move = Rect{5, 6, 7, 8};
    Rect r4 = std::move(r4_move);

    r1 = r2;

    ASSERT_EQ(1, r1.x);
    ASSERT_EQ(2, r1.y);
    ASSERT_EQ(3, r1.width);
    ASSERT_EQ(4, r1.height);

    ASSERT_EQ(1, r2.x);
    ASSERT_EQ(2, r2.y);
    ASSERT_EQ(3, r2.width);
    ASSERT_EQ(4, r2.height);

    ASSERT_EQ(1, r3.x);
    ASSERT_EQ(2, r3.y);
    ASSERT_EQ(3, r3.width);
    ASSERT_EQ(4, r3.height);

    ASSERT_EQ(5, r4.x);
    ASSERT_EQ(6, r4.y);
    ASSERT_EQ(7, r4.width);
    ASSERT_EQ(8, r4.height);

    ASSERT_EQ(r1, r2);
    ASSERT_EQ(r2, r3);
    ASSERT_NE(r3, r4);
}

TEST(RectTest, Operators1)
{
    Point p = {1, 2};
    Size  s = {3, 4};
    Rect  r = {5, 6, 7, 8};

    ASSERT_EQ(Rect(6, 8,  7,  8), r + p);
    ASSERT_EQ(Rect(4, 4,  7,  8), r - p);
    ASSERT_EQ(Rect(5, 6, 10, 12), r + s);
    ASSERT_EQ(Rect(5, 6,  4,  4), r - s);

    Rect temp;
    temp = r; temp += p;
    ASSERT_EQ(Rect(6, 8,  7,  8), temp);
    temp = r; temp -= p;
    ASSERT_EQ(Rect(4, 4,  7,  8), temp);
    temp = r; temp += s;
    ASSERT_EQ(Rect(5, 6, 10, 12), temp);
    temp = r; temp -= s;
    ASSERT_EQ(Rect(5, 6,  4,  4), temp);
}

TEST(RectTest, Operators2)
{
    /*
     * 0 |  1  2  3  4  5
     * --+--------------------
     *   |
     * 1 |  +-----+
     *   |  |     |
     * 2 |  |  +-----+
     *   |  |  |  |  |
     * 3 |  +- |--+  |
     *   |     |     |
     * 4 |     +-----+
     *   |
     * 5 |
     */
    Rect r1 = {1, 1, 2, 2};
    Rect r2 = {2, 2, 2, 2};

    ASSERT_EQ(Rect(2, 2, 1, 1), r1 & r2);
    ASSERT_EQ(Rect(1, 1, 3, 3), r1 | r2);
}

TEST(RectTest, Operators3)
{
    /*
     * 0 |  1  2  3  4  5
     * --+--------------------
     *   |
     * 1 |  +--+
     *   |  |  |
     * 2 |  +--+
     *   |
     * 3 |        +--+
     *   |        |  |
     * 4 |        +--+
     *   |
     * 5 |
     */
    Rect r1 = {1, 1, 1, 1};
    Rect r2 = {3, 3, 1, 1};

    Rect r_union = r1 & r2;
    Rect r_intersection = r1 | r2;

    ASSERT_TRUE(r_union.empty());
    ASSERT_FALSE(r_intersection.empty());

    ASSERT_EQ(Rect(3, 3, -1, -1), r_union);
    ASSERT_EQ(Rect(1, 1, 3, 3), r_intersection);
}

TEST(RectTest, Utility)
{
    Point p = {10, 20};
    Size  s = {30, 40};
    Rect  r = {p.x, p.y, s.width, s.height};
    int   a = s.width * s.height;

    ASSERT_EQ(p, r.point());
    ASSERT_EQ(s, r.size ());
    ASSERT_EQ(a, r.area ());
};

TEST(RectTest, Methods)
{
    /*
     *  0 |  10  20
     * ---+--------
     *    |
     * 10 |   +---+
     *    |   |   |
     * 20 |   +---+
     */
    Rect r = {20, 20, -10, -10};

    ASSERT_EQ(Point(10, 10), r.getLeftTop());
    ASSERT_EQ(Point(20, 10), r.getRightTop());
    ASSERT_EQ(Point(10, 20), r.getLeftBottom());
    ASSERT_EQ(Point(20, 20), r.getRightBottom());
}

TEST(RectTest, CheckInside)
{
    /*
     *  0 |  10  20  30
     * ---+------------
     *    |
     * 10 |
     *    |
     * 20 |       +---+
     *    |       |   |
     * 30 |       +---+
     */
    Rect r = {20, 20, 10, 10};

    Point p1 = {30, 25};
    Point p2 = {25, 25};
    ASSERT_TRUE(r.contains(p1));
    ASSERT_TRUE(r.contains(p2));
    ASSERT_TRUE(r.contains(Rect(p1, p2)));

    Point p3 = {10, 25};
    Point p4 = {40, 25};
    Point p5 = {25, 15};
    Point p6 = {25, 35};
    ASSERT_FALSE(r.contains(p3));
    ASSERT_FALSE(r.contains(p4));
    ASSERT_FALSE(r.contains(p5));
    ASSERT_FALSE(r.contains(p6));
    ASSERT_FALSE(r.contains(Rect(p1, p3)));
    ASSERT_FALSE(r.contains(Rect(p1, p4)));
    ASSERT_FALSE(r.contains(Rect(p1, p5)));
    ASSERT_FALSE(r.contains(Rect(p1, p6)));
    ASSERT_FALSE(r.contains(Rect(p2, p3)));
    ASSERT_FALSE(r.contains(Rect(p2, p4)));
    ASSERT_FALSE(r.contains(Rect(p2, p5)));
    ASSERT_FALSE(r.contains(Rect(p2, p6)));
}

TEST(RectTest, ClipRect_True)
{
    /*
     *  0 |  10  20  30  40  50
     * ---+--------------------
     *    |
     * 10 |   +-------+
     *    |   |       |
     * 20 |   |   +-------+
     *    |   |   |   |   |
     * 30 |   +---|---+   |
     *    |       |       |
     * 40 |       +-------+
     *    |
     * 50 |
     */
    Rect clip;
    ASSERT_TRUE(Rect(20, 20, 20, 20).clip(Rect(30, 30, -20, -20), &clip));

    Rect predict = {20, 20, 10, 10};
    ASSERT_EQ(predict, clip);
}

TEST(RectTest, ClipRect_False)
{
    /*
     *  0 |  10  20  30  40  50
     * ---+--------------------
     *    |
     * 10 |           +---+
     *    |           |   |
     * 20 |   +---+   +---+
     *    |   |   |
     * 30 |   +---+
     *    |
     * 40 |
     */
    ASSERT_FALSE(Rect(10, 20, 10, 10).clip(Rect(30, 10, 10, 10)));
}

TEST(RectTest, AbsoluteRect)
{
    /*
     *  0 |  10  20
     * ---+--------
     *    |
     * 10 |   +---+
     *    |   |   |
     * 20 |   +---+ <-(x,y)
     */
    Rect r = {20, 20, -10, -10};
    ASSERT_EQ(Rect(10, 10, 10, 10), r.absolute());
    ASSERT_EQ(Rect(10, 10, 10, 10), Rect(10, 10, 10, 10).absolute());
}

TEST(RectTest, StretchByCenter)
{
    /*
     *  0 |  10  20  30  40  50
     * ---+--------------------
     *    |
     * 10 |   +-----------+
     *    |   |           |
     * 20 |   |   +---+   |
     *    |   |   |   |   |
     * 30 |   |   +---+   |
     *    |   |           |
     * 40 |   +-----------+
     *    |
     * 50 |
     */
    Rect r = {20, 20, 10, 10};
    ASSERT_EQ(Rect(10, 10, 30, 30), r.stretchByCenter(10));
}

TEST(RectTest, String)
{
    Rect p = {1, 2, 3, 4};
    ASSERT_FALSE(p.toString().empty());
}

namespace __impl {

struct TestRect
{
    int x, y, w, h;
};

} // namespace __impl

TEST(RectTest, Convert)
{
    using namespace __impl;
    TestRect const TEST_RECT = Rect(1, 2, 3, 4).toOther<TestRect>();
    ASSERT_EQ(1, TEST_RECT.x);
    ASSERT_EQ(2, TEST_RECT.y);
    ASSERT_EQ(3, TEST_RECT.w);
    ASSERT_EQ(4, TEST_RECT.h);
}

<|endoftext|>


<commit_before>#include "CardiacNash2000Material.h"
#include "TensorHelpers.h"

using namespace TensorHelpers;

template<>
InputParameters validParams<CardiacNash2000Material>()
{
  InputParameters params = validParams<CardiacMechanicsMaterial>();
  params.addRequiredParam<std::vector<Real> >("k_MN", "Material parameters k_MN in following order: k_11, k_22, k_33, k_12, k_23, k_13. Unit: kPa.");
  params.addRequiredParam<std::vector<Real> >("a_MN", "Material parameters a_MN in following order: a_11, a_22, a_33, a_12, a_23, a_13. Unitless.");
  params.addRequiredParam<std::vector<Real> >("b_MN", "Material parameters b_MN in following order: b_11, b_22, b_33, b_12, b_23, b_13. Unitless.");
  return params;
}

CardiacNash2000Material::CardiacNash2000Material(const std::string  & name,
                                                 InputParameters parameters)
  :CardiacMechanicsMaterial(name, parameters),
   _k(SymmTensor(getParam<std::vector<Real> >("k_MN"))),
   _a(SymmTensor(getParam<std::vector<Real> >("a_MN"))),
   _b(SymmTensor(getParam<std::vector<Real> >("b_MN")))
{
  for (int M=0;M<3;M++)
    for (int N=M;N<3;N++)
       if (_k(M,N)<0 || _a(M,N)<=0 || _b(M,N)<=0) mooseError("CardiacNash2000Material: invalid material parameters.");
}

void
CardiacNash2000Material::computeQpStressProperties(const SymmTensor & /*C*/, const SymmTensor &E)
{
  // 2nd Piola-Kirchhoff stress tensor: T(MN) = 1/2[dW/dE(MN) + dW/dE(NM)] + [- p + Ta delta(M1) delta(N1) ] C^-1(MN)
  // We make use of dW/dE(MN) == dW/dE(NM) and will add active tension and pressure terms outside (see #CardiacMechanicsMaterial)
  SymmTensor T(0);
  // Derivative of T: D(MNPQ) = dT(MN)/dE(PQ)
  CardiacElasticityTensor D;
  // We will sum up the elastic energy contributions inside the loop
  Real W(0);

  for (unsigned int M=0;M<3;M++)
    for (unsigned int N=M;N<3;N++)
    {
      const Real k(_k(M,N));
      const Real e(std::abs(E(M,N)));
      const Real a(_a(M,N));
      const Real b(_b(M,N));
      if (e>a) mooseError("CardiacNash2000Material: E_{MN} >= a_{MN} - the strain is too large for this model");
      const Real d(std::abs(a - e));
      const Real f( b*e/d );
      const Real g( k*pow(d,-b) );

      const Real fact(M==N ? 1.0 : 0.5);

      T(M,N) = fact * g * e * ( 2+f );

      // insane loop to cover all elements of the symmetric 4th order tensor exactly once. The if-construct avoids douple-counting for major-symmetry pairs of MN<->PQ
      for (unsigned int P=M;P<3;P++)
        for (unsigned int Q=P;Q<3;Q++)
          if (P != M || Q >= N)
            D(M,N,P,Q) = fact * g * ( 2 + (4+e/d+f)*f );

      W += fact * g * e*e;
    }

  _stress[_qp] = T;
  _stress_derivative[_qp] = D;
  _W[_qp] = W;
}

<commit_msg>minor simplification in derivative loop in CardiacNash2000Material<commit_after>#include "CardiacNash2000Material.h"
#include "TensorHelpers.h"

using namespace TensorHelpers;

template<>
InputParameters validParams<CardiacNash2000Material>()
{
  InputParameters params = validParams<CardiacMechanicsMaterial>();
  params.addRequiredParam<std::vector<Real> >("k_MN", "Material parameters k_MN in following order: k_11, k_22, k_33, k_12, k_23, k_13. Unit: kPa.");
  params.addRequiredParam<std::vector<Real> >("a_MN", "Material parameters a_MN in following order: a_11, a_22, a_33, a_12, a_23, a_13. Unitless.");
  params.addRequiredParam<std::vector<Real> >("b_MN", "Material parameters b_MN in following order: b_11, b_22, b_33, b_12, b_23, b_13. Unitless.");
  return params;
}

CardiacNash2000Material::CardiacNash2000Material(const std::string  & name,
                                                 InputParameters parameters)
  :CardiacMechanicsMaterial(name, parameters),
   _k(SymmTensor(getParam<std::vector<Real> >("k_MN"))),
   _a(SymmTensor(getParam<std::vector<Real> >("a_MN"))),
   _b(SymmTensor(getParam<std::vector<Real> >("b_MN")))
{
  for (int M=0;M<3;M++)
    for (int N=M;N<3;N++)
       if (_k(M,N)<0 || _a(M,N)<=0 || _b(M,N)<=0) mooseError("CardiacNash2000Material: invalid material parameters.");
}

void
CardiacNash2000Material::computeQpStressProperties(const SymmTensor & /*C*/, const SymmTensor &E)
{
  // 2nd Piola-Kirchhoff stress tensor: T(MN) = 1/2[dW/dE(MN) + dW/dE(NM)] + [- p + Ta delta(M1) delta(N1) ] C^-1(MN)
  // We make use of dW/dE(MN) == dW/dE(NM) and will add active tension and pressure terms outside (see #CardiacMechanicsMaterial)
  SymmTensor T(0);
  // Derivative of T: D(MNPQ) = dT(MN)/dE(PQ)
  CardiacElasticityTensor D;
  // We will sum up the elastic energy contributions inside the loop
  Real W(0);

  for (unsigned int M=0;M<3;M++)
    for (unsigned int N=M;N<3;N++)
    {
      const Real k(_k(M,N));
      const Real e(std::abs(E(M,N)));
      const Real a(_a(M,N));
      const Real b(_b(M,N));
      if (e>a) mooseError("CardiacNash2000Material: E_{MN} >= a_{MN} - the strain is too large for this model");
      const Real d(std::abs(a - e));
      const Real f( b*e/d );
      const Real g( k*pow(d,-b) );

      const Real fact(M==N ? 1.0 : 0.5);

      T(M,N) = fact * g * e * ( 2+f );

      // loop to cover all elements of the symmetric 4th order tensor, major-symmetry pairs of MN<->PQ are traversed twice, which avoids an if-construct inside the loop
      for (unsigned int P=M;P<3;P++)
        for (unsigned int Q=P;Q<3;Q++)
            D(M,N,P,Q) = fact * g * ( 2 + (4+e/d+f)*f );

      W += fact * g * e*e;
    }

  _stress[_qp] = T;
  _stress_derivative[_qp] = D;
  _W[_qp] = W;
}

<|endoftext|>