<commit_before>
// Note - pyconfig.h must be included before condor_common to avoid
// re-definition warnings.
# include <pyconfig.h>
# if defined(__APPLE__)
# undef HAVE_SSIZE_T
# include <pyport.h>
# endif

#include "condor_common.h"

#include <boost/python.hpp>

#include "daemon.h"
#include "daemon_types.h"
#include "condor_commands.h"
#include "condor_attributes.h"
#include "compat_classad.h"

#include "classad_wrapper.h"
#include "module_lock.h"

using namespace boost::python;

enum DaemonCommands {
  DDAEMONS_OFF = DAEMONS_OFF,
  DDAEMONS_OFF_FAST = DAEMONS_OFF_FAST,
  DDAEMONS_OFF_PEACEFUL = DAEMONS_OFF_PEACEFUL,
  DDAEMON_OFF = DAEMON_OFF,
  DDAEMON_OFF_FAST = DAEMON_OFF_FAST,
  DDAEMON_OFF_PEACEFUL = DAEMON_OFF_PEACEFUL,
  DDC_OFF_FAST = DC_OFF_FAST,
  DDC_OFF_PEACEFUL = DC_OFF_PEACEFUL,
  DDC_OFF_GRACEFUL = DC_OFF_GRACEFUL,
  DDC_SET_PEACEFUL_SHUTDOWN = DC_SET_PEACEFUL_SHUTDOWN,
  DDC_SET_FORCE_SHUTDOWN = DC_SET_FORCE_SHUTDOWN,
  DDC_OFF_FORCE = DC_OFF_FORCE,
  DDC_RECONFIG_FULL = DC_RECONFIG_FULL,
  DRESTART = RESTART,
  DRESTART_PEACEFUL = RESTART_PEACEFUL
};

void send_command(const ClassAdWrapper & ad, DaemonCommands dc, const std::string &target="")
{
    std::string addr;
    if (!ad.EvaluateAttrString(ATTR_MY_ADDRESS, addr))
    {
        PyErr_SetString(PyExc_ValueError, "Address not available in location ClassAd.");
        throw_error_already_set();
    }
    std::string ad_type_str;
    if (!ad.EvaluateAttrString(ATTR_MY_TYPE, ad_type_str))
    {
        PyErr_SetString(PyExc_ValueError, "Daemon type not available in location ClassAd.");
        throw_error_already_set();
    }
    int ad_type = AdTypeFromString(ad_type_str.c_str());
    if (ad_type == NO_AD)
    {
        printf("ad type %s.\n", ad_type_str.c_str());
        PyErr_SetString(PyExc_ValueError, "Unknown ad type.");
        throw_error_already_set();
    }
    daemon_t d_type;
    switch (ad_type) {
    case MASTER_AD: d_type = DT_MASTER; break;
    case STARTD_AD: d_type = DT_STARTD; break;
    case SCHEDD_AD: d_type = DT_SCHEDD; break;
    case NEGOTIATOR_AD: d_type = DT_NEGOTIATOR; break;
    case COLLECTOR_AD: d_type = DT_COLLECTOR; break;
    default:
        d_type = DT_NONE;
        PyErr_SetString(PyExc_ValueError, "Unknown daemon type.");
        throw_error_already_set();
    }

    ClassAd ad_copy; ad_copy.CopyFrom(ad);
    Daemon d(&ad_copy, d_type, NULL);
    bool result;
    {
    condor::ModuleLock ml;
    result = !d.locate();
    }
    if (result)
    {
        PyErr_SetString(PyExc_RuntimeError, "Unable to locate daemon.");
        throw_error_already_set();
    }
    ReliSock sock;
    {
    condor::ModuleLock ml;
    result = !sock.connect(d.addr());
    }
    if (result)
    {
        PyErr_SetString(PyExc_RuntimeError, "Unable to connect to the remote daemon");
        throw_error_already_set();
    }
    {
    condor::ModuleLock ml;
    result = !d.startCommand(dc, &sock, 0, NULL);
    }
    if (result)
    {
        PyErr_SetString(PyExc_RuntimeError, "Failed to start command.");
        throw_error_already_set();
    }
    if (target.size())
    {
        std::string target_to_send = target;
        if (!sock.code(target_to_send))
        {
            PyErr_SetString(PyExc_RuntimeError, "Failed to send target.");
            throw_error_already_set();
        }
        if (!sock.end_of_message())
        {
            PyErr_SetString(PyExc_RuntimeError, "Failed to send end-of-message.");
            throw_error_already_set();
        }
    }
    sock.close();
}

void
enable_debug()
{
    dprintf_set_tool_debug("TOOL", 0);
}

void
enable_log()
{
    dprintf_config("TOOL");
}

BOOST_PYTHON_FUNCTION_OVERLOADS(send_command_overloads, send_command, 2, 3);

void
export_dc_tool()
{
    enum_<DaemonCommands>("DaemonCommands")
        .value("DaemonsOff", DDAEMONS_OFF)
        .value("DaemonsOffFast", DDAEMONS_OFF_FAST)
        .value("DaemonsOffPeaceful", DDAEMONS_OFF_PEACEFUL)
        .value("DaemonOff", DDAEMON_OFF)
        .value("DaemonOffFast", DDAEMON_OFF_FAST)
        .value("DaemonOffPeaceful", DDAEMON_OFF_PEACEFUL)
        .value("OffGraceful", DDC_OFF_GRACEFUL)
        .value("OffPeaceful", DDC_OFF_PEACEFUL)
        .value("OffFast", DDC_OFF_FAST)
        .value("OffForce", DDC_OFF_FORCE)
        .value("SetPeacefulShutdown", DDC_SET_PEACEFUL_SHUTDOWN)
        .value("SetForceShutdown", DDC_SET_FORCE_SHUTDOWN)
        .value("Reconfig", DDC_RECONFIG_FULL)
        .value("Restart", DRESTART)
        .value("RestartPeacful", DRESTART_PEACEFUL)
        ;

    def("send_command", send_command, send_command_overloads("Send a command to a HTCondor daemon specified by a location ClassAd\n"
        ":param ad: An ad specifying the location of the daemon; typically, found by using Collector.locate(...).\n"
        ":param dc: A command type; must be a member of the enum DaemonCommands.\n"
        ":param target: Some commands require additional arguments; for example, sending DaemonOff to a master requires one to specify which subsystem to turn off."
        "  If this parameter is given, the daemon is sent an additional argument."))
        ;

    def("enable_debug", enable_debug, "Turn on debug logging output from HTCondor.  Logs to stderr.");
    def("enable_log", enable_log, "Turn on logging output from HTCondor.  Logs to the file specified by the parameter TOOL_LOG.");
}
<commit_msg>Add python bindings for condor_squawk. #4875<commit_after>
// Note - pyconfig.h must be included before condor_common to avoid
// re-definition warnings.
# include <pyconfig.h>
# if defined(__APPLE__)
# undef HAVE_SSIZE_T
# include <pyport.h>
# endif

#include "condor_common.h"

#include <boost/python.hpp>

#include "daemon.h"
#include "daemon_types.h"
#include "condor_commands.h"
#include "condor_attributes.h"
#include "compat_classad.h"
#include "condor_config.h"

#include "classad_wrapper.h"
#include "old_boost.h"
#include "module_lock.h"

using namespace boost::python;

enum DaemonCommands {
  DDAEMONS_OFF = DAEMONS_OFF,
  DDAEMONS_OFF_FAST = DAEMONS_OFF_FAST,
  DDAEMONS_OFF_PEACEFUL = DAEMONS_OFF_PEACEFUL,
  DDAEMON_OFF = DAEMON_OFF,
  DDAEMON_OFF_FAST = DAEMON_OFF_FAST,
  DDAEMON_OFF_PEACEFUL = DAEMON_OFF_PEACEFUL,
  DDC_OFF_FAST = DC_OFF_FAST,
  DDC_OFF_PEACEFUL = DC_OFF_PEACEFUL,
  DDC_OFF_GRACEFUL = DC_OFF_GRACEFUL,
  DDC_SET_PEACEFUL_SHUTDOWN = DC_SET_PEACEFUL_SHUTDOWN,
  DDC_SET_FORCE_SHUTDOWN = DC_SET_FORCE_SHUTDOWN,
  DDC_OFF_FORCE = DC_OFF_FORCE,
  DDC_RECONFIG_FULL = DC_RECONFIG_FULL,
  DRESTART = RESTART,
  DRESTART_PEACEFUL = RESTART_PEACEFUL
};

void send_command(const ClassAdWrapper & ad, DaemonCommands dc, const std::string &target="")
{
    std::string addr;
    if (!ad.EvaluateAttrString(ATTR_MY_ADDRESS, addr))
    {
        PyErr_SetString(PyExc_ValueError, "Address not available in location ClassAd.");
        throw_error_already_set();
    }
    std::string ad_type_str;
    if (!ad.EvaluateAttrString(ATTR_MY_TYPE, ad_type_str))
    {
        PyErr_SetString(PyExc_ValueError, "Daemon type not available in location ClassAd.");
        throw_error_already_set();
    }
    int ad_type = AdTypeFromString(ad_type_str.c_str());
    if (ad_type == NO_AD)
    {
        printf("ad type %s.\n", ad_type_str.c_str());
        PyErr_SetString(PyExc_ValueError, "Unknown ad type.");
        throw_error_already_set();
    }
    daemon_t d_type;
    switch (ad_type) {
    case MASTER_AD: d_type = DT_MASTER; break;
    case STARTD_AD: d_type = DT_STARTD; break;
    case SCHEDD_AD: d_type = DT_SCHEDD; break;
    case NEGOTIATOR_AD: d_type = DT_NEGOTIATOR; break;
    case COLLECTOR_AD: d_type = DT_COLLECTOR; break;
    default:
        d_type = DT_NONE;
        PyErr_SetString(PyExc_ValueError, "Unknown daemon type.");
        throw_error_already_set();
    }

    ClassAd ad_copy; ad_copy.CopyFrom(ad);
    Daemon d(&ad_copy, d_type, NULL);
    bool result;
    {
    condor::ModuleLock ml;
    result = !d.locate();
    }
    if (result)
    {
        PyErr_SetString(PyExc_RuntimeError, "Unable to locate daemon.");
        throw_error_already_set();
    }
    ReliSock sock;
    {
    condor::ModuleLock ml;
    result = !sock.connect(d.addr());
    }
    if (result)
    {
        PyErr_SetString(PyExc_RuntimeError, "Unable to connect to the remote daemon");
        throw_error_already_set();
    }
    {
    condor::ModuleLock ml;
    result = !d.startCommand(dc, &sock, 0, NULL);
    }
    if (result)
    {
        PyErr_SetString(PyExc_RuntimeError, "Failed to start command.");
        throw_error_already_set();
    }
    if (target.size())
    {
        std::string target_to_send = target;
        if (!sock.code(target_to_send))
        {
            PyErr_SetString(PyExc_RuntimeError, "Failed to send target.");
            throw_error_already_set();
        }
        if (!sock.end_of_message())
        {
            PyErr_SetString(PyExc_RuntimeError, "Failed to send end-of-message.");
            throw_error_already_set();
        }
    }
    sock.close();
}

