<commit_before>#include <QMessageBox>
#include "newannotationdialog.h"
#include "ui_newannotationdialog.h"
#include "classesdialog.h"

#include <AnnotatorLib/Commands/NewAnnotation.h>
#include "plugins/pluginloader.h"
#include "controller/commandcontroller.h"

NewAnnotationDialog::NewAnnotationDialog(AnnotatorLib::Session *session,
                                 unsigned long frame_nmb,
                                 AnnotatorLib::Object* selected_obj,
                                 QWidget *parent)
    : QDialog(parent), session(session), frame_nmb(frame_nmb), selected_obj(selected_obj), ui(new Ui::NewAnnotationDialog) {

  ui->setupUi(this);
  if (selected_obj == nullptr || session->getFrame(frame_nmb)->getObject(selected_obj) != nullptr ) {
    ui->radioButtonSelObj->setEnabled(false);
    ui->radioButtonSelObj->setChecked(false);
    ui->radioButtonNewObj->setChecked(true);
    ui->radioButtonNewObj->setEnabled(false);
  }
  if (ui->radioButtonNewObj->isChecked()) {
      this->on_radioButtonNewObj_clicked();
  } else if (ui->radioButtonSelObj->isChecked()) {
      this->on_radioButtonSelObj_clicked();
  }
  ui->frameSpinBox->setValue(frame_nmb);
  reloadClasses();
}

NewAnnotationDialog::~NewAnnotationDialog() { delete ui; }

void NewAnnotationDialog::setDimensions(float x, float y, float w, float h) {
  this->x = x;
  this->y = y;
  this->w = w;
  this->h = h;
  ui->positionValue->setText(QString::number(w) + " x " +
                             QString::number(h) + " @ " +
                             QString::number(x) + " | " +
                             QString::number(y));
}

void NewAnnotationDialog::createObject() {

  AnnotatorLib::Class * selClass = this->session->getClass(ui->objectClassComboBox->currentText().toStdString());
  if(selClass == nullptr){
      (void) QMessageBox::information(this, tr("Error"),
                                                          tr("No such class registered."), QMessageBox::Ok);
      return;
  }

  AnnotatorLib::Frame *frame = session->getFrame(this->frame_nmb);
  unsigned long id = (unsigned long)ui->objectIdLineEdit->text().toULong();

  AnnotatorLib::Commands::NewAnnotation *nA;
  if (this->ui->radioButtonNewObj->isChecked()) {
    nA = new AnnotatorLib::Commands::NewAnnotation(
            id, selClass, frame, x, y, w, h, this->session, false);
  } else {
    nA = new AnnotatorLib::Commands::NewAnnotation(
              session->getObject(id), frame, x, y, w, h, this->session, false);
  }
  CommandController::instance()->execute(nA);

  Annotator::Plugin *plugin =
      Annotator::PluginLoader::getInstance().getCurrent();
  plugin->setObject(nA->getAnnotation()->getObject());
  plugin->setLastAnnotation(nA->getAnnotation());
}

void NewAnnotationDialog::reloadClasses()
{
    ui->objectClassComboBox->clear();
    for(AnnotatorLib::Class * c: session->getClasses()){
        ui->objectClassComboBox->addItem(QString::fromStdString(c->getName()));
    }
}

void NewAnnotationDialog::done(int r) {

  if(QDialog::Accepted == r) {
    if(!checkValues()) {
      return;
    }
    createObject();
  }
  QDialog::done(r);
}

bool NewAnnotationDialog::checkValues() {

  if (ui->objectIdLineEdit->text().isEmpty()) {
    (void) QMessageBox::information(this, tr("No ID"),
        tr("Please supply an ID."), QMessageBox::Ok);
    return false;
  }
  if (ui->objectClassComboBox->currentText().isEmpty()) {
    (void) QMessageBox::information(this, tr("No Name"),
        tr("Please supply a class for the object."), QMessageBox::Ok);
    return false;
  }
  return true;
}

void NewAnnotationDialog::on_editClassesButton_clicked()
{
    ClassesDialog dialog(session, this);
    dialog.exec();
    reloadClasses();
}

void NewAnnotationDialog::on_radioButtonSelObj_clicked()
{
    ui->objectIdLineEdit->setText(QString::number(this->selected_obj->getId()));
    ui->editClassesButton->hide();
    ui->objectClassComboBox->setEnabled(false);
}

void NewAnnotationDialog::on_radioButtonNewObj_clicked()
{
    ui->objectIdLineEdit->setText(QString::number(AnnotatorLib::Object::genId()));
    ui->editClassesButton->show();
    ui->objectClassComboBox->setEnabled(true);
}

<commit_msg>rename<commit_after>#include <QMessageBox>
#include "newannotationdialog.h"
#include "ui_newannotationdialog.h"
#include "classesdialog.h"

#include <AnnotatorLib/Commands/NewAnnotation.h>
#include "plugins/pluginloader.h"
#include "controller/commandcontroller.h"

NewAnnotationDialog::NewAnnotationDialog(AnnotatorLib::Session *session,
                                 unsigned long frame_nmb,
                                 AnnotatorLib::Object* selected_obj,
                                 QWidget *parent)
    : QDialog(parent), session(session), frame_nmb(frame_nmb), selected_obj(selected_obj), ui(new Ui::NewAnnotationDialog) {

  ui->setupUi(this);
  if (selected_obj == nullptr || session->getFrame(frame_nmb)->getObject(selected_obj) != nullptr ) {
    ui->radioButtonSelObj->setEnabled(false);
    ui->radioButtonSelObj->setChecked(false);
    ui->radioButtonNewObj->setChecked(true);
    ui->radioButtonNewObj->setEnabled(false);
  }
  if (ui->radioButtonNewObj->isChecked()) {
      this->on_radioButtonNewObj_clicked();
  } else if (ui->radioButtonSelObj->isChecked()) {
      this->on_radioButtonSelObj_clicked();
  }
  ui->frameSpinBox->setValue(frame_nmb);
  reloadClasses();
}

NewAnnotationDialog::~NewAnnotationDialog() { delete ui; }

void NewAnnotationDialog::setDimensions(float x, float y, float w, float h) {
  this->x = x;
  this->y = y;
  this->w = w;
  this->h = h;
  ui->positionValue->setText(QString::number(w) + " x " +
                             QString::number(h) + " @ " +
                             QString::number(x) + " | " +
                             QString::number(y));
}

void NewAnnotationDialog::createAnnotation() {

  AnnotatorLib::Class * selClass = this->session->getClass(ui->objectClassComboBox->currentText().toStdString());
  if(selClass == nullptr){
      (void) QMessageBox::information(this, tr("Error"),
                                                          tr("No such class registered."), QMessageBox::Ok);
      return;
  }

  AnnotatorLib::Frame *frame = session->getFrame(this->frame_nmb);
  unsigned long id = (unsigned long)ui->objectIdLineEdit->text().toULong();

  AnnotatorLib::Commands::NewAnnotation *nA;
  if (this->ui->radioButtonNewObj->isChecked()) {
    nA = new AnnotatorLib::Commands::NewAnnotation(
            id, selClass, frame, x, y, w, h, this->session, false);
  } else {
    nA = new AnnotatorLib::Commands::NewAnnotation(
              session->getObject(id), frame, x, y, w, h, this->session, false);
  }
  CommandController::instance()->execute(nA);

  Annotator::Plugin *plugin =
      Annotator::PluginLoader::getInstance().getCurrent();
  plugin->setObject(nA->getAnnotation()->getObject());
  plugin->setLastAnnotation(nA->getAnnotation());
}

void NewAnnotationDialog::reloadClasses()
{
    ui->objectClassComboBox->clear();
    for(AnnotatorLib::Class * c: session->getClasses()){
        ui->objectClassComboBox->addItem(QString::fromStdString(c->getName()));
    }
}

void NewAnnotationDialog::done(int r) {

  if(QDialog::Accepted == r) {
    if(!checkValues()) {
      return;
    }
    createAnnotation();
  }
  QDialog::done(r);
}

bool NewAnnotationDialog::checkValues() {

  if (ui->objectIdLineEdit->text().isEmpty()) {
    (void) QMessageBox::information(this, tr("No ID"),
        tr("Please supply an ID."), QMessageBox::Ok);
    return false;
  }
  if (ui->objectClassComboBox->currentText().isEmpty()) {
    (void) QMessageBox::information(this, tr("No Name"),
        tr("Please supply a class for the object."), QMessageBox::Ok);
    return false;
  }
  return true;
}

void NewAnnotationDialog::on_editClassesButton_clicked()
{
    ClassesDialog dialog(session, this);
    dialog.exec();
    reloadClasses();
}

void NewAnnotationDialog::on_radioButtonSelObj_clicked()
{
    ui->objectIdLineEdit->setText(QString::number(this->selected_obj->getId()));
    ui->editClassesButton->hide();
    ui->objectClassComboBox->setEnabled(false);
}

void NewAnnotationDialog::on_radioButtonNewObj_clicked()
{
    ui->objectIdLineEdit->setText(QString::number(AnnotatorLib::Object::genId()));
    ui->editClassesButton->show();
    ui->objectClassComboBox->setEnabled(true);
}

<|endoftext|>


<commit_before>#ifndef RAPIDXML_PRINT_HPP_INCLUDED
#define RAPIDXML_PRINT_HPP_INCLUDED

// Copyright (C) 2006, 2009 Marcin Kalicinski
// Version 1.13
// Revision $DateTime: 2009/05/13 01:46:17 $
//! \file rapidxml_print.hpp This file contains rapidxml printer implementation

#include "rapidxml.hpp"

// Only include streams if not disabled
#ifndef RAPIDXML_NO_STREAMS
    #include <ostream>
    #include <iterator>
#endif

namespace rapidxml
{

    ///////////////////////////////////////////////////////////////////////
    // Printing flags

    const int print_no_indenting = 0x1;   //!< Printer flag instructing the printer to suppress indenting of XML. See print() function.

    ///////////////////////////////////////////////////////////////////////
    // Internal

    //! \cond internal
    namespace internal
    {

        ///////////////////////////////////////////////////////////////////////////
        // Internal character operations

        // Copy characters from given range to given output iterator
        template<class OutIt, class Ch>
        inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out)
        {
            while (begin != end)
                *out++ = *begin++;
            return out;
        }

        // Copy characters from given range to given output iterator and expand
        // characters into references (< > ' " &)
        template<class OutIt, class Ch>
        inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out)
        {
            while (begin != end)
            {
                if (*begin == noexpand)
                {
                    *out++ = *begin;    // No expansion, copy character
                }
                else
                {
                    switch (*begin)
                    {
                    case Ch('<'):
                        *out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';');
                        break;
                    case Ch('>'):
                        *out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';');
                        break;
                    case Ch('\''):
                        *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';');
                        break;
                    case Ch('"'):
                        *out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';');
                        break;
                    case Ch('&'):
                        *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';');
                        break;
                    default:
                        *out++ = *begin;    // No expansion, copy character
                    }
                }
                ++begin;    // Step to next character
            }
            return out;
        }

        // Fill given output iterator with repetitions of the same character
        template<class OutIt, class Ch>
        inline OutIt fill_chars(OutIt out, int n, Ch ch)
        {
            for (int i = 0; i < n; ++i)
                *out++ = ch;
            return out;
        }

        // Find character
        template<class Ch, Ch ch>
        inline bool find_char(const Ch *begin, const Ch *end)
        {
            while (begin != end)
                if (*begin++ == ch)
                    return true;
            return false;
        }

        ///////////////////////////////////////////////////////////////////////////
        // Internal printing operations

        // Print node
        template<class OutIt, class Ch>
        inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            // Print proper node type
            switch (node->type())
            {

            // Document
            case node_document:
                out = print_children(out, node, flags, indent);
                break;

            // Element
            case node_element:
                out = print_element_node(out, node, flags, indent);
                break;

            // Data
            case node_data:
                out = print_data_node(out, node, flags, indent);
                break;

            // CDATA
            case node_cdata:
                out = print_cdata_node(out, node, flags, indent);
                break;

            // Declaration
            case node_declaration:
                out = print_declaration_node(out, node, flags, indent);
                break;

            // Comment
            case node_comment:
                out = print_comment_node(out, node, flags, indent);
                break;

            // Doctype
            case node_doctype:
                out = print_doctype_node(out, node, flags, indent);
                break;

            // Pi
            case node_pi:
                out = print_pi_node(out, node, flags, indent);
                break;

                // Unknown
            default:
                assert(0);
                break;
            }

            // If indenting not disabled, add line break after node
            if (!(flags & print_no_indenting))
                *out = Ch('\n'), ++out;

            // Return modified iterator
            return out;
        }

        // Print children of the node
        template<class OutIt, class Ch>
        inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            for (xml_node<Ch> *child = node->first_node(); child; child = child->next_sibling())
                out = print_node(out, child, flags, indent);
            return out;
        }

        // Print attributes of the node
        template<class OutIt, class Ch>
        inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int flags)
        {
            for (xml_attribute<Ch> *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute())
            {
                if (attribute->name() && attribute->value())
                {
                    // Print attribute name
                    *out = Ch(' '), ++out;
                    out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out);
                    *out = Ch('='), ++out;
                    // Print attribute value using appropriate quote type
                    if (find_char<Ch, Ch('"')>(attribute->value(), attribute->value() + attribute->value_size()))
                    {
                        *out = Ch('\''), ++out;
                        out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out);
                        *out = Ch('\''), ++out;
                    }
                    else
                    {
                        *out = Ch('"'), ++out;
                        out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out);
                        *out = Ch('"'), ++out;
                    }
                }
            }
            return out;
        }

        // Print data node
        template<class OutIt, class Ch>
        inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            assert(node->type() == node_data);
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
            return out;
        }

        // Print data node
        template<class OutIt, class Ch>
        inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            assert(node->type() == node_cdata);
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            *out = Ch('<'); ++out;
            *out = Ch('!'); ++out;
            *out = Ch('['); ++out;
            *out = Ch('C'); ++out;
            *out = Ch('D'); ++out;
            *out = Ch('A'); ++out;
            *out = Ch('T'); ++out;
            *out = Ch('A'); ++out;
            *out = Ch('['); ++out;
            out = copy_chars(node->value(), node->value() + node->value_size(), out);
            *out = Ch(']'); ++out;
            *out = Ch(']'); ++out;
            *out = Ch('>'); ++out;
            return out;
        }

        // Print element node
        template<class OutIt, class Ch>
        inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            assert(node->type() == node_element);

            // Print element name and attributes, if any
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            *out = Ch('<'), ++out;
            out = copy_chars(node->name(), node->name() + node->name_size(), out);
            out = print_attributes(out, node, flags);

            // If node is childless
            if (node->value_size() == 0 && !node->first_node())
            {
                // Print childless node tag ending
                *out = Ch('/'), ++out;
                *out = Ch('>'), ++out;
            }
            else
            {
                // Print normal node tag ending
                *out = Ch('>'), ++out;

                // Test if node contains a single data node only (and no other nodes)
                xml_node<Ch> *child = node->first_node();
                if (!child)
                {
                    // If node has no children, only print its value without indenting
                    out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
                }
                else if (child->next_sibling() == 0 && child->type() == node_data)
                {
                    // If node has a sole data child, only print its value without indenting
                    out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out);
                }
                else
                {
                    // Print all children with full indenting
                    if (!(flags & print_no_indenting))
                        *out = Ch('\n'), ++out;
                    out = print_children(out, node, flags, indent + 1);
                    if (!(flags & print_no_indenting))
                        out = fill_chars(out, indent, Ch('\t'));
                }

                // Print node end
                *out = Ch('<'), ++out;
                *out = Ch('/'), ++out;
                out = copy_chars(node->name(), node->name() + node->name_size(), out);
                *out = Ch('>'), ++out;
            }
            return out;
        }

        // Print declaration node
        template<class OutIt, class Ch>
        inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            // Print declaration start
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            *out = Ch('<'), ++out;
            *out = Ch('?'), ++out;
            *out = Ch('x'), ++out;
            *out = Ch('m'), ++out;
            *out = Ch('l'), ++out;

            // Print attributes
            out = print_attributes(out, node, flags);

            // Print declaration end
            *out = Ch('?'), ++out;
            *out = Ch('>'), ++out;

            return out;
        }

        // Print comment node
        template<class OutIt, class Ch>
        inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            assert(node->type() == node_comment);
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            *out = Ch('<'), ++out;
            *out = Ch('!'), ++out;
            *out = Ch('-'), ++out;
            *out = Ch('-'), ++out;
            out = copy_chars(node->value(), node->value() + node->value_size(), out);
            *out = Ch('-'), ++out;
            *out = Ch('-'), ++out;
            *out = Ch('>'), ++out;
            return out;
        }

        // Print doctype node
        template<class OutIt, class Ch>
        inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            assert(node->type() == node_doctype);
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            *out = Ch('<'), ++out;
            *out = Ch('!'), ++out;
            *out = Ch('D'), ++out;
            *out = Ch('O'), ++out;
            *out = Ch('C'), ++out;
            *out = Ch('T'), ++out;
            *out = Ch('Y'), ++out;
            *out = Ch('P'), ++out;
            *out = Ch('E'), ++out;
            *out = Ch(' '), ++out;
            out = copy_chars(node->value(), node->value() + node->value_size(), out);
            *out = Ch('>'), ++out;
            return out;
        }

        // Print pi node
        template<class OutIt, class Ch>
        inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            assert(node->type() == node_pi);
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            *out = Ch('<'), ++out;
            *out = Ch('?'), ++out;
            out = copy_chars(node->name(), node->name() + node->name_size(), out);
            *out = Ch(' '), ++out;
            out = copy_chars(node->value(), node->value() + node->value_size(), out);
            *out = Ch('?'), ++out;
            *out = Ch('>'), ++out;
            return out;
        }

    }
    //! \endcond

    ///////////////////////////////////////////////////////////////////////////
    // Printing

    //! Prints XML to given output iterator.
    //! \param out Output iterator to print to.
    //! \param node Node to be printed. Pass xml_document to print entire document.
    //! \param flags Flags controlling how XML is printed.
    //! \return Output iterator pointing to position immediately after last character of printed text.
    template<class OutIt, class Ch>
    inline OutIt print(OutIt out, const xml_node<Ch> &node, int flags = 0)
    {
        return internal::print_node(out, &node, flags, 0);
    }

#ifndef RAPIDXML_NO_STREAMS

    //! Prints XML to given output stream.
    //! \param out Output stream to print to.
    //! \param node Node to be printed. Pass xml_document to print entire document.
    //! \param flags Flags controlling how XML is printed.
    //! \return Output stream.
    template<class Ch>
    inline basic_ostream<Ch> &print(basic_ostream<Ch> &out, const xml_node<Ch> &node, int flags = 0)
    {
        print(ostream_iterator<Ch>(out), node, flags);
        return out;
    }

    //! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process.
    //! \param out Output stream to print to.
    //! \param node Node to be printed.
    //! \return Output stream.
    template<class Ch>
    inline basic_ostream<Ch> &operator <<(basic_ostream<Ch> &out, const xml_node<Ch> &node)
    {
        return print(out, node);
    }

#endif

}

#endif
<commit_msg>Fix for rapidXML print operations.<commit_after>#ifndef RAPIDXML_PRINT_HPP_INCLUDED
#define RAPIDXML_PRINT_HPP_INCLUDED

// Copyright (C) 2006, 2009 Marcin Kalicinski
// Version 1.13
// Revision $DateTime: 2009/05/13 01:46:17 $
//! \file rapidxml_print.hpp This file contains rapidxml printer implementation

#include "rapidxml.hpp"

// Only include streams if not disabled
#ifndef RAPIDXML_NO_STREAMS
    #include <ostream>
    #include <iterator>
#endif

namespace rapidxml
{

    ///////////////////////////////////////////////////////////////////////
    // Printing flags

    const int print_no_indenting = 0x1;   //!< Printer flag instructing the printer to suppress indenting of XML. See print() function.

    ///////////////////////////////////////////////////////////////////////
    // Internal

    //! \cond internal
    namespace internal
    {

        ///////////////////////////////////////////////////////////////////////////
        // Internal character operations

        // Copy characters from given range to given output iterator
        template<class OutIt, class Ch>
        inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out)
        {
            while (begin != end)
                *out++ = *begin++;
            return out;
        }

        // Copy characters from given range to given output iterator and expand
        // characters into references (< > ' " &)
        template<class OutIt, class Ch>
        inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out)
        {
            while (begin != end)
            {
                if (*begin == noexpand)
                {
                    *out++ = *begin;    // No expansion, copy character
                }
                else
                {
                    switch (*begin)
                    {
                    case Ch('<'):
                        *out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';');
                        break;
                    case Ch('>'):
                        *out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';');
                        break;
                    case Ch('\''):
                        *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';');
                        break;
                    case Ch('"'):
                        *out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';');
                        break;
                    case Ch('&'):
                        *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';');
                        break;
                    default:
                        *out++ = *begin;    // No expansion, copy character
                    }
                }
                ++begin;    // Step to next character
            }
            return out;
        }

        // Fill given output iterator with repetitions of the same character
        template<class OutIt, class Ch>
        inline OutIt fill_chars(OutIt out, int n, Ch ch)
        {
            for (int i = 0; i < n; ++i)
                *out++ = ch;
            return out;
        }

        // Find character
        template<class Ch, Ch ch>
        inline bool find_char(const Ch *begin, const Ch *end)
        {
            while (begin != end)
                if (*begin++ == ch)
                    return true;
            return false;
        }

        ///////////////////////////////////////////////////////////////////////////
        // Internal printing operations

			// ADDED BY CRAIG JEFFREY
			// January 20th 2016
			// Fixes name lookup changes noted here https://gcc.gnu.org/gcc-4.7/porting_to.html
			template<class OutIt, class Ch>
			inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent);

			template<class OutIt, class Ch>
			inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int flags);

			template<class OutIt, class Ch>
			inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);

			template<class OutIt, class Ch>
			inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);

			template<class OutIt, class Ch>
			inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);

			template<class OutIt, class Ch>
			inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);

			template<class OutIt, class Ch>
			inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);

			template<class OutIt, class Ch>
			inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);

			template<class OutIt, class Ch>
			inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
			// END OF ADDITION

        // Print node
        template<class OutIt, class Ch>
        inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            // Print proper node type
            switch (node->type())
            {

            // Document
            case node_document:
                out = print_children(out, node, flags, indent);
                break;

            // Element
            case node_element:
                out = print_element_node(out, node, flags, indent);
                break;

            // Data
            case node_data:
                out = print_data_node(out, node, flags, indent);
                break;

            // CDATA
            case node_cdata:
                out = print_cdata_node(out, node, flags, indent);
                break;

            // Declaration
            case node_declaration:
                out = print_declaration_node(out, node, flags, indent);
                break;

            // Comment
            case node_comment:
                out = print_comment_node(out, node, flags, indent);
                break;

            // Doctype
            case node_doctype:
                out = print_doctype_node(out, node, flags, indent);
                break;

            // Pi
            case node_pi:
                out = print_pi_node(out, node, flags, indent);
                break;

                // Unknown
            default:
                assert(0);
                break;
            }

            // If indenting not disabled, add line break after node
            if (!(flags & print_no_indenting))
                *out = Ch('\n'), ++out;

            // Return modified iterator
            return out;
        }

        // Print children of the node
        template<class OutIt, class Ch>
        inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            for (xml_node<Ch> *child = node->first_node(); child; child = child->next_sibling())
                out = print_node(out, child, flags, indent);
            return out;
        }

        // Print attributes of the node
        template<class OutIt, class Ch>
        inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int flags)
        {
            for (xml_attribute<Ch> *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute())
            {
                if (attribute->name() && attribute->value())
                {
                    // Print attribute name
                    *out = Ch(' '), ++out;
                    out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out);
                    *out = Ch('='), ++out;
                    // Print attribute value using appropriate quote type
                    if (find_char<Ch, Ch('"')>(attribute->value(), attribute->value() + attribute->value_size()))
                    {
                        *out = Ch('\''), ++out;
                        out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out);
                        *out = Ch('\''), ++out;
                    }
                    else
                    {
                        *out = Ch('"'), ++out;
                        out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out);
                        *out = Ch('"'), ++out;
                    }
                }
            }
            return out;
        }

        // Print data node
        template<class OutIt, class Ch>
        inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            assert(node->type() == node_data);
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
            return out;
        }

        // Print data node
        template<class OutIt, class Ch>
        inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            assert(node->type() == node_cdata);
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            *out = Ch('<'); ++out;
            *out = Ch('!'); ++out;
            *out = Ch('['); ++out;
            *out = Ch('C'); ++out;
            *out = Ch('D'); ++out;
            *out = Ch('A'); ++out;
            *out = Ch('T'); ++out;
            *out = Ch('A'); ++out;
            *out = Ch('['); ++out;
            out = copy_chars(node->value(), node->value() + node->value_size(), out);
            *out = Ch(']'); ++out;
            *out = Ch(']'); ++out;
            *out = Ch('>'); ++out;
            return out;
        }

        // Print element node
        template<class OutIt, class Ch>
        inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            assert(node->type() == node_element);

            // Print element name and attributes, if any
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            *out = Ch('<'), ++out;
            out = copy_chars(node->name(), node->name() + node->name_size(), out);
            out = print_attributes(out, node, flags);

            // If node is childless
            if (node->value_size() == 0 && !node->first_node())
            {
                // Print childless node tag ending
                *out = Ch('/'), ++out;
                *out = Ch('>'), ++out;
            }
            else
            {
                // Print normal node tag ending
                *out = Ch('>'), ++out;

                // Test if node contains a single data node only (and no other nodes)
                xml_node<Ch> *child = node->first_node();
                if (!child)
                {
                    // If node has no children, only print its value without indenting
                    out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
                }
                else if (child->next_sibling() == 0 && child->type() == node_data)
                {
                    // If node has a sole data child, only print its value without indenting
                    out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out);
                }
                else
                {
                    // Print all children with full indenting
                    if (!(flags & print_no_indenting))
                        *out = Ch('\n'), ++out;
                    out = print_children(out, node, flags, indent + 1);
                    if (!(flags & print_no_indenting))
                        out = fill_chars(out, indent, Ch('\t'));
                }

                // Print node end
                *out = Ch('<'), ++out;
                *out = Ch('/'), ++out;
                out = copy_chars(node->name(), node->name() + node->name_size(), out);
                *out = Ch('>'), ++out;
            }
            return out;
        }

        // Print declaration node
        template<class OutIt, class Ch>
        inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            // Print declaration start
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            *out = Ch('<'), ++out;
            *out = Ch('?'), ++out;
            *out = Ch('x'), ++out;
            *out = Ch('m'), ++out;
            *out = Ch('l'), ++out;

            // Print attributes
            out = print_attributes(out, node, flags);

            // Print declaration end
            *out = Ch('?'), ++out;
            *out = Ch('>'), ++out;

            return out;
        }

        // Print comment node
        template<class OutIt, class Ch>
        inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            assert(node->type() == node_comment);
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            *out = Ch('<'), ++out;
            *out = Ch('!'), ++out;
            *out = Ch('-'), ++out;
            *out = Ch('-'), ++out;
            out = copy_chars(node->value(), node->value() + node->value_size(), out);
            *out = Ch('-'), ++out;
            *out = Ch('-'), ++out;
            *out = Ch('>'), ++out;
            return out;
        }

        // Print doctype node
        template<class OutIt, class Ch>
        inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            assert(node->type() == node_doctype);
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            *out = Ch('<'), ++out;
            *out = Ch('!'), ++out;
            *out = Ch('D'), ++out;
            *out = Ch('O'), ++out;
            *out = Ch('C'), ++out;
            *out = Ch('T'), ++out;
            *out = Ch('Y'), ++out;
            *out = Ch('P'), ++out;
            *out = Ch('E'), ++out;
            *out = Ch(' '), ++out;
            out = copy_chars(node->value(), node->value() + node->value_size(), out);
            *out = Ch('>'), ++out;
            return out;
        }

        // Print pi node
        template<class OutIt, class Ch>
        inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
        {
            assert(node->type() == node_pi);
            if (!(flags & print_no_indenting))
                out = fill_chars(out, indent, Ch('\t'));
            *out = Ch('<'), ++out;
            *out = Ch('?'), ++out;
            out = copy_chars(node->name(), node->name() + node->name_size(), out);
            *out = Ch(' '), ++out;
            out = copy_chars(node->value(), node->value() + node->value_size(), out);
            *out = Ch('?'), ++out;
            *out = Ch('>'), ++out;
            return out;
        }

    }
    //! \endcond

    ///////////////////////////////////////////////////////////////////////////
    // Printing

    //! Prints XML to given output iterator.
    //! \param out Output iterator to print to.
    //! \param node Node to be printed. Pass xml_document to print entire document.
    //! \param flags Flags controlling how XML is printed.
    //! \return Output iterator pointing to position immediately after last character of printed text.
    template<class OutIt, class Ch>
    inline OutIt print(OutIt out, const xml_node<Ch> &node, int flags = 0)
    {
        return internal::print_node(out, &node, flags, 0);
    }

#ifndef RAPIDXML_NO_STREAMS

    //! Prints XML to given output stream.
    //! \param out Output stream to print to.
    //! \param node Node to be printed. Pass xml_document to print entire document.
    //! \param flags Flags controlling how XML is printed.
    //! \return Output stream.
    template<class Ch>
    inline basic_ostream<Ch> &print(basic_ostream<Ch> &out, const xml_node<Ch> &node, int flags = 0)
    {
        print(ostream_iterator<Ch>(out), node, flags);
        return out;
    }

    //! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process.
    //! \param out Output stream to print to.
    //! \param node Node to be printed.
    //! \return Output stream.
    template<class Ch>
    inline basic_ostream<Ch> &operator <<(basic_ostream<Ch> &out, const xml_node<Ch> &node)
    {
        return print(out, node);
    }

#endif

}

#endif
<|endoftext|>


<commit_before>
#include "application.h"
SYSTEM_MODE(MANUAL);

#include "OledDisplay.h"
#include "RHT03.h"
#include "TMP3x.h"
#include "common.h"
#include "rgbled.h"

// function prototypes
void drawPattern();
void drawText();
void drawTemp();
void getTemp();

int btnUp = D6;
int btnDn = D5;
int btnHome = D3;

bool btnUpLatch = false;
bool btnDnLatch = false;
bool btnHomeLatch = false;

double avgTemp = 0.0;

uint drawMode = 0;
uint textMode = 0;

OledDisplay display = OledDisplay(D1, D2, D0);;
RHT03 rht = RHT03(D4, D7);
TMP3x tmp36 = TMP3x(A0, 10, 1000);

void setup() {

  pinMode(btnUp, INPUT_PULLUP);
  pinMode(btnDn, INPUT_PULLUP);
  pinMode(btnHome, INPUT_PULLUP);

  // Spark.variable("reading", &reading, DOUBLE);
  // Spark.variable("volts", &volts, DOUBLE);
  // Spark.variable("temp", &avgTemp, DOUBLE);

  RGB.control(true);
  RGB.color(0, 0, 0);

  display.begin();
}

void loop() {
  tmp36.poll();
  if (rht.poll()) {
    drawTemp();
  }

  // curTime = millis();
  // // get temp once per second
  // if (lastTime + 3000 < curTime) {
  //   lastTime = curTime;
  //   display.clear(CLEAR_OLED);
  //   drawTemp();
  // }

  if (digitalRead(btnHome) == LOW) {
    if (btnHomeLatch) { // only draw once per press
      drawPattern();
      btnHomeLatch = false;
    }
  } else {
    btnHomeLatch = true;
  }

  if (digitalRead(btnUp) == LOW) {
    RGB.color(0,0,255);
    if (btnUpLatch) { // only draw once per press
      drawTemp();
      btnUpLatch = false;
    }
  } else {
    btnUpLatch = true;
  }

  if (digitalRead(btnDn) == LOW) {
    RGB.color(255,0,0);
    if (btnDnLatch) { // only draw once per press
      drawText();
      btnDnLatch = false;
    }
  } else {
    btnDnLatch = true;
  }
}

void initStat() {
}

void drawTemp() {
  //display.clear(CLEAR_OLED);
  display.setFont(0);
  char tempStr[8];

  double ftemp = tmp36.getTempF();
  ftemp = (ftemp / 10);
  sprintf(tempStr, "%.1ff a", ftemp);
  display.writeText(1, 1, tempStr);

  ftemp = rht.getTempF();
  ftemp = ftemp / 10;
  sprintf(tempStr, "%.1ff d", ftemp);
  display.writeText(1, 2, tempStr);

  ftemp = rht.getRH();
  ftemp = ftemp / 10;
  sprintf(tempStr, "%.1f%%rh", ftemp);
  display.writeText(1, 3, tempStr);

  sprintf(tempStr, "%d.%d  ", rht.getIntCount(), rht.getIgnCount());
  display.writeText(1, 4, tempStr);
}

void drawPattern() {
  display.resetPage();

  switch (drawMode) {
    case 0: // blank page
      RGB.color(255,0,0);
      display.clear(CLEAR_BUFF);
      break;
    case 1: // horizontal lines
      RGB.color(0,255,0);
      display.fill(0xaa);
      break;
    case 2: // vertical lines
      RGB.color(0,0,255);
      for (int i=0; i<6; i++) {
        for (int j=0; j<32; j++) {
          int c = j*2;
          display.setByte(i, c, 0xff);
          display.setByte(i, c+1, 0x00);
        }
      }
      break;
    case 3: {// count
      RGB.color(255,255,0);
      byte val = 0x00;
      for (int i=0; i<6; i++) {
        for (int j=0; j<64; j++) {
          display.setByte(i, j, val++);
          if (val > 0xff) val = 0x00;
        }
      }
      break;
    }
    case 4: // diagnal lines
      RGB.color(255,0,255);
      for (int i=0; i<6; i++) {
        for (int j=0; j<8; j++) {
          int c = j*8;
          display.setByte(i, c,   0x01);
          display.setByte(i, c+1, 0x02);
          display.setByte(i, c+2, 0x04);
          display.setByte(i, c+3, 0x08);
          display.setByte(i, c+4, 0x10);
          display.setByte(i, c+5, 0x20);
          display.setByte(i, c+6, 0x40);
          display.setByte(i, c+7, 0x80);
        }
      }
      break;
    case 5: // progression
      RGB.color(0,255,255);
      for (int i=0; i<6; i++) {
        for (int j=0; j<8; j++) {
          int c = j*8;
          display.setByte(i, c,   0x01);
          display.setByte(i, c+1, 0x03);
          display.setByte(i, c+2, 0x07);
          display.setByte(i, c+3, 0x0f);
          display.setByte(i, c+4, 0x1f);
          display.setByte(i, c+5, 0x3f);
          display.setByte(i, c+6, 0x7f);
          display.setByte(i, c+7, 0xff);
        }
      }
      break;
  }
  display.display();

  drawMode += 1;
  if (drawMode > 5) {
      drawMode = 0;
  }
}

void drawText() {
  display.clear(CLEAR_OLED);
  display.setFont(textMode);
  switch (textMode) {
    case 0: // small
    case 1: // med
      RGB.color(textMode==0?255:0, textMode==0?0:255, 0);
      display.writeText(0, 0, "12345");
      display.writeText(1, 1, "67890");
      display.writeText(2, 2, "Hello");
      if (textMode == 0) display.writeText(3, 3, "World");
      break;
    case 2: // large
      RGB.color(0,0,255);
      display.writeText(0, 0, "12345");
      break;
  }

  textMode += 1;
  if (textMode > 1) {
    textMode = 0;
  }
}
<commit_msg>Updated for new fonts<commit_after>
#include "application.h"
SYSTEM_MODE(MANUAL);

#include "rgbled.h"

#include "RHT03.h"
#include "TMP3x.h"
#include "OledDisplay.h"
#include "font_lcd6x8.h"
#include "font_lcd11x16.h"
#include "font_12x16_bold.h"
#include "common.h"

// function prototypes
void drawPattern();
void drawText();
void drawTemp();
void getTemp();

int btnUp = D6;
int btnDn = D5;
int btnHome = D3;

bool btnUpLatch = false;
bool btnDnLatch = false;
bool btnHomeLatch = false;

double avgTemp = 0.0;

uint drawMode = 0;
uint textMode = 0;

OledDisplay display = OledDisplay(D1, D2, D0);;
RHT03 rht = RHT03(D4, D7);
TMP3x tmp36 = TMP3x(A0, 10, 1000);

const font_t* font_lcdSm = parseFont(FONT_LCD6X8);
const font_t* font_lcdLg = parseFont(FONT_LCD11X16);
const font_t* font_bold  = parseFont(FONT_12X16_BOLD);

void setup() {

  pinMode(btnUp, INPUT_PULLUP);
  pinMode(btnDn, INPUT_PULLUP);
  pinMode(btnHome, INPUT_PULLUP);

  // Spark.variable("reading", &reading, DOUBLE);
  // Spark.variable("volts", &volts, DOUBLE);
  // Spark.variable("temp", &avgTemp, DOUBLE);

  RGB.control(true);
  RGB.color(0, 0, 0);

  display.begin();
}

void loop() {
  tmp36.poll();
  if (rht.poll()) {
    drawTemp();
  }

  // curTime = millis();
  // // get temp once per second
  // if (lastTime + 3000 < curTime) {
  //   lastTime = curTime;
  //   display.clear(CLEAR_OLED);
  //   drawTemp();
  // }

  if (digitalRead(btnHome) == LOW) {
    if (btnHomeLatch) { // only draw once per press
      drawPattern();
      btnHomeLatch = false;
    }
  } else {
    btnHomeLatch = true;
  }

  if (digitalRead(btnUp) == LOW) {
    RGB.color(0,0,255);
    if (btnUpLatch) { // only draw once per press
      drawTemp();
      btnUpLatch = false;
    }
  } else {
    btnUpLatch = true;
  }

  if (digitalRead(btnDn) == LOW) {
    RGB.color(255,0,0);
    if (btnDnLatch) { // only draw once per press
      drawText();
      btnDnLatch = false;
    }
  } else {
    btnDnLatch = true;
  }
}

void initStat() {
}

void drawTemp() {
  display.clear(CLEAR_OLED);
  display.setFont(font_lcdLg);
  char tempStr[8];

  double ftemp = tmp36.getTempF();
  ftemp = (ftemp / 10);

  sprintf(tempStr, "%.1f\x7f", ftemp);
  display.writeText(0, 0, tempStr);

  ftemp = rht.getTempF();
  ftemp = ftemp / 10;
  sprintf(tempStr, "%.1f\x7f", ftemp);
  display.writeText(0, 1, tempStr);

  ftemp = rht.getRH();
  ftemp = ftemp / 10;
  sprintf(tempStr, "%.1f%%", ftemp);
  display.writeText(0, 2, tempStr);

  // sprintf(tempStr, "%d.%d  ", rht.getIntCount(), rht.getIgnCount());
  // display.writeText(1, 4, tempStr);
  display.display();
}

void drawPattern() {
  display.resetPage();

  switch (drawMode) {
    case 0: // blank page
      RGB.color(255,0,0);
      display.clear(CLEAR_BUFF);
      break;
    case 1: // horizontal lines
      RGB.color(0,255,0);
      display.fill(0xaa);
      break;
    case 2: // vertical lines
      RGB.color(0,0,255);
      for (int i=0; i<6; i++) {
        for (int j=0; j<32; j++) {
          int c = j*2;
          display.setByte(i, c, 0xff);
          display.setByte(i, c+1, 0x00);
        }
      }
      break;
    case 3: {// count
      RGB.color(255,255,0);
      byte val = 0x00;
      for (int i=0; i<6; i++) {
        for (int j=0; j<64; j++) {
          display.setByte(i, j, val++);
          if (val > 0xff) val = 0x00;
        }
      }
      break;
    }
    case 4: // diagnal lines
      RGB.color(255,0,255);
      for (int i=0; i<6; i++) {
        for (int j=0; j<8; j++) {
          int c = j*8;
          display.setByte(i, c,   0x01);
          display.setByte(i, c+1, 0x02);
          display.setByte(i, c+2, 0x04);
          display.setByte(i, c+3, 0x08);
          display.setByte(i, c+4, 0x10);
          display.setByte(i, c+5, 0x20);
          display.setByte(i, c+6, 0x40);
          display.setByte(i, c+7, 0x80);
        }
      }
      break;
    case 5: // progression
      RGB.color(0,255,255);
      for (int i=0; i<6; i++) {
        for (int j=0; j<8; j++) {
          int c = j*8;
          display.setByte(i, c,   0x01);
          display.setByte(i, c+1, 0x03);
          display.setByte(i, c+2, 0x07);
          display.setByte(i, c+3, 0x0f);
          display.setByte(i, c+4, 0x1f);
          display.setByte(i, c+5, 0x3f);
          display.setByte(i, c+6, 0x7f);
          display.setByte(i, c+7, 0xff);
        }
      }
      break;
  }
  display.display();

  drawMode += 1;
  if (drawMode > 5) {
      drawMode = 0;
  }
}

void drawText() {
  display.clear(CLEAR_OLED);
  // display.setFont(textMode);
  switch (textMode) {
    case 0: // small
    case 1: // med
    case 2: // bold
      // RGB.color(textMode==0?255:0, textMode==0?0:255, 0);
      display.writeText(0, 0, "12345");
      display.writeText(0, 1, "Hello");
      display.writeText(0, 2, "World");
      break;
    case 3: // large
    case 4:
    case 5:
      // RGB.color(0,0,255);
      display.writeText(0, 0, "12345");
      if (textMode < 5) {
        display.writeText(0, 1, "67890");
      }
      break;
  }

  textMode += 1;
  if (textMode > 5) {
    textMode = 0;
  }
}
<|endoftext|>


<commit_before>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * 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.
 *
 *******************************************************************************/
#ifndef GUARD_MIOPEN_GEMM_DRIVER_HPP
#define GUARD_MIOPEN_GEMM_DRIVER_HPP

#include "InputFlags.hpp"
#include "driver.hpp"
#include <algorithm>
#include <cstdlib>
#include <float.h>
#include <memory>
#include <miopen/miopen.h>
#include <numeric>
#include <vector>

template <typename T>
class GemmDriver : public Driver
{
    public:
    GemmDriver() : Driver() {}

    int AddCmdLineArgs();
    int ParseCmdLineArgs(int argc, char* argv[]);
    InputFlags& GetInputFlags() { return inflags; }

    int GetandSetData();
    std::vector<int> GetInputTensorLengthsFromCmdLine();

    int AllocateBuffersAndCopy();

    int RunForwardGPU();

    int RunBackwardGPU();

    int VerifyBackward();
    int VerifyForward();
    ~GemmDriver() {}

    private:
    InputFlags inflags;

    std::unique_ptr<GPUMem> a_dev;
    std::unique_ptr<GPUMem> b_dev;
    std::unique_ptr<GPUMem> c_dev;

    std::vector<T> a;
    std::vector<T> b;
    std::vector<T> c;
    std::vector<T> chost;

    int M, N, K; // Netlib BLAS dims, user inputs
    bool transA, transB;
    T alpha, beta;

    int lda, ldb;
};

template <typename T>
int GemmDriver<T>::AddCmdLineArgs()
{
    inflags.AddInputFlag("forw", 'F', "1", "Run only Forward Gemm (Default=1)", "int");
    inflags.AddInputFlag("batchsize", 'b', "1", "batch size for Gemm (Default=1)", "int");
    inflags.AddInputFlag("a_h", 'm', "256", "Height of A matrix (Default=256)", "int");
    inflags.AddInputFlag("a_w", 'k', "256", "Width of A matrix (Default=256)", "int");
    inflags.AddInputFlag("b_w", 'n', "256", "Width of B matrix (Default=256)", "int");
    inflags.AddInputFlag("alpha", 'A', "1.0", "Gemm alpha (Default=1.0)", "double");
    inflags.AddInputFlag("beta", 'B', "0.0", "Gemm beta (Default=0.0)", "double");
    inflags.AddInputFlag("transA", 'u', "0", "Transpose A matrix (Default=0)", "int");
    inflags.AddInputFlag("transB", 'v', "0", "Transpose B matrix (Default=0)", "int");
    inflags.AddInputFlag("iter", 'i', "10", "Number of Iterations (Default=10)", "int");
    inflags.AddInputFlag("verify", 'V', "0", "Verify Each Layer (Default=1)", "int");
    inflags.AddInputFlag("time", 't', "0", "Time Each Layer (Default=0)", "int");

    return 0;
}

template <typename T>
int GemmDriver<T>::ParseCmdLineArgs(int argc, char* argv[])
{
    inflags.Parse(argc, argv);

    if(inflags.GetValueInt("time") == 1)
    {
        miopenEnableProfiling(GetHandle(), true);
    }
    return 0;
}

template <typename T>
int GemmDriver<T>::GetandSetData()
{

    M = inflags.GetValueInt("a_h");
    K = inflags.GetValueInt("a_w");
    N = inflags.GetValueInt("b_w");

    transA = inflags.GetValueInt("transA");
    transB = inflags.GetValueInt("transB");

    alpha = inflags.GetValueDouble("alpha");
    beta  = inflags.GetValueDouble("beta");

    lda = transA == 0 ? K : M;
    ldb = transB == 0 ? N : K;

    return (0);
}

template <typename T>
int GemmDriver<T>::AllocateBuffersAndCopy()
{

    size_t a_sz = M * K;
    size_t b_sz = K * N;
    size_t c_sz = M * N;
#if MIOPEN_BACKEND_OPENCL
    cl_context ctx;

    clGetCommandQueueInfo(q, CL_QUEUE_CONTEXT, sizeof(cl_context), &ctx, NULL);
#elif MIOPEN_BACKEND_HIP
    uint32_t ctx = 0;
#endif
    a_dev = std::unique_ptr<GPUMem>(new GPUMem(ctx, a_sz, sizeof(T)));
    b_dev = std::unique_ptr<GPUMem>(new GPUMem(ctx, b_sz, sizeof(T)));
    c_dev = std::unique_ptr<GPUMem>(new GPUMem(ctx, c_sz, sizeof(T)));

    a     = std::vector<T>(a_sz);
    b     = std::vector<T>(b_sz);
    c     = std::vector<T>(c_sz, 0.);
    chost = std::vector<T>(c_sz, 0.);

    for(int i = 0; i < a_sz; i++)
    {
        a[i] = static_cast<T>(static_cast<double>(rand()) * (1.0 / RAND_MAX));
    }

    for(int i = 0; i < b_sz; i++)
    {
        b[i] = static_cast<double>((rand()) * (1.0 / RAND_MAX) - 0.5) * 0.001;
    }
#if MIOPEN_BACKEND_OPENCL
    cl_int status;
#elif MIOPEN_BACKEND_HIP
    int status;
#endif
    status = a_dev->ToGPU(q, a.data());
    status |= b_dev->ToGPU(q, b.data());
    status |= c_dev->ToGPU(q, c.data());

    if(status != CL_SUCCESS)
        printf("Error copying data to GPU\n");

    return miopenStatusSuccess;
}

template <typename T>
int GemmDriver<T>::RunForwardGPU()
{

#if MIOPEN_USE_MIOPENGEMM
    miopenGemm(GetHandle(),
               false, // isDataColMajor
               transA,
               transB,
               M,
               N,
               K,
               &alpha,
               a_dev->GetMem(),
               lda,
               b_dev->GetMem(),
               ldb,
               &beta,
               c_dev->GetMem(),
               N);

    if(inflags.GetValueInt("time") == 1)
    {
        float time = 0.0;
        miopenGetKernelTime(GetHandle(), &time);
        printf("GPU Kernel Time Gemm Elapsed: %f ms\n", time);
    }

    c_dev->FromGPU(GetStream(), c.data());
#else
    std::cerr << "GEMM is not supported\n";
#endif
    return miopenStatusSuccess;
}

template <typename T>
int GemmDriver<T>::RunBackwardGPU()
{
    return (0);
}

template <typename T>
int GemmDriver<T>::VerifyForward()
{
    return 0;
}

template <typename T>
int GemmDriver<T>::VerifyBackward()
{
    return 0;
}

#endif // GUARD_MIOPEN_GEMM_DRIVER_HPP
<commit_msg>including gemm api explicitly<commit_after>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * 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.
 *
 *******************************************************************************/
#ifndef GUARD_MIOPEN_GEMM_DRIVER_HPP
#define GUARD_MIOPEN_GEMM_DRIVER_HPP

#include "InputFlags.hpp"
#include "driver.hpp"
#include <algorithm>
#include <cstdlib>
#include <float.h>
#include <memory>
#include <miopen/miopen.h>
#include <numeric>
#include <vector>

miopenStatus_t miopenGemm(miopenHandle_t handle,
                          bool isDataColMajor,
                          bool transA,
                          bool transB,
                          int M,
                          int N,
                          int K,
                          const void* alpha,
                          const void* A,
                          int lda,
                          const void* B,
                          int ldb,
                          const void* beta,
                          void* C,
                          int ldc,
                          int find);

template <typename T>
class GemmDriver : public Driver
{
    public:
    GemmDriver() : Driver() {}

    int AddCmdLineArgs();
    int ParseCmdLineArgs(int argc, char* argv[]);
    InputFlags& GetInputFlags() { return inflags; }

    int GetandSetData();
    std::vector<int> GetInputTensorLengthsFromCmdLine();

    int AllocateBuffersAndCopy();

    int RunForwardGPU();

    int RunBackwardGPU();

    int VerifyBackward();
    int VerifyForward();
    ~GemmDriver() {}

    private:
    InputFlags inflags;

    std::unique_ptr<GPUMem> a_dev;
    std::unique_ptr<GPUMem> b_dev;
    std::unique_ptr<GPUMem> c_dev;

    std::vector<T> a;
    std::vector<T> b;
    std::vector<T> c;
    std::vector<T> chost;

    int M, N, K; // Netlib BLAS dims, user inputs
    bool transA, transB;
    T alpha, beta;

    int lda, ldb;
};

template <typename T>
int GemmDriver<T>::AddCmdLineArgs()
{
    inflags.AddInputFlag("forw", 'F', "1", "Run only Forward Gemm (Default=1)", "int");
    inflags.AddInputFlag("batchsize", 'b', "1", "batch size for Gemm (Default=1)", "int");
    inflags.AddInputFlag("a_h", 'm', "256", "Height of A matrix (Default=256)", "int");
    inflags.AddInputFlag("a_w", 'k', "256", "Width of A matrix (Default=256)", "int");
    inflags.AddInputFlag("b_w", 'n', "256", "Width of B matrix (Default=256)", "int");
    inflags.AddInputFlag("alpha", 'A', "1.0", "Gemm alpha (Default=1.0)", "double");
    inflags.AddInputFlag("beta", 'B', "0.0", "Gemm beta (Default=0.0)", "double");
    inflags.AddInputFlag("transA", 'u', "0", "Transpose A matrix (Default=0)", "int");
    inflags.AddInputFlag("transB", 'v', "0", "Transpose B matrix (Default=0)", "int");
    inflags.AddInputFlag("iter", 'i', "10", "Number of Iterations (Default=10)", "int");
    inflags.AddInputFlag("verify", 'V', "0", "Verify Each Layer (Default=1)", "int");
    inflags.AddInputFlag("time", 't', "0", "Time Each Layer (Default=0)", "int");

    return 0;
}

template <typename T>
int GemmDriver<T>::ParseCmdLineArgs(int argc, char* argv[])
{
    inflags.Parse(argc, argv);

    if(inflags.GetValueInt("time") == 1)
    {
        miopenEnableProfiling(GetHandle(), true);
    }
    return 0;
}

template <typename T>
int GemmDriver<T>::GetandSetData()
{

    M = inflags.GetValueInt("a_h");
    K = inflags.GetValueInt("a_w");
    N = inflags.GetValueInt("b_w");

    transA = inflags.GetValueInt("transA");
    transB = inflags.GetValueInt("transB");

    alpha = inflags.GetValueDouble("alpha");
    beta  = inflags.GetValueDouble("beta");

    lda = transA == 0 ? K : M;
    ldb = transB == 0 ? N : K;

    return (0);
}

template <typename T>
int GemmDriver<T>::AllocateBuffersAndCopy()
{

    size_t a_sz = M * K;
    size_t b_sz = K * N;
    size_t c_sz = M * N;
#if MIOPEN_BACKEND_OPENCL
    cl_context ctx;

    clGetCommandQueueInfo(q, CL_QUEUE_CONTEXT, sizeof(cl_context), &ctx, NULL);
#elif MIOPEN_BACKEND_HIP
    uint32_t ctx = 0;
#endif
    a_dev = std::unique_ptr<GPUMem>(new GPUMem(ctx, a_sz, sizeof(T)));
    b_dev = std::unique_ptr<GPUMem>(new GPUMem(ctx, b_sz, sizeof(T)));
    c_dev = std::unique_ptr<GPUMem>(new GPUMem(ctx, c_sz, sizeof(T)));

    a     = std::vector<T>(a_sz);
    b     = std::vector<T>(b_sz);
    c     = std::vector<T>(c_sz, 0.);
    chost = std::vector<T>(c_sz, 0.);

    for(int i = 0; i < a_sz; i++)
    {
        a[i] = static_cast<T>(static_cast<double>(rand()) * (1.0 / RAND_MAX));
    }

    for(int i = 0; i < b_sz; i++)
    {
        b[i] = static_cast<double>((rand()) * (1.0 / RAND_MAX) - 0.5) * 0.001;
    }
#if MIOPEN_BACKEND_OPENCL
    cl_int status;
#elif MIOPEN_BACKEND_HIP
    int status;
#endif
    status = a_dev->ToGPU(q, a.data());
    status |= b_dev->ToGPU(q, b.data());
    status |= c_dev->ToGPU(q, c.data());

    if(status != CL_SUCCESS)
        printf("Error copying data to GPU\n");

    return miopenStatusSuccess;
}

template <typename T>
int GemmDriver<T>::RunForwardGPU()
{

#if MIOPEN_USE_MIOPENGEMM
    miopenGemm(GetHandle(),
               false, // isDataColMajor
               transA,
               transB,
               M,
               N,
               K,
               &alpha,
               a_dev->GetMem(),
               lda,
               b_dev->GetMem(),
               ldb,
               &beta,
               c_dev->GetMem(),
               N,
               0); // find is off (0)

    if(inflags.GetValueInt("time") == 1)
    {
        float time = 0.0;
        miopenGetKernelTime(GetHandle(), &time);
        printf("GPU Kernel Time Gemm Elapsed: %f ms\n", time);
    }

    c_dev->FromGPU(GetStream(), c.data());
#else
    std::cerr << "GEMM is not supported\n";
#endif
    return miopenStatusSuccess;
}

template <typename T>
int GemmDriver<T>::RunBackwardGPU()
{
    return (0);
}

template <typename T>
int GemmDriver<T>::VerifyForward()
{
    return 0;
}

template <typename T>
int GemmDriver<T>::VerifyBackward()
{
    return 0;
}

#endif // GUARD_MIOPEN_GEMM_DRIVER_HPP
<|endoftext|>


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

  Copyright (c) 2008 Bruno Virlet <bruno.virlet@gmail.com>

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

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "monthview.h"
#include "monthscene.h"
#include "monthitem.h"
#include "monthgraphicsitems.h"
#include "koglobals.h"
#include "koprefs.h"
#include "koeventpopupmenu.h"
#include "kohelper.h"

#include <kcal/incidence.h>
#include <kcal/calendar.h>

#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QToolButton>
#include <QWheelEvent>
#include <QKeyEvent>
#include <QDate>
#include <QTimer>

using namespace KOrg;

MonthView::MonthView( Calendar *calendar, QWidget *parent )
  : KOEventView( calendar, parent )
{
  QHBoxLayout *topLayout = new QHBoxLayout( this );

  mView = new MonthGraphicsView( this );

  mScene = new MonthScene( this, calendar );
  mView->setScene( mScene );
  topLayout->addWidget( mView );

  QVBoxLayout *rightLayout = new QVBoxLayout( );
  rightLayout->setSpacing( 0 );
  rightLayout->setMargin( 0 );

  // push buttons to the bottom
  rightLayout->addStretch( 1 );

  QToolButton *minusMonth = new QToolButton( this );
  minusMonth->setIcon( KIcon( "arrow-up-double" ) );
  minusMonth->setToolTip( i18n( "Go back one month" ) );
  minusMonth->setAutoRaise( true );
  connect( minusMonth, SIGNAL(clicked()),
           this, SLOT(moveBackMonth()) );

  QToolButton *minusWeek = new QToolButton( this );
  minusWeek->setIcon( KIcon( "arrow-up" ) );
  minusWeek->setToolTip( i18n( "Go back one week" ) );
  minusWeek->setAutoRaise( true );
  connect( minusWeek, SIGNAL(clicked()),
           this, SLOT(moveBackWeek()) );

  QToolButton *plusWeek = new QToolButton( this );
  plusWeek->setIcon( KIcon( "arrow-down" ) );
  plusWeek->setToolTip( i18n( "Go forward one week" ) );
  plusWeek->setAutoRaise( true );
  connect( plusWeek, SIGNAL(clicked()),
           this, SLOT(moveFwdWeek()) );

  QToolButton *plusMonth = new QToolButton( this );
  plusMonth->setIcon( KIcon( "arrow-down-double" ) );
  plusMonth->setToolTip( i18n( "Go forward one month" ) );
  plusMonth->setAutoRaise( true );
  connect( plusMonth, SIGNAL(clicked()),
           this, SLOT(moveFwdMonth()) );

  rightLayout->addWidget( minusMonth );
  rightLayout->addWidget( minusWeek );
  rightLayout->addWidget( plusWeek );
  rightLayout->addWidget( plusMonth );

  topLayout->addLayout( rightLayout );

  mViewPopup = eventPopup();

  connect( mScene, SIGNAL(showIncidencePopupSignal(Incidence *,const QDate &)),
           mViewPopup, SLOT(showIncidencePopup(Incidence *,const QDate &)) );

  connect( mScene, SIGNAL(showNewEventPopupSignal()),
           SLOT(showNewEventPopup()) );

  connect( mScene, SIGNAL(incidenceSelected(Incidence *)),
           this, SIGNAL(incidenceSelected(Incidence *)) );
}

MonthView::~MonthView()
{
}

int MonthView::currentDateCount()
{
  return mStartDate.daysTo( mEndDate );
}

int MonthView::maxDatesHint()
{
  return 6 * 7;
}

DateList MonthView::selectedDates()
{
  DateList list;

  if ( mScene->selectedCell() ) {
    list << mScene->selectedCell()->date();
  }

  return list;
}

bool MonthView::eventDurationHint( QDateTime &startDt, QDateTime &endDt, bool &allDay )
{
  if ( mScene->selectedCell() ) {
    startDt.setDate( mScene->selectedCell()->date() );
    endDt.setDate( mScene->selectedCell()->date() );
    allDay = true;
    return true;
  }

  return false;
}

void MonthView::showIncidences( const Incidence::List & )
{
}

void MonthView::changeIncidenceDisplay( Incidence *incidence, int action )
{
  Q_UNUSED( incidence );
  Q_UNUSED( action );

  //TODO: add some more intelligence here...

  // don't call reloadIncidences() directly. It would delete all
  // MonthItems, but this changeIncidenceDisplay()-method was probably
  // called by one of the MonthItem objects. So only shedule a reload
  // as event
  QTimer::singleShot( 0, this, SLOT(reloadIncidences()) );
}

void MonthView::addIncidence( Incidence *incidence )
{
  Q_UNUSED( incidence );

  //TODO: add some more intelligence here...
  reloadIncidences();
}

void MonthView::updateView()
{
  mView->update();
}

void MonthView::wheelEvent( QWheelEvent *event )
{
  // invert direction to get scroll-like behaviour
  if ( event->delta() > 0 ) {
    moveStartDate( -1, 0 );
  } else if ( event->delta() < 0 ) {
    moveStartDate( 1, 0 );
  }

  // call accept in every case, we do not want anybody else to react
  event->accept();
}

void MonthView::keyPressEvent( QKeyEvent *event )
{
  if ( event->key() == Qt::Key_PageUp ) {
    moveStartDate( 0, -1 );
    event->accept();
  } else if ( event->key() == Qt::Key_PageDown ) {
    moveStartDate( 0, 1 );
    event->accept();
  } else {
    event->ignore();
  }
}

void MonthView::moveBackMonth()
{
  moveStartDate( 0, -1 );
}

void MonthView::moveBackWeek()
{
  moveStartDate( -1, 0 );
}

void MonthView::moveFwdWeek()
{
  moveStartDate( 1, 0 );
}

void MonthView::moveFwdMonth()
{
  moveStartDate( 0, 1 );
}

void MonthView::moveStartDate( int weeks, int months )
{
  QDate startDate;
  if ( weeks != 0 ) {
    startDate = mStartDate.addDays( weeks * 7 );
  }
  if ( months != 0 ) {
    startDate = mStartDate.addMonths( months );
  }

  setStartDate( startDate );
}

void MonthView::showDates( const QDate &start, const QDate &end )
{
  Q_UNUSED( end );

  setStartDate( start );
}

void MonthView::setStartDate( const QDate &start )
{
  int weekdayCol = ( start.dayOfWeek() + 7 - KGlobal::locale()->weekStartDay() ) % 7;
  mStartDate = start.addDays( -weekdayCol );

  mEndDate = mStartDate.addDays( 6 * 7 - 1 );

  // take "middle" day's month as current month
  mCurrentMonth = mStartDate.addDays( ( 6 * 7 ) / 2 ).month();

  reloadIncidences();
}

void MonthView::reloadIncidences()
{
  // keep selection if it exists
  Incidence *incidenceSelected = 0;
  if ( mScene->selectedItem() ) {
    IncidenceMonthItem *tmp = dynamic_cast<IncidenceMonthItem *>( mScene->selectedItem() );
    if ( tmp ) {
      incidenceSelected = tmp->incidence();
    }
  }

  mScene->resetAll();

  // build monthcells hash
  int i = 0;
  for ( QDate d = mStartDate; d <= mEndDate; d = d.addDays( 1 ) ) {
    mScene->mMonthCellMap[ d ] = new MonthCell( i, d, mScene );
    i ++;
  }

  // build global event list
  KDateTime::Spec timeSpec = KOPrefs::instance()->timeSpec();
  Incidence::List incidences = calendar()->incidences();

  foreach ( Incidence *incidence, incidences ) {
    // An event could start before the currently displayed date, so we
    // have to check at least those dates before the start date, which would
    // cause the event to span into the displayed date range.
    int offset = 0;
    Event *event;
    if ( ( event = dynamic_cast<Event *>( incidence ) ) ) {
      offset = event->dtStart().daysTo( event->dtEnd() );
    }
    for ( QDate d = mStartDate.addDays( -offset ); d <= mEndDate; d = d.addDays( 1 ) ) {
      if ( incidence->recursOn( d, timeSpec ) ) {
        MonthItem *manager = new IncidenceMonthItem( mScene, incidence, d );
        mScene->mManagerList << manager;
        if ( incidenceSelected == incidence ) {
          // If there was an item selected before, reselect it.
          mScene->selectItem( manager );
        }
      }
    }
  }

  // add holidays
  for ( QDate d = mStartDate; d <= mEndDate; d = d.addDays( 1 ) ) {
    QStringList holidays( KOGlobals::self()->holiday( d ) );
    if ( !holidays.isEmpty() ) {
      MonthItem *holidayItem =
        new HolidayMonthItem(
          mScene, d,
          holidays.join( i18nc( "delimiter for joining holiday names", "," ) ) );
      mScene->mManagerList << holidayItem;
    }
  }

  // sort it
  qSort( mScene->mManagerList.begin(),
         mScene->mManagerList.end(),
         MonthItem::greaterThan );

  // build each month's cell event list
  foreach ( MonthItem *manager, mScene->mManagerList ) {
    for ( QDate d = manager->startDate(); d <= manager->endDate(); d = d.addDays( 1 ) ) {
      MonthCell *cell = mScene->mMonthCellMap.value( d );
      if ( cell ) {
        cell->mMonthItemList << manager;
      }
    }
  }

  foreach ( MonthItem *manager, mScene->mManagerList ) {
    manager->updateMonthGraphicsItems();
    manager->updatePosition();
  }

  foreach ( MonthItem *manager, mScene->mManagerList ) {
    manager->updateGeometry();
  }

  mScene->setInitialized( true );
  mView->update();
  mScene->update();
}

QDate MonthView::averageDate() const
{
  return startDate().addDays( startDate().daysTo( endDate() ) / 2 );
}
<commit_msg>backport SVN commit 883935 by winterz:<commit_after>/*
  This file is part of KOrganizer.

  Copyright (c) 2008 Bruno Virlet <bruno.virlet@gmail.com>

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

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "monthview.h"
#include "monthscene.h"
#include "monthitem.h"
#include "monthgraphicsitems.h"
#include "koglobals.h"
#include "koprefs.h"
#include "koeventpopupmenu.h"
#include "kohelper.h"

#include <kcal/incidence.h>
#include <kcal/calendar.h>

#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QToolButton>
#include <QWheelEvent>
#include <QKeyEvent>
#include <QDate>
#include <QTimer>

using namespace KOrg;

MonthView::MonthView( Calendar *calendar, QWidget *parent )
  : KOEventView( calendar, parent )
{
  QHBoxLayout *topLayout = new QHBoxLayout( this );

  mView = new MonthGraphicsView( this );

  mScene = new MonthScene( this, calendar );
  mView->setScene( mScene );
  topLayout->addWidget( mView );

  QVBoxLayout *rightLayout = new QVBoxLayout( );
  rightLayout->setSpacing( 0 );
  rightLayout->setMargin( 0 );

  // push buttons to the bottom
  rightLayout->addStretch( 1 );

  QToolButton *minusMonth = new QToolButton( this );
  minusMonth->setIcon( KIcon( "arrow-up-double" ) );
  minusMonth->setToolTip( i18n( "Go back one month" ) );
  minusMonth->setAutoRaise( true );
  connect( minusMonth, SIGNAL(clicked()),
           this, SLOT(moveBackMonth()) );

  QToolButton *minusWeek = new QToolButton( this );
  minusWeek->setIcon( KIcon( "arrow-up" ) );
  minusWeek->setToolTip( i18n( "Go back one week" ) );
  minusWeek->setAutoRaise( true );
  connect( minusWeek, SIGNAL(clicked()),
           this, SLOT(moveBackWeek()) );

  QToolButton *plusWeek = new QToolButton( this );
  plusWeek->setIcon( KIcon( "arrow-down" ) );
  plusWeek->setToolTip( i18n( "Go forward one week" ) );
  plusWeek->setAutoRaise( true );
  connect( plusWeek, SIGNAL(clicked()),
           this, SLOT(moveFwdWeek()) );

  QToolButton *plusMonth = new QToolButton( this );
  plusMonth->setIcon( KIcon( "arrow-down-double" ) );
  plusMonth->setToolTip( i18n( "Go forward one month" ) );
  plusMonth->setAutoRaise( true );
  connect( plusMonth, SIGNAL(clicked()),
           this, SLOT(moveFwdMonth()) );

  rightLayout->addWidget( minusMonth );
  rightLayout->addWidget( minusWeek );
  rightLayout->addWidget( plusWeek );
  rightLayout->addWidget( plusMonth );

  topLayout->addLayout( rightLayout );

  mViewPopup = eventPopup();

  connect( mScene, SIGNAL(showIncidencePopupSignal(Incidence *,const QDate &)),
           mViewPopup, SLOT(showIncidencePopup(Incidence *,const QDate &)) );

  connect( mScene, SIGNAL(showNewEventPopupSignal()),
           SLOT(showNewEventPopup()) );

  connect( mScene, SIGNAL(incidenceSelected(Incidence *)),
           this, SIGNAL(incidenceSelected(Incidence *)) );
}

MonthView::~MonthView()
{
}

int MonthView::currentDateCount()
{
  return mStartDate.daysTo( mEndDate );
}

int MonthView::maxDatesHint()
{
  return 6 * 7;
}

DateList MonthView::selectedDates()
{
  DateList list;

  if ( mScene->selectedCell() ) {
    list << mScene->selectedCell()->date();
  }

  return list;
}

bool MonthView::eventDurationHint( QDateTime &startDt, QDateTime &endDt, bool &allDay )
{
  if ( mScene->selectedCell() ) {
    startDt.setDate( mScene->selectedCell()->date() );
    endDt.setDate( mScene->selectedCell()->date() );
    allDay = true;
    return true;
  }

  return false;
}

void MonthView::showIncidences( const Incidence::List & )
{
}

void MonthView::changeIncidenceDisplay( Incidence *incidence, int action )
{
  Q_UNUSED( incidence );
  Q_UNUSED( action );

  //TODO: add some more intelligence here...

  // don't call reloadIncidences() directly. It would delete all
  // MonthItems, but this changeIncidenceDisplay()-method was probably
  // called by one of the MonthItem objects. So only shedule a reload
  // as event
  QTimer::singleShot( 0, this, SLOT(reloadIncidences()) );
}

void MonthView::addIncidence( Incidence *incidence )
{
  Q_UNUSED( incidence );

  //TODO: add some more intelligence here...
  reloadIncidences();
}

void MonthView::updateView()
{
  mView->update();
}

void MonthView::wheelEvent( QWheelEvent *event )
{
  // invert direction to get scroll-like behaviour
  if ( event->delta() > 0 ) {
    moveStartDate( -1, 0 );
  } else if ( event->delta() < 0 ) {
    moveStartDate( 1, 0 );
  }

  // call accept in every case, we do not want anybody else to react
  event->accept();
}

void MonthView::keyPressEvent( QKeyEvent *event )
{
  if ( event->key() == Qt::Key_PageUp ) {
    moveStartDate( 0, -1 );
    event->accept();
  } else if ( event->key() == Qt::Key_PageDown ) {
    moveStartDate( 0, 1 );
    event->accept();
  } else {
    event->ignore();
  }
}

void MonthView::moveBackMonth()
{
  moveStartDate( 0, -1 );
}

void MonthView::moveBackWeek()
{
  moveStartDate( -1, 0 );
}

void MonthView::moveFwdWeek()
{
  moveStartDate( 1, 0 );
}

void MonthView::moveFwdMonth()
{
  moveStartDate( 0, 1 );
}

void MonthView::moveStartDate( int weeks, int months )
{
  QDate startDate;
  if ( weeks != 0 ) {
    startDate = mStartDate.addDays( weeks * 7 );
  }
  if ( months != 0 ) {
    startDate = mStartDate.addMonths( months );
  }

  setStartDate( startDate );
}

void MonthView::showDates( const QDate &start, const QDate &end )
{
  Q_UNUSED( end );

  setStartDate( start );
}

void MonthView::setStartDate( const QDate &start )
{
  int weekdayCol = ( start.dayOfWeek() + 7 - KGlobal::locale()->weekStartDay() ) % 7;
  mStartDate = start.addDays( -weekdayCol );

  mEndDate = mStartDate.addDays( 6 * 7 - 1 );

  // take "middle" day's month as current month
  mCurrentMonth = mStartDate.addDays( ( 6 * 7 ) / 2 ).month();

  reloadIncidences();
}

void MonthView::reloadIncidences()
{
  // keep selection if it exists
  Incidence *incidenceSelected = 0;
  if ( mScene->selectedItem() ) {
    IncidenceMonthItem *tmp = dynamic_cast<IncidenceMonthItem *>( mScene->selectedItem() );
    if ( tmp ) {
      incidenceSelected = tmp->incidence();
    }
  }

  mScene->resetAll();

  // build monthcells hash
  int i = 0;
  for ( QDate d = mStartDate; d <= mEndDate; d = d.addDays( 1 ) ) {
    mScene->mMonthCellMap[ d ] = new MonthCell( i, d, mScene );
    i ++;
  }

  // build global event list
  KDateTime::Spec timeSpec = KOPrefs::instance()->timeSpec();
  Incidence::List incidences = calendar()->incidences();

  foreach ( Incidence *incidence, incidences ) {
    if ( incidence->type() == "Todo" && !KOPrefs::instance()->showAllDayTodo() ) {
      continue;
    }

    // An event could start before the currently displayed date, so we
    // have to check at least those dates before the start date, which would
    // cause the event to span into the displayed date range.
    int offset = 0;
    Event *event;
    if ( ( event = dynamic_cast<Event *>( incidence ) ) ) {
      offset = event->dtStart().daysTo( event->dtEnd() );
    }
    for ( QDate d = mStartDate.addDays( -offset ); d <= mEndDate; d = d.addDays( 1 ) ) {
      if ( incidence->recursOn( d, timeSpec ) ) {
        MonthItem *manager = new IncidenceMonthItem( mScene, incidence, d );
        mScene->mManagerList << manager;
        if ( incidenceSelected == incidence ) {
          // If there was an item selected before, reselect it.
          mScene->selectItem( manager );
        }
      }
    }
  }

  // add holidays
  for ( QDate d = mStartDate; d <= mEndDate; d = d.addDays( 1 ) ) {
    QStringList holidays( KOGlobals::self()->holiday( d ) );
    if ( !holidays.isEmpty() ) {
      MonthItem *holidayItem =
        new HolidayMonthItem(
          mScene, d,
          holidays.join( i18nc( "delimiter for joining holiday names", "," ) ) );
      mScene->mManagerList << holidayItem;
    }
  }

  // sort it
  qSort( mScene->mManagerList.begin(),
         mScene->mManagerList.end(),
         MonthItem::greaterThan );

  // build each month's cell event list
  foreach ( MonthItem *manager, mScene->mManagerList ) {
    for ( QDate d = manager->startDate(); d <= manager->endDate(); d = d.addDays( 1 ) ) {
      MonthCell *cell = mScene->mMonthCellMap.value( d );
      if ( cell ) {
        cell->mMonthItemList << manager;
      }
    }
  }

  foreach ( MonthItem *manager, mScene->mManagerList ) {
    manager->updateMonthGraphicsItems();
    manager->updatePosition();
  }

  foreach ( MonthItem *manager, mScene->mManagerList ) {
    manager->updateGeometry();
  }

  mScene->setInitialized( true );
  mView->update();
  mScene->update();
}

QDate MonthView::averageDate() const
{
  return startDate().addDays( startDate().daysTo( endDate() ) / 2 );
}
<|endoftext|>


<commit_before>#include "utils/rename-existing/rename-existing-table-model.h"
#include <QColor>
#include <QPixmap>
#include <QVariant>

RenameExistingTableModel::RenameExistingTableModel(const QList<RenameExistingFile> &files, QString folder, QObject *parent)
	: QAbstractTableModel(parent), m_files(files), m_folder(folder)
{}

int RenameExistingTableModel::rowCount(const QModelIndex &parent) const
{
	Q_UNUSED(parent);
	return m_files.count();
}

int RenameExistingTableModel::columnCount(const QModelIndex &parent) const
{
	Q_UNUSED(parent);
	return 3;
}

QVariant RenameExistingTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
	if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
		switch (section)
		{
			case 0: return QString("Thumbnail");
			case 1: return QString("Original");
			case 2: return QString("Destination");
		}
	}
	return {};
}

QVariant RenameExistingTableModel::data(const QModelIndex &index, int role) const
{
	const RenameExistingFile &image = m_files[index.row()];

	// Preview in the first column
	if (index.column() == 0 && role == Qt::DecorationRole) {
		return QPixmap(image.path).scaledToHeight(50, Qt::SmoothTransformation);
	}

	// Original path in the second column
	if (index.column() == 1 && role == Qt::DisplayRole) {
		return image.path.right(image.path.length() - m_folder.length() - 1);
	}

	// New path in the third column
	if (index.column() == 3) {
		// "no change" in red if there isn't
		if (image.path == image.newPath) {
			if (role == Qt::ForegroundRole) {
				return QVariant::fromValue(QColor(Qt::red));
			}
			if (role == Qt::DisplayRole) {
				return QString("No change");
			}
		}

		if (Qt::DisplayRole) {
			return image.newPath.right(image.newPath.length() - m_folder.length() - 1);
		}
	}

	return {};
}
<commit_msg>Fix new path not showing in 'rename existing' tool (fix #2068)<commit_after>#include "utils/rename-existing/rename-existing-table-model.h"
#include <QColor>
#include <QPixmap>
#include <QVariant>

RenameExistingTableModel::RenameExistingTableModel(const QList<RenameExistingFile> &files, QString folder, QObject *parent)
	: QAbstractTableModel(parent), m_files(files), m_folder(folder)
{}

int RenameExistingTableModel::rowCount(const QModelIndex &parent) const
{
	Q_UNUSED(parent);
	return m_files.count();
}

int RenameExistingTableModel::columnCount(const QModelIndex &parent) const
{
	Q_UNUSED(parent);
	return 3;
}

QVariant RenameExistingTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
	if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
		switch (section)
		{
			case 0: return QString("Thumbnail");
			case 1: return QString("Original");
			case 2: return QString("Destination");
		}
	}
	return {};
}

QVariant RenameExistingTableModel::data(const QModelIndex &index, int role) const
{
	const RenameExistingFile &image = m_files[index.row()];

	// Preview in the first column
	if (index.column() == 0 && role == Qt::DecorationRole) {
		return QPixmap(image.path).scaledToHeight(50, Qt::SmoothTransformation);
	}

	// Original path in the second column
	if (index.column() == 1 && role == Qt::DisplayRole) {
		return image.path.right(image.path.length() - m_folder.length() - 1);
	}

	// New path in the third column
	if (index.column() == 2) {
		// "no change" in red if there isn't
		if (image.path == image.newPath) {
			if (role == Qt::ForegroundRole) {
				return QVariant::fromValue(QColor(Qt::red));
			}
			if (role == Qt::DisplayRole) {
				return QString("No change");
			}
		}

		if (role == Qt::DisplayRole) {
			return image.newPath.right(image.newPath.length() - m_folder.length() - 1);
		}
	}

	return {};
}
<|endoftext|>