<commit_before>/*
The OpenTRV project licenses this file to you
under the Apache Licence, Version 2.0 (the "Licence");
you may not use this file except in compliance
with the Licence. You may obtain a copy of the Licence at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the Licence is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the Licence for the
specific language governing permissions and limitations
under the Licence.

Author(s) / Copyright (s): Damon Hart-Davis 2016
*/

/*
 * OTRadValve TempControl tests.
 */

#include <gtest/gtest.h>
#include <stdio.h>
#include <stdlib.h>

#include "OTSIM900Link.h"

// Test the getter function definitely does what it should.
TEST(OTSIM900Link, getterFunction)
{
    const char SIM900_PIN[] = "1111";
    const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config(false, SIM900_PIN, NULL, NULL, NULL);
    EXPECT_EQ(SIM900_PIN[0], SIM900Config.get((const uint8_t *)SIM900Config.PIN));
}

// Test for general sanity of OTSIM900Link.
// Make sure that an instance can be created and does not die horribly.
// Underlying simulated serial/SIM900 never accepts data or responds, eg like a dead card.
TEST(OTSIM900Link,basicsDeadCard)
{
    const bool verbose = false;

    class NULLSerialStream final : public Stream
      {
      public:
        void begin(unsigned long) { }
        void begin(unsigned long, uint8_t);
        void end();

        virtual size_t write(uint8_t c) override { if(verbose) { fprintf(stderr, "%c\n", (char) c); } return(0); }
        virtual int available() override { return(-1); }
        virtual int read() override { return(-1); }
        virtual int peek() override { return(-1); }
        virtual void flush() override { }
      };
    OTSIM900Link::OTSIM900Link<0, 0, 0, NULLSerialStream> l0;
    EXPECT_TRUE(l0.begin());
    EXPECT_EQ(OTSIM900Link::GET_STATE, l0._getState());
    // Try to hang just by calling poll() repeatedly.
    for(int i = 0; i < 100; ++i) { l0.poll(); }
    EXPECT_GE(OTSIM900Link::START_UP, l0._getState()) << "should keep trying to start with GET_STATE, RETRY_GET_STATE and START_UP";
    // ...
    l0.end();
}

// Test for general sanity of OTSIM900Link.
// Make sure that an instance can be created and does not die horribly.
// Underlying simulated serial/SIM900 accepts output, does not respond.
namespace B1
{
const bool verbose = true;

// Does a trivial simulation of SIM900, responding to start of 'A' of AT command.
// Exercises every major non-PANIC state of the OTSIM900Link implementation.
class TrivialSimulator final : public Stream
  {
  public:
    // Events exposed.
    static bool haveSeenCommandStart;

  private:
    // Command being collected from OTSIM900Link.
    bool waitingForCommand = true;
    bool collectingCommand = false;
    // Entire request starting "AT"; no trailing CR or LF stored.
    std::string command;

    // Reply (postfix) being returned to OTSIM900Link: empty if none.
    std::string reply;

  public:
    void begin(unsigned long) { }
    void begin(unsigned long, uint8_t);
    void end();

    virtual size_t write(uint8_t uc) override
      {
      const char c = (char)uc;
      if(waitingForCommand)
        {
        // Look for leading 'A' of 'AT' to start a command.
        if('A' == c)
          {
          waitingForCommand = false;
          collectingCommand = true;
          command = 'A';
          haveSeenCommandStart = true; // Note at least one command start.
          }
        }
      else
        {
        // Look for CR (or LF) to terminate a command.
        if(('\r' == c) || ('\n' == c))
          {
          waitingForCommand = true;
          collectingCommand = false;
          if(verbose) { fprintf(stderr, "command received: %s\n", command.c_str()); }
          // Respond to particular commands...
          if("AT" == command) { reply = "AT\r"; }  // Relevant states: GET_STATE, RETRY_GET_STATE, START_UP
          // DHD20161101: "No PIN" response (deliberately not typical SIM900 response) resulted in SIGSEGV from not checking getResponse() result for NULL.
          // Should futz/vary the response to check sensitivity.
          // TODO: have at least one response be expected SIM900 answer for no-PIN SIM.
          else if("AT+CPIN?" == command) { reply = (random() & 1) ? "No PIN\r" : "OK READY\r"; }  // Relevant states: CHECK_PIN
          else if("AT+CREG?" == command) { reply = (random() & 1) ? "+CREG: 0,0\r" : "+CREG: 0,5\r"; } // Relevant states: WAIT_FOR_REGISTRATION
//          else if("AT+CSTT=apn" == command) { reply = (random() & 1) ? "gbfhs\r" : "\n  OK\r"; } // Relevant states: SET_APN
          }
        else if(collectingCommand) { command += c; }
        }
      if(verbose) { if(isprint(c)) { fprintf(stderr, "<%c\n", c); } else { fprintf(stderr, "< %d\n", (int)c); } }
      return(1);
      }
    virtual int read() override
        {
        if(0 == reply.size()) { return(-1); }
        const char c = reply[0];
        if(verbose) { if(isprint(c)) { fprintf(stderr, ">%c\n", c); } else { fprintf(stderr, "> %d\n", (int)c); } }
        reply.erase(0, 1);
        return(c);
        }
    virtual int available() override { return(-1); }
    virtual int peek() override { return(-1); }
    virtual void flush() override { }
  };
// Events exposed.
bool TrivialSimulator::haveSeenCommandStart;
}
TEST(OTSIM900Link,basicsSimpleSimulator)
{
//    const bool verbose = true;

    //srandomdev(); // Seed random() for use in simulator.

    const char SIM900_PIN[] = "1111";
    const char SIM900_APN[] = "apn";
    const char SIM900_UDP_ADDR[] = "0.0.0.0"; // ORS server
    const char SIM900_UDP_PORT[] = "9999";
    const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config(false, SIM900_PIN, SIM900_APN, SIM900_UDP_ADDR, SIM900_UDP_PORT);
    const OTRadioLink::OTRadioChannelConfig l0Config(&SIM900Config, true);

    ASSERT_FALSE(B1::TrivialSimulator::haveSeenCommandStart);
    OTSIM900Link::OTSIM900Link<0, 0, 0, B1::TrivialSimulator> l0;
    EXPECT_TRUE(l0.configure(1, &l0Config));
    EXPECT_TRUE(l0.begin());
    EXPECT_EQ(OTSIM900Link::GET_STATE, l0._getState());
    // Try to hang just by calling poll() repeatedly.
    for(int i = 0; i < 100; ++i) { l0.poll(); }
    EXPECT_TRUE(B1::TrivialSimulator::haveSeenCommandStart) << "should see some attempt to communicate with SIM900";
    EXPECT_LE(OTSIM900Link::WAIT_FOR_REGISTRATION, l0._getState()) << "should make it to at least WAIT_FOR_REGISTRATION";
    // ...
    l0.end();
}

<commit_msg>working on set apn test<commit_after>/*
The OpenTRV project licenses this file to you
under the Apache Licence, Version 2.0 (the "Licence");
you may not use this file except in compliance
with the Licence. You may obtain a copy of the Licence at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the Licence is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the Licence for the
specific language governing permissions and limitations
under the Licence.

Author(s) / Copyright (s): Damon Hart-Davis 2016
*/

/*
 * OTRadValve TempControl tests.
 */

#include <gtest/gtest.h>
#include <stdio.h>
#include <stdlib.h>

#include "OTSIM900Link.h"

// Test the getter function definitely does what it should.
TEST(OTSIM900Link, getterFunction)
{
    const char SIM900_PIN[] = "1111";
    const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config(false, SIM900_PIN, NULL, NULL, NULL);
    EXPECT_EQ(SIM900_PIN[0], SIM900Config.get((const uint8_t *)SIM900Config.PIN));
}

// Test for general sanity of OTSIM900Link.
// Make sure that an instance can be created and does not die horribly.
// Underlying simulated serial/SIM900 never accepts data or responds, eg like a dead card.
TEST(OTSIM900Link,basicsDeadCard)
{
    const bool verbose = false;

    class NULLSerialStream final : public Stream
      {
      public:
        void begin(unsigned long) { }
        void begin(unsigned long, uint8_t);
        void end();

        virtual size_t write(uint8_t c) override { if(verbose) { fprintf(stderr, "%c\n", (char) c); } return(0); }
        virtual int available() override { return(-1); }
        virtual int read() override { return(-1); }
        virtual int peek() override { return(-1); }
        virtual void flush() override { }
      };
    OTSIM900Link::OTSIM900Link<0, 0, 0, NULLSerialStream> l0;
    EXPECT_TRUE(l0.begin());
    EXPECT_EQ(OTSIM900Link::GET_STATE, l0._getState());
    // Try to hang just by calling poll() repeatedly.
    for(int i = 0; i < 100; ++i) { l0.poll(); }
    EXPECT_GE(OTSIM900Link::START_UP, l0._getState()) << "should keep trying to start with GET_STATE, RETRY_GET_STATE and START_UP";
    // ...
    l0.end();
}

// Test for general sanity of OTSIM900Link.
// Make sure that an instance can be created and does not die horribly.
// Underlying simulated serial/SIM900 accepts output, does not respond.
namespace B1
{
const bool verbose = true;

// Does a trivial simulation of SIM900, responding to start of 'A' of AT command.
// Exercises every major non-PANIC state of the OTSIM900Link implementation.
class TrivialSimulator final : public Stream
  {
  public:
    // Events exposed.
    static bool haveSeenCommandStart;

  private:
    // Command being collected from OTSIM900Link.
    bool waitingForCommand = true;
    bool collectingCommand = false;
    // Entire request starting "AT"; no trailing CR or LF stored.
    std::string command;

    // Reply (postfix) being returned to OTSIM900Link: empty if none.
    std::string reply;

  public:
    void begin(unsigned long) { }
    void begin(unsigned long, uint8_t);
    void end();

    virtual size_t write(uint8_t uc) override
      {
      const char c = (char)uc;
      if(waitingForCommand)
        {
        // Look for leading 'A' of 'AT' to start a command.
        if('A' == c)
          {
          waitingForCommand = false;
          collectingCommand = true;
          command = 'A';
          haveSeenCommandStart = true; // Note at least one command start.
          }
        }
      else
        {
        // Look for CR (or LF) to terminate a command.
        if(('\r' == c) || ('\n' == c))
          {
          waitingForCommand = true;
          collectingCommand = false;
          if(verbose) { fprintf(stderr, "command received: %s\n", command.c_str()); }
          // Respond to particular commands...
          if("AT" == command) { reply = "AT\r"; }  // Relevant states: GET_STATE, RETRY_GET_STATE, START_UP
          // DHD20161101: "No PIN" response (deliberately not typical SIM900 response) resulted in SIGSEGV from not checking getResponse() result for NULL.
          // Should futz/vary the response to check sensitivity.
          // TODO: have at least one response be expected SIM900 answer for no-PIN SIM.
          else if("AT+CPIN?" == command) { reply = (random() & 1) ? "No PIN\r" : "OK READY\r"; }  // Relevant states: CHECK_PIN
          else if("AT+CREG?" == command) { reply = (random() & 1) ? "+CREG: 0,0\r" : "+CREG: 0,5\r"; } // Relevant states: WAIT_FOR_REGISTRATION
          else if("AT+CSTT=apn" == command) { reply = (random() & 1) ? "gbfhs\r" : "AT+CSTT\r\n\r\nOK\r"; } // Relevant states: SET_APN
          }
        else if(collectingCommand) { command += c; }
        }
      if(verbose) { if(isprint(c)) { fprintf(stderr, "<%c\n", c); } else { fprintf(stderr, "< %d\n", (int)c); } }
      return(1);
      }
    virtual int read() override
        {
        if(0 == reply.size()) { return(-1); }
        const char c = reply[0];
        if(verbose) { if(isprint(c)) { fprintf(stderr, ">%c\n", c); } else { fprintf(stderr, "> %d\n", (int)c); } }
        reply.erase(0, 1);
        return(c);
        }
    virtual int available() override { return(-1); }
    virtual int peek() override { return(-1); }
    virtual void flush() override { }
  };
// Events exposed.
bool TrivialSimulator::haveSeenCommandStart;
}
TEST(OTSIM900Link,basicsSimpleSimulator)
{
//    const bool verbose = true;

    //srandomdev(); // Seed random() for use in simulator.

    const char SIM900_PIN[] = "1111";
    const char SIM900_APN[] = "apn";
    const char SIM900_UDP_ADDR[] = "0.0.0.0"; // ORS server
    const char SIM900_UDP_PORT[] = "9999";
    const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config(false, SIM900_PIN, SIM900_APN, SIM900_UDP_ADDR, SIM900_UDP_PORT);
    const OTRadioLink::OTRadioChannelConfig l0Config(&SIM900Config, true);

    ASSERT_FALSE(B1::TrivialSimulator::haveSeenCommandStart);
    OTSIM900Link::OTSIM900Link<0, 0, 0, B1::TrivialSimulator> l0;
    EXPECT_TRUE(l0.configure(1, &l0Config));
    EXPECT_TRUE(l0.begin());
    EXPECT_EQ(OTSIM900Link::GET_STATE, l0._getState());
    // Try to hang just by calling poll() repeatedly.
    for(int i = 0; i < 100; ++i) { l0.poll(); }
    EXPECT_TRUE(B1::TrivialSimulator::haveSeenCommandStart) << "should see some attempt to communicate with SIM900";
    EXPECT_LE(OTSIM900Link::WAIT_FOR_REGISTRATION, l0._getState()) << "should make it to at least WAIT_FOR_REGISTRATION";
    // ...
    l0.end();
}

<|endoftext|>


<commit_before>#include "Connection.h"
#include "ConnectionDelegate.h"

#include <boost/bind.hpp>

#include <iostream>

std::shared_ptr<Connection> Connection::Create(const std::string address, unsigned short port, std::shared_ptr<ConnectionDelegate> delegate) {
    auto connection = std::shared_ptr<Connection>(new Connection(delegate));
    connection->start(address, port);
    return connection;
}

Connection::Connection(std::shared_ptr<ConnectionDelegate> dlgt)
: service()
, work(service)
, socket(service)
, delegate(dlgt)
, thread(boost::bind(&boost::asio::io_service::run, &service)) {
}

Connection::~Connection() {
    service.stop();
    thread.join();
}

void Connection::start(const std::string address, unsigned short port) {
    boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(address), port);
    socket.async_connect(endpoint, [this] (const boost::system::error_code &err) {
        if (!err) {
            read();
            delegate->onConnect();
        } else {
            std::cerr << "Failed to connect to server. Error: " << err.message() << std::endl;
        }
    });
}

void Connection::write(const std::string &message) {
    socket.async_send(boost::asio::buffer(message + "\r\n"), [this] (const boost::system::error_code &err, size_t bytes) {
        if (!err) {
            std::cout << bytes << " written" << std::endl;
        } else {
            std::cerr << "Failed to write to server. Error: " << err.message() << std::endl;
        }
    });
}

void Connection::read() {
    socket.async_receive(boost::asio::buffer(readBuffer), [this] (const boost::system::error_code &err, size_t bytes) {
        if (!err) {
            std::string copy(readBuffer, bytes);
            std::cout << copy;
            read();
        } else {
            if (err == boost::asio::error::eof) {
                std::cerr << "Connection closed" << std::endl;
            } else {
                std::cerr << "Failed to read. Error: " << err.message() << std::endl;
            }
        }
    });
}
<commit_msg>get rid of Boost.Bind<commit_after>#include "Connection.h"
#include "ConnectionDelegate.h"

#include <iostream>

std::shared_ptr<Connection> Connection::Create(const std::string address, unsigned short port, std::shared_ptr<ConnectionDelegate> delegate) {
    auto connection = std::shared_ptr<Connection>(new Connection(delegate));
    connection->start(address, port);
    return connection;
}

Connection::Connection(std::shared_ptr<ConnectionDelegate> dlgt)
: service()
, work(service)
, socket(service)
, delegate(dlgt)
, thread([this] () { service.run(); }) {
}

Connection::~Connection() {
    service.stop();
    thread.join();
}

void Connection::start(const std::string address, unsigned short port) {
    boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(address), port);
    socket.async_connect(endpoint, [this] (const boost::system::error_code &err) {
        if (!err) {
            read();
            delegate->onConnect();
        } else {
            std::cerr << "Failed to connect to server. Error: " << err.message() << std::endl;
        }
    });
}

void Connection::write(const std::string &message) {
    socket.async_send(boost::asio::buffer(message + "\r\n"), [this] (const boost::system::error_code &err, size_t bytes) {
        if (!err) {
            std::cout << bytes << " written" << std::endl;
        } else {
            std::cerr << "Failed to write to server. Error: " << err.message() << std::endl;
        }
    });
}

void Connection::read() {
    socket.async_receive(boost::asio::buffer(readBuffer), [this] (const boost::system::error_code &err, size_t bytes) {
        if (!err) {
            std::string copy(readBuffer, bytes);
            std::cout << copy;
            read();
        } else {
            if (err == boost::asio::error::eof) {
                std::cerr << "Connection closed" << std::endl;
            } else {
                std::cerr << "Failed to read. Error: " << err.message() << std::endl;
            }
        }
    });
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "ParagraphShadowNode.h"
#include "ParagraphMeasurementCache.h"
#include "ParagraphState.h"

namespace facebook {
namespace react {

char const ParagraphComponentName[] = "Paragraph";

AttributedString ParagraphShadowNode::getAttributedString() const {
  if (!cachedAttributedString_.has_value()) {
    auto textAttributes = TextAttributes::defaultTextAttributes();
    textAttributes.apply(getProps()->textAttributes);

    cachedAttributedString_ = BaseTextShadowNode::getAttributedString(
        textAttributes, shared_from_this());
  }

  return cachedAttributedString_.value();
}

void ParagraphShadowNode::setTextLayoutManager(
    SharedTextLayoutManager textLayoutManager) {
  ensureUnsealed();
  textLayoutManager_ = textLayoutManager;
}

void ParagraphShadowNode::setMeasureCache(
    ParagraphMeasurementCache const *cache) {
  ensureUnsealed();
  measureCache_ = cache;
}

void ParagraphShadowNode::updateStateIfNeeded() {
  ensureUnsealed();

  auto attributedString = getAttributedString();
  auto const &state = getStateData();
  if (state.attributedString == attributedString) {
    return;
  }

  setStateData(ParagraphState{attributedString, textLayoutManager_});
}

#pragma mark - LayoutableShadowNode

Size ParagraphShadowNode::measure(LayoutConstraints layoutConstraints) const {
  AttributedString attributedString = getAttributedString();

  if (attributedString.isEmpty()) {
    return {0, 0};
  }

  ParagraphAttributes const paragraphAttributes =
      getProps()->paragraphAttributes;

  assert(measureCache_);

  return measureCache_->get(
      ParagraphMeasurementCacheKey{
          attributedString, paragraphAttributes, layoutConstraints},
      [&](ParagraphMeasurementCacheKey const &key) {
        return textLayoutManager_->measure(
            attributedString, paragraphAttributes, layoutConstraints);
      });

  return textLayoutManager_->measure(
      attributedString, paragraphAttributes, layoutConstraints);
}

void ParagraphShadowNode::layout(LayoutContext layoutContext) {
  updateStateIfNeeded();
  ConcreteViewShadowNode::layout(layoutContext);
}

} // namespace react
} // namespace facebook
<commit_msg>Fix crash in Paragraph component<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "ParagraphShadowNode.h"
#include "ParagraphMeasurementCache.h"
#include "ParagraphState.h"

namespace facebook {
namespace react {

char const ParagraphComponentName[] = "Paragraph";

AttributedString ParagraphShadowNode::getAttributedString() const {
  if (!cachedAttributedString_.has_value()) {
    auto textAttributes = TextAttributes::defaultTextAttributes();
    textAttributes.apply(getProps()->textAttributes);

    cachedAttributedString_ = BaseTextShadowNode::getAttributedString(
        textAttributes, shared_from_this());
  }

  return cachedAttributedString_.value();
}

void ParagraphShadowNode::setTextLayoutManager(
    SharedTextLayoutManager textLayoutManager) {
  ensureUnsealed();
  textLayoutManager_ = textLayoutManager;
}

void ParagraphShadowNode::setMeasureCache(
    ParagraphMeasurementCache const *cache) {
  ensureUnsealed();
  measureCache_ = cache;
}

void ParagraphShadowNode::updateStateIfNeeded() {
  ensureUnsealed();

  auto attributedString = getAttributedString();
  auto const &state = getStateData();

  assert(textLayoutManager_);
  assert(
      (!state.layoutManager || state.layoutManager == textLayoutManager_) &&
      "`StateData` refers to a different `TextLayoutManager`");

  if (state.attributedString == attributedString &&
      state.layoutManager == textLayoutManager_) {
    return;
  }

  setStateData(ParagraphState{attributedString, textLayoutManager_});
}

#pragma mark - LayoutableShadowNode

Size ParagraphShadowNode::measure(LayoutConstraints layoutConstraints) const {
  AttributedString attributedString = getAttributedString();

  if (attributedString.isEmpty()) {
    return {0, 0};
  }

  ParagraphAttributes const paragraphAttributes =
      getProps()->paragraphAttributes;

  assert(measureCache_);

  return measureCache_->get(
      ParagraphMeasurementCacheKey{
          attributedString, paragraphAttributes, layoutConstraints},
      [&](ParagraphMeasurementCacheKey const &key) {
        return textLayoutManager_->measure(
            attributedString, paragraphAttributes, layoutConstraints);
      });

  return textLayoutManager_->measure(
      attributedString, paragraphAttributes, layoutConstraints);
}

void ParagraphShadowNode::layout(LayoutContext layoutContext) {
  updateStateIfNeeded();
  ConcreteViewShadowNode::layout(layoutContext);
}

} // namespace react
} // namespace facebook
<|endoftext|>


<commit_before>#include "qtfirebaseanalytics.h"

#include <QGuiApplication>

namespace analytics = ::firebase::analytics;

QtFirebaseAnalytics *QtFirebaseAnalytics::self = 0;

QtFirebaseAnalytics::QtFirebaseAnalytics(QObject* parent) : QObject(parent)
{
    if(self == 0) {
        self = this;
        qDebug() << self << "::QtFirebaseAnalytics" << "singleton";
    }

    _ready = false;
    _initializing = false;

    if(qFirebase->ready())
        init();
    else {
        connect(qFirebase,&QtFirebase::readyChanged, this, &QtFirebaseAnalytics::init);
        qFirebase->requestInit();
    }
}

QtFirebaseAnalytics::~QtFirebaseAnalytics()
{
    if(_ready) {
        qDebug() << self << "::~QtFirebaseAnalytics" << "shutting down";
        analytics::Terminate();
        _ready = false;
        self = 0;
    }
}

bool QtFirebaseAnalytics::checkInstance(const char *function)
{
    bool b = (QtFirebaseAnalytics::self != 0);
    if (!b)
        qWarning("QtFirebaseAnalytics::%s: Please instantiate the QtFirebaseAnalytics object first", function);
    return b;
}

void QtFirebaseAnalytics::setUserProperty(const QString &propertyName, const QString &propertyValue)
{
    if(!_ready) {
        qDebug() << this << "::setUserProperty native part not ready";
        return;
    }

    qDebug() << this << "::setUserProperty" << propertyName << ":" << propertyValue;
    analytics::SetUserProperty(propertyName.toLatin1().constData(), propertyValue.toLatin1().constData());
}

void QtFirebaseAnalytics::setCurrentScreen(const QString &screenName, const QString &screenClass)
{
    if(!_ready) {
        qDebug() << this << "::setCurrentScreen native part not ready";
        return;
    }

    qDebug() << this << "::setCurrentScreen" << screenName << ":" << screenClass ;
    analytics::SetCurrentScreen(screenName.toLatin1().constData(), screenClass.toLatin1().constData());
}

void QtFirebaseAnalytics::logEvent(const QString &name)
{
    if(!_ready) {
        qDebug() << this << "::logEvent native part not ready";
        return;
    }

    qDebug() << this << "::logEvent" << name << "logging (no parameters)";
    analytics::LogEvent(name.toUtf8().constData());
}

void QtFirebaseAnalytics::logEvent(const QString &name, const QString &parameterName, const QString &parameterValue)
{
    if(!_ready) {
        qDebug() << this << "::logEvent native part not ready";
        return;
    }

    qDebug() << this << "::logEvent" << name << "logging string parameter" << parameterName << ":" << parameterValue;
    analytics::LogEvent(name.toUtf8().constData(), parameterName.toUtf8().constData(),parameterValue.toUtf8().constData());
}

void QtFirebaseAnalytics::logEvent(const QString &name, const QString &parameterName, const double parameterValue)
{
    if(!_ready) {
        qDebug() << this << "::logEvent native part not ready";
        return;
    }

    qDebug() << this << "::logEvent" << name << "logging double parameter" << parameterName << ":" << parameterValue;
    analytics::LogEvent(name.toUtf8().constData(), parameterName.toUtf8().constData(),parameterValue);
}

void QtFirebaseAnalytics::logEvent(const QString &name, const QString &parameterName, const int parameterValue)
{
    if(!_ready) {
        qDebug() << this << "::logEvent native part not ready";
        return;
    }

    qDebug() << this << "::logEvent" << name << "logging int parameter" << parameterName << ":" << parameterValue;
    analytics::LogEvent(name.toUtf8().constData(), parameterName.toUtf8().constData(),parameterValue);
}

void QtFirebaseAnalytics::logEvent(const QString &name, const QVariantMap bundle)
{
    if(!_ready) {
        qDebug() << this << "::logEvent native part not ready";
        return;
    }

    analytics::Parameter *parameters = new analytics::Parameter[bundle.size()];

    QByteArrayList keys;
    QByteArrayList strings;

    QMapIterator<QString, QVariant> i(bundle);
    int index = 0;
    while (i.hasNext()) {
        i.next();

        keys.append(i.key().toLocal8Bit());
        QString eventKey = i.key();
        QVariant variant = i.value();

        if(variant.type() == QVariant::Type(QMetaType::Int)) {
            parameters[index] = analytics::Parameter(keys.at(index).constData(), variant.toInt());
            qDebug() << this << "::logEvent" << "bundle parameter" << eventKey << ":" << variant.toInt();
        } else if(variant.type() == QVariant::Type(QMetaType::Double)) {
            parameters[index] = analytics::Parameter(keys.at(index).constData(),variant.toDouble());
            qDebug() << this << "::logEvent" << "bundle parameter" << eventKey << ":" << variant.toDouble();
        } else if(variant.type() == QVariant::Type(QMetaType::QString)) {
            strings.append(variant.toString().toLocal8Bit());
            parameters[index] = analytics::Parameter(keys.at(index).constData(), strings.at(strings.size()-1).constData());
            qDebug() << this << "::logEvent" << "bundle parameter" << eventKey << ":" << strings.at(strings.size()-1);
        } else {
            qWarning() << this << "::logEvent" << "bundle parameter" << eventKey << "has unsupported data type. Sending empty strings";
            parameters[index] = analytics::Parameter("", "");
        }

        index++;
    }

    qDebug() << this << "::logEvent" << "logging" << "bundle" << name;
    analytics::LogEvent(name.toUtf8().constData(), parameters, bundle.size());
    delete[] parameters;
    parameters = 0;
}

QVariantList QtFirebaseAnalytics::userProperties() const
{
    return _userProperties;
}

void QtFirebaseAnalytics::setUserProperties(const QVariantList &userProperties)
{
    if(!_ready) {
        qDebug() << this << "::setUserProperties native part not ready";
        return;
    }

    if (_userProperties != userProperties) {
        _userProperties = userProperties;

        if(_userProperties.size() > 25) {

        }

        unsigned index = 0;
        for (QVariantList::iterator j = _userProperties.begin(); j != _userProperties.end(); j++)
        {
            if((*j).canConvert<QVariantMap>()) {

                QVariantMap map = (*j).toMap();

                if(!map.isEmpty()) {
                    if(map.first().canConvert<QString>()) {
                        QString key = map.firstKey();
                        QString value = map.first().toString();
                        setUserProperty(key,value);
                    }
                }

            } else {
                qWarning() << this << "::setUserProperties" << "wrong entry in userProperties list at index" << index;
            }
            index++;
        }
        emit userPropertiesChanged();
    }
}

QString QtFirebaseAnalytics::userId() const
{
    return _userId;
}

void QtFirebaseAnalytics::setUserId(const QString &userId)
{
    if(!_ready) {
        qDebug() << this << "::setUserId native part not ready";
        return;
    }

    QString aUserId = userId;
    if(aUserId.isEmpty()) {
        unsetUserId();
    }
    if(aUserId.length() > 36) {
        aUserId = aUserId.left(36);
        qWarning() << this << "::setUserId" << "ID longer than allowed 36 chars" << "TRUNCATED to" << aUserId;
    }
    if(_userId != aUserId) {
        _userId = aUserId;
        analytics::SetUserId(_userId.toLatin1().constData());
        qDebug() << this << "::setUserId sat to" << _userId;
        emit userIdChanged();
    }
}

void QtFirebaseAnalytics::unsetUserId()
{
    if(!_ready) {
        qDebug() << this << "::unsetUserId native part not ready";
        return;
    }

    if(!_userId.isEmpty()) {
        _userId.clear();
        analytics::SetUserId(NULL);
        emit userIdChanged();
    }
}

unsigned int QtFirebaseAnalytics::sessionTimeout() const
{
    return _sessionTimeout;
}

void QtFirebaseAnalytics::setSessionTimeout(unsigned int sessionTimeout)
{
    if(_sessionTimeout != sessionTimeout) {
        _sessionTimeout = sessionTimeout;
        emit sessionTimeoutChanged();
    }
}

bool QtFirebaseAnalytics::ready()
{
    return _ready;
}

void QtFirebaseAnalytics::setReady(bool ready)
{
    if (_ready != ready) {
        _ready = ready;
        qDebug() << self << "::setReady" << ready;
        emit readyChanged();
    }
}

bool QtFirebaseAnalytics::enabled()
{
    return _enabled;
}

void QtFirebaseAnalytics::setEnabled(bool enabled)
{
    if(!_ready) {
        qDebug() << this << "::setEnabled native part not ready";
        return;
    }

    if (_enabled != enabled) {
        analytics::SetAnalyticsCollectionEnabled(enabled);
        _enabled = enabled;
        qDebug() << self << "::setEnabled" << enabled;
        emit enabledChanged();
    }
}

unsigned int QtFirebaseAnalytics::minimumSessionDuration()
{
    return _minimumSessionDuration;
}

void QtFirebaseAnalytics::setMinimumSessionDuration(unsigned int minimumSessionDuration)
{
    if(!_ready) {
        qDebug() << this << "::setMinimumSessionDuration native part not ready";
        return;
    }

    if (_minimumSessionDuration != minimumSessionDuration) {
        analytics::SetMinimumSessionDuration(minimumSessionDuration);
        _minimumSessionDuration = minimumSessionDuration;
        qDebug() << self << "::setMinimumSessionDuration" << minimumSessionDuration;
        emit minimumSessionDurationChanged();
    }
}

void QtFirebaseAnalytics::init()
{
    if(!qFirebase->ready()) {
        qDebug() << self << "::init" << "base not ready";
        return;
    }

    if(!_ready && !_initializing) {
        _initializing = true;

        analytics::Initialize(*qFirebase->firebaseApp());
        qDebug() << self << "::init" << "native initialized";
        _initializing = false;
        setReady(true);
    }
}
<commit_msg>Convert bundle event parameters toUtf8 insted of toLocal8Bit<commit_after>#include "qtfirebaseanalytics.h"

#include <QGuiApplication>

namespace analytics = ::firebase::analytics;

QtFirebaseAnalytics *QtFirebaseAnalytics::self = 0;

QtFirebaseAnalytics::QtFirebaseAnalytics(QObject* parent) : QObject(parent)
{
    if(self == 0) {
        self = this;
        qDebug() << self << "::QtFirebaseAnalytics" << "singleton";
    }

    _ready = false;
    _initializing = false;

    if(qFirebase->ready())
        init();
    else {
        connect(qFirebase,&QtFirebase::readyChanged, this, &QtFirebaseAnalytics::init);
        qFirebase->requestInit();
    }
}

QtFirebaseAnalytics::~QtFirebaseAnalytics()
{
    if(_ready) {
        qDebug() << self << "::~QtFirebaseAnalytics" << "shutting down";
        analytics::Terminate();
        _ready = false;
        self = 0;
    }
}

bool QtFirebaseAnalytics::checkInstance(const char *function)
{
    bool b = (QtFirebaseAnalytics::self != 0);
    if (!b)
        qWarning("QtFirebaseAnalytics::%s: Please instantiate the QtFirebaseAnalytics object first", function);
    return b;
}

void QtFirebaseAnalytics::setUserProperty(const QString &propertyName, const QString &propertyValue)
{
    if(!_ready) {
        qDebug() << this << "::setUserProperty native part not ready";
        return;
    }

    qDebug() << this << "::setUserProperty" << propertyName << ":" << propertyValue;
    analytics::SetUserProperty(propertyName.toLatin1().constData(), propertyValue.toLatin1().constData());
}

void QtFirebaseAnalytics::setCurrentScreen(const QString &screenName, const QString &screenClass)
{
    if(!_ready) {
        qDebug() << this << "::setCurrentScreen native part not ready";
        return;
    }

    qDebug() << this << "::setCurrentScreen" << screenName << ":" << screenClass ;
    analytics::SetCurrentScreen(screenName.toLatin1().constData(), screenClass.toLatin1().constData());
}

void QtFirebaseAnalytics::logEvent(const QString &name)
{
    if(!_ready) {
        qDebug() << this << "::logEvent native part not ready";
        return;
    }

    qDebug() << this << "::logEvent" << name << "logging (no parameters)";
    analytics::LogEvent(name.toUtf8().constData());
}

void QtFirebaseAnalytics::logEvent(const QString &name, const QString &parameterName, const QString &parameterValue)
{
    if(!_ready) {
        qDebug() << this << "::logEvent native part not ready";
        return;
    }

    qDebug() << this << "::logEvent" << name << "logging string parameter" << parameterName << ":" << parameterValue;
    analytics::LogEvent(name.toUtf8().constData(), parameterName.toUtf8().constData(),parameterValue.toUtf8().constData());
}

void QtFirebaseAnalytics::logEvent(const QString &name, const QString &parameterName, const double parameterValue)
{
    if(!_ready) {
        qDebug() << this << "::logEvent native part not ready";
        return;
    }

    qDebug() << this << "::logEvent" << name << "logging double parameter" << parameterName << ":" << parameterValue;
    analytics::LogEvent(name.toUtf8().constData(), parameterName.toUtf8().constData(),parameterValue);
}

void QtFirebaseAnalytics::logEvent(const QString &name, const QString &parameterName, const int parameterValue)
{
    if(!_ready) {
        qDebug() << this << "::logEvent native part not ready";
        return;
    }

    qDebug() << this << "::logEvent" << name << "logging int parameter" << parameterName << ":" << parameterValue;
    analytics::LogEvent(name.toUtf8().constData(), parameterName.toUtf8().constData(),parameterValue);
}

void QtFirebaseAnalytics::logEvent(const QString &name, const QVariantMap bundle)
{
    if(!_ready) {
        qDebug() << this << "::logEvent native part not ready";
        return;
    }

    analytics::Parameter *parameters = new analytics::Parameter[bundle.size()];

    QByteArrayList keys;
    QByteArrayList strings;

    QMapIterator<QString, QVariant> i(bundle);
    int index = 0;
    while (i.hasNext()) {
        i.next();

        keys.append(i.key().toUtf8());
        QString eventKey = i.key();
        QVariant variant = i.value();

        if(variant.type() == QVariant::Type(QMetaType::Int)) {
            parameters[index] = analytics::Parameter(keys.at(index).constData(), variant.toInt());
            qDebug() << this << "::logEvent" << "bundle parameter" << eventKey << ":" << variant.toInt();
        } else if(variant.type() == QVariant::Type(QMetaType::Double)) {
            parameters[index] = analytics::Parameter(keys.at(index).constData(),variant.toDouble());
            qDebug() << this << "::logEvent" << "bundle parameter" << eventKey << ":" << variant.toDouble();
        } else if(variant.type() == QVariant::Type(QMetaType::QString)) {
            strings.append(variant.toString().toUtf8());
            parameters[index] = analytics::Parameter(keys.at(index).constData(), strings.at(strings.size()-1).constData());
            qDebug() << this << "::logEvent" << "bundle parameter" << eventKey << ":" << strings.at(strings.size()-1);
        } else {
            qWarning() << this << "::logEvent" << "bundle parameter" << eventKey << "has unsupported data type. Sending empty strings";
            parameters[index] = analytics::Parameter("", "");
        }

        index++;
    }

    qDebug() << this << "::logEvent" << "logging" << "bundle" << name;
    analytics::LogEvent(name.toUtf8().constData(), parameters, bundle.size());
    delete[] parameters;
    parameters = 0;
}

QVariantList QtFirebaseAnalytics::userProperties() const
{
    return _userProperties;
}

void QtFirebaseAnalytics::setUserProperties(const QVariantList &userProperties)
{
    if(!_ready) {
        qDebug() << this << "::setUserProperties native part not ready";
        return;
    }

    if (_userProperties != userProperties) {
        _userProperties = userProperties;

        if(_userProperties.size() > 25) {

        }

        unsigned index = 0;
        for (QVariantList::iterator j = _userProperties.begin(); j != _userProperties.end(); j++)
        {
            if((*j).canConvert<QVariantMap>()) {

                QVariantMap map = (*j).toMap();

                if(!map.isEmpty()) {
                    if(map.first().canConvert<QString>()) {
                        QString key = map.firstKey();
                        QString value = map.first().toString();
                        setUserProperty(key,value);
                    }
                }

            } else {
                qWarning() << this << "::setUserProperties" << "wrong entry in userProperties list at index" << index;
            }
            index++;
        }
        emit userPropertiesChanged();
    }
}

QString QtFirebaseAnalytics::userId() const
{
    return _userId;
}

void QtFirebaseAnalytics::setUserId(const QString &userId)
{
    if(!_ready) {
        qDebug() << this << "::setUserId native part not ready";
        return;
    }

    QString aUserId = userId;
    if(aUserId.isEmpty()) {
        unsetUserId();
    }
    if(aUserId.length() > 36) {
        aUserId = aUserId.left(36);
        qWarning() << this << "::setUserId" << "ID longer than allowed 36 chars" << "TRUNCATED to" << aUserId;
    }
    if(_userId != aUserId) {
        _userId = aUserId;
        analytics::SetUserId(_userId.toLatin1().constData());
        qDebug() << this << "::setUserId sat to" << _userId;
        emit userIdChanged();
    }
}

void QtFirebaseAnalytics::unsetUserId()
{
    if(!_ready) {
        qDebug() << this << "::unsetUserId native part not ready";
        return;
    }

    if(!_userId.isEmpty()) {
        _userId.clear();
        analytics::SetUserId(NULL);
        emit userIdChanged();
    }
}

unsigned int QtFirebaseAnalytics::sessionTimeout() const
{
    return _sessionTimeout;
}

void QtFirebaseAnalytics::setSessionTimeout(unsigned int sessionTimeout)
{
    if(_sessionTimeout != sessionTimeout) {
        _sessionTimeout = sessionTimeout;
        emit sessionTimeoutChanged();
    }
}

bool QtFirebaseAnalytics::ready()
{
    return _ready;
}

void QtFirebaseAnalytics::setReady(bool ready)
{
    if (_ready != ready) {
        _ready = ready;
        qDebug() << self << "::setReady" << ready;
        emit readyChanged();
    }
}

bool QtFirebaseAnalytics::enabled()
{
    return _enabled;
}

void QtFirebaseAnalytics::setEnabled(bool enabled)
{
    if(!_ready) {
        qDebug() << this << "::setEnabled native part not ready";
        return;
    }

    if (_enabled != enabled) {
        analytics::SetAnalyticsCollectionEnabled(enabled);
        _enabled = enabled;
        qDebug() << self << "::setEnabled" << enabled;
        emit enabledChanged();
    }
}

unsigned int QtFirebaseAnalytics::minimumSessionDuration()
{
    return _minimumSessionDuration;
}

void QtFirebaseAnalytics::setMinimumSessionDuration(unsigned int minimumSessionDuration)
{
    if(!_ready) {
        qDebug() << this << "::setMinimumSessionDuration native part not ready";
        return;
    }

    if (_minimumSessionDuration != minimumSessionDuration) {
        analytics::SetMinimumSessionDuration(minimumSessionDuration);
        _minimumSessionDuration = minimumSessionDuration;
        qDebug() << self << "::setMinimumSessionDuration" << minimumSessionDuration;
        emit minimumSessionDurationChanged();
    }
}

void QtFirebaseAnalytics::init()
{
    if(!qFirebase->ready()) {
        qDebug() << self << "::init" << "base not ready";
        return;
    }

    if(!_ready && !_initializing) {
        _initializing = true;

        analytics::Initialize(*qFirebase->firebaseApp());
        qDebug() << self << "::init" << "native initialized";
        _initializing = false;
        setReady(true);
    }
}
<|endoftext|>


<commit_before>#include "types.hh"
#include <map>

namespace doanimate {
	namespace types {
		namespace implementation {
			const type_info type_info::boolean = type_info_enum::boolean;
			const type_info type_info::integer = type_info_enum::integer;
			const type_info type_info::number = type_info_enum::number;
			const type_info type_info::any = type_info_enum::any;
			const type_info type_info::string = type_info_enum::string;
			const type_info type_info::none = type_info::tuple({});
			const type_info type_info::position = type_info::tuple(type_info::number, 2)
				.labeled("position");
			const type_info type_info::position2d = type_info::position;
			const type_info type_info::position3d = type_info::tuple(type_info::number, 3)
				.labeled("position3d");
			const type_info type_info::color = type_info::tuple(type_info::number, 4)
				.labeled("color");
			const type_info type_info::color_without_alpha = type_info::position3d
				.labeled("color_without_alpha");
			const type_info type_info::renderable = type_info::function(
					type_info::color,
					{type_info::position2d}
				).labeled("renderable");
			const type_info type_info::sound = type_info::function(
					type_info::number,
					{type_info::number}
				).labeled("sound");
		}

		type_info simplify(const type_info t) {
			return apply_specialization(t, {});
		}

		type_info apply_specialization(const type_info t, const std::vector<type_info> args) {
			if (t.is_code()) {
				auto ins = t.code_inputs();
				auto outs = t.code_outputs();
				for (auto& i : ins)
					i = apply_specialization(i, args);
				for (auto& i : outs)
					i = apply_specialization(i, args);
				return type_info::code(ins, outs);
			}
			else if (t.is_list())
				return type_info::list(apply_specialization(t.list_of(), args));
			else if (t.is_tuple()) {
				auto ts = t.tuple_types();
				for (auto& i : ts)
					i = apply_specialization(i, args);
				return type_info::tuple(ts);
			}
			else if (t.is_function()) {
				auto args2 = t.function_arguments();
				for (auto& i : args2)
					i = apply_specialization(i, args);
				return type_info::function(apply_specialization(t.function_return_type(), args), args2);
			}
			else if (t.is_specialization())
				return apply_specialization(t.specialization_template(), t.specialization_parameters());
			else if (t.is_generic_parameter())
				return args[t.generic_parameter_index()];
			else
				return t;
		}

		std::string to_string(const std::vector<type_info> ts) {
			bool first = true;
			std::string out = "[";
			for (const auto& i : ts) {
				out += to_string(i);
				if (first)
					first = false;
				else
					out += ", ";
			}
			return out + "]";
		}

		const std::map<type_info, std::string> names {
			{type_info::boolean, "boolean"},
				{type_info::integer, "integer"},
				{type_info::number, "number"},
				{type_info::string, "string"},
				{type_info::any, "any"}
		};

		std::string to_string(const type_info t) {
			if (t.has_label())
				return t.label();
			else if (t.is_code())
				return "code[" + to_string(t.code_inputs()) + ", " + to_string(t.code_outputs()) + "]";
			else if (t.is_list())
				return "list[" + to_string(t.list_of()) + "]";
			else if (t.is_repeated_tuple())
				return "tuple[" + to_string(t.repeated_tuple_of()) + ", " + std::to_string(t.repeated_tuple_length()) + "]";
			else if (t.is_tuple())
				return "tuple" + to_string(t.tuple_types());
			else if (t.is_function())
				return "function[" + to_string(t.function_return_type()) + ", " + to_string(t.function_arguments()) + "]";
			else if (t.is_specialization())
				return "specialize[" + to_string(t.specialization_template()) + ", " + to_string(t.specialization_parameters()) + "]";
			else if (t.is_generic_parameter())
				return "template_parameter[" + std::to_string(t.generic_parameter_index()) + "]";
			else
				return (*names.find(t)).second;
		}
	}
}
<commit_msg>Fixed formatting in types.cc<commit_after>#include "types.hh"
#include <map>

namespace doanimate {
	namespace types {
		namespace implementation {
			const type_info type_info::boolean = type_info_enum::boolean;
			const type_info type_info::integer = type_info_enum::integer;
			const type_info type_info::number = type_info_enum::number;
			const type_info type_info::any = type_info_enum::any;
			const type_info type_info::string = type_info_enum::string;
			const type_info type_info::none = type_info::tuple({});
			const type_info type_info::position = type_info::tuple(type_info::number, 2)
				.labeled("position");
			const type_info type_info::position2d = type_info::position;
			const type_info type_info::position3d = type_info::tuple(type_info::number, 3)
				.labeled("position3d");
			const type_info type_info::color = type_info::tuple(type_info::number, 4)
				.labeled("color");
			const type_info type_info::color_without_alpha = type_info::position3d
				.labeled("color_without_alpha");
			const type_info type_info::renderable = type_info::function(
					type_info::color,
					{type_info::position2d}
				).labeled("renderable");
			const type_info type_info::sound = type_info::function(
					type_info::number,
					{type_info::number}
				).labeled("sound");
		}

		type_info simplify(const type_info t) {
			return apply_specialization(t, {});
		}

		type_info apply_specialization(const type_info t, const std::vector<type_info> args) {
			if (t.is_code()) {
				auto ins = t.code_inputs();
				auto outs = t.code_outputs();
				for (auto& i : ins)
					i = apply_specialization(i, args);
				for (auto& i : outs)
					i = apply_specialization(i, args);
				return type_info::code(ins, outs);
			}
			else if (t.is_list())
				return type_info::list(apply_specialization(t.list_of(), args));
			else if (t.is_tuple()) {
				auto ts = t.tuple_types();
				for (auto& i : ts)
					i = apply_specialization(i, args);
				return type_info::tuple(ts);
			}
			else if (t.is_function()) {
				auto args2 = t.function_arguments();
				for (auto& i : args2)
					i = apply_specialization(i, args);
				return type_info::function(apply_specialization(t.function_return_type(), args), args2);
			}
			else if (t.is_specialization())
				return apply_specialization(t.specialization_template(), t.specialization_parameters());
			else if (t.is_generic_parameter())
				return args[t.generic_parameter_index()];
			else
				return t;
		}

		std::string to_string(const std::vector<type_info> ts) {
			bool first = true;
			std::string out = "[";
			for (const auto& i : ts) {
				out += to_string(i);
				if (first)
					first = false;
				else
					out += ", ";
			}
			return out + "]";
		}

		const std::map<type_info, std::string> names {
			{type_info::boolean, "boolean"},
			{type_info::integer, "integer"},
			{type_info::number, "number"},
			{type_info::string, "string"},
			{type_info::any, "any"}
		};

		std::string to_string(const type_info t) {
			if (t.has_label())
				return t.label();
			else if (t.is_code())
				return "code[" + to_string(t.code_inputs()) + ", " + to_string(t.code_outputs()) + "]";
			else if (t.is_list())
				return "list[" + to_string(t.list_of()) + "]";
			else if (t.is_repeated_tuple())
				return "tuple[" + to_string(t.repeated_tuple_of()) + ", " + std::to_string(t.repeated_tuple_length()) + "]";
			else if (t.is_tuple())
				return "tuple" + to_string(t.tuple_types());
			else if (t.is_function())
				return "function[" + to_string(t.function_return_type()) + ", " + to_string(t.function_arguments()) + "]";
			else if (t.is_specialization())
				return "specialize[" + to_string(t.specialization_template()) + ", " + to_string(t.specialization_parameters()) + "]";
			else if (t.is_generic_parameter())
				return "template_parameter[" + std::to_string(t.generic_parameter_index()) + "]";
			else
				return (*names.find(t)).second;
		}
	}
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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_svl.hxx"

#include <stdio.h>

#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#include <com/sun/star/ucb/InsertCommandArgument.hpp>
#include <com/sun/star/ucb/NameClashException.hpp>
#include <com/sun/star/io/WrongFormatException.hpp>

#include <osl/time.h>
#include <osl/security.hxx>
#include <osl/socket.hxx>

#include <rtl/string.hxx>
#include <rtl/ustring.hxx>
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>

#include <comphelper/processfactory.hxx>

#include <tools/urlobj.hxx>
#include <unotools/bootstrap.hxx>

#include <ucbhelper/content.hxx>

#include <unotools/useroptions.hxx>

#include <svl/documentlockfile.hxx>

using namespace ::com::sun::star;

namespace svt {

sal_Bool DocumentLockFile::m_bAllowInteraction = sal_True;

// ----------------------------------------------------------------------
DocumentLockFile::DocumentLockFile( const ::rtl::OUString& aOrigURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
: LockFileCommon( aOrigURL, xFactory, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".~lock." ) ) )
{
}

// ----------------------------------------------------------------------
DocumentLockFile::~DocumentLockFile()
{
}

// ----------------------------------------------------------------------
void DocumentLockFile::WriteEntryToStream( uno::Sequence< ::rtl::OUString > aEntry, uno::Reference< io::XOutputStream > xOutput )
{
    ::osl::MutexGuard aGuard( m_aMutex );

    ::rtl::OUStringBuffer aBuffer;

    for ( sal_Int32 nEntryInd = 0; nEntryInd < aEntry.getLength(); nEntryInd++ )
    {
        aBuffer.append( EscapeCharacters( aEntry[nEntryInd] ) );
        if ( nEntryInd < aEntry.getLength() - 1 )
            aBuffer.append( (sal_Unicode)',' );
        else
            aBuffer.append( (sal_Unicode)';' );
    }

    ::rtl::OString aStringData( ::rtl::OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ) );
    uno::Sequence< sal_Int8 > aData( (sal_Int8*)aStringData.getStr(), aStringData.getLength() );
    xOutput->writeBytes( aData );
}

// ----------------------------------------------------------------------
sal_Bool DocumentLockFile::CreateOwnLockFile()
{
    ::osl::MutexGuard aGuard( m_aMutex );

    try
    {
        uno::Reference< io::XStream > xTempFile(
            m_xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.TempFile")) ),
            uno::UNO_QUERY_THROW );
        uno::Reference< io::XSeekable > xSeekable( xTempFile, uno::UNO_QUERY_THROW );

        uno::Reference< io::XInputStream > xInput = xTempFile->getInputStream();
        uno::Reference< io::XOutputStream > xOutput = xTempFile->getOutputStream();

        if ( !xInput.is() || !xOutput.is() )
            throw uno::RuntimeException();

        uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry();
        WriteEntryToStream( aNewEntry, xOutput );
        xOutput->closeOutput();

        xSeekable->seek( 0 );

        uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
        ::ucbhelper::Content aTargetContent( m_aURL, xEnv );

        ucb::InsertCommandArgument aInsertArg;
        aInsertArg.Data = xInput;
        aInsertArg.ReplaceExisting = sal_False;
        uno::Any aCmdArg;
        aCmdArg <<= aInsertArg;
        aTargetContent.executeCommand( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ), aCmdArg );

        // try to let the file be hidden if possible
        try {
            aTargetContent.setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ), uno::makeAny( sal_True ) );
        } catch( uno::Exception& ) {}
    }
    catch( ucb::NameClashException& )
    {
        return sal_False;
    }

    return sal_True;
}

// ----------------------------------------------------------------------
uno::Sequence< ::rtl::OUString > DocumentLockFile::GetLockData()
{
    ::osl::MutexGuard aGuard( m_aMutex );

    uno::Reference< io::XInputStream > xInput = OpenStream();
    if ( !xInput.is() )
        throw uno::RuntimeException();

    const sal_Int32 nBufLen = 32000;
    uno::Sequence< sal_Int8 > aBuffer( nBufLen );

    sal_Int32 nRead = 0;

    nRead = xInput->readBytes( aBuffer, nBufLen );
    xInput->closeInput();

    if ( nRead == nBufLen )
        throw io::WrongFormatException();

    sal_Int32 nCurPos = 0;
    return ParseEntry( aBuffer, nCurPos );
}

// ----------------------------------------------------------------------
uno::Reference< io::XInputStream > DocumentLockFile::OpenStream()
{
    ::osl::MutexGuard aGuard( m_aMutex );

    uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
        uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleFileAccess(
            xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SimpleFileAccess")) ),
            uno::UNO_QUERY_THROW );

    // the file can be opened readonly, no locking will be done
    return xSimpleFileAccess->openFileRead( m_aURL );
}

// ----------------------------------------------------------------------
sal_Bool DocumentLockFile::OverwriteOwnLockFile()
{
    // allows to overwrite the lock file with the current data
    try
    {
        uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
        ::ucbhelper::Content aTargetContent( m_aURL, xEnv );

        uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry();

        uno::Reference< io::XStream > xStream = aTargetContent.openWriteableStreamNoLock();
        uno::Reference< io::XOutputStream > xOutput = xStream->getOutputStream();
        uno::Reference< io::XTruncate > xTruncate( xOutput, uno::UNO_QUERY_THROW );

        xTruncate->truncate();
        WriteEntryToStream( aNewEntry, xOutput );
        xOutput->closeOutput();
    }
    catch( uno::Exception& )
    {
        return sal_False;
    }

    return sal_True;
}

// ----------------------------------------------------------------------
void DocumentLockFile::RemoveFile()
{
    ::osl::MutexGuard aGuard( m_aMutex );

    // TODO/LATER: the removing is not atomar, is it possible in general to make it atomar?
    uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry();
    uno::Sequence< ::rtl::OUString > aFileData = GetLockData();

    if ( aFileData.getLength() < LOCKFILE_ENTRYSIZE )
        throw io::WrongFormatException();

    if ( !aFileData[LOCKFILE_SYSUSERNAME_ID].equals( aNewEntry[LOCKFILE_SYSUSERNAME_ID] )
      || !aFileData[LOCKFILE_LOCALHOST_ID].equals( aNewEntry[LOCKFILE_LOCALHOST_ID] )
      || !aFileData[LOCKFILE_USERURL_ID].equals( aNewEntry[LOCKFILE_USERURL_ID] ) )
        throw io::IOException(); // not the owner, access denied

    uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
    uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleFileAccess(
        xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SimpleFileAccess")) ),
        uno::UNO_QUERY_THROW );
    xSimpleFileAccess->kill( m_aURL );
}

} // namespace svt

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Related: rhbz#668057 Some Support locking files on more than just file<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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_svl.hxx"

#include <stdio.h>

#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#include <com/sun/star/ucb/InsertCommandArgument.hpp>
#include <com/sun/star/ucb/NameClashException.hpp>
#include <com/sun/star/io/WrongFormatException.hpp>

#include <osl/time.h>
#include <osl/security.hxx>
#include <osl/socket.hxx>

#include <rtl/string.hxx>
#include <rtl/ustring.hxx>
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>

#include <comphelper/processfactory.hxx>

#include <tools/urlobj.hxx>
#include <unotools/bootstrap.hxx>

#include <ucbhelper/content.hxx>

#include <unotools/useroptions.hxx>

#include <svl/documentlockfile.hxx>

using namespace ::com::sun::star;

namespace svt {

sal_Bool DocumentLockFile::m_bAllowInteraction = sal_True;

// ----------------------------------------------------------------------
DocumentLockFile::DocumentLockFile( const ::rtl::OUString& aOrigURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
: LockFileCommon( aOrigURL, xFactory, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".~lock." ) ) )
{
}

// ----------------------------------------------------------------------
DocumentLockFile::~DocumentLockFile()
{
}

// ----------------------------------------------------------------------
void DocumentLockFile::WriteEntryToStream( uno::Sequence< ::rtl::OUString > aEntry, uno::Reference< io::XOutputStream > xOutput )
{
    ::osl::MutexGuard aGuard( m_aMutex );

    ::rtl::OUStringBuffer aBuffer;

    for ( sal_Int32 nEntryInd = 0; nEntryInd < aEntry.getLength(); nEntryInd++ )
    {
        aBuffer.append( EscapeCharacters( aEntry[nEntryInd] ) );
        if ( nEntryInd < aEntry.getLength() - 1 )
            aBuffer.append( (sal_Unicode)',' );
        else
            aBuffer.append( (sal_Unicode)';' );
    }

    ::rtl::OString aStringData( ::rtl::OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ) );
    uno::Sequence< sal_Int8 > aData( (sal_Int8*)aStringData.getStr(), aStringData.getLength() );
    xOutput->writeBytes( aData );
}

// ----------------------------------------------------------------------
sal_Bool DocumentLockFile::CreateOwnLockFile()
{
    ::osl::MutexGuard aGuard( m_aMutex );

    try
    {
        uno::Reference< io::XStream > xTempFile(
            m_xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.TempFile")) ),
            uno::UNO_QUERY_THROW );
        uno::Reference< io::XSeekable > xSeekable( xTempFile, uno::UNO_QUERY_THROW );

        uno::Reference< io::XInputStream > xInput = xTempFile->getInputStream();
        uno::Reference< io::XOutputStream > xOutput = xTempFile->getOutputStream();

        if ( !xInput.is() || !xOutput.is() )
            throw uno::RuntimeException();

        uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry();
        WriteEntryToStream( aNewEntry, xOutput );
        xOutput->closeOutput();

        xSeekable->seek( 0 );

        uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
        ::ucbhelper::Content aTargetContent( m_aURL, xEnv );

        ucb::InsertCommandArgument aInsertArg;
        aInsertArg.Data = xInput;
        aInsertArg.ReplaceExisting = sal_False;
        uno::Any aCmdArg;
        aCmdArg <<= aInsertArg;
        aTargetContent.executeCommand( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ), aCmdArg );

        // try to let the file be hidden if possible
        try {
            aTargetContent.setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ), uno::makeAny( sal_True ) );
        } catch( uno::Exception& ) {}
    }
    catch( ucb::NameClashException& )
    {
        return sal_False;
    }

    return sal_True;
}

// ----------------------------------------------------------------------
uno::Sequence< ::rtl::OUString > DocumentLockFile::GetLockData()
{
    ::osl::MutexGuard aGuard( m_aMutex );

    uno::Reference< io::XInputStream > xInput = OpenStream();
    if ( !xInput.is() )
        throw uno::RuntimeException();

    const sal_Int32 nBufLen = 32000;
    uno::Sequence< sal_Int8 > aBuffer( nBufLen );

    sal_Int32 nRead = 0;

    nRead = xInput->readBytes( aBuffer, nBufLen );
    xInput->closeInput();

    if ( nRead == nBufLen )
        throw io::WrongFormatException();

    sal_Int32 nCurPos = 0;
    return ParseEntry( aBuffer, nCurPos );
}

// ----------------------------------------------------------------------
uno::Reference< io::XInputStream > DocumentLockFile::OpenStream()
{
    ::osl::MutexGuard aGuard( m_aMutex );

    uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
    ::ucbhelper::Content aSourceContent( m_aURL, xEnv );

    // the file can be opened readonly, no locking will be done
    return aSourceContent.openStream();
}

// ----------------------------------------------------------------------
sal_Bool DocumentLockFile::OverwriteOwnLockFile()
{
    // allows to overwrite the lock file with the current data
    try
    {
        uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
        ::ucbhelper::Content aTargetContent( m_aURL, xEnv );

        uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry();

        uno::Reference< io::XStream > xStream = aTargetContent.openWriteableStreamNoLock();
        uno::Reference< io::XOutputStream > xOutput = xStream->getOutputStream();
        uno::Reference< io::XTruncate > xTruncate( xOutput, uno::UNO_QUERY_THROW );

        xTruncate->truncate();
        WriteEntryToStream( aNewEntry, xOutput );
        xOutput->closeOutput();
    }
    catch( uno::Exception& )
    {
        return sal_False;
    }

    return sal_True;
}

// ----------------------------------------------------------------------
void DocumentLockFile::RemoveFile()
{
    ::osl::MutexGuard aGuard( m_aMutex );

    // TODO/LATER: the removing is not atomar, is it possible in general to make it atomar?
    uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry();
    uno::Sequence< ::rtl::OUString > aFileData = GetLockData();

    if ( aFileData.getLength() < LOCKFILE_ENTRYSIZE )
        throw io::WrongFormatException();

    if ( !aFileData[LOCKFILE_SYSUSERNAME_ID].equals( aNewEntry[LOCKFILE_SYSUSERNAME_ID] )
      || !aFileData[LOCKFILE_LOCALHOST_ID].equals( aNewEntry[LOCKFILE_LOCALHOST_ID] )
      || !aFileData[LOCKFILE_USERURL_ID].equals( aNewEntry[LOCKFILE_USERURL_ID] ) )
        throw io::IOException(); // not the owner, access denied

    uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
    ::ucbhelper::Content aCnt(m_aURL, xEnv);
    aCnt.executeCommand(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("delete")),
        uno::makeAny(sal_Bool(sal_True)));
}

} // namespace svt

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/// @file
/// @author  Ivan Vucica
/// @version 1.31
///
/// @section LICENSE
///
/// This program is free software; you can redistribute it and/or modify it under
/// the terms of the BSD license: http://www.opensource.org/licenses/bsd-license.php

#include <windows.h>

#include "main.h"
#include "RenderSystem.h"
#include "Window.h"

bool gAprilShouldInvokeQuitCallback = false;
int april_main (void (*anAprilInit)(const harray<hstr>&), void (*anAprilDestroy)(), int _argc, char **_argv)
{
    harray<hstr> argv;
	if(_argv)
	{
		for (int i = 0; i < _argc; i++)
		{
			argv.push_back(_argv[i]);
		}
	}

	anAprilInit(argv);
    april::rendersys->getWindow()->enterMainLoop();
	anAprilDestroy();
	return 0;
}<commit_msg>- fixed line endings<commit_after>/// @file
/// @author  Ivan Vucica
/// @version 1.31
///
/// @section LICENSE
///
/// This program is free software; you can redistribute it and/or modify it under
/// the terms of the BSD license: http://www.opensource.org/licenses/bsd-license.php

#include <windows.h>

#include "main.h"
#include "RenderSystem.h"
#include "Window.h"

bool gAprilShouldInvokeQuitCallback = false;
int april_main (void (*anAprilInit)(const harray<hstr>&), void (*anAprilDestroy)(), int _argc, char **_argv)
{
    harray<hstr> argv;
	if(_argv)
	{
		for (int i = 0; i < _argc; i++)
		{
			argv.push_back(_argv[i]);
		}
	}

	anAprilInit(argv);
    april::rendersys->getWindow()->enterMainLoop();
	anAprilDestroy();
	return 0;
}<|endoftext|>


<commit_before>/*   _____
 * /\  _  \                     __
 * \ \ \_\ \      __    __  __ /\_\
 *  \ \  __ \   /'_ `\ /\ \/\ \\/\ \
 *   \ \ \/\ \ /\ \_\ \\ \ \_\ \\ \ \
 *    \ \_\ \_\\ \____ \\ \____/ \ \_\
 *     \/_/\/_/ \/____\ \\/___/   \/_/
 *                /\____/
 *                \_/__/
 *
 * Copyright (c) 2011 Joshua Larouche
 *
 *
 * License: (BSD)
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name of Agui nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER 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 "Agui/Widgets/ToolTip/ToolTip.hpp"

namespace agui {

	ToolTip::ToolTip()
		: align(ALIGN_TOP_LEFT), invoker(NULL)
	{
		resizableText.setSingleLine(false);
		setVisibility(false);
		setFocusable(false);
		setTabable(false);
		setPreferredOffset(Point(10,10));
	}

	void ToolTip::mouseClick( MouseEvent &mouseEvent )
	{

		if(mouseEvent.getButton() == MOUSE_BUTTON_LEFT)
			dispatchActionEvent(ActionEvent(this));
	}

	void ToolTip::showToolTip( const std::string& text, int width, int x, int y, Widget* invoker )
	{
		this->invoker = invoker;

		setLocation(x,y);
		int w = width <= 0 ? 1000 : width;
		resizableText.makeTextLines(getFont(),text,wrappedText,w);

		int newHeight = wrappedText.size() * getFont()->getLineHeight();

		int newWidth = w;

			int widestLine = -1;
			for(size_t i = 0; i < wrappedText.size(); ++i)
			{
				int curWidth = getFont()->getTextWidth(wrappedText[i]);
				if(curWidth > widestLine)
				{
					widestLine = curWidth;
				}
			}

			if(widestLine < width)
			newWidth = widestLine;

		newWidth += (getMargin(SIDE_LEFT) + getMargin(SIDE_RIGHT));
		newHeight += (getMargin(SIDE_TOP) + getMargin(SIDE_BOTTOM));

		setSize(newWidth,newHeight);

		setVisibility(true);
	}

	const std::vector<std::string>& ToolTip::getAreaText() const
	{
		return wrappedText;
	}

	void ToolTip::paintBackground( const PaintEvent &paintEvent )
	{
		paintEvent.graphics()->drawFilledRectangle(
			getSizeRectangle(),getBackColor());
	}

	void ToolTip::paintComponent( const PaintEvent &paintEvent )
	{
		resizableText.drawTextArea(
			paintEvent.graphics(),getFont(),getInnerRectangle(),
			getFontColor(),getAreaText(),align);
	}

	void ToolTip::setTextAlignment( AreaAlignmentEnum alignment )
	{
		align = alignment;
	}

	agui::AreaAlignmentEnum ToolTip::getTextAlignment() const
	{
		return align;
	}

	void ToolTip::hideToolTip()
	{
		setVisibility(false);
		invoker = NULL;
	}

	void ToolTip::setPreferredOffset( Point offset )
	{
		preferredOffset = offset;
	}

	Point ToolTip::getPreferredOffset() const
	{
		return preferredOffset;
	}

	Widget* ToolTip::getInvoker() const
	{
		return invoker;
	}

}

<commit_msg>Added border around the tooltip widget, it looks better this way.<commit_after>/*   _____
 * /\  _  \                     __
 * \ \ \_\ \      __    __  __ /\_\
 *  \ \  __ \   /'_ `\ /\ \/\ \\/\ \
 *   \ \ \/\ \ /\ \_\ \\ \ \_\ \\ \ \
 *    \ \_\ \_\\ \____ \\ \____/ \ \_\
 *     \/_/\/_/ \/____\ \\/___/   \/_/
 *                /\____/
 *                \_/__/
 *
 * Copyright (c) 2011 Joshua Larouche
 *
 *
 * License: (BSD)
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name of Agui nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER 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 "Agui/Widgets/ToolTip/ToolTip.hpp"

namespace agui {

	ToolTip::ToolTip()
		: align(ALIGN_TOP_LEFT), invoker(NULL)
	{
		resizableText.setSingleLine(false);
		setVisibility(false);
		setFocusable(false);
		setTabable(false);
		setPreferredOffset(Point(10,10));
	}

	void ToolTip::mouseClick( MouseEvent &mouseEvent )
	{

		if(mouseEvent.getButton() == MOUSE_BUTTON_LEFT)
			dispatchActionEvent(ActionEvent(this));
	}

	void ToolTip::showToolTip( const std::string& text, int width, int x, int y, Widget* invoker )
	{
		this->invoker = invoker;

		setLocation(x,y);
		int w = width <= 0 ? 1000 : width;
		resizableText.makeTextLines(getFont(),text,wrappedText,w);

		int newHeight = wrappedText.size() * getFont()->getLineHeight();

		int newWidth = w;

			int widestLine = -1;
			for(size_t i = 0; i < wrappedText.size(); ++i)
			{
				int curWidth = getFont()->getTextWidth(wrappedText[i]);
				if(curWidth > widestLine)
				{
					widestLine = curWidth;
				}
			}

			if(widestLine < width)
			newWidth = widestLine;

		newWidth += (getMargin(SIDE_LEFT) + getMargin(SIDE_RIGHT));
		newHeight += (getMargin(SIDE_TOP) + getMargin(SIDE_BOTTOM));

		setSize(newWidth,newHeight);

		setVisibility(true);
	}

	const std::vector<std::string>& ToolTip::getAreaText() const
	{
		return wrappedText;
	}

	void ToolTip::paintBackground( const PaintEvent &paintEvent )
	{
		paintEvent.graphics()->drawFilledRectangle(
			getSizeRectangle(),getBackColor());
    paintEvent.graphics()->drawRectangle(getSizeRectangle(), getFontColor());
	}

	void ToolTip::paintComponent( const PaintEvent &paintEvent )
	{
		resizableText.drawTextArea(
			paintEvent.graphics(),getFont(),getInnerRectangle(),
			getFontColor(),getAreaText(),align);
	}

	void ToolTip::setTextAlignment( AreaAlignmentEnum alignment )
	{
		align = alignment;
	}

	agui::AreaAlignmentEnum ToolTip::getTextAlignment() const
	{
		return align;
	}

	void ToolTip::hideToolTip()
	{
		setVisibility(false);
		invoker = NULL;
	}

	void ToolTip::setPreferredOffset( Point offset )
	{
		preferredOffset = offset;
	}

	Point ToolTip::getPreferredOffset() const
	{
		return preferredOffset;
	}
	Widget* ToolTip::getInvoker() const
	{
		return invoker;
	}

}

<|endoftext|>


<commit_before>//
// Copyright (c) 2016 James A. Chappell
//
#include "Fetch.h"

#include <stdexcept>
#include <string.h>

using namespace std;
using namespace Storage_B::Curlpp;

class CurlGlobalInit
{
public:
  CurlGlobalInit()
  {
    Curl::GlobalInit();
  }

  CurlGlobalInit(const CurlGlobalInit&) = delete;
  CurlGlobalInit& operator=(const CurlGlobalInit&) = delete;

  ~CurlGlobalInit()
  {
     Curl::GlobalCleanup();
  }
};

static CurlGlobalInit init;

Fetch::Fetch(const char *url)
  : curl_(make_unique<Curl>())
{
  curl_->SetOpt(CURLOPT_WRITEFUNCTION, read_result);

  if (url)
  {
    Url(url);
  }
}

long Fetch::fetch(CURLoption option, string& result) const
{
  curl_->SetOpt(option, &result);

  long http_status;
  CURLcode res = curl_->Perform(http_status);

  if (res != CURLE_OK)
  {
    string error;
    if (curl_->error() && (strlen(curl_->error()) > 0))
    {
      error = curl_->error();
    }
    else
    {
      error = "CURLcode = " + to_string(res);
    }
    switch(res)
    {
      case CURLE_URL_MALFORMAT:
        throw logic_error(error);
        break;

      default:
        throw runtime_error(error);
        break;
    }
  }

  return http_status;
}

size_t Fetch::read_result(void *buffer, size_t size, size_t nmemb,
                            void *stream)
{
  auto *out = static_cast<string *>(stream);
  if (out)
  {
    auto buf_size = size * nmemb;
    *out += string((const char* )buffer);
    return buf_size;
  }

  return -1;
}
<commit_msg>change include<commit_after>//
// Copyright (c) 2016 James A. Chappell
//
#include "Fetch.h"

#include <stdexcept>
#include <cstring>

using namespace std;
using namespace Storage_B::Curlpp;

class CurlGlobalInit
{
public:
  CurlGlobalInit()
  {
    Curl::GlobalInit();
  }

  CurlGlobalInit(const CurlGlobalInit&) = delete;
  CurlGlobalInit& operator=(const CurlGlobalInit&) = delete;

  ~CurlGlobalInit()
  {
     Curl::GlobalCleanup();
  }
};

static CurlGlobalInit init;

Fetch::Fetch(const char *url)
  : curl_(make_unique<Curl>())
{
  curl_->SetOpt(CURLOPT_WRITEFUNCTION, read_result);

  if (url)
  {
    Url(url);
  }
}

long Fetch::fetch(CURLoption option, string& result) const
{
  curl_->SetOpt(option, &result);

  long http_status;
  CURLcode res = curl_->Perform(http_status);

  if (res != CURLE_OK)
  {
    string error;
    if (curl_->error() && (strlen(curl_->error()) > 0))
    {
      error = curl_->error();
    }
    else
    {
      error = "CURLcode = " + to_string(res);
    }
    switch(res)
    {
      case CURLE_URL_MALFORMAT:
        throw logic_error(error);
        break;

      default:
        throw runtime_error(error);
        break;
    }
  }

  return http_status;
}

size_t Fetch::read_result(void *buffer, size_t size, size_t nmemb,
                            void *stream)
{
  auto *out = static_cast<string *>(stream);
  if (out)
  {
    auto buf_size = size * nmemb;
    *out += string((const char* )buffer);
    return buf_size;
  }

  return -1;
}
<|endoftext|>


<commit_before>#include "VecMatMath.hpp"
#include <cmath>

#define PI 3.14159265

using namespace std;

vec3 cross(const vec3 &a, const vec3 &b)
{
    return
    {{
        + (a[1] * b[2] - b[1] * a[2]),
        - (a[0] * b[2] - b[0] * a[2]),
        + (a[0] * b[1] - b[0] * a[1])
    }};
}

vec3 mult(const mat3& m, const vec3& a)
{
    return {{
        a[0] * m[0][0] + a[1] * m[1][0] + a[2] * m[2][0],
        a[0] * m[0][1] + a[1] * m[1][1] + a[2] * m[2][1],
        a[0] * m[0][2] + a[1] * m[1][2] + a[2] * m[2][2]
    }};
}

mat3 getRotationMatrix(vec3 axis, float rads)
{
    axis = unitVec(axis);

    return {{
        {{
            cos(rads) + (axis[0] * axis[0]) * (1.0 - cos(rads)),
            (axis[1] * axis[0]) * (1.0 - cos(rads)) + axis[2] * sin(rads),
            (axis[2] * axis[0]) * (1.0 - cos(rads)) - axis[1] * sin(rads)
        }},
        {{
            (axis[0] * axis[1]) * (1.0 - cos(rads)) - axis[2] * sin(rads),
            cos(rads) + (axis[1] * axis[1]) * (1 - cos(rads)),
            (axis[2] * axis[1]) * (1.0 - cos(rads)) + axis[0] * sin(rads)
        }},
        {{
            (axis[0] * axis[2]) * (1.0 - cos(rads)) + axis[1] * sin(rads),
            (axis[1] * axis[2]) * (1.0 - cos(rads)) - axis[0] * sin(rads),
            cos(rads) + (axis[2] * axis[2]) * (1.0 - cos(rads))
        }}
    }};
}

<commit_msg>fix the double type warning error thing<commit_after>#include "VecMatMath.hpp"
#include <cmath>

#define PI 3.14159265

using namespace std;

vec3 cross(const vec3 &a, const vec3 &b)
{
    return
    {{
        + (a[1] * b[2] - b[1] * a[2]),
        - (a[0] * b[2] - b[0] * a[2]),
        + (a[0] * b[1] - b[0] * a[1])
    }};
}

vec3 mult(const mat3& m, const vec3& a)
{
    return {{
        a[0] * m[0][0] + a[1] * m[1][0] + a[2] * m[2][0],
        a[0] * m[0][1] + a[1] * m[1][1] + a[2] * m[2][1],
        a[0] * m[0][2] + a[1] * m[1][2] + a[2] * m[2][2]
    }};
}

mat3 getRotationMatrix(vec3 axis, float rads)
{
    axis = unitVec(axis);

    return {{
        {{
            cos(rads) + (axis[0] * axis[0]) * (1 - cos(rads)),
            (axis[1] * axis[0]) * (1 - cos(rads)) + axis[2] * sin(rads),
            (axis[2] * axis[0]) * (1 - cos(rads)) - axis[1] * sin(rads)
        }},
        {{
            (axis[0] * axis[1]) * (1 - cos(rads)) - axis[2] * sin(rads),
            cos(rads) + (axis[1] * axis[1]) * (1 - cos(rads)),
            (axis[2] * axis[1]) * (1 - cos(rads)) + axis[0] * sin(rads)
        }},
        {{
            (axis[0] * axis[2]) * (1 - cos(rads)) + axis[1] * sin(rads),
            (axis[1] * axis[2]) * (1 - cos(rads)) - axis[0] * sin(rads),
            cos(rads) + (axis[2] * axis[2]) * (1 - cos(rads))
        }}
    }};
}

<|endoftext|>