void send_alive(boost::python::object ad_obj=boost::python::object(), boost::python::object pid_obj=boost::python::object(), boost::python::object timeout_obj=boost::python::object())
{
    std::string addr;
    if (ad_obj.ptr() == Py_None)
    {
        char *inherit_var = getenv("CONDOR_INHERIT");
        if (!inherit_var) {THROW_EX(RuntimeError, "No location specified and $CONDOR_INHERIT not in Unix environment.");}
        std::string inherit(inherit_var);
        boost::python::object inherit_obj(inherit);
        boost::python::object inherit_split = inherit_obj.attr("split")();
        if (py_len(inherit_split) < 2) {THROW_EX(RuntimeError, "$CONDOR_INHERIT Unix environment variable malformed.");}
        addr = boost::python::extract<std::string>(inherit_split[1]);
    }
    else
    {
        const ClassAdWrapper ad = boost::python::extract<ClassAdWrapper>(ad_obj);
        if (!ad.EvaluateAttrString(ATTR_MY_ADDRESS, addr))
        {
            THROW_EX(ValueError, "Address not available in location ClassAd.");
        }
    }
    int pid = getpid();
    if (pid_obj.ptr() != Py_None)
    {
        pid = boost::python::extract<int>(pid_obj);
    }
    int timeout;
    if (timeout_obj.ptr() == Py_None)
    {
        timeout = param_integer("NOT_RESPONDING_TIMEOUT");
    }
    else
    {
        timeout = boost::python::extract<int>(timeout_obj);
    }
    if (timeout < 1) {timeout = 1;}

    classy_counted_ptr<Daemon> daemon = new Daemon(DT_ANY, addr.c_str());
    classy_counted_ptr<ChildAliveMsg> msg = new ChildAliveMsg(pid, timeout, 0, 0, true);

    {
        condor::ModuleLock ml;
        daemon->sendBlockingMsg(msg.get());
    }
        if (msg->deliveryStatus() != DCMsg::DELIVERY_SUCCEEDED)
        {
            THROW_EX(RuntimeError, "Failed to deliver keepalive message.");
        }
}

void
enable_debug()
{
    dprintf_set_tool_debug("TOOL", 0);
}

void
enable_log()
{
    dprintf_config("TOOL");
}

BOOST_PYTHON_FUNCTION_OVERLOADS(send_command_overloads, send_command, 2, 3);

void
export_dc_tool()
{
    enum_<DaemonCommands>("DaemonCommands")
        .value("DaemonsOff", DDAEMONS_OFF)
        .value("DaemonsOffFast", DDAEMONS_OFF_FAST)
        .value("DaemonsOffPeaceful", DDAEMONS_OFF_PEACEFUL)
        .value("DaemonOff", DDAEMON_OFF)
        .value("DaemonOffFast", DDAEMON_OFF_FAST)
        .value("DaemonOffPeaceful", DDAEMON_OFF_PEACEFUL)
        .value("OffGraceful", DDC_OFF_GRACEFUL)
        .value("OffPeaceful", DDC_OFF_PEACEFUL)
        .value("OffFast", DDC_OFF_FAST)
        .value("OffForce", DDC_OFF_FORCE)
        .value("SetPeacefulShutdown", DDC_SET_PEACEFUL_SHUTDOWN)
        .value("SetForceShutdown", DDC_SET_FORCE_SHUTDOWN)
        .value("Reconfig", DDC_RECONFIG_FULL)
        .value("Restart", DRESTART)
        .value("RestartPeacful", DRESTART_PEACEFUL)
        ;

    def("send_command", send_command, send_command_overloads("Send a command to a HTCondor daemon specified by a location ClassAd\n"
        ":param ad: An ad specifying the location of the daemon; typically, found by using Collector.locate(...).\n"
        ":param dc: A command type; must be a member of the enum DaemonCommands.\n"
        ":param target: Some commands require additional arguments; for example, sending DaemonOff to a master requires one to specify which subsystem to turn off."
        "  If this parameter is given, the daemon is sent an additional argument."))
        ;

    def("send_alive", send_alive, "Send a keepalive to a HTCondor daemon\n"
        ":param ad: An ad specifying the location of the daemon; typically, found by using Collector.locate(...).\n"
        ":param pid: A process identifier for the keepalive.  Defaults to None, which indicates to utilize the value of os.getpid().\n"
        ":param timeout: The number of seconds this keepalive is valid.  After that time, if the condor_master has not\nreceived a new .keepalive for this process, it will be terminated.  Defaults is controlled by the parameter NOT_RESPONDING_TIMEOUT.\n",
        (boost::python::arg("ad") = boost::python::object(), boost::python::arg("pid")=boost::python::object(), boost::python::arg("timeout")=boost::python::object())
       )
       ;

    def("enable_debug", enable_debug, "Turn on debug logging output from HTCondor.  Logs to stderr.");
    def("enable_log", enable_log, "Turn on logging output from HTCondor.  Logs to the file specified by the parameter TOOL_LOG.");
}
<|endoftext|>


<commit_before>/*************************************************************************************
** The MIT License (MIT)
**
** Knobs is a free Qt and QML based widget.
** Copyright (c) 2015 Ashish Dabhade
** Email: ashishd157@gmail.com
**
** 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 "knob.h"

Knob::Knob(QQuickItem *parent)
    : QQuickItem(parent),
      m_size(200),
      m_color(QColor(135,206,235)),
      m_backgroundColor(QColor(241,241,241)),
      m_foregroundColor(Qt::white),
      m_textColor(Qt::red),
      m_borderColor(Qt::darkGray),
      m_value(0),
      m_minimumValue(0),
      m_maximumValue(100),
      m_percent(0),
      m_readOnly(false),
      m_pieMultiColor(false),
      m_meter(false),
      m_style(Knob::Pie),
      m_needleType(Knob::Point),
      m_pieType(Knob::Flat),
      m_mode(Knob::Normal),
      m_engine(0),
      m_base(0),
      m_text(0)
{
    setSmooth(true);
    setAntialiasing(true);
}

Knob::~Knob()
{
    delete m_base;
    m_base = 0;
    delete m_text;
    m_text = 0;
}

void Knob::classBegin()
{ }

void Knob::componentComplete()
{
    setWidth(m_size);
    setHeight(m_size);
    m_engine = qmlEngine(parentItem());
    connect(parentItem(),&QQuickItem::destroyed,m_engine,&QQmlEngine::deleteLater);
    base();top();mid();
    if(m_style==Knob::Needle&&m_needleType==Knob::Point&&m_meter==true)
        showMeter();
}

void Knob::base()
{
    m_base = new Dial(this);
    connect(parentItem(),&QQuickItem::destroyed,m_base,&QQuickItem::deleteLater);
    m_base->setProperty("x",x());
    m_base->setProperty("y",y());
    m_base->setProperty("z",0.1);
    m_base->setProperty("width",m_size);
    m_base->setProperty("height",m_size);
    m_base->setProperty("color",m_backgroundColor);
    m_base->setProperty("borderColor",m_borderColor);
}

void Knob::showMeter()
{
    Meter *meter = new Meter(m_base);
    connect(parentItem(),&QQuickItem::destroyed,meter,&QQuickItem::deleteLater);
    meter->setProperty("x",x());
    meter->setProperty("y",y());
    meter->setProperty("z",0.2);
    meter->setProperty("width",m_size);
    meter->setProperty("height",m_size);
}

void Knob::top()
{
    Dial *m_top = new Dial(m_base);
    connect(parentItem(),&QQuickItem::destroyed,m_top,&QQuickItem::deleteLater);
    m_top->setProperty("bottom",false);
    qreal w = m_needleType < 7 ? qreal(m_size/1.5) : qreal(m_size/1.2);
    m_top->setProperty("x",m_base->width()/2.0-w/2.0);
    m_top->setProperty("y",m_base->height()/2.0-w/2.0);
    m_top->setProperty("z",0.4);
    m_top->setProperty("width",w);
    m_top->setProperty("height",w);
    m_top->setProperty("color",m_foregroundColor);
    m_top->setProperty("borderColor",m_borderColor);

    QQmlComponent component(m_engine);
    component.setData(Component::getComponent("Text"),QUrl());
    m_text = qobject_cast<QQuickItem*>(component.create());
    m_text->setParentItem(m_base);
    m_text->setProperty("z",0.5);
    m_text->setProperty("color",m_textColor);
    QFont f; f.setPointSize(16);
    m_text->setProperty("font",f);
    m_text->setProperty("text",m_mode==Knob::Percent?QString::number(m_percent)+"%":QString::number(m_minimumValue));
}

void Knob::mid()
{
    QQuickItem *item = 0;
    QUrl url("qrc:/qml/");
    QQmlComponent component(m_engine);
    auto percentSlot = [=](const int &percent) { m_text->setProperty("text",QString::number(percent)+"%");};
    auto valueSlot = [=](const int &value) { m_text->setProperty("text",QString::number(value));};
    switch(m_style) {
        case Knob::Pie: {
            component.setData(Component::getComponent("PieStyle",m_mode==Knob::Percent?"percent":"value"),url);
            PieStyle *pie = qobject_cast<PieStyle*>(component.create());
            if(m_mode==Knob::Normal) {
                connect(pie,&PieStyle::valueChanged,valueSlot);
                connect(this,&Knob::valueChanged,[=](const int &value) {
                    if(pie->animationRunning()) return;
                    pie->setProperty("value",value);});
            } else {
                connect(pie,&PieStyle::percentChanged,percentSlot);
                connect(this,&Knob::percentChanged,[=](const int &percent) {
                    if(pie->animationRunning()) return;
                    pie->setProperty("percent",percent);});
            }
            makeConnections(*pie);
            item = pie;
            item->setProperty("multicolor",m_pieMultiColor);
            item->setProperty("style",m_pieType);
            break;
        }
        case Knob::Arc: {
            component.setData(Component::getComponent("ArcStyle",m_mode==Knob::Percent?"percent":"value"),url);
            ArcStyle *arc = qobject_cast<ArcStyle*>(component.create());
            if(m_mode==Knob::Normal) {
                connect(arc,&ArcStyle::valueChanged,valueSlot);
                connect(this,&Knob::valueChanged,[=](const int &value) {
                    if(arc->animationRunning()) return;
                    arc->setProperty("value",value);});
            } else {
                connect(arc,&ArcStyle::percentChanged,percentSlot);
                connect(this,&Knob::percentChanged,[=](const int &percent) {
                    if(arc->animationRunning()) return;
                    arc->setProperty("percent",percent);});
            }
            makeConnections(*arc);
            item = arc;
            break;
        }
        case Knob::Needle: {
            component.setData(Component::getComponent("NeedleStyle",m_mode==Knob::Percent?"percent":"value"),url);
            NeedleStyle *needle = qobject_cast<NeedleStyle*>(component.create());
            if(m_mode==Knob::Normal) {
                connect(needle,&NeedleStyle::valueChanged,valueSlot);
                connect(this,&Knob::valueChanged,[=](const int &value) {
                    if(needle->animationRunning()) return;
                    needle->setProperty("value",value);});
            } else {
                connect(needle,&NeedleStyle::percentChanged,percentSlot);
                connect(this,&Knob::percentChanged,[=](const int &percent) {
                    if(needle->animationRunning()) return;
                    needle->setProperty("percent",percent);});
            }
            makeConnections(*needle);
            item = needle;
            item->setProperty("style",m_needleType);
            break;
        }
    }
    item->setParentItem(m_base);
    item->setProperty("z",0.3);
    item->setProperty("width",m_size);
    item->setProperty("height",m_size);
    item->setProperty("color",m_color);
    item->setProperty("minValue",m_minimumValue);
    item->setProperty("maxValue",m_maximumValue);
    item->setProperty("readOnly",m_readOnly);
    item->setProperty("mode",m_mode);
    m_mode==Knob::Normal ? item->setProperty("value",m_value) : item->setProperty("percent",m_percent);
}

void Knob::makeConnections(QQuickItem &item)
{
    connect(&item,SIGNAL(valueChanged(int)),this,SLOT(setValue(int)));
    connect(&item,SIGNAL(percentChanged(int)),this,SLOT(setPercent(int)));
    connect(parentItem(),&QQuickItem::destroyed,&item,&QQuickItem::deleteLater);
}

void Knob::setSize(qreal arg)
{
    if (m_size == arg)
        return;

    m_size = arg;
    if(m_size<100)
        m_size = 100;
    emit sizeChanged(m_size);
}

<commit_msg>Update knob.cpp<commit_after>/*************************************************************************************
** The MIT License (MIT)
**
** Knobs is a free Qt and QML based widget.
** Copyright (c) 2015 Ashish Dabhade
** Email: ashishd157@gmail.com
**
** 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 "knob.h"

Knob::Knob(QQuickItem *parent)
    : QQuickItem(parent),
      m_size(200),
      m_color(QColor(135,206,235)),
      m_backgroundColor(QColor(241,241,241)),
      m_foregroundColor(Qt::white),
      m_textColor(Qt::red),
      m_borderColor(Qt::darkGray),
      m_value(0),
      m_minimumValue(0),
      m_maximumValue(100),
      m_percent(0),
      m_readOnly(false),
      m_pieMultiColor(false),
      m_meter(false),
      m_style(Knob::Pie),
      m_needleType(Knob::Point),
      m_pieType(Knob::Flat),
      m_mode(Knob::Normal),
      m_engine(0),
      m_base(0),
      m_text(0)
{
    setSmooth(true);
    setAntialiasing(true);
}

Knob::~Knob()
{
    delete m_base;
    m_base = 0;
    delete m_text;
    m_text = 0;
}

void Knob::classBegin()
{ }

void Knob::componentComplete()
{
    setWidth(m_size);
    setHeight(m_size);
    m_engine = qmlEngine(parentItem());
    connect(parentItem(),&QQuickItem::destroyed,m_engine,&QQmlEngine::deleteLater);
    base();top();mid();
    if(m_style==Knob::Needle&&m_needleType==Knob::Point&&m_meter==true)
        showMeter();
}

void Knob::base()
{
    m_base = new Dial(this);
    connect(parentItem(),&QQuickItem::destroyed,m_base,&QQuickItem::deleteLater);
    m_base->setProperty("x",x());
    m_base->setProperty("y",y());
    m_base->setProperty("z",0.1);
    m_base->setProperty("width",m_size);
    m_base->setProperty("height",m_size);
    m_base->setProperty("color",m_backgroundColor);
    m_base->setProperty("borderColor",m_borderColor);
}

void Knob::showMeter()
{
    Meter *meter = new Meter(m_base);
    connect(parentItem(),&QQuickItem::destroyed,meter,&QQuickItem::deleteLater);
    meter->setProperty("x",x());
    meter->setProperty("y",y());
    meter->setProperty("z",0.2);
    meter->setProperty("width",m_size);
    meter->setProperty("height",m_size);
}

void Knob::top()
{
    Dial *m_top = new Dial(m_base);
    connect(parentItem(),&QQuickItem::destroyed,m_top,&QQuickItem::deleteLater);
    m_top->setProperty("bottom",false);
    qreal w = m_needleType < 7 ? qreal(m_size/1.5) : qreal(m_size/1.2);
    m_top->setProperty("x",m_base->width()/2.0-w/2.0);
    m_top->setProperty("y",m_base->height()/2.0-w/2.0);
    m_top->setProperty("z",0.4);
    m_top->setProperty("width",w);
    m_top->setProperty("height",w);
    m_top->setProperty("color",m_foregroundColor);
    m_top->setProperty("borderColor",m_borderColor);

    QQmlComponent component(m_engine);
    component.setData(Component::getComponent("Text"),QUrl());
    m_text = qobject_cast<QQuickItem*>(component.create());
    m_text->setParentItem(m_base);
    m_text->setProperty("z",0.5);
    m_text->setProperty("color",m_textColor);
    QFont f; f.setPointSize(16);
    m_text->setProperty("font",f);
    m_text->setProperty("text",m_mode==Knob::Percent?QString::number(m_percent)+"%":QString::number(m_minimumValue));
}

void Knob::mid()
{
    QQuickItem *item = 0;
    QUrl url("qrc:/qml/");
    QQmlComponent component(m_engine);
    auto percentSlot = [=](const int &percent) { m_text->setProperty("text",QString::number(percent)+"%");};
    auto valueSlot = [=](const int &value) { m_text->setProperty("text",QString::number(value));};
    switch(m_style) {
        case Knob::Pie: {
            component.setData(Component::getComponent("PieStyle",m_mode==Knob::Percent?"percent":"value"),url);
            PieStyle *pie = qobject_cast<PieStyle*>(component.create());
            if(m_mode==Knob::Normal) {
                connect(pie,&PieStyle::valueChanged,valueSlot);
                connect(this,&Knob::valueChanged,[=](const int &value) {
                    if(pie->animationRunning()) return;
                    pie->setProperty("value",value);});
            } else {
                connect(pie,&PieStyle::percentChanged,percentSlot);
                connect(this,&Knob::percentChanged,[=](const int &percent) {
                    if(pie->animationRunning()) return;
                    pie->setProperty("percent",percent);});
            }
            makeConnections(*pie);
            item = pie;
            item->setProperty("multicolor",m_pieMultiColor);
            item->setProperty("style",m_pieType);
            break;
        }
        case Knob::Arc: {
            component.setData(Component::getComponent("ArcStyle",m_mode==Knob::Percent?"percent":"value"),url);
            ArcStyle *arc = qobject_cast<ArcStyle*>(component.create());
            if(m_mode==Knob::Normal) {
                connect(arc,&ArcStyle::valueChanged,valueSlot);
                connect(this,&Knob::valueChanged,[=](const int &value) {
                    if(arc->animationRunning()) return;
                    arc->setProperty("value",value);});
            } else {
                connect(arc,&ArcStyle::percentChanged,percentSlot);
                connect(this,&Knob::percentChanged,[=](const int &percent) {
                    if(arc->animationRunning()) return;
                    arc->setProperty("percent",percent);});
            }
            makeConnections(*arc);
            item = arc;
            break;
        }
        case Knob::Needle: {
            component.setData(Component::getComponent("NeedleStyle",m_mode==Knob::Percent?"percent":"value"),url);
            NeedleStyle *needle = qobject_cast<NeedleStyle*>(component.create());
            if(m_mode==Knob::Normal) {
                connect(needle,&NeedleStyle::valueChanged,valueSlot);
                connect(this,&Knob::valueChanged,[=](const int &value) {
                    if(needle->animationRunning()) return;
                    needle->setProperty("value",value);});
            } else {
                connect(needle,&NeedleStyle::percentChanged,percentSlot);
                connect(this,&Knob::percentChanged,[=](const int &percent) {
                    if(needle->animationRunning()) return;
                    needle->setProperty("percent",percent);});
            }
            makeConnections(*needle);
            item = needle;
            item->setProperty("style",m_needleType);
            break;
        }
    }
    item->setParentItem(m_base);
    item->setProperty("z",0.3);
    item->setProperty("width",m_size);
    item->setProperty("height",m_size);
    item->setProperty("color",m_color);
    item->setProperty("minValue",m_minimumValue);
    item->setProperty("maxValue",m_maximumValue);
    item->setProperty("readOnly",m_readOnly);
    item->setProperty("mode",m_mode);
    m_mode==Knob::Normal ? item->setProperty("value",m_value) : item->setProperty("percent",m_percent);
}

void Knob::makeConnections(QQuickItem &item)
{
    connect(&item,SIGNAL(valueChanged(int)),this,SLOT(setValue(int)));
    connect(&item,SIGNAL(percentChanged(int)),this,SLOT(setPercent(int)));
    connect(this,SIGNAL(maximumValueChanged(int)),&item,SLOT(setMaxValue(int)));
    connect(this,SIGNAL(minimumValueChanged(int)),&item,SLOT(setMinValue(int)));
    connect(parentItem(),&QQuickItem::destroyed,&item,&QQuickItem::deleteLater);
}

void Knob::setSize(qreal arg)
{
    if (m_size == arg)
        return;

    m_size = arg;
    if(m_size<100)
        m_size = 100;
    emit sizeChanged(m_size);
}

<|endoftext|>


<commit_before>#include "quickgridstar.h"

QuickRowDefinition::QuickRowDefinition(QQuickItem *parent) :
    QQuickItem(parent),
    _weight(1.0f)
{
}

QuickColumnDefinition::QuickColumnDefinition(QQuickItem *parent) :
    QQuickItem(parent),
    _weight(1.0f)
{
}

QuickGridStarAttached::QuickGridStarAttached(QObject *object) :
    QObject(object),
    _ignore(false),
    _row(0),
    _column(0),
    _rowSpan(1),
    _columnSpan(1)
{
}

QuickGridStar::QuickGridStar(QQuickItem *parent) :
    QQuickItem(parent)
{
}

QuickGridStar::~QuickGridStar()
{
    for(QuickGridItem *item : _items)
    {
        delete item;
    }
}

void QuickGridStar::componentComplete()
{
    QList<QQuickItem *>
        children = childItems();

    for(QQuickItem *child : children)
    {
        QString
            className(child->metaObject()->className());

        if(!className.compare("QuickRowDefinition"))
        {
            QuickRowDefinition
                *definition = qobject_cast<QuickRowDefinition *>(child);

            _gridDefinition.addRowDefinition(definition->_weight);
        }
        else if(!className.compare("QuickColumnDefinition"))
        {
            QuickColumnDefinition
                *definition = qobject_cast<QuickColumnDefinition *>(child);

            _gridDefinition.addColumnDefinition(definition->_weight);
        }
        else
        {
            QuickGridStarAttached
                *attached = qobject_cast<QuickGridStarAttached *>(qmlAttachedPropertiesObject<QuickGridStar>(child));

            if(!attached->_ignore)
            {
                _items << new QuickGridItem(child, attached);
            }
        }
    }

    for(QuickGridItem *item : _items)
    {
        _gridDefinition.calculateBounds(item->_attached->_row, item->_attached->_column, item->_attached->_rowSpan, item->_attached->_columnSpan);
    }

    QQuickItem::componentComplete();
}

void QuickGridStar::itemChange(ItemChange change, const ItemChangeData &value)
{
    QCoreApplication::postEvent(this, new QEvent(QEvent::LayoutRequest));

    QQuickItem::itemChange(change, value);
}

bool QuickGridStar::event(QEvent *e)
{
    if(e->type() == QEvent::LayoutRequest)
    {
        updateGeometry();
    }

    return QQuickItem::event(e);
}

void QuickGridStar::updateGeometry()
{
    QSizeF
        size(width(), height());

    if(size.isEmpty())
    {
        QObject
            *parentObject = parent();

        if(parentObject->isWindowType())
        {
            QQuickWindow
                *quickWindow = qobject_cast<QQuickWindow *>(parentObject);

            size = QSizeF(quickWindow->width(), quickWindow->height());
        }
        else
        {
            QQuickItem
                *quickItem = qobject_cast<QQuickItem *>(parentObject);

            size = QSizeF(quickItem->width(), quickItem->height());
        }
    }

    QRectF
        rect(QPointF(0.f, 0.f), size);

    for(QuickGridItem *item : _items)
    {
        QRectF
            cellRect(_gridDefinition.cellRect(rect, item->_attached->_row, item->_attached->_column, item->_attached->_rowSpan, item->_attached->_columnSpan));

        item->_item->setPosition(cellRect.topLeft());
        item->_item->setWidth(cellRect.width());
        item->_item->setHeight(cellRect.height());
    }
}

QuickGridStarAttached *QuickGridStar::qmlAttachedProperties(QObject *object)
{
    return new QuickGridStarAttached(object);
}

void QuickGridStar::registerTypes()
{
    qmlRegisterType<QuickGridStar>("com.quick.gridStar", 1, 0, "GridStar");
    qmlRegisterType<QuickRowDefinition>("com.quick.gridStar", 1, 0, "RowDefinition");
    qmlRegisterType<QuickColumnDefinition>("com.quick.gridStar", 1, 0, "ColumnDefinition");
}
<commit_msg>Update quickgridstar.cpp<commit_after>#include "quickgridstar.h"

QuickRowDefinition::QuickRowDefinition(QQuickItem *parent) :
    QQuickItem(parent),
    _weight(1.0f)
{
}

QuickColumnDefinition::QuickColumnDefinition(QQuickItem *parent) :
    QQuickItem(parent),
    _weight(1.0f)
{
}

QuickGridStarAttached::QuickGridStarAttached(QObject *object) :
    QObject(object),
    _ignore(false),
    _dirty(true),
    _row(0),
    _column(0),
    _rowSpan(1),
    _columnSpan(1),
    _rowSpanActual(1),
    _columnSpanActual(1)
{
}

void QuickGridStarAttached::setRow(qint32 row)
{
    _row = row;

    _dirty = true;
}

void QuickGridStarAttached::setColumn(qint32 column)
{
    _column = column;

    _dirty = true;
}

void QuickGridStarAttached::setRowSpan(qint32 rowSpan)
{
    _rowSpan = rowSpan;

    _dirty = true;
}

void QuickGridStarAttached::setColumnSpan(qint32 columnSpan)
{
    _columnSpan = columnSpan;

    _dirty = true;
}

qint32 QuickGridStarAttached::getRow()
{
    return _row;
}

qint32 QuickGridStarAttached::getColumn()
{
    return _column;
}

qint32 QuickGridStarAttached::getRowSpan()
{
    return _rowSpan;
}

qint32 QuickGridStarAttached::getColumnSpan()
{
    return _columnSpan;
}

QuickGridStar::QuickGridStar(QQuickItem *parent) :
    QQuickItem(parent)
{
}

QuickGridStar::~QuickGridStar()
{
}

qint32 QuickGridStar::rowCount()
{
    return _gridDefinition.rowCount();
}

qint32 QuickGridStar::columnCount()
{
    return _gridDefinition.columnCount();
}

QVariant QuickGridStar::itemsAt(qint32 row, qint32 column)
{
    QVariantList
            quickItems;

    for(QQuickItem *item : _items)
    {
        QuickGridStarAttached
                *attached = qobject_cast<QuickGridStarAttached *>(qmlAttachedPropertiesObject<QuickGridStar>(item));

        if(attached->_row == row && attached->_column == column)
        {
            quickItems << QVariant::fromValue(item);
        }
    }

    return quickItems;
}

void QuickGridStar::addItem(QObject *object, qint32 row, qint32 column, qint32 rowSpan, qint32 columnSpan)
{
    removeItem(object);

    object->setParent(this);

    QuickGridStarAttached
            *attached = qobject_cast<QuickGridStarAttached *>(qmlAttachedPropertiesObject<QuickGridStar>(object));

    attached->_row = row;
    attached->_column = column;
    attached->_rowSpan = rowSpan;
    attached->_columnSpan = columnSpan;

    QQuickItem
            *item = qobject_cast<QQuickItem *>(object);

    _items << item;
}

bool QuickGridStar::removeItem(QObject *object)
{
    return _items.removeOne(qobject_cast<QQuickItem *>(object));
}

void QuickGridStar::addRowDefinition(qreal weight, qint32 row)
{
    for(QQuickItem *item : _items)
    {
        QuickGridStarAttached
            *attached = qobject_cast<QuickGridStarAttached *>(qmlAttachedPropertiesObject<QuickGridStar>(item));

        if(attached->_row >= row)
        {
            attached->_row++;
        }

        attached->_dirty = true;
    }

    _gridDefinition.addRowDefinition(weight, row);
}

void QuickGridStar::addColumnDefinition(qreal weight, qint32 column)
{
    for(QQuickItem *item : _items)
    {
        QuickGridStarAttached
            *attached = qobject_cast<QuickGridStarAttached *>(qmlAttachedPropertiesObject<QuickGridStar>(item));

        if(attached->_column >= column)
        {
            attached->_column++;
        }

        attached->_dirty = true;
    }

    _gridDefinition.addColumnDefinition(weight, column);
}

void QuickGridStar::removeRowDefinition(qint32 row)
{
    for(QQuickItem *item : _items)
    {
        QuickGridStarAttached
            *attached = qobject_cast<QuickGridStarAttached *>(qmlAttachedPropertiesObject<QuickGridStar>(item));

        if(attached->_row >= row)
        {
            attached->_row--;
        }

        attached->_dirty = true;
    }

    _gridDefinition.removeRowDefinition(row);
}

void QuickGridStar::removeColumnDefinition(qint32 column)
{
    for(QQuickItem *item : _items)
    {
        QuickGridStarAttached
            *attached = qobject_cast<QuickGridStarAttached *>(qmlAttachedPropertiesObject<QuickGridStar>(item));

        if(attached->_column >= column)
        {
            attached->_column--;
        }

        attached->_dirty = true;
    }

    _gridDefinition.removeColumnDefinition(column);
}

void QuickGridStar::componentComplete()
{
    QList<QQuickItem *>
        children = childItems();

    for(QQuickItem *child : children)
    {
        QString
            className(child->metaObject()->className());

        if(!className.compare("QuickRowDefinition"))
        {
            QuickRowDefinition
                *definition = qobject_cast<QuickRowDefinition *>(child);

            _gridDefinition.addRowDefinition(definition->_weight);
        }
        else if(!className.compare("QuickColumnDefinition"))
        {
            QuickColumnDefinition
                *definition = qobject_cast<QuickColumnDefinition *>(child);

            _gridDefinition.addColumnDefinition(definition->_weight);
        }
        else
        {
            QuickGridStarAttached
                *attached = qobject_cast<QuickGridStarAttached *>(qmlAttachedPropertiesObject<QuickGridStar>(child));

            if(!attached->_ignore)
            {
                _items << child;
            }
        }
    }

    QQuickItem::componentComplete();
}

void QuickGridStar::itemChange(ItemChange change, const ItemChangeData &value)
{
    QCoreApplication::postEvent(this, new QEvent(QEvent::LayoutRequest));

    QQuickItem::itemChange(change, value);
}

bool QuickGridStar::event(QEvent *e)
{
    if(e->type() == QEvent::LayoutRequest)
    {
        updateGeometry();
    }

    return QQuickItem::event(e);
}

void QuickGridStar::updateGeometry()
{
    QSizeF
        size(width(), height());

    if(size.isEmpty())
    {
        QObject
            *parentObject = parent();

        if(parentObject->isWindowType())
        {
            QQuickWindow
                *quickWindow = qobject_cast<QQuickWindow *>(parentObject);

            size = QSizeF(quickWindow->width(), quickWindow->height());
        }
        else
        {
            QQuickItem
                *quickItem = qobject_cast<QQuickItem *>(parentObject);

            size = QSizeF(quickItem->width(), quickItem->height());
        }
    }

    QRectF
        rect(QPointF(0.0f, 0.0f), size);

    for(QQuickItem *item : _items)
    {
        QuickGridStarAttached
                *attached = qobject_cast<QuickGridStarAttached *>(qmlAttachedPropertiesObject<QuickGridStar>(item));

        if(attached->_dirty)
        {
            attached->_rowSpanActual = attached->_rowSpan;
            attached->_columnSpanActual = attached->_columnSpan;

            _gridDefinition.calculateBounds(attached->_row, attached->_column, attached->_rowSpanActual, attached->_columnSpanActual);

            attached->_dirty = false;
        }

        QRectF
            cellRect(_gridDefinition.cellRect(rect, attached->_row, attached->_column, attached->_rowSpanActual, attached->_columnSpanActual));

        item->setPosition(cellRect.topLeft());
        item->setWidth(cellRect.width());
        item->setHeight(cellRect.height());
    }
}

QuickGridStarAttached *QuickGridStar::qmlAttachedProperties(QObject *object)
{
    return new QuickGridStarAttached(object);
}

void QuickGridStar::registerTypes()
{
    qmlRegisterType<QuickGridStar>("com.quick.gridStar", 1, 0, "GridStar");
    qmlRegisterType<QuickRowDefinition>("com.quick.gridStar", 1, 0, "RowDefinition");
    qmlRegisterType<QuickColumnDefinition>("com.quick.gridStar", 1, 0, "ColumnDefinition");
}
<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011,2012 Preferred Networks and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "server_base.hpp"

#include <stdio.h>
#include <sys/file.h>
#include <cerrno>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include "jubatus/core/common/exception.hpp"
#include "jubatus/core/framework/mixable.hpp"
#include "jubatus/util/system/syscall.h"
#include "mixer/mixer.hpp"
#include "save_load.hpp"
#include "../framework/server_util.hpp"
#include "../common/logger/logger.hpp"

namespace jubatus {
namespace server {
namespace framework {

namespace {

std::string build_local_path(
    const server_argv& a,
    const std::string& type,
    const std::string& id) {
  std::ostringstream path;
  path << a.datadir << '/' << a.eth << '_' << a.port << '_' << type << '_' << id
      << ".jubatus";
  return path.str();
}

void load_file_impl(server_base& server,
    const std::string& path, const std::string& id) {
  LOG(INFO) << "starting load from " << path;

  std::ifstream ifs(path.c_str(), std::ios::binary);
  if (!ifs) {
    throw JUBATUS_EXCEPTION(
      core::common::exception::runtime_error("cannot open input file")
      << core::common::exception::error_file_name(path)
      << core::common::exception::error_errno(errno));
  }

  ifs.exceptions(std::ios_base::failbit | std::ios_base::badbit);
  try {
    framework::load_server(ifs, server, id);
    ifs.close();
  } catch (const std::ios_base::failure&) {
    throw JUBATUS_EXCEPTION(
      core::common::exception::runtime_error("cannot read input file")
      << core::common::exception::error_file_name(path)
      << core::common::exception::error_errno(errno));
  }

  server.update_loaded_status(path);
  LOG(INFO) << "loaded from " << path;
}

class fp_holder {
 public:
  explicit fp_holder(FILE* fp)
    : fp_(fp)
  {}

 private:
  fp_holder(const fp_holder&);
  void operator=(const fp_holder&);

 public:
  ~fp_holder() {
    close();
  }

  FILE* get() const {
    return fp_;
  }

  int close() {
    int ret = 0;

    if (fp_) {
      ret = fclose(fp_);
      fp_ = 0;
    }

    return ret;
  }

 private:
  FILE* fp_;
};

}  // namespace

server_base::server_base(const server_argv& a)
    : argv_(a),
      update_count_(0),
      last_saved_(0, 0),
      last_saved_path_(""),
      last_loaded_(0, 0),
      last_loaded_path_("") {
}

bool server_base::clear() {
  get_driver()->clear();
  return true;
}

std::map<std::string, std::string> server_base::save(const std::string& id) {
  const std::string path = build_local_path(argv_, argv_.type, id);
  LOG(INFO) << "starting save to " << path;

  fp_holder fp(fopen(path.c_str(), "wb"));
  if (fp.get() == 0) {
    throw JUBATUS_EXCEPTION(
      core::common::exception::runtime_error("cannot open output file")
      << core::common::exception::error_file_name(path)
      << core::common::exception::error_errno(errno));
  }

  int fd = fileno(fp.get());
  if (flock(fd, LOCK_EX | LOCK_NB) < 0) {  // try exclusive lock
    throw
      JUBATUS_EXCEPTION(core::common::exception::runtime_error(
          "cannot get the lock of file; any RPC is saving to same file?")
        << core::common::exception::error_file_name(path)
        << core::common::exception::error_errno(errno));
  }

  try {
    framework::save_server(fp.get(), *this, id);
    if (fp.close()) {
      goto write_failure;
    }
  } catch (const std::ios_base::failure&) {
    goto write_failure;
  }
  // putting error handling code here is to prevent skipping variable
  // initialization. skipping variable declaration causes undefined behavior.
  if (0) {
   write_failure:
    int tmperrno = errno;
    if (remove(path.c_str()) < 0) {
      LOG(WARNING) << "failed to cleanup dirty model file: " << path << ": "
        << jubatus::util::system::syscall::get_error_msg(errno);
    }
    throw JUBATUS_EXCEPTION(
      core::common::exception::runtime_error("cannot write output file")
      << core::common::exception::error_file_name(path)
      << core::common::exception::error_errno(tmperrno));
  }

  update_saved_status(path);
  LOG(INFO) << "saved to " << path;

  std::map<std::string, std::string> ret;
  ret.insert(std::make_pair(get_server_identifier(argv_), path));
  return ret;
}

bool server_base::load(const std::string& id) {
  load_file_impl(*this, get_server_identifier(argv_), id);
  return true;
}

void server_base::load_file(const std::string& path) {
  load_file_impl(*this, path, "");
}

void server_base::event_model_updated() {
  ++update_count_;
  if (mixer::mixer* m = get_mixer()) {
    m->updated();
  }
}

void server_base::update_saved_status(const std::string& path) {
  last_saved_ = jubatus::util::system::time::get_clock_time();
  last_saved_path_ = path;
}

void server_base::update_loaded_status(const std::string& path) {
  last_loaded_ = jubatus::util::system::time::get_clock_time();
  last_loaded_path_ = path;
}

}  // namespace framework
}  // namespace server
}  // namespace jubatus
<commit_msg>Revert "use get_server_identifier()"<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011,2012 Preferred Networks and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "server_base.hpp"

#include <stdio.h>
#include <sys/file.h>
#include <cerrno>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include "jubatus/core/common/exception.hpp"
#include "jubatus/core/framework/mixable.hpp"
#include "jubatus/util/system/syscall.h"
#include "mixer/mixer.hpp"
#include "save_load.hpp"
#include "../common/logger/logger.hpp"

namespace jubatus {
namespace server {
namespace framework {

namespace {

std::string build_local_path(
    const server_argv& a,
    const std::string& type,
    const std::string& id) {
  std::ostringstream path;
  path << a.datadir << '/' << a.eth << '_' << a.port << '_' << type << '_' << id
      << ".jubatus";
  return path.str();
}

void load_file_impl(server_base& server,
    const std::string& path, const std::string& id) {
  LOG(INFO) << "starting load from " << path;

  std::ifstream ifs(path.c_str(), std::ios::binary);
  if (!ifs) {
    throw JUBATUS_EXCEPTION(
      core::common::exception::runtime_error("cannot open input file")
      << core::common::exception::error_file_name(path)
      << core::common::exception::error_errno(errno));
  }

  ifs.exceptions(std::ios_base::failbit | std::ios_base::badbit);
  try {
    framework::load_server(ifs, server, id);
    ifs.close();
  } catch (const std::ios_base::failure&) {
    throw JUBATUS_EXCEPTION(
      core::common::exception::runtime_error("cannot read input file")
      << core::common::exception::error_file_name(path)
      << core::common::exception::error_errno(errno));
  }

  server.update_loaded_status(path);
  LOG(INFO) << "loaded from " << path;
}

class fp_holder {
 public:
  explicit fp_holder(FILE* fp)
    : fp_(fp)
  {}

 private:
  fp_holder(const fp_holder&);
  void operator=(const fp_holder&);

 public:
  ~fp_holder() {
    close();
  }

  FILE* get() const {
    return fp_;
  }

  int close() {
    int ret = 0;

    if (fp_) {
      ret = fclose(fp_);
      fp_ = 0;
    }

    return ret;
  }

 private:
  FILE* fp_;
};

}  // namespace

server_base::server_base(const server_argv& a)
    : argv_(a),
      update_count_(0),
      last_saved_(0, 0),
      last_saved_path_(""),
      last_loaded_(0, 0),
      last_loaded_path_("") {
}

bool server_base::clear() {
  get_driver()->clear();
  return true;
}

std::map<std::string, std::string> server_base::save(const std::string& id) {
  const std::string path = build_local_path(argv_, argv_.type, id);
  LOG(INFO) << "starting save to " << path;

  fp_holder fp(fopen(path.c_str(), "wb"));
  if (fp.get() == 0) {
    throw JUBATUS_EXCEPTION(
      core::common::exception::runtime_error("cannot open output file")
      << core::common::exception::error_file_name(path)
      << core::common::exception::error_errno(errno));
  }

  int fd = fileno(fp.get());
  if (flock(fd, LOCK_EX | LOCK_NB) < 0) {  // try exclusive lock
    throw
      JUBATUS_EXCEPTION(core::common::exception::runtime_error(
          "cannot get the lock of file; any RPC is saving to same file?")
        << core::common::exception::error_file_name(path)
        << core::common::exception::error_errno(errno));
  }

  try {
    framework::save_server(fp.get(), *this, id);
    if (fp.close()) {
      goto write_failure;
    }
  } catch (const std::ios_base::failure&) {
    goto write_failure;
  }
  // putting error handling code here is to prevent skipping variable
  // initialization. skipping variable declaration causes undefined behavior.
  if (0) {
   write_failure:
    int tmperrno = errno;
    if (remove(path.c_str()) < 0) {
      LOG(WARNING) << "failed to cleanup dirty model file: " << path << ": "
        << jubatus::util::system::syscall::get_error_msg(errno);
    }
    throw JUBATUS_EXCEPTION(
      core::common::exception::runtime_error("cannot write output file")
      << core::common::exception::error_file_name(path)
      << core::common::exception::error_errno(tmperrno));
  }

  update_saved_status(path);
  LOG(INFO) << "saved to " << path;

  std::map<std::string, std::string> ret;
  ret.insert(std::make_pair(get_server_identifier(argv_), path));
  return ret;
}

bool server_base::load(const std::string& id) {
  load_file_impl(*this, build_local_path(argv_, argv_.type, id), id);
  return true;
}

void server_base::load_file(const std::string& path) {
  load_file_impl(*this, path, "");
}

void server_base::event_model_updated() {
  ++update_count_;
  if (mixer::mixer* m = get_mixer()) {
    m->updated();
  }
}

void server_base::update_saved_status(const std::string& path) {
  last_saved_ = jubatus::util::system::time::get_clock_time();
  last_saved_path_ = path;
}

void server_base::update_loaded_status(const std::string& path) {
  last_loaded_ = jubatus::util::system::time::get_clock_time();
  last_loaded_path_ = path;
}

}  // namespace framework
}  // namespace server
}  // namespace jubatus
<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

// We keep the list of all unit tests in a global location so it's easier to see which
// ones are enabled/disabled

#include "FactSystemTestGeneric.h"
#include "FactSystemTestPX4.h"
#include "FileDialogTest.h"
#include "FlightGearTest.h"
#include "GeoTest.h"
#include "LinkManagerTest.h"
#include "MessageBoxTest.h"
#include "MissionItemTest.h"
#include "SimpleMissionItemTest.h"
#include "SurveyMissionItemTest.h"
#include "MissionControllerTest.h"
#include "MissionManagerTest.h"
#include "RadioConfigTest.h"
#include "MavlinkLogTest.h"
#include "MainWindowTest.h"
#include "FileManagerTest.h"
#include "TCPLinkTest.h"
#include "ParameterManagerTest.h"
#include "MissionCommandTreeTest.h"
#include "LogDownloadTest.h"
#include "SendMavCommandTest.h"
#include "VisualMissionItemTest.h"
#include "CameraSectionTest.h"
#include "SpeedSectionTest.h"
#include "PlanMasterControllerTest.h"
#include "MissionSettingsTest.h"
#include "QGCMapPolygonTest.h"

UT_REGISTER_TEST(FactSystemTestGeneric)
UT_REGISTER_TEST(FactSystemTestPX4)
UT_REGISTER_TEST(FileDialogTest)
UT_REGISTER_TEST(FlightGearUnitTest)
UT_REGISTER_TEST(GeoTest)
UT_REGISTER_TEST(LinkManagerTest)
UT_REGISTER_TEST(MessageBoxTest)
UT_REGISTER_TEST(MissionItemTest)
UT_REGISTER_TEST(SimpleMissionItemTest)
UT_REGISTER_TEST(MissionControllerTest)
UT_REGISTER_TEST(MissionManagerTest)
UT_REGISTER_TEST(RadioConfigTest)
UT_REGISTER_TEST(TCPLinkTest)
UT_REGISTER_TEST(ParameterManagerTest)
UT_REGISTER_TEST(MissionCommandTreeTest)
UT_REGISTER_TEST(LogDownloadTest)
UT_REGISTER_TEST(SendMavCommandTest)
UT_REGISTER_TEST(SurveyMissionItemTest)
UT_REGISTER_TEST(CameraSectionTest)
UT_REGISTER_TEST(SpeedSectionTest)
UT_REGISTER_TEST(PlanMasterControllerTest)
UT_REGISTER_TEST(MissionSettingsTest)
UT_REGISTER_TEST(QGCMapPolygonTest)

// List of unit test which are currently disabled.
// If disabling a new test, include reason in comment.

// FIXME: Temporarily disabled until this can be stabilized
//UT_REGISTER_TEST(MainWindowTest)

// Onboard file support has been removed until it can be make to work correctly
//UT_REGISTER_TEST(FileManagerTest)

// Needs to be update for latest updates
//UT_REGISTER_TEST(MavlinkLogTest)
<commit_msg>Revert "Remove FileManager unit test"<commit_after>/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

// We keep the list of all unit tests in a global location so it's easier to see which
// ones are enabled/disabled

#include "FactSystemTestGeneric.h"
#include "FactSystemTestPX4.h"
#include "FileDialogTest.h"
#include "FlightGearTest.h"
#include "GeoTest.h"
#include "LinkManagerTest.h"
#include "MessageBoxTest.h"
#include "MissionItemTest.h"
#include "SimpleMissionItemTest.h"
#include "SurveyMissionItemTest.h"
#include "MissionControllerTest.h"
#include "MissionManagerTest.h"
#include "RadioConfigTest.h"
#include "MavlinkLogTest.h"
#include "MainWindowTest.h"
#include "FileManagerTest.h"
#include "TCPLinkTest.h"
#include "ParameterManagerTest.h"
#include "MissionCommandTreeTest.h"
#include "LogDownloadTest.h"
#include "SendMavCommandTest.h"
#include "VisualMissionItemTest.h"
#include "CameraSectionTest.h"
#include "SpeedSectionTest.h"
#include "PlanMasterControllerTest.h"
#include "MissionSettingsTest.h"
#include "QGCMapPolygonTest.h"

UT_REGISTER_TEST(FactSystemTestGeneric)
UT_REGISTER_TEST(FactSystemTestPX4)
UT_REGISTER_TEST(FileDialogTest)
UT_REGISTER_TEST(FlightGearUnitTest)
UT_REGISTER_TEST(GeoTest)
UT_REGISTER_TEST(LinkManagerTest)
UT_REGISTER_TEST(MessageBoxTest)
UT_REGISTER_TEST(MissionItemTest)
UT_REGISTER_TEST(SimpleMissionItemTest)
UT_REGISTER_TEST(MissionControllerTest)
UT_REGISTER_TEST(MissionManagerTest)
UT_REGISTER_TEST(RadioConfigTest)
UT_REGISTER_TEST(TCPLinkTest)
UT_REGISTER_TEST(FileManagerTest)
UT_REGISTER_TEST(ParameterManagerTest)
UT_REGISTER_TEST(MissionCommandTreeTest)
UT_REGISTER_TEST(LogDownloadTest)
UT_REGISTER_TEST(SendMavCommandTest)
UT_REGISTER_TEST(SurveyMissionItemTest)
UT_REGISTER_TEST(CameraSectionTest)
UT_REGISTER_TEST(SpeedSectionTest)
UT_REGISTER_TEST(PlanMasterControllerTest)
UT_REGISTER_TEST(MissionSettingsTest)
UT_REGISTER_TEST(QGCMapPolygonTest)

// List of unit test which are currently disabled.
// If disabling a new test, include reason in comment.

// FIXME: Temporarily disabled until this can be stabilized
//UT_REGISTER_TEST(MainWindowTest)

// Needs to be update for latest updates
//UT_REGISTER_TEST(MavlinkLogTest)
<|endoftext|>


<commit_before>/* -*- C++ -*-
   This file implements the business card look.

   the KDE addressbook

   $ Author: Mirko Boehm $
   $ Copyright: (C) 1996-2001, Mirko Boehm $
   $ Contact: mirko@kde.org
   http://www.kde.org $
   $ License: GPL with the following explicit clarification:
   This code may be linked against any version of the Qt toolkit
   from Troll Tech, Norway. $

   $Revision$
*/

#include "look_details.h"
#include <qdir.h>
#include <qcursor.h>
#include "kabentrypainter.h"
#include "global.h"
#include <kdebug.h>
#include <kglobalsettings.h>
#include <kinstance.h>
#include <kstandarddirs.h>
#include <klocale.h>
#include <kconfig.h>
#include <qpainter.h>
#include <qpopupmenu.h>

#define GRID 5

const QString KABDetailedView::BorderedBGDir="kab3part/backgrounds/bordered/";
const QString KABDetailedView::TiledBGDir="kab3part/backgrounds/tiled/";

KABDetailedView::KABDetailedView(QWidget* parent, const char* name)
    : KABBasicLook(parent, name),
      epainter(0),
      bgStyle(None),
      defaultBGColor(white),
      headlineBGColor(darkBlue),
      headlineTextColor(yellow),
      Grid(3),
      menuBorderedBG(0),
      menuTiledBG(0)
{
    KToggleAction** actions[]= {
        &actionShowAddresses,
        &actionShowEmails,
        &actionShowTelephones,
        &actionShowURLs
    };
    QString texts[]= {
        i18n("Show Postal Addresses"),
        i18n("Show Email Addresses"),
        i18n("Show Telephone Numbers"),
        i18n("Show Web Pages (URLs)")
    };
    QFont general=KGlobalSettings::generalFont();
    QFont fixed=KGlobalSettings::fixedFont();
    QString gfont=general.family();
    QString ffont=fixed.family();
    int gpointsize=general.pixelSize(); // it is a joke
    int fpointsize=fixed.pixelSize();
    epainter=new KABEntryPainter
             (Qt::black, headlineTextColor,
              useHeadlineBGColor, headlineBGColor,
              QFont(gfont, gpointsize+4, QFont::Bold, true),
              QFont(gfont, gpointsize+2, QFont::Bold, true),
              QFont(gfont, gpointsize, QFont::Normal, false),
              QFont(ffont, fpointsize, QFont::Normal, false),
              QFont(gfont, gpointsize, QFont::Normal, false));
    const int Size=sizeof(actions)/sizeof(actions[0]);
    // ----- create some actions:
    for(int count=0; count<Size; ++count)
    {
        *actions[count]=new KToggleAction(texts[count]);
        (*actions[count])->setChecked(true);
    }
    // ----- we would like to track mouse movement:
    setMouseTracking(true);
    /*
    // ----- find preferred size:
    // Since the detailed look does not prefer a size it uses the
    // preferred size of the editing look to avoid flickering resizing.
    KABEditLook *editlook=new KABEditLook(api, this);
    setMinimumSize(editlook->minimumSizeHint());
    delete editlook;
    */
}

KABDetailedView::~KABDetailedView()
{
    if(epainter!=0) delete epainter;
}

bool KABDetailedView::getBackground(QString path, QPixmap& image)
{
    QMap<QString, QPixmap>::iterator pos;
    pos=backgrounds.find(path);
    if(pos==backgrounds.end())
    { // the image has not been loaded previously
        if(image.load(path))
	{
            backgrounds[path]=image;
            return true;
	} else {
            return false;
	}
    } else {
        // image found in cache
        image=pos.data();
        return true;
    }
}

void KABDetailedView::paintEvent(QPaintEvent*)
{
    const int BorderSpace=Grid;
    QPixmap pm(width(), height());
    QPainter p;
    QRect entryArea=QRect(BorderSpace, Grid, width()-Grid-BorderSpace,
                          height()-2*Grid);
    p.begin(&pm);
    // ----- load the background pattern, or clear the painter:
    p.setPen(darkBlue);
    p.setBrush(defaultBGColor);
    p.drawRect(0, 0, width(), height());
    switch(bgStyle)
    {
    case Tiled:
        p.drawTiledPixmap(1, 1, width()-2, height()-2, background);
        break;
    case Bordered:
        p.drawTiledPixmap(1, 1,
                          QMIN(width()-2,
                               background.width()),
                          height()-2, background);
        break;
    case None: // no BG image defined for this entry:
    default:
        if(useDefaultBGImage)
        {
            p.drawTiledPixmap(1, 1, width()-2, height()-2, defaultBGImage);
        }
        break;
    };
    p.setViewport(entryArea);
    epainter->setShowAddresses(actionShowAddresses->isChecked());
    epainter->setShowEmails(actionShowEmails->isChecked());
    epainter->setShowTelephones(actionShowTelephones->isChecked());
    epainter->setShowURLs(actionShowURLs->isChecked());
    epainter->printEntry(current,
                         QRect(0, 0, entryArea.width(), entryArea.height()),
                         &p);
    p.end();
    bitBlt(this, 0, 0, &pm);
}

void KABDetailedView::mouseMoveEvent(QMouseEvent *e)
{
    QPoint bias(Grid, Grid);
    int rc;
    bool hit=false;
    // -----
    if((rc=epainter->hitsEmail(e->pos()-bias))!=-1)
    {
        //       kdDebug() << "KABDetailedView::mouseMoveEvent: "
        // << "pointer touches email "
        // 		<< rc << endl;
        hit=true;
    }
    else
        if((rc=epainter->hitsURLs(e->pos()-bias))!=-1)
        {
            // 	kdDebug() << "KABDetailedView::mouseMoveEvent: "
            // << "pointer touches URL "
            // 		  << rc << endl;
            hit=true;
        }
        else
            if((rc=epainter->hitsTelephones(e->pos()-bias))!=-1)
            {
                // 	  kdDebug() << "KABDetailedView::mouseMoveEvent: "
                // << "pointer touches telephone no. "
                // 		    << rc << endl;
                hit=true;
            }
            else
                if((rc=epainter->hitsTalkAddresses(e->pos()-bias))!=-1)
                {
                    // 	    kdDebug() << "KABDetailedView::mouseMoveEvent: "
                    // << "pointer touches talk address "
                    // 		      << rc << endl;
                    hit=true;
                }
    if(hit)
    {
        if(cursor().shape()!=PointingHandCursor)
	{
            setCursor(PointingHandCursor);
	}
    } else {
        if(cursor().shape()!=ArrowCursor)
	{
            setCursor(ArrowCursor);
	}
    }
}

void KABDetailedView::mousePressEvent(QMouseEvent *e)
{
    QPopupMenu menu(this);
    QPopupMenu *menuBG=new QPopupMenu(&menu);
    menuBorderedBG=new QPopupMenu(&menu);
    menuTiledBG=new QPopupMenu(&menu);
    menu.insertItem(i18n("Select Background"), menuBG);
    menuBG->insertItem(i18n("Bordered Backgrounds"), menuBorderedBG);
    menuBG->insertItem(i18n("Tiled Backgrounds"), menuTiledBG);
    menu.insertSeparator();
    QPoint point=e->pos()-QPoint(Grid, Grid);
    int rc;
    QStringList dirsBorderedBG, dirsTiledBG;
    QDir dir;
    // -----
    switch(e->button())
    {
    case QMouseEvent::RightButton:
        if(m_ro)
        {
            menu.setItemEnabled(menu.idAt(0), false);
        } else {
            // @todo: settings need to be saved in view options
            // ----- load background options:
            dirsBorderedBG=KGlobal::instance()->dirs()->findDirs
                           ("data", BorderedBGDir);
            if(dirsBorderedBG.count()>0)
            {
                dir.setPath(dirsBorderedBG[0]);
                borders=dir.entryList(QDir::Files);
                for(unsigned count=0; count<borders.count(); ++count)
                {
                    menuBorderedBG->insertItem(borders[count], count);
                }
                connect(menuBorderedBG, SIGNAL(activated(int)),
                        this, SLOT(slotBorderedBGSelected(int)));
            } else {
                menuBG->setItemEnabled(menuBG->idAt(0), false);
            }
            dirsTiledBG=KGlobal::instance()->dirs()->findDirs
                        ("data", TiledBGDir);
            if(dirsTiledBG.count()>0)
            {
                dir.setPath(dirsTiledBG[0]);
                tiles=dir.entryList(QDir::Files);
                for(unsigned count=0; count<tiles.count(); ++count)
                {
                    menuTiledBG->insertItem(tiles[count], count);
                }
                connect(menuTiledBG, SIGNAL(activated(int)),
                        this, SLOT(slotTiledBGSelected(int)));
            } else {
                menuBG->setItemEnabled(menuBG->idAt(1), false);
            }
        }
        // ----- done, plug actions:
        actionShowAddresses->plug(&menu);
        actionShowEmails->plug(&menu);
        actionShowTelephones->plug(&menu);
        actionShowURLs->plug(&menu);
        // ----- done, execute menu:
        menu.exec(e->globalPos());
        break;
    case QMouseEvent::LeftButton:
        // ----- find whether the pointer touches an email address, URL,
        // talk address or telephone number:
        if((rc=epainter->hitsEmail(point))!=-1)
	{
            emit(sendEmail(current.emails()[rc]));
            break;
	}
        if((rc=epainter->hitsURLs(point))!=-1)
	{
            emit(browse(current.url().prettyURL()));
            break;
	}
        if((rc=epainter->hitsTelephones(point))!=-1)
	{
            /* emit(call(current.telephone.at(2*rc),
               current.telephone.at(2*rc+1))); */
            kdDebug() << "KABDetailedView::mousePressEvent: ni (calling)."
                      << endl;
            break;
	}
        if((rc=epainter->hitsTalkAddresses(point))!=-1)
	{
            /* emit(talk(current.talk.at(rc))); */
            kdDebug() << "KABDetailedView::mousePressEvent: ni (invoking ktalk)."
                      << endl;
            break;
	}
        kdDebug() << "KABDetailedView::mousePressEvent: not over active item."
                  << endl;
        break;
    default:
        break;
    };
    menuBorderedBG=0;
    menuTiledBG=0;
}

void KABDetailedView::setEntry(const KABC::Addressee& e)
{

    BackgroundStyle style=None;
    QString dir, file, styleSetting;
    KABBasicLook::setEntry(e);
    // @todo: preload path and styleSetting with possible preference values
    // ----- load the background image:
    styleSetting=current.custom("kab", "BackgroundStyle");
    style=(BackgroundStyle)styleSetting.toInt();
    file=current.custom("kab", "BackgroundImage");
    if(!file.isEmpty())
    {
        switch(style)
        {
        case Tiled:
            dir=TiledBGDir;
            break;
        case Bordered:
            dir=BorderedBGDir;
            break;
        case None:
        default:
            break;
        }
        // ----- path is located under KDEDIR/share:
        QStringList dirs;
        dirs=KGlobal::instance()->dirs()->findDirs("data", dir);
        bgStyle=None;
        if(!dirs.isEmpty())
        {
            unsigned count;
            for(count=0; count<dirs.count(); ++count)
            {
                QDir folder;
                folder.setPath(dirs[count]);
                file=folder.absPath()+"/"+file;
                if(getBackground(file, background))
                {
                    bgStyle=style;
                    break;
                }
            }
            if(count==dirs.count())
            {   // not found:
                kdDebug() << "KABDetailedView::setEntry: " << file
                          << " not locatable." << endl;
            }
        }
    } else { // no background here:
        bgStyle=None;
        background.resize(0,0);
    }
    repaint(false);
}

void KABDetailedView::slotBorderedBGSelected(int index)
{
    if(index>=0 && (unsigned)index<borders.count() && !readonly())
    {
        // ----- get the selection and make it a full path:
        QString path=borders[index];
        bgStyle=Bordered;
        current.insertCustom("kab", "BackgroundStyle", QString().setNum(bgStyle));
        current.insertCustom("kab", "BackgroundImage", path);
        setEntry(current);
        emit(entryChanged());
    }
}

void KABDetailedView::slotTiledBGSelected(int index)
{
    if(index>=0 && (unsigned)index<tiles.count() && !readonly())
    {
        QString path=tiles[index];
        bgStyle=Tiled;
        current.insertCustom("kab", "BackgroundStyle", QString().setNum(bgStyle));
        current.insertCustom("kab", "BackgroundImage", path);
        setEntry(current);
        emit(entryChanged());
    }
}

void KABDetailedView::setReadonly(bool state)
{
    KABBasicLook::setReadonly(state);
    repaint(false);
}

void KABDetailedView::configure(KConfig *config)
{
    QFont general=KGlobalSettings::generalFont();
    QFont fixed=KGlobalSettings::fixedFont();
    QString gfont=general.family();
    QString ffont=fixed.family();
    int gpointsize=general.pixelSize(); // it is a joke
    int fpointsize=fixed.pixelSize();
    // -----
    bool useBGImage=true;
    config->setGroup(ConfigView);
    // ----- load the default background image:
    QString bgImage;
    useDefaultBGImage=config->readBoolEntry
                      (ConfigView_UseDefaultBackground, useBGImage);
    defaultBGColor=config->readColorEntry
                   (ConfigView_DefaultBackgroundColor, &white);
    bgImage=config->readEntry
            (ConfigView_DefaultBackgroundImage,
             "konqueror/tiles/kenwimer.png");
    if(useDefaultBGImage)
    {
        unsigned count=0;
        QStringList dirs=KGlobal::instance()->dirs()->findDirs("data", "/");
        if(!dirs.isEmpty())
        {
            for(count=0; count<dirs.count(); ++count)
            {
                // kdDebug() << "Trying " << dirs[count] + "/" + bgImage << endl;
                if(getBackground(dirs[count] + "/" + bgImage, defaultBGImage))
                {
                    break;
                }
            }
        }
        if(count==dirs.count())
        {
            useDefaultBGImage=getBackground(bgImage, defaultBGImage);
            if(!useDefaultBGImage)
            {
                kdDebug() << "KABDetailedView::configure: "
                          << "default BG image selected, but could not be loaded."
                          << endl;
            }
        }
    }
//     kdDebug() << "KABDetailedView::configure: "
//               << "default BG color is " << defaultBGColor.name()
//               << ", default BG image is " << bgImage
//               << ", BG image is "
//               << (useDefaultBGImage ? "in use." : "not used.")
//               << endl;
    // ----- default background color:
    defaultBGColor=config->readColorEntry
                   (ConfigView_DefaultBackgroundColor, &white);
    // -----
    headlineBGColor=config->readColorEntry
                    (ConfigView_HeadlineBGColor, &darkBlue);
    headlineTextColor=config->readColorEntry
                      (ConfigView_HeadlineTextColor, &yellow);
    useHeadlineBGColor=config->readBoolEntry(ConfigView_UseHeadlineBGColor, true);
    // -----
    if(epainter!=0)
    {
        delete epainter;
        epainter=0;
    }
    epainter=new KABEntryPainter
             (Qt::black, headlineTextColor,
              useHeadlineBGColor, headlineBGColor,
              QFont(gfont, gpointsize+4, QFont::Bold, true),
              QFont(gfont, gpointsize+2, QFont::Bold, true),
              QFont(gfont, gpointsize, QFont::Normal, false),
              QFont(ffont, fpointsize, QFont::Normal, false),
              QFont(gfont, gpointsize, QFont::Normal, false));
}

#include "look_details.moc"
<commit_msg><commit_after>/* -*- C++ -*-
   This file implements the business card look.

   the KDE addressbook

   $ Author: Mirko Boehm $
   $ Copyright: (C) 1996-2001, Mirko Boehm $
   $ Contact: mirko@kde.org
   http://www.kde.org $
   $ License: GPL with the following explicit clarification:
   This code may be linked against any version of the Qt toolkit
   from Troll Tech, Norway. $

   $Revision$
*/

#include "look_details.h"
#include <qdir.h>
#include <qcursor.h>
#include "kabentrypainter.h"
#include "global.h"
#include <kdebug.h>
#include <kglobalsettings.h>
#include <kinstance.h>
#include <kstandarddirs.h>
#include <klocale.h>
#include <kconfig.h>
#include <qpainter.h>
#include <qpopupmenu.h>

#define GRID 5

const QString KABDetailedView::BorderedBGDir="kab3part/backgrounds/bordered/";
const QString KABDetailedView::TiledBGDir="kab3part/backgrounds/tiled/";

KABDetailedView::KABDetailedView(QWidget* parent, const char* name)
    : KABBasicLook(parent, name),
      epainter(0),
      bgStyle(None),
      defaultBGColor(white),
      headlineBGColor(darkBlue),
      headlineTextColor(yellow),
      Grid(3),
      menuBorderedBG(0),
      menuTiledBG(0)
{
    KToggleAction** actions[]= {
        &actionShowAddresses,
        &actionShowEmails,
        &actionShowTelephones,
        &actionShowURLs
    };
    QString texts[]= {
        i18n("Show Postal Addresses"),
        i18n("Show Email Addresses"),
        i18n("Show Telephone Numbers"),
        i18n("Show Web Pages (URLs)")
    };
    QFont general=KGlobalSettings::generalFont();
    QFont fixed=KGlobalSettings::fixedFont();
    QString gfont=general.family();
    QString ffont=fixed.family();
    int gpointsize=general.pixelSize();
    if ( gpointsize == -1 )
      gpointsize = general.pointSize();

    int fpointsize=fixed.pixelSize();
    if ( fpointsize == -1 )
      fpointsize = fixed.pointSize();

    epainter=new KABEntryPainter
             (Qt::black, headlineTextColor,
              useHeadlineBGColor, headlineBGColor,
              QFont(gfont, gpointsize+4, QFont::Bold, true),
              QFont(gfont, gpointsize+2, QFont::Bold, true),
              QFont(gfont, gpointsize, QFont::Normal, false),
              QFont(ffont, fpointsize, QFont::Normal, false),
              QFont(gfont, gpointsize, QFont::Normal, false));
    const int Size=sizeof(actions)/sizeof(actions[0]);
    // ----- create some actions:
    for(int count=0; count<Size; ++count)
    {
        *actions[count]=new KToggleAction(texts[count]);
        (*actions[count])->setChecked(true);
    }
    // ----- we would like to track mouse movement:
    setMouseTracking(true);
    /*
    // ----- find preferred size:
    // Since the detailed look does not prefer a size it uses the
    // preferred size of the editing look to avoid flickering resizing.
    KABEditLook *editlook=new KABEditLook(api, this);
    setMinimumSize(editlook->minimumSizeHint());
    delete editlook;
    */
}

KABDetailedView::~KABDetailedView()
{
    if(epainter!=0) delete epainter;
}

bool KABDetailedView::getBackground(QString path, QPixmap& image)
{
    QMap<QString, QPixmap>::iterator pos;
    pos=backgrounds.find(path);
    if(pos==backgrounds.end())
    { // the image has not been loaded previously
        if(image.load(path))
	{
            backgrounds[path]=image;
            return true;
	} else {
            return false;
	}
    } else {
        // image found in cache
        image=pos.data();
        return true;
    }
}

void KABDetailedView::paintEvent(QPaintEvent*)
{
    const int BorderSpace=Grid;
    QPixmap pm(width(), height());
    QPainter p;
    QRect entryArea=QRect(BorderSpace, Grid, width()-Grid-BorderSpace,
                          height()-2*Grid);
    p.begin(&pm);
    // ----- load the background pattern, or clear the painter:
    p.setPen(darkBlue);
    p.setBrush(defaultBGColor);
    p.drawRect(0, 0, width(), height());
    switch(bgStyle)
    {
    case Tiled:
        p.drawTiledPixmap(1, 1, width()-2, height()-2, background);
        break;
    case Bordered:
        p.drawTiledPixmap(1, 1,
                          QMIN(width()-2,
                               background.width()),
                          height()-2, background);
        break;
    case None: // no BG image defined for this entry:
    default:
        if(useDefaultBGImage)
        {
            p.drawTiledPixmap(1, 1, width()-2, height()-2, defaultBGImage);
        }
        break;
    };
    p.setViewport(entryArea);
    epainter->setShowAddresses(actionShowAddresses->isChecked());
    epainter->setShowEmails(actionShowEmails->isChecked());
    epainter->setShowTelephones(actionShowTelephones->isChecked());
    epainter->setShowURLs(actionShowURLs->isChecked());
    epainter->printEntry(current,
                         QRect(0, 0, entryArea.width(), entryArea.height()),
                         &p);
    p.end();
    bitBlt(this, 0, 0, &pm);
}

void KABDetailedView::mouseMoveEvent(QMouseEvent *e)
{
    QPoint bias(Grid, Grid);
    int rc;
    bool hit=false;
    // -----
    if((rc=epainter->hitsEmail(e->pos()-bias))!=-1)
    {
        //       kdDebug() << "KABDetailedView::mouseMoveEvent: "
        // << "pointer touches email "
        // 		<< rc << endl;
        hit=true;
    }
    else
        if((rc=epainter->hitsURLs(e->pos()-bias))!=-1)
        {
            // 	kdDebug() << "KABDetailedView::mouseMoveEvent: "
            // << "pointer touches URL "
            // 		  << rc << endl;
            hit=true;
        }
        else
            if((rc=epainter->hitsTelephones(e->pos()-bias))!=-1)
            {
                // 	  kdDebug() << "KABDetailedView::mouseMoveEvent: "
                // << "pointer touches telephone no. "
                // 		    << rc << endl;
                hit=true;
            }
            else
                if((rc=epainter->hitsTalkAddresses(e->pos()-bias))!=-1)
                {
                    // 	    kdDebug() << "KABDetailedView::mouseMoveEvent: "
                    // << "pointer touches talk address "
                    // 		      << rc << endl;
                    hit=true;
                }
    if(hit)
    {
        if(cursor().shape()!=PointingHandCursor)
	{
            setCursor(PointingHandCursor);
	}
    } else {
        if(cursor().shape()!=ArrowCursor)
	{
            setCursor(ArrowCursor);
	}
    }
}

void KABDetailedView::mousePressEvent(QMouseEvent *e)
{
    QPopupMenu menu(this);
    QPopupMenu *menuBG=new QPopupMenu(&menu);
    menuBorderedBG=new QPopupMenu(&menu);
    menuTiledBG=new QPopupMenu(&menu);
    menu.insertItem(i18n("Select Background"), menuBG);
    menuBG->insertItem(i18n("Bordered Backgrounds"), menuBorderedBG);
    menuBG->insertItem(i18n("Tiled Backgrounds"), menuTiledBG);
    menu.insertSeparator();
    QPoint point=e->pos()-QPoint(Grid, Grid);
    int rc;
    QStringList dirsBorderedBG, dirsTiledBG;
    QDir dir;
    // -----
    switch(e->button())
    {
    case QMouseEvent::RightButton:
        if(m_ro)
        {
            menu.setItemEnabled(menu.idAt(0), false);
        } else {
            // @todo: settings need to be saved in view options
            // ----- load background options:
            dirsBorderedBG=KGlobal::instance()->dirs()->findDirs
                           ("data", BorderedBGDir);
            if(dirsBorderedBG.count()>0)
            {
                dir.setPath(dirsBorderedBG[0]);
                borders=dir.entryList(QDir::Files);
                for(unsigned count=0; count<borders.count(); ++count)
                {
                    menuBorderedBG->insertItem(borders[count], count);
                }
                connect(menuBorderedBG, SIGNAL(activated(int)),
                        this, SLOT(slotBorderedBGSelected(int)));
            } else {
                menuBG->setItemEnabled(menuBG->idAt(0), false);
            }
            dirsTiledBG=KGlobal::instance()->dirs()->findDirs
                        ("data", TiledBGDir);
            if(dirsTiledBG.count()>0)
            {
                dir.setPath(dirsTiledBG[0]);
                tiles=dir.entryList(QDir::Files);
                for(unsigned count=0; count<tiles.count(); ++count)
                {
                    menuTiledBG->insertItem(tiles[count], count);
                }
                connect(menuTiledBG, SIGNAL(activated(int)),
                        this, SLOT(slotTiledBGSelected(int)));
            } else {
                menuBG->setItemEnabled(menuBG->idAt(1), false);
            }
        }
        // ----- done, plug actions:
        actionShowAddresses->plug(&menu);
        actionShowEmails->plug(&menu);
        actionShowTelephones->plug(&menu);
        actionShowURLs->plug(&menu);
        // ----- done, execute menu:
        menu.exec(e->globalPos());
        break;
    case QMouseEvent::LeftButton:
        // ----- find whether the pointer touches an email address, URL,
        // talk address or telephone number:
        if((rc=epainter->hitsEmail(point))!=-1)
	{
            emit(sendEmail(current.emails()[rc]));
            break;
	}
        if((rc=epainter->hitsURLs(point))!=-1)
	{
            emit(browse(current.url().prettyURL()));
            break;
	}
        if((rc=epainter->hitsTelephones(point))!=-1)
	{
            /* emit(call(current.telephone.at(2*rc),
               current.telephone.at(2*rc+1))); */
            kdDebug() << "KABDetailedView::mousePressEvent: ni (calling)."
                      << endl;
            break;
	}
        if((rc=epainter->hitsTalkAddresses(point))!=-1)
	{
            /* emit(talk(current.talk.at(rc))); */
            kdDebug() << "KABDetailedView::mousePressEvent: ni (invoking ktalk)."
                      << endl;
            break;
	}
        kdDebug() << "KABDetailedView::mousePressEvent: not over active item."
                  << endl;
        break;
    default:
        break;
    };
    menuBorderedBG=0;
    menuTiledBG=0;
}

void KABDetailedView::setEntry(const KABC::Addressee& e)
{

    BackgroundStyle style=None;
    QString dir, file, styleSetting;
    KABBasicLook::setEntry(e);
    // @todo: preload path and styleSetting with possible preference values
    // ----- load the background image:
    styleSetting=current.custom("kab", "BackgroundStyle");
    style=(BackgroundStyle)styleSetting.toInt();
    file=current.custom("kab", "BackgroundImage");
    if(!file.isEmpty())
    {
        switch(style)
        {
        case Tiled:
            dir=TiledBGDir;
            break;
        case Bordered:
            dir=BorderedBGDir;
            break;
        case None:
        default:
            break;
        }
        // ----- path is located under KDEDIR/share:
        QStringList dirs;
        dirs=KGlobal::instance()->dirs()->findDirs("data", dir);
        bgStyle=None;
        if(!dirs.isEmpty())
        {
            unsigned count;
            for(count=0; count<dirs.count(); ++count)
            {
                QDir folder;
                folder.setPath(dirs[count]);
                file=folder.absPath()+"/"+file;
                if(getBackground(file, background))
                {
                    bgStyle=style;
                    break;
                }
            }
            if(count==dirs.count())
            {   // not found:
                kdDebug() << "KABDetailedView::setEntry: " << file
                          << " not locatable." << endl;
            }
        }
    } else { // no background here:
        bgStyle=None;
        background.resize(0,0);
    }
    repaint(false);
}

void KABDetailedView::slotBorderedBGSelected(int index)
{
    if(index>=0 && (unsigned)index<borders.count() && !readonly())
    {
        // ----- get the selection and make it a full path:
        QString path=borders[index];
        bgStyle=Bordered;
        current.insertCustom("kab", "BackgroundStyle", QString().setNum(bgStyle));
        current.insertCustom("kab", "BackgroundImage", path);
        setEntry(current);
        emit(entryChanged());
    }
}

void KABDetailedView::slotTiledBGSelected(int index)
{
    if(index>=0 && (unsigned)index<tiles.count() && !readonly())
    {
        QString path=tiles[index];
        bgStyle=Tiled;
        current.insertCustom("kab", "BackgroundStyle", QString().setNum(bgStyle));
        current.insertCustom("kab", "BackgroundImage", path);
        setEntry(current);
        emit(entryChanged());
    }
}

void KABDetailedView::setReadonly(bool state)
{
    KABBasicLook::setReadonly(state);
    repaint(false);
}

void KABDetailedView::configure(KConfig *config)
{
    QFont general=KGlobalSettings::generalFont();
    QFont fixed=KGlobalSettings::fixedFont();
    QString gfont=general.family();
    QString ffont=fixed.family();

    int gpointsize=general.pixelSize();
    if ( gpointsize == -1 )
      gpointsize = general.pointSize();

    int fpointsize=fixed.pixelSize();
    if ( fpointsize == -1 )
      fpointsize = fixed.pointSize();

    // -----
    bool useBGImage=true;
    config->setGroup(ConfigView);
    // ----- load the default background image:
    QString bgImage;
    useDefaultBGImage=config->readBoolEntry
                      (ConfigView_UseDefaultBackground, useBGImage);
    defaultBGColor=config->readColorEntry
                   (ConfigView_DefaultBackgroundColor, &white);
    bgImage=config->readEntry
            (ConfigView_DefaultBackgroundImage,
             "konqueror/tiles/kenwimer.png");
    if(useDefaultBGImage)
    {
        unsigned count=0;
        QStringList dirs=KGlobal::instance()->dirs()->findDirs("data", "/");
        if(!dirs.isEmpty())
        {
            for(count=0; count<dirs.count(); ++count)
            {
                // kdDebug() << "Trying " << dirs[count] + "/" + bgImage << endl;
                if(getBackground(dirs[count] + "/" + bgImage, defaultBGImage))
                {
                    break;
                }
            }
        }
        if(count==dirs.count())
        {
            useDefaultBGImage=getBackground(bgImage, defaultBGImage);
            if(!useDefaultBGImage)
            {
                kdDebug() << "KABDetailedView::configure: "
                          << "default BG image selected, but could not be loaded."
                          << endl;
            }
        }
    }
//     kdDebug() << "KABDetailedView::configure: "
//               << "default BG color is " << defaultBGColor.name()
//               << ", default BG image is " << bgImage
//               << ", BG image is "
//               << (useDefaultBGImage ? "in use." : "not used.")
//               << endl;
    // ----- default background color:
    defaultBGColor=config->readColorEntry
                   (ConfigView_DefaultBackgroundColor, &white);
    // -----
    headlineBGColor=config->readColorEntry
                    (ConfigView_HeadlineBGColor, &darkBlue);
    headlineTextColor=config->readColorEntry
                      (ConfigView_HeadlineTextColor, &yellow);
    useHeadlineBGColor=config->readBoolEntry(ConfigView_UseHeadlineBGColor, true);
    // -----
    if(epainter!=0)
    {
        delete epainter;
        epainter=0;
    }
    epainter=new KABEntryPainter
             (Qt::black, headlineTextColor,
              useHeadlineBGColor, headlineBGColor,
              QFont(gfont, gpointsize+4, QFont::Bold, true),
              QFont(gfont, gpointsize+2, QFont::Bold, true),
              QFont(gfont, gpointsize, QFont::Normal, false),
              QFont(ffont, fpointsize, QFont::Normal, false),
              QFont(gfont, gpointsize, QFont::Normal, false));
}

#include "look_details.moc"
<|endoftext|>