<commit_before>#include <QAction>
#include <QApplication>
#include <QClipboard>
#include <QBoxLayout>
#include <QPushButton>
#include <QTime>
#include <QTimer>
#ifdef TABCOMPLETION
#include <QCompleter>
QCompleter *completer=0;
#endif

#include "base.h"
#include "dialog.h"
#include "dlog.h"
#include "menu.h"
#include "note.h"
#include "proj.h"
#include "term.h"
#include "tedit.h"
#include "svr.h"
#include "state.h"
#include "recent.h"

using namespace std;

Term *term=0;
Tedit *tedit=0;

QString LastLaunch;
QTime LastLaunchTime;
QTimer *timer=0;

// ---------------------------------------------------------------------
OneWin::OneWin()
{
  note = new Note();
  split=new QSplitter(Qt::Vertical);
  split->addWidget(makeframe((QWidget *)note));
  split->addWidget(makeframe((QWidget *)term));
  QList<int> n;
  n << 0 << 1;
  //split->setSizes(n);
  QVBoxLayout *layout=new QVBoxLayout();
  layout->setContentsMargins(0,0,0,0);
  layout->addWidget(split);
  setLayout(layout);
  term->setFocus();
  show();
}

// ---------------------------------------------------------------------
void OneWin::closeEvent(QCloseEvent *event)
{
  term->filequit(true);
  event->ignore();
}

// ---------------------------------------------------------------------
QFrame *OneWin::makeframe(QWidget *w)
{
  QFrame *f=new QFrame();
  //f->setFrameStyle(QFrame::Panel | QFrame::Raised);
  f->setFrameStyle(QFrame::StyledPanel);
  QVBoxLayout *b=new QVBoxLayout();
  b->setContentsMargins(0,0,0,0);
  b->addWidget(w);
  f->setLayout(b);
  return f;
}

// ---------------------------------------------------------------------
Term::Term()
{
  QVBoxLayout *layout=new QVBoxLayout;
  layout->setContentsMargins(layout->contentsMargins());
  layout->setSpacing(0);
  menuBar = new Menu();
  tedit = new Tedit;
  layout->addWidget(menuBar);
  layout->addWidget(tedit);
  setWindowTitle("Term");
  menuBar->createActions();
  menuBar->createMenus("term");
  setLayout(layout);
  if (!ShowIde) setVisible(ShowIde);
  timer=new QTimer;
  connect(timer, SIGNAL(timeout()),this,SLOT(systimer()));
  QMetaObject::connectSlotsByName(this);
}

// ---------------------------------------------------------------------
void Term::activate()
{
  if (!term->isVisible()) return;
  activateWindow();
  raise();
  tedit->setFocus();
}

// ---------------------------------------------------------------------
void Term::changeEvent(QEvent *event)
{
  if (event->type()==QEvent::ActivationChange && isActiveWindow())
    setactivewindow(this);
  QWidget::changeEvent(event);
}

// ---------------------------------------------------------------------
void Term::cleantemp()
{
  QRegExp re("\\d*");
  QDir d=QDir(cpath("~temp"));
  d.setFilter(QDir::Files|QDir::Writable);
  QStringList t=d.entryList(QStringList() << "*.ijs");
  foreach (QString e,t)
    if (re.exactMatch(e.left(e.size()-4))) {
      QFile f(d.filePath(e));
      if (f.size()==0)
        f.remove();
    }
}

// ---------------------------------------------------------------------
void Term::closeEvent(QCloseEvent *event)
{
  filequit(false);
  event->ignore();
}

// ---------------------------------------------------------------------
void Term::displayform(int p)
{
  jcon->cmddo("0 0$9!:3[" + q2s((QString::number(p))));
}

// ---------------------------------------------------------------------
bool Term::filequit(bool ignoreconfirm)
{
  dlog_write();
  if (note && (!note->saveall())) return false;
  if (note2 && (!note2->saveall())) return false;

// save clipboard
  QClipboard *clipboard = app->clipboard();
  QEvent e=QEvent(QEvent::Clipboard);
  app->sendEvent(clipboard,&e);

  if (ignoreconfirm) {
    jcon->cmd("2!:55[0");
    cleantemp();
    state_quit();
    app->quit();
   delete app;
    return true;
  } else if ((!config.ConfirmClose) ||
             queryOK("Term","OK to exit " + config.Lang + "?")) {
    jcon->cmd("2!:55[0");
    cleantemp();
    state_quit();
    app->quit();
    delete app;
    return true;
  } else
    return false;
}

// ---------------------------------------------------------------------
// this run after configs read...
void Term::fini()
{
  menuBar->createMenus_fini("term");
  tedit->setFont(config.Font);
  QPalette p = palette();
  p.setColor(QPalette::Base, config.TermBack.color);
  p.setColor(QPalette::Text, config.TermFore.color);
  p.setColor(QPalette::Highlight, config.TermSelb.color);
  p.setColor(QPalette::HighlightedText, config.TermSelt.color);
  tedit->setPalette(p);
  setWindowIcon(QIcon(":/images/jgreen.png"));
  if (config.TermSyntaxHighlight)
    highlight(tedit->document());
#ifdef TABCOMPLETION
  completer = new QCompleter(this);
  completer->setModel(getcompletermodel(completer,config.ConfigPath.filePath(config.CompletionFile)));
  completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
  completer->setCaseSensitivity(Qt::CaseInsensitive);
  completer->setWrapAround(false);
  if (config.Completion)
    tedit->setCompleter(completer);
  else
    tedit->setCompleter(0);
#endif
  tedit->setprompt();
  if (config.SingleWin)
    new OneWin();
  else if (ShowIde)
    show();
  move(config.TermPosX[0],config.TermPosX[1]);
  resize(config.TermPosX[2],config.TermPosX[3]);
}

// ---------------------------------------------------------------------
void Term::keyPressEvent(QKeyEvent *event)
{
  switch (event->key()) {
  case Qt::Key_Escape:
    if (config.EscClose) {
      if (!filequit(false))
        event->accept();
    }
    break;
  default:
    QWidget::keyPressEvent(event);
  }
}

// ---------------------------------------------------------------------
// bug in Qt - this gets called twice, so need to check time...
void Term::launchpad_triggered(QAction *a)
{
  QString s=a->objectName();

  s=s.mid(config.LaunchPadPrefix.size());
  QTime t=QTime::currentTime();
  if (LastLaunch==s && LastLaunchTime.secsTo(t)<2) return;
  LastLaunch=s;
  LastLaunchTime=t;
  int i=config.LaunchPadKeys.indexOf(s);

  if (i<0) return;
  tedit->loadscript(config.LaunchPadValues.at(i),false);
}

// ---------------------------------------------------------------------
void Term::load(QString s, bool d)
{
  tedit->load(s,d);
}

// ---------------------------------------------------------------------
void Term::pacman()
{
  jcon->cmddo("require 'pacman ~addons/ide/qt/pacman.ijs'");
  jcon->cmddo("runpacman_jpacman_ 0");
}

// ---------------------------------------------------------------------
void Term::projectenable()
{
  bool b=project.Id.size()>0;
  menuBar->runprojectAct->setEnabled(b);
  menuBar->projectcloseAct->setEnabled(b);
}

// ---------------------------------------------------------------------
void Term::refresh()
{
  if (!term->isVisible()) return;
  tedit->resizer();
}

// ---------------------------------------------------------------------
void Term::removeprompt()
{
  tedit->removeprompt();
}

// ---------------------------------------------------------------------
void Term::resizeEvent(QResizeEvent *event)
{
  tedit->setresized(0);
  QWidget::resizeEvent(event);
}

// ---------------------------------------------------------------------
void Term::smact()
{
  if (!term->isVisible()) return;
  term->activateWindow();
  term->raise();
  term->repaint();
}

// ---------------------------------------------------------------------
void Term::smprompt(QString s)
{
  tedit->smprompt=s;
}

// ---------------------------------------------------------------------
void Term::systimer()
{
  jcon->cmddo("(i.0 0)\"_ sys_timer_z_$0");
}

// ---------------------------------------------------------------------
void Term::vieweditor()
{
  if (note) {
    note->activate();
  } else {
    note = new Note();
    if (recent.ProjectOpen)
      note->projectopen(true);
    note->show();
  }
}

<commit_msg>astyle<commit_after>#include <QAction>
#include <QApplication>
#include <QClipboard>
#include <QBoxLayout>
#include <QPushButton>
#include <QTime>
#include <QTimer>
#ifdef TABCOMPLETION
#include <QCompleter>
QCompleter *completer=0;
#endif

#include "base.h"
#include "dialog.h"
#include "dlog.h"
#include "menu.h"
#include "note.h"
#include "proj.h"
#include "term.h"
#include "tedit.h"
#include "svr.h"
#include "state.h"
#include "recent.h"

using namespace std;

Term *term=0;
Tedit *tedit=0;

QString LastLaunch;
QTime LastLaunchTime;
QTimer *timer=0;

// ---------------------------------------------------------------------
OneWin::OneWin()
{
  note = new Note();
  split=new QSplitter(Qt::Vertical);
  split->addWidget(makeframe((QWidget *)note));
  split->addWidget(makeframe((QWidget *)term));
  QList<int> n;
  n << 0 << 1;
  //split->setSizes(n);
  QVBoxLayout *layout=new QVBoxLayout();
  layout->setContentsMargins(0,0,0,0);
  layout->addWidget(split);
  setLayout(layout);
  term->setFocus();
  show();
}

// ---------------------------------------------------------------------
void OneWin::closeEvent(QCloseEvent *event)
{
  term->filequit(true);
  event->ignore();
}

// ---------------------------------------------------------------------
QFrame *OneWin::makeframe(QWidget *w)
{
  QFrame *f=new QFrame();
  //f->setFrameStyle(QFrame::Panel | QFrame::Raised);
  f->setFrameStyle(QFrame::StyledPanel);
  QVBoxLayout *b=new QVBoxLayout();
  b->setContentsMargins(0,0,0,0);
  b->addWidget(w);
  f->setLayout(b);
  return f;
}

// ---------------------------------------------------------------------
Term::Term()
{
  QVBoxLayout *layout=new QVBoxLayout;
  layout->setContentsMargins(layout->contentsMargins());
  layout->setSpacing(0);
  menuBar = new Menu();
  tedit = new Tedit;
  layout->addWidget(menuBar);
  layout->addWidget(tedit);
  setWindowTitle("Term");
  menuBar->createActions();
  menuBar->createMenus("term");
  setLayout(layout);
  if (!ShowIde) setVisible(ShowIde);
  timer=new QTimer;
  connect(timer, SIGNAL(timeout()),this,SLOT(systimer()));
  QMetaObject::connectSlotsByName(this);
}

// ---------------------------------------------------------------------
void Term::activate()
{
  if (!term->isVisible()) return;
  activateWindow();
  raise();
  tedit->setFocus();
}

// ---------------------------------------------------------------------
void Term::changeEvent(QEvent *event)
{
  if (event->type()==QEvent::ActivationChange && isActiveWindow())
    setactivewindow(this);
  QWidget::changeEvent(event);
}

// ---------------------------------------------------------------------
void Term::cleantemp()
{
  QRegExp re("\\d*");
  QDir d=QDir(cpath("~temp"));
  d.setFilter(QDir::Files|QDir::Writable);
  QStringList t=d.entryList(QStringList() << "*.ijs");
  foreach (QString e,t)
    if (re.exactMatch(e.left(e.size()-4))) {
      QFile f(d.filePath(e));
      if (f.size()==0)
        f.remove();
    }
}

// ---------------------------------------------------------------------
void Term::closeEvent(QCloseEvent *event)
{
  filequit(false);
  event->ignore();
}

// ---------------------------------------------------------------------
void Term::displayform(int p)
{
  jcon->cmddo("0 0$9!:3[" + q2s((QString::number(p))));
}

// ---------------------------------------------------------------------
bool Term::filequit(bool ignoreconfirm)
{
  dlog_write();
  if (note && (!note->saveall())) return false;
  if (note2 && (!note2->saveall())) return false;

// save clipboard
  QClipboard *clipboard = app->clipboard();
  QEvent e=QEvent(QEvent::Clipboard);
  app->sendEvent(clipboard,&e);

  if (ignoreconfirm) {
    jcon->cmd("2!:55[0");
    cleantemp();
    state_quit();
    app->quit();
    delete app;
    return true;
  } else if ((!config.ConfirmClose) ||
             queryOK("Term","OK to exit " + config.Lang + "?")) {
    jcon->cmd("2!:55[0");
    cleantemp();
    state_quit();
    app->quit();
    delete app;
    return true;
  } else
    return false;
}

// ---------------------------------------------------------------------
// this run after configs read...
void Term::fini()
{
  menuBar->createMenus_fini("term");
  tedit->setFont(config.Font);
  QPalette p = palette();
  p.setColor(QPalette::Base, config.TermBack.color);
  p.setColor(QPalette::Text, config.TermFore.color);
  p.setColor(QPalette::Highlight, config.TermSelb.color);
  p.setColor(QPalette::HighlightedText, config.TermSelt.color);
  tedit->setPalette(p);
  setWindowIcon(QIcon(":/images/jgreen.png"));
  if (config.TermSyntaxHighlight)
    highlight(tedit->document());
#ifdef TABCOMPLETION
  completer = new QCompleter(this);
  completer->setModel(getcompletermodel(completer,config.ConfigPath.filePath(config.CompletionFile)));
  completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
  completer->setCaseSensitivity(Qt::CaseInsensitive);
  completer->setWrapAround(false);
  if (config.Completion)
    tedit->setCompleter(completer);
  else
    tedit->setCompleter(0);
#endif
  tedit->setprompt();
  if (config.SingleWin)
    new OneWin();
  else if (ShowIde)
    show();
  move(config.TermPosX[0],config.TermPosX[1]);
  resize(config.TermPosX[2],config.TermPosX[3]);
}

// ---------------------------------------------------------------------
void Term::keyPressEvent(QKeyEvent *event)
{
  switch (event->key()) {
  case Qt::Key_Escape:
    if (config.EscClose) {
      if (!filequit(false))
        event->accept();
    }
    break;
  default:
    QWidget::keyPressEvent(event);
  }
}

// ---------------------------------------------------------------------
// bug in Qt - this gets called twice, so need to check time...
void Term::launchpad_triggered(QAction *a)
{
  QString s=a->objectName();

  s=s.mid(config.LaunchPadPrefix.size());
  QTime t=QTime::currentTime();
  if (LastLaunch==s && LastLaunchTime.secsTo(t)<2) return;
  LastLaunch=s;
  LastLaunchTime=t;
  int i=config.LaunchPadKeys.indexOf(s);

  if (i<0) return;
  tedit->loadscript(config.LaunchPadValues.at(i),false);
}

// ---------------------------------------------------------------------
void Term::load(QString s, bool d)
{
  tedit->load(s,d);
}

// ---------------------------------------------------------------------
void Term::pacman()
{
  jcon->cmddo("require 'pacman ~addons/ide/qt/pacman.ijs'");
  jcon->cmddo("runpacman_jpacman_ 0");
}

// ---------------------------------------------------------------------
void Term::projectenable()
{
  bool b=project.Id.size()>0;
  menuBar->runprojectAct->setEnabled(b);
  menuBar->projectcloseAct->setEnabled(b);
}

// ---------------------------------------------------------------------
void Term::refresh()
{
  if (!term->isVisible()) return;
  tedit->resizer();
}

// ---------------------------------------------------------------------
void Term::removeprompt()
{
  tedit->removeprompt();
}

// ---------------------------------------------------------------------
void Term::resizeEvent(QResizeEvent *event)
{
  tedit->setresized(0);
  QWidget::resizeEvent(event);
}

// ---------------------------------------------------------------------
void Term::smact()
{
  if (!term->isVisible()) return;
  term->activateWindow();
  term->raise();
  term->repaint();
}

// ---------------------------------------------------------------------
void Term::smprompt(QString s)
{
  tedit->smprompt=s;
}

// ---------------------------------------------------------------------
void Term::systimer()
{
  jcon->cmddo("(i.0 0)\"_ sys_timer_z_$0");
}

// ---------------------------------------------------------------------
void Term::vieweditor()
{
  if (note) {
    note->activate();
  } else {
    note = new Note();
    if (recent.ProjectOpen)
      note->projectopen(true);
    note->show();
  }
}

<|endoftext|>


<commit_before>extern "C" {
#include <libpdbg.h>
}

#include "fapi_data_process.hpp"

#include <attributes_info.H>
#include <fmt/format.h>

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <list>
#include <map>
#include <phosphor-logging/elog.hpp>
#include <sstream>
#include <string>

namespace openpower
{
namespace pels
{
namespace phal
{

using namespace phosphor::logging;

/**
 * Used to pass buffer to pdbg callback api to get required target
 * data (attributes) based on given data (attribute).
 */
struct TargetInfo
{
    ATTR_PHYS_BIN_PATH_Type physBinPath;
    ATTR_LOCATION_CODE_Type locationCode;
    ATTR_PHYS_DEV_PATH_Type physDevPath;
    ATTR_MRU_ID_Type mruId;

    bool deconfigure;

    TargetInfo()
    {
        memset(&physBinPath, '\0', sizeof(physBinPath));
        memset(&locationCode, '\0', sizeof(locationCode));
        memset(&physDevPath, '\0', sizeof(physDevPath));
        mruId = 0;
        deconfigure = false;
    }
};

/**
 * Used to return in callback function which are used to get
 * physical path value and it binary format value.
 *
 * The value for constexpr defined based on pdbg_target_traverse function usage.
 */
constexpr int continueTgtTraversal = 0;
constexpr int requireAttrFound = 1;
constexpr int requireAttrNotFound = 2;

/**
 * @brief Used to get target location code from phal device tree
 *
 * @param[in] target current device tree target
 * @param[out] appPrivData used for accessing|storing from|to application
 *
 * @return 0 to continue traverse, non-zero to stop traverse
 */
int pdbgCallbackToGetTgtReqAttrsVal(struct pdbg_target* target,
                                    void* appPrivData)
{
    TargetInfo* targetInfo = static_cast<TargetInfo*>(appPrivData);

    ATTR_PHYS_BIN_PATH_Type physBinPath;
    /**
     * TODO: Issue: phal/pdata#16
     * Should not use direct pdbg api to read attribute. Need to use DT_GET_PROP
     * macro for bmc app's and this will call libdt-api api but, it will print
     * "pdbg_target_get_attribute failed" trace if attribute is not found and
     * this callback will call recursively by using pdbg_target_traverse() until
     * find expected attribute based on return code from this callback. Because,
     * need to do target iteration to get actual attribute (ATTR_PHYS_BIN_PATH)
     * value when device tree target info doesn't know to read attribute from
     * device tree. So, Due to this error trace user will get confusion while
     * looking traces. Hence using pdbg api to avoid trace until libdt-api
     * provides log level setup.
     */
    if (!pdbg_target_get_attribute(
            target, "ATTR_PHYS_BIN_PATH",
            std::stoi(dtAttr::fapi2::ATTR_PHYS_BIN_PATH_Spec),
            dtAttr::fapi2::ATTR_PHYS_BIN_PATH_ElementCount, physBinPath))
    {
        return continueTgtTraversal;
    }

    if (std::memcmp(physBinPath, targetInfo->physBinPath,
                    sizeof(physBinPath)) != 0)
    {
        return continueTgtTraversal;
    }

    if (DT_GET_PROP(ATTR_LOCATION_CODE, target, targetInfo->locationCode))
    {
        log<level::ERR>("Could not read LOCATION_CODE attribute");
        return requireAttrNotFound;
    }

    if (DT_GET_PROP(ATTR_PHYS_DEV_PATH, target, targetInfo->physDevPath))
    {
        log<level::ERR>("Could not read PHYS_DEV_PATH attribute");
        return requireAttrNotFound;
    }

    if (DT_GET_PROP(ATTR_MRU_ID, target, targetInfo->mruId))
    {
        log<level::ERR>("Could not read MRU_ID attribute");
        return requireAttrNotFound;
    }

    if (targetInfo->deconfigure)
    {
        ATTR_HWAS_STATE_Type hwasState;
        if (DT_GET_PROP(ATTR_HWAS_STATE, target, hwasState))
        {
            log<level::ERR>("Could not read HWAS_STATE attribute");
            return requireAttrNotFound;
        }

        log<level::INFO>(fmt::format("Marking target({}) as Non-Functional",
                                     targetInfo->physDevPath)
                             .c_str());
        hwasState.functional = 0;

        if (DT_SET_PROP(ATTR_HWAS_STATE, target, hwasState))
        {
            log<level::ERR>("Could not write HWAS_STATE attribute");
            return requireAttrNotFound;
        }
    }

    return requireAttrFound;
}

/**
 * @brief Used to get target info (attributes data)
 *
 * To get target required attributes value using another attribute value
 * ("PHYS_BIN_PATH" which is present in same target attributes list) by using
 * "ipdbg_target_traverse" api because, here we have attribute value only and
 * doesn't have respective device tree target info to get required attributes
 * values from it attributes list.
 *
 * @param[in] physBinPath to pass PHYS_BIN_PATH value
 * @param[out] targetInfo to pas buufer to fill with required attributes
 *
 * @return true on success otherwise false
 */
bool getTgtReqAttrsVal(const std::vector<uint8_t>& physBinPath,
                       TargetInfo& targetInfo)
{
    std::memcpy(&targetInfo.physBinPath, physBinPath.data(),
                sizeof(targetInfo.physBinPath));

    int ret = pdbg_target_traverse(NULL, pdbgCallbackToGetTgtReqAttrsVal,
                                   &targetInfo);
    if (ret == 0)
    {
        log<level::ERR>(fmt::format("Given ATTR_PHYS_BIN_PATH value({}) "
                                    "not found in phal device tree",
                                    targetInfo.physBinPath)
                            .c_str());
        return false;
    }
    else if (ret == requireAttrNotFound)
    {
        return false;
    }

    return true;
}

/**
 * @brief GET PEL priority from pHAL priority
 *
 * The pHAL callout priority is in different format than PEL format
 * so, this api is used to return current phal supported priority into
 * PEL expected format.
 *
 * @param[in] phalPriority used to pass phal priority format string
 *
 * @return pel priority format string else empty if failure
 *
 * @note For "NONE" returning "L" (LOW)
 */
static std::string getPelPriority(const std::string& phalPriority)
{
    const std::map<std::string, std::string> priorityMap = {
        {"HIGH", "H"}, {"MEDIUM", "M"}, {"LOW", "L"}, {"NONE", "L"}};

    auto it = priorityMap.find(phalPriority);
    if (it == priorityMap.end())
    {
        log<level::ERR>(fmt::format("Unsupported phal priority({}) is given "
                                    "to get pel priority format",
                                    phalPriority)
                            .c_str());
        return "H";
    }

    return it->second;
}

void convertFAPItoPELformat(FFDC& ffdc, json& pelJSONFmtCalloutDataList,
                            FFDCData& ffdcUserData)
{
    if (ffdc.ffdc_type == FFDC_TYPE_HWP)
    {
        // Adding hardware procedures return code details
        ffdcUserData.emplace_back("HWP_RC", ffdc.hwp_errorinfo.rc);
        ffdcUserData.emplace_back("HWP_RC_DESC", ffdc.hwp_errorinfo.rc_desc);

        // Adding hardware procedures required ffdc data for debug
        for_each(
            ffdc.hwp_errorinfo.ffdcs_data.begin(),
            ffdc.hwp_errorinfo.ffdcs_data.end(),
            [&ffdcUserData](std::pair<std::string, std::string>& ele) -> void {
                std::string keyWithPrefix("HWP_FFDC_");
                keyWithPrefix.append(ele.first);

                ffdcUserData.emplace_back(keyWithPrefix, ele.second);
            });

        // Adding hardware callout details
        int calloutCount = 0;
        for_each(
            ffdc.hwp_errorinfo.hwcallouts.begin(),
            ffdc.hwp_errorinfo.hwcallouts.end(),
            [&ffdcUserData, &calloutCount,
             &pelJSONFmtCalloutDataList](const HWCallout& hwCallout) -> void {
                calloutCount++;
                std::stringstream keyPrefix;
                keyPrefix << "HWP_HW_CO_" << std::setfill('0') << std::setw(2)
                          << calloutCount << "_";

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("HW_ID"),
                    hwCallout.hwid);

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("PRIORITY"),
                    hwCallout.callout_priority);

                phal::TargetInfo targetInfo;
                phal::getTgtReqAttrsVal(hwCallout.target_entity_path,
                                        targetInfo);

                std::string locationCode = std::string(targetInfo.locationCode);
                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("LOC_CODE"),
                    locationCode);

                std::string physPath = std::string(targetInfo.physDevPath);
                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("PHYS_PATH"), physPath);

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("CLK_POS"),
                    std::to_string(hwCallout.clkPos));

                json jsonCalloutData;
                jsonCalloutData["LocationCode"] = locationCode;
                std::string pelPriority =
                    getPelPriority(hwCallout.callout_priority);
                jsonCalloutData["Priority"] = pelPriority;

                if (targetInfo.mruId != 0)
                {
                    jsonCalloutData["MRUs"] = json::array({
                        {{"ID", targetInfo.mruId}, {"Priority", pelPriority}},
                    });
                }

                pelJSONFmtCalloutDataList.emplace_back(jsonCalloutData);
            });

        // Adding CDG (callout, deconfigure and guard) targets details
        calloutCount = 0;
        for_each(
            ffdc.hwp_errorinfo.cdg_targets.begin(),
            ffdc.hwp_errorinfo.cdg_targets.end(),
            [&ffdcUserData, &calloutCount,
             &pelJSONFmtCalloutDataList](const CDG_Target& cdg_tgt) -> void {
                calloutCount++;
                std::stringstream keyPrefix;
                keyPrefix << "HWP_CDG_TGT_" << std::setfill('0') << std::setw(2)
                          << calloutCount << "_";

                phal::TargetInfo targetInfo;
                targetInfo.deconfigure = cdg_tgt.deconfigure;

                phal::getTgtReqAttrsVal(cdg_tgt.target_entity_path, targetInfo);

                std::string locationCode = std::string(targetInfo.locationCode);
                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("LOC_CODE"),
                    locationCode);
                std::string physPath = std::string(targetInfo.physDevPath);
                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("PHYS_PATH"), physPath);

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("CO_REQ"),
                    (cdg_tgt.callout == true ? "true" : "false"));

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("CO_PRIORITY"),
                    cdg_tgt.callout_priority);

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("DECONF_REQ"),
                    (cdg_tgt.deconfigure == true ? "true" : "false"));

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("GUARD_REQ"),
                    (cdg_tgt.guard == true ? "true" : "false"));

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("GUARD_TYPE"),
                    cdg_tgt.guard_type);

                json jsonCalloutData;
                jsonCalloutData["LocationCode"] = locationCode;
                std::string pelPriority =
                    getPelPriority(cdg_tgt.callout_priority);
                jsonCalloutData["Priority"] = pelPriority;

                if (targetInfo.mruId != 0)
                {
                    jsonCalloutData["MRUs"] = json::array({
                        {{"ID", targetInfo.mruId}, {"Priority", pelPriority}},
                    });
                }
                jsonCalloutData["Deconfigured"] = cdg_tgt.deconfigure;
                jsonCalloutData["Guarded"] = cdg_tgt.guard;

                pelJSONFmtCalloutDataList.emplace_back(jsonCalloutData);
            });
    }
    else if ((ffdc.ffdc_type != FFDC_TYPE_NONE) &&
             (ffdc.ffdc_type != FFDC_TYPE_UNSUPPORTED))
    {
        log<level::ERR>(fmt::format("Unsupported phal FFDC type to create PEL. "
                                    "MSG: {}",
                                    ffdc.message)
                            .c_str());
    }
}

} // namespace phal
} // namespace pels
} // namespace openpower
<commit_msg>PEL: Guard related service action support for SBE logs<commit_after>extern "C" {
#include <libpdbg.h>
}

#include "fapi_data_process.hpp"

#include <attributes_info.H>
#include <fmt/format.h>

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <list>
#include <map>
#include <phosphor-logging/elog.hpp>
#include <sstream>
#include <string>

namespace openpower
{
namespace pels
{
namespace phal
{

using namespace phosphor::logging;

/**
 * Used to pass buffer to pdbg callback api to get required target
 * data (attributes) based on given data (attribute).
 */
struct TargetInfo
{
    ATTR_PHYS_BIN_PATH_Type physBinPath;
    ATTR_LOCATION_CODE_Type locationCode;
    ATTR_PHYS_DEV_PATH_Type physDevPath;
    ATTR_MRU_ID_Type mruId;

    bool deconfigure;

    TargetInfo()
    {
        memset(&physBinPath, '\0', sizeof(physBinPath));
        memset(&locationCode, '\0', sizeof(locationCode));
        memset(&physDevPath, '\0', sizeof(physDevPath));
        mruId = 0;
        deconfigure = false;
    }
};

/**
 * Used to return in callback function which are used to get
 * physical path value and it binary format value.
 *
 * The value for constexpr defined based on pdbg_target_traverse function usage.
 */
constexpr int continueTgtTraversal = 0;
constexpr int requireAttrFound = 1;
constexpr int requireAttrNotFound = 2;

/**
 * @brief Used to get target location code from phal device tree
 *
 * @param[in] target current device tree target
 * @param[out] appPrivData used for accessing|storing from|to application
 *
 * @return 0 to continue traverse, non-zero to stop traverse
 */
int pdbgCallbackToGetTgtReqAttrsVal(struct pdbg_target* target,
                                    void* appPrivData)
{
    TargetInfo* targetInfo = static_cast<TargetInfo*>(appPrivData);

    ATTR_PHYS_BIN_PATH_Type physBinPath;
    /**
     * TODO: Issue: phal/pdata#16
     * Should not use direct pdbg api to read attribute. Need to use DT_GET_PROP
     * macro for bmc app's and this will call libdt-api api but, it will print
     * "pdbg_target_get_attribute failed" trace if attribute is not found and
     * this callback will call recursively by using pdbg_target_traverse() until
     * find expected attribute based on return code from this callback. Because,
     * need to do target iteration to get actual attribute (ATTR_PHYS_BIN_PATH)
     * value when device tree target info doesn't know to read attribute from
     * device tree. So, Due to this error trace user will get confusion while
     * looking traces. Hence using pdbg api to avoid trace until libdt-api
     * provides log level setup.
     */
    if (!pdbg_target_get_attribute(
            target, "ATTR_PHYS_BIN_PATH",
            std::stoi(dtAttr::fapi2::ATTR_PHYS_BIN_PATH_Spec),
            dtAttr::fapi2::ATTR_PHYS_BIN_PATH_ElementCount, physBinPath))
    {
        return continueTgtTraversal;
    }

    if (std::memcmp(physBinPath, targetInfo->physBinPath,
                    sizeof(physBinPath)) != 0)
    {
        return continueTgtTraversal;
    }

    if (DT_GET_PROP(ATTR_LOCATION_CODE, target, targetInfo->locationCode))
    {
        log<level::ERR>("Could not read LOCATION_CODE attribute");
        return requireAttrNotFound;
    }

    if (DT_GET_PROP(ATTR_PHYS_DEV_PATH, target, targetInfo->physDevPath))
    {
        log<level::ERR>("Could not read PHYS_DEV_PATH attribute");
        return requireAttrNotFound;
    }

    if (DT_GET_PROP(ATTR_MRU_ID, target, targetInfo->mruId))
    {
        log<level::ERR>("Could not read MRU_ID attribute");
        return requireAttrNotFound;
    }

    if (targetInfo->deconfigure)
    {
        ATTR_HWAS_STATE_Type hwasState;
        if (DT_GET_PROP(ATTR_HWAS_STATE, target, hwasState))
        {
            log<level::ERR>("Could not read HWAS_STATE attribute");
            return requireAttrNotFound;
        }

        log<level::INFO>(fmt::format("Marking target({}) as Non-Functional",
                                     targetInfo->physDevPath)
                             .c_str());
        hwasState.functional = 0;

        if (DT_SET_PROP(ATTR_HWAS_STATE, target, hwasState))
        {
            log<level::ERR>("Could not write HWAS_STATE attribute");
            return requireAttrNotFound;
        }
    }

    return requireAttrFound;
}

/**
 * @brief Used to get target info (attributes data)
 *
 * To get target required attributes value using another attribute value
 * ("PHYS_BIN_PATH" which is present in same target attributes list) by using
 * "ipdbg_target_traverse" api because, here we have attribute value only and
 * doesn't have respective device tree target info to get required attributes
 * values from it attributes list.
 *
 * @param[in] physBinPath to pass PHYS_BIN_PATH value
 * @param[out] targetInfo to pas buufer to fill with required attributes
 *
 * @return true on success otherwise false
 */
bool getTgtReqAttrsVal(const std::vector<uint8_t>& physBinPath,
                       TargetInfo& targetInfo)
{
    std::memcpy(&targetInfo.physBinPath, physBinPath.data(),
                sizeof(targetInfo.physBinPath));

    int ret = pdbg_target_traverse(NULL, pdbgCallbackToGetTgtReqAttrsVal,
                                   &targetInfo);
    if (ret == 0)
    {
        log<level::ERR>(fmt::format("Given ATTR_PHYS_BIN_PATH value({}) "
                                    "not found in phal device tree",
                                    targetInfo.physBinPath)
                            .c_str());
        return false;
    }
    else if (ret == requireAttrNotFound)
    {
        return false;
    }

    return true;
}

/**
 * @brief GET PEL priority from pHAL priority
 *
 * The pHAL callout priority is in different format than PEL format
 * so, this api is used to return current phal supported priority into
 * PEL expected format.
 *
 * @param[in] phalPriority used to pass phal priority format string
 *
 * @return pel priority format string else empty if failure
 *
 * @note For "NONE" returning "L" (LOW)
 */
static std::string getPelPriority(const std::string& phalPriority)
{
    const std::map<std::string, std::string> priorityMap = {
        {"HIGH", "H"}, {"MEDIUM", "M"}, {"LOW", "L"}, {"NONE", "L"}};

    auto it = priorityMap.find(phalPriority);
    if (it == priorityMap.end())
    {
        log<level::ERR>(fmt::format("Unsupported phal priority({}) is given "
                                    "to get pel priority format",
                                    phalPriority)
                            .c_str());
        return "H";
    }

    return it->second;
}

void convertFAPItoPELformat(FFDC& ffdc, json& pelJSONFmtCalloutDataList,
                            FFDCData& ffdcUserData)
{
    if (ffdc.ffdc_type == FFDC_TYPE_HWP)
    {
        // Adding hardware procedures return code details
        ffdcUserData.emplace_back("HWP_RC", ffdc.hwp_errorinfo.rc);
        ffdcUserData.emplace_back("HWP_RC_DESC", ffdc.hwp_errorinfo.rc_desc);

        // Adding hardware procedures required ffdc data for debug
        for_each(
            ffdc.hwp_errorinfo.ffdcs_data.begin(),
            ffdc.hwp_errorinfo.ffdcs_data.end(),
            [&ffdcUserData](std::pair<std::string, std::string>& ele) -> void {
                std::string keyWithPrefix("HWP_FFDC_");
                keyWithPrefix.append(ele.first);

                ffdcUserData.emplace_back(keyWithPrefix, ele.second);
            });

        // Adding hardware callout details
        int calloutCount = 0;
        for_each(
            ffdc.hwp_errorinfo.hwcallouts.begin(),
            ffdc.hwp_errorinfo.hwcallouts.end(),
            [&ffdcUserData, &calloutCount,
             &pelJSONFmtCalloutDataList](const HWCallout& hwCallout) -> void {
                calloutCount++;
                std::stringstream keyPrefix;
                keyPrefix << "HWP_HW_CO_" << std::setfill('0') << std::setw(2)
                          << calloutCount << "_";

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("HW_ID"),
                    hwCallout.hwid);

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("PRIORITY"),
                    hwCallout.callout_priority);

                phal::TargetInfo targetInfo;
                phal::getTgtReqAttrsVal(hwCallout.target_entity_path,
                                        targetInfo);

                std::string locationCode = std::string(targetInfo.locationCode);
                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("LOC_CODE"),
                    locationCode);

                std::string physPath = std::string(targetInfo.physDevPath);
                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("PHYS_PATH"), physPath);

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("CLK_POS"),
                    std::to_string(hwCallout.clkPos));

                json jsonCalloutData;
                jsonCalloutData["LocationCode"] = locationCode;
                std::string pelPriority =
                    getPelPriority(hwCallout.callout_priority);
                jsonCalloutData["Priority"] = pelPriority;

                if (targetInfo.mruId != 0)
                {
                    jsonCalloutData["MRUs"] = json::array({
                        {{"ID", targetInfo.mruId}, {"Priority", pelPriority}},
                    });
                }

                pelJSONFmtCalloutDataList.emplace_back(jsonCalloutData);
            });

        // Adding CDG (callout, deconfigure and guard) targets details
        calloutCount = 0;
        for_each(
            ffdc.hwp_errorinfo.cdg_targets.begin(),
            ffdc.hwp_errorinfo.cdg_targets.end(),
            [&ffdcUserData, &calloutCount,
             &pelJSONFmtCalloutDataList](const CDG_Target& cdg_tgt) -> void {
                calloutCount++;
                std::stringstream keyPrefix;
                keyPrefix << "HWP_CDG_TGT_" << std::setfill('0') << std::setw(2)
                          << calloutCount << "_";

                phal::TargetInfo targetInfo;
                targetInfo.deconfigure = cdg_tgt.deconfigure;

                phal::getTgtReqAttrsVal(cdg_tgt.target_entity_path, targetInfo);

                std::string locationCode = std::string(targetInfo.locationCode);
                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("LOC_CODE"),
                    locationCode);
                std::string physPath = std::string(targetInfo.physDevPath);
                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("PHYS_PATH"), physPath);

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("CO_REQ"),
                    (cdg_tgt.callout == true ? "true" : "false"));

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("CO_PRIORITY"),
                    cdg_tgt.callout_priority);

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("DECONF_REQ"),
                    (cdg_tgt.deconfigure == true ? "true" : "false"));

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("GUARD_REQ"),
                    (cdg_tgt.guard == true ? "true" : "false"));

                ffdcUserData.emplace_back(
                    std::string(keyPrefix.str()).append("GUARD_TYPE"),
                    cdg_tgt.guard_type);

                json jsonCalloutData;
                jsonCalloutData["LocationCode"] = locationCode;
                std::string pelPriority =
                    getPelPriority(cdg_tgt.callout_priority);
                jsonCalloutData["Priority"] = pelPriority;

                if (targetInfo.mruId != 0)
                {
                    jsonCalloutData["MRUs"] = json::array({
                        {{"ID", targetInfo.mruId}, {"Priority", pelPriority}},
                    });
                }
                jsonCalloutData["Deconfigured"] = cdg_tgt.deconfigure;
                jsonCalloutData["Guarded"] = cdg_tgt.guard;
                jsonCalloutData["GuardType"] = cdg_tgt.guard_type;
                jsonCalloutData["EntityPath"] = cdg_tgt.target_entity_path;

                pelJSONFmtCalloutDataList.emplace_back(jsonCalloutData);
            });
    }
    else if ((ffdc.ffdc_type != FFDC_TYPE_NONE) &&
             (ffdc.ffdc_type != FFDC_TYPE_UNSUPPORTED))
    {
        log<level::ERR>(fmt::format("Unsupported phal FFDC type to create PEL. "
                                    "MSG: {}",
                                    ffdc.message)
                            .c_str());
    }
}

} // namespace phal
} // namespace pels
} // namespace openpower
<|endoftext|>


<commit_before>/*
** Copyright 2011-2012 Merethis
**
** This file is part of Centreon Clib.
**
** Centreon Clib is free software: you can redistribute it
** and/or modify it under the terms of the GNU Affero General Public
** License as published by the Free Software Foundation, either version
** 3 of the License, or (at your option) any later version.
**
** Centreon Clib 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
** Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public
** License along with Centreon Clib. If not, see
** <http://www.gnu.org/licenses/>.
*/

#ifndef CC_EXCEPTIONS_BASIC_HH
#  define CC_EXCEPTIONS_BASIC_HH

#  include <exception>
#  include <string>
#  include "com/centreon/namespace.hh"
#  include "com/centreon/misc/stringifier.hh"

CC_BEGIN()

namespace               exceptions {
  /**
   *  @class basic basic.hh "com/centreon/exceptions/basic.hh"
   *  @brief Base exception class.
   *
   *  Simple exception class containing an basic error message.
   */
  class                 basic : public std::exception {
  public:
                        basic() throw();
                        basic(
                          char const* file,
                          char const* function,
                          int line) throw ();
                        basic(basic const& right) throw ();
    virtual             ~basic() throw ();
    virtual basic&      operator=(basic const& right) throw ();
    template<typename T>
    basic&              operator<<(T t) throw () {
      _buffer << t;
      return (*this);
    }
    virtual char const* what() const throw ();

  private:
    basic&              _internal_copy(basic const& right);

    misc::stringifier   _buffer;
  };
}

CC_END()

#  if defined(__GNUC__)
#    define FUNCTION __PRETTY_FUNCTION__
#  elif defined(_MSC_VER)
#    define FUNCTION __FUNCSIG__
#  else
#    define FUNCTION __func__
#  endif // GCC, Visual or other.

#  ifndef NDEBUG
#    define basic_error() com::centreon::exceptions::basic( \
                          __FILE__,                         \
                          FUNCTION,                         \
                          __LINE__)
#  else
#    define basic_error() com::centreon::exceptions::basic()
#  endif // !NDEBUG
#endif // !CC_EXCEPTIONS_BASIC_HH
<commit_msg>Try to use __FUNCSIG__ instead of _MSC_VER.<commit_after>/*
** Copyright 2011-2012 Merethis
**
** This file is part of Centreon Clib.
**
** Centreon Clib is free software: you can redistribute it
** and/or modify it under the terms of the GNU Affero General Public
** License as published by the Free Software Foundation, either version
** 3 of the License, or (at your option) any later version.
**
** Centreon Clib 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
** Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public
** License along with Centreon Clib. If not, see
** <http://www.gnu.org/licenses/>.
*/

#ifndef CC_EXCEPTIONS_BASIC_HH
#  define CC_EXCEPTIONS_BASIC_HH

#  include <exception>
#  include <string>
#  include "com/centreon/namespace.hh"
#  include "com/centreon/misc/stringifier.hh"

CC_BEGIN()

namespace               exceptions {
  /**
   *  @class basic basic.hh "com/centreon/exceptions/basic.hh"
   *  @brief Base exception class.
   *
   *  Simple exception class containing an basic error message.
   */
  class                 basic : public std::exception {
  public:
                        basic() throw();
                        basic(
                          char const* file,
                          char const* function,
                          int line) throw ();
                        basic(basic const& right) throw ();
    virtual             ~basic() throw ();
    virtual basic&      operator=(basic const& right) throw ();
    template<typename T>
    basic&              operator<<(T t) throw () {
      _buffer << t;
      return (*this);
    }
    virtual char const* what() const throw ();

  private:
    basic&              _internal_copy(basic const& right);

    misc::stringifier   _buffer;
  };
}

CC_END()

#  if defined(__GNUC__)
#    define FUNCTION __PRETTY_FUNCTION__
#  elif defined(__FUNCSIG__)
#    define FUNCTION __FUNCSIG__
#  else
#    define FUNCTION __func__
#  endif // GCC, Visual or other.

#  ifndef NDEBUG
#    define basic_error() com::centreon::exceptions::basic( \
                          __FILE__,                         \
                          FUNCTION,                         \
                          __LINE__)
#  else
#    define basic_error() com::centreon::exceptions::basic()
#  endif // !NDEBUG
#endif // !CC_EXCEPTIONS_BASIC_HH
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: standardcontrol.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-06 13:46:58 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _EXTENSIONS_PROPCTRLR_STANDARDCONTROL_HXX_
#define _EXTENSIONS_PROPCTRLR_STANDARDCONTROL_HXX_

#ifndef _EXTENSIONS_PROPCTRLR_COMMONCONTROL_HXX_
#include "commoncontrol.hxx"
#endif
#ifndef _SV_FIELD_HXX
#include <vcl/field.hxx>
#endif
#ifndef _LONGCURR_HXX
#include <vcl/longcurr.hxx>
#endif
#ifndef _CTRLBOX_HXX
#include <svtools/ctrlbox.hxx>
#endif
#ifndef _SV_LSTBOX_HXX
#include <vcl/lstbox.hxx>
#endif
#ifndef _SV_COMBOBOX_HXX
#include <vcl/combobox.hxx>
#endif
#ifndef _CALENDAR_HXX
#include <svtools/calendar.hxx>
#endif

class PushButton;
class MultiLineEdit;
//............................................................................
namespace pcr
{
//............................................................................

    //========================================================================
    //= OTimeControl
    //========================================================================
    class OTimeControl : public OCommonBehaviourControl, TimeField
    {
    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            OTimeControl( Window* pParent, WinBits nWinStyle = WB_TABSTOP);

            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;
    };

    //========================================================================
    //= ODateControl
    //========================================================================
    class ODateControl : public OCommonBehaviourControl, CalendarField
    {
    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            ODateControl( Window* pParent, WinBits nWinStyle = WB_TABSTOP);

            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;
    };

    //========================================================================
    //= OEditControl
    //========================================================================
    class OEditControl : public OCommonBehaviourControl, Edit
    {
    protected:
        sal_Bool                            m_bIsPassword : 1;

    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            OEditControl(Window* _pParent, sal_Bool _bPassWord, WinBits nWinStyle = WB_TABSTOP);

            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;

    protected:
            virtual void modified(Window* _pSource);
    };

    //========================================================================
    //= OCurrencyControl
    //========================================================================
    class OCurrencyControl : public OCommonBehaviourControl, LongCurrencyField
    {
    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            OCurrencyControl( Window* pParent,sal_uInt16 nDigits,
                                                        WinBits nWinStyle = WB_TABSTOP);

            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;
    };

    //========================================================================
    //= ONumericControl
    //========================================================================
    class ONumericControl : public OCommonBehaviourControl, MetricField
    {
    private:
        FieldUnit   m_eValueUnit;

    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
            ONumericControl( Window* pParent, sal_uInt16 nDigits, WinBits nWinStyle = WB_TABSTOP );

            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;

            void                            SetMin(sal_Int32 _nMin) { MetricField::SetMin(_nMin); }
            void                            SetMax(sal_Int32 _nMax) { MetricField::SetMax(_nMax); }
            void                            SetFieldUnit( FieldUnit _eUnit ) { MetricField::SetUnit( _eUnit ); }
            void                            SetValueUnit( FieldUnit _eUnit ) { m_eValueUnit = _eUnit; }

    protected:
        MetricField::SetUnit;
        MetricField::SetCustomUnitText;
        MetricField::GetCurUnitText;
        MetricField::SetValue;
    protected:
    inline long  GetLastValue() const { return mnLastValue; }
    };

    //========================================================================
    //= OColorControl
    //========================================================================
    class OColorControl : public OCommonBehaviourControl, ColorListBox
    {
    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            OColorControl( Window* pParent, WinBits nWinStyle = WB_TABSTOP |WB_DROPDOWN|WB_AUTOSIZE);

            // property value handling
            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;

            // list handling
            virtual sal_Bool                HasList();
            virtual void                    ClearList();
            virtual void                    InsertCtrEntry( const ::rtl::OUString& rString, sal_uInt16 nPos = LISTBOX_APPEND );

            virtual void                    SetCtrSize(const Size& rSize);

    protected:
            virtual void modified(Window* _pSource);
    };

    //========================================================================
    //= OListboxControl
    //========================================================================
    class OListboxControl : public OCommonBehaviourControl, ListBox
    {
    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            OListboxControl( Window* pParent, WinBits nWinStyle = WB_TABSTOP|WB_SORT|WB_DROPDOWN|WB_AUTOSIZE);

            // property value handling
            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;

            // list handling
            virtual sal_Bool                HasList();
            virtual void                    ClearList();
            virtual void                    InsertCtrEntry( const ::rtl::OUString& rString, sal_uInt16 nPos = LISTBOX_APPEND );

            virtual void                    SetCtrSize(const Size& rSize);

    protected:
            virtual void modified(Window* _pSource);
    };

    //========================================================================
    //= OComboboxControl
    //========================================================================
    class OComboboxControl : public OCommonBehaviourControl, ComboBox
    {
    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            OComboboxControl( Window* pParent,
                                                    WinBits nWinStyle = WB_TABSTOP | WB_SORT | WB_DROPDOWN | WB_AUTOSIZE);

            // property value handling
            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;

            // list handling
            virtual sal_Bool                HasList();
            virtual void                    ClearList();
            virtual void                    InsertCtrEntry( const ::rtl::OUString& rString, sal_uInt16 nPos = LISTBOX_APPEND );

            virtual void                    SetCtrSize(const Size& rSize);

    };

    //========================================================================
    //= OMultilineEditControl
    //========================================================================
    class OMultilineFloatingEdit;
    class OMultilineEditControl : public OCommonBehaviourControl, Edit
    {
            OMultilineFloatingEdit*             m_pFloatingEdit;
            MultiLineEdit*                      m_pImplEdit;
            PushButton*                         m_pDropdownButton;
            sal_Bool                            m_bDropdown :1;
            sal_Bool                            m_bEdit     :1;

            DECL_LINK(ReturnHdl,OMultilineFloatingEdit*);
            DECL_LINK(DropDownHdl, PushButton*);

    protected:

            virtual long                    PreNotify( NotifyEvent& rNEvt );
            void                            Resize();

            long                            FindPos(long nSinglePos);

    public:
                                            OMultilineEditControl( Window* pParent,sal_Bool bEdit,
                                                        WinBits nWinStyle = WB_TABSTOP | WB_DROPDOWN);

                                            ~OMultilineEditControl();

            virtual sal_Bool                ShowDropDown( sal_Bool bShow );

            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;

            virtual void                    SetLocked(sal_Bool bLocked=sal_True);
    protected:
            virtual void modified(Window* _pSource);
    };

//............................................................................
} // namespace pcr
//............................................................................

#endif // _EXTENSIONS_PROPCTRLR_STANDARDCONTROL_HXX_

<commit_msg>INTEGRATION: CWS eforms2 (1.3.24); FILE MERGED 2004/07/27 14:06:30 fs 1.3.24.3: RESYNC: (1.3-1.4); FILE MERGED 2004/07/16 15:41:44 fs 1.3.24.2: #114856# +DateTime type, and some cleanup at the IBrowserControl 2004/04/26 11:30:56 fs 1.3.24.1: some cleanup/consolidation<commit_after>/*************************************************************************
 *
 *  $RCSfile: standardcontrol.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-16 12:12:45 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _EXTENSIONS_PROPCTRLR_STANDARDCONTROL_HXX_
#define _EXTENSIONS_PROPCTRLR_STANDARDCONTROL_HXX_

#ifndef _EXTENSIONS_PROPCTRLR_COMMONCONTROL_HXX_
#include "commoncontrol.hxx"
#endif
#ifndef _SV_FIELD_HXX
#include <vcl/field.hxx>
#endif
#ifndef _LONGCURR_HXX
#include <vcl/longcurr.hxx>
#endif
#ifndef _CTRLBOX_HXX
#include <svtools/ctrlbox.hxx>
#endif
#ifndef _SV_LSTBOX_HXX
#include <vcl/lstbox.hxx>
#endif
#ifndef _SV_COMBOBOX_HXX
#include <vcl/combobox.hxx>
#endif
#ifndef _CALENDAR_HXX
#include <svtools/calendar.hxx>
#endif
#ifndef _FMTFIELD_HXX_
#include <svtools/fmtfield.hxx>
#endif

#include <memory>

class PushButton;
class MultiLineEdit;
//............................................................................
namespace pcr
{
//............................................................................

    class StringRepresentation;

    //========================================================================
    //= OTimeControl
    //========================================================================
    class OTimeControl : public OCommonBehaviourControl, TimeField
    {
    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            OTimeControl( Window* pParent, WinBits nWinStyle = WB_TABSTOP);

            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;
    };

    //========================================================================
    //= ODateControl
    //========================================================================
    class ODateControl : public OCommonBehaviourControl, CalendarField
    {
    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            ODateControl( Window* pParent, WinBits nWinStyle = WB_TABSTOP);

            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;
    };

    //========================================================================
    //= OEditControl
    //========================================================================
    class OEditControl : public OCommonBehaviourControl, Edit
    {
    protected:
        sal_Bool                            m_bIsPassword : 1;

    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            OEditControl(Window* _pParent, sal_Bool _bPassWord, WinBits nWinStyle = WB_TABSTOP);

            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;

    protected:
            virtual void modified(Window* _pSource);
    };

    //========================================================================
    //= OCurrencyControl
    //========================================================================
    class OCurrencyControl : public OCommonBehaviourControl, LongCurrencyField
    {
    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            OCurrencyControl( Window* pParent,sal_uInt16 nDigits,
                                                        WinBits nWinStyle = WB_TABSTOP);

            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;
    };

    //========================================================================
    //= ODateTimeControl
    //========================================================================
    class ODateTimeControl : public OCommonBehaviourControl, FormattedField
    {
    private:
        ::std::auto_ptr< StringRepresentation > m_pConverter;

    public:
                                            ODateTimeControl( Window* pParent,sal_uInt16 nDigits, WinBits nWinStyle = WB_TABSTOP );

            virtual void                    SetProperty( const ::rtl::OUString& _rString,sal_Bool _bIsUnknown = sal_False );
            virtual ::rtl::OUString         GetProperty() const;
    };

    //========================================================================
    //= ONumericControl
    //========================================================================
    class ONumericControl : public OCommonBehaviourControl, MetricField
    {
    private:
        FieldUnit   m_eValueUnit;

    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
            ONumericControl( Window* pParent, sal_uInt16 nDigits, WinBits nWinStyle = WB_TABSTOP );

            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;

            void                            SetMin(sal_Int32 _nMin) { MetricField::SetMin(_nMin); }
            void                            SetMax(sal_Int32 _nMax) { MetricField::SetMax(_nMax); }
            void                            SetFieldUnit( FieldUnit _eUnit ) { MetricField::SetUnit( _eUnit ); }
            void                            SetValueUnit( FieldUnit _eUnit ) { m_eValueUnit = _eUnit; }

    protected:
        MetricField::SetUnit;
        MetricField::SetCustomUnitText;
        MetricField::GetCurUnitText;
        MetricField::SetValue;
    protected:
    inline long  GetLastValue() const { return mnLastValue; }
    };

    //========================================================================
    //= OColorControl
    //========================================================================
    class OColorControl : public OCommonBehaviourControl, ColorListBox
    {
    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            OColorControl( Window* pParent, WinBits nWinStyle = WB_TABSTOP |WB_DROPDOWN|WB_AUTOSIZE);

            // property value handling
            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;

            // list handling
            virtual sal_Bool                HasList();
            virtual void                    ClearList();
            virtual void                    InsertCtrEntry( const ::rtl::OUString& rString, sal_uInt16 nPos = LISTBOX_APPEND );

            virtual void                    SetCtrSize(const Size& rSize);

    protected:
            virtual void modified(Window* _pSource);
    };

    //========================================================================
    //= OListboxControl
    //========================================================================
    class OListboxControl : public OCommonBehaviourControl, ListBox
    {
    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            OListboxControl( Window* pParent, WinBits nWinStyle = WB_TABSTOP|WB_SORT|WB_DROPDOWN|WB_AUTOSIZE);

            // property value handling
            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;

            // list handling
            virtual sal_Bool                HasList();
            virtual void                    ClearList();
            virtual void                    InsertCtrEntry( const ::rtl::OUString& rString, sal_uInt16 nPos = LISTBOX_APPEND );

            virtual void                    SetCtrSize(const Size& rSize);

    protected:
            virtual void modified(Window* _pSource);
    };

    //========================================================================
    //= OComboboxControl
    //========================================================================
    class OComboboxControl : public OCommonBehaviourControl, ComboBox
    {
    protected:
            virtual long                    PreNotify( NotifyEvent& rNEvt );

    public:
                                            OComboboxControl( Window* pParent,
                                                    WinBits nWinStyle = WB_TABSTOP | WB_SORT | WB_DROPDOWN | WB_AUTOSIZE);

            // property value handling
            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;

            // list handling
            virtual sal_Bool                HasList();
            virtual void                    ClearList();
            virtual void                    InsertCtrEntry( const ::rtl::OUString& rString, sal_uInt16 nPos = LISTBOX_APPEND );

            virtual void                    SetCtrSize(const Size& rSize);

    };

    //========================================================================
    //= OMultilineEditControl
    //========================================================================
    class OMultilineFloatingEdit;
    class OMultilineEditControl : public OCommonBehaviourControl, Edit
    {
            OMultilineFloatingEdit*             m_pFloatingEdit;
            MultiLineEdit*                      m_pImplEdit;
            PushButton*                         m_pDropdownButton;
            sal_Bool                            m_bDropdown :1;
            sal_Bool                            m_bEdit     :1;

            DECL_LINK(ReturnHdl,OMultilineFloatingEdit*);
            DECL_LINK(DropDownHdl, PushButton*);

    protected:

            virtual long                    PreNotify( NotifyEvent& rNEvt );
            void                            Resize();

            long                            FindPos(long nSinglePos);

    public:
                                            OMultilineEditControl( Window* pParent,sal_Bool bEdit,
                                                        WinBits nWinStyle = WB_TABSTOP | WB_DROPDOWN);

                                            ~OMultilineEditControl();

            virtual sal_Bool                ShowDropDown( sal_Bool bShow );

            virtual void                    SetProperty(const ::rtl::OUString &rString,sal_Bool bIsUnknown=sal_False);
            virtual ::rtl::OUString         GetProperty()const;

    protected:
            virtual void modified(Window* _pSource);
    };

//............................................................................
} // namespace pcr
//............................................................................

#endif // _EXTENSIONS_PROPCTRLR_STANDARDCONTROL_HXX_

<|endoftext|>


<commit_before>#include "tilesetController.hpp"

#include "tilesetManager.hpp"

#include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/Sprite.hpp>

#include <SFGUI/Adjustment.hpp>
#include <SFGUI/Box.hpp>
#include <SFGUI/Button.hpp>
#include <SFGUI/Desktop.hpp>
#include <SFGUI/Frame.hpp>
#include <SFGUI/Image.hpp>
#include <SFGUI/Label.hpp>
#include <SFGUI/Scale.hpp>

TilesetController::TilesetController(TilesetManager &tilesetManager, sfg::Desktop &desktop) :
  mTilesetManager(tilesetManager),
  mDesktop(desktop)
{
  initGui();
}

void TilesetController::update()
{
  //Offset
  static auto lastOffset = mCurrentOffset;
  if (lastOffset != mCurrentOffset)
  {
    lastOffset = mCurrentOffset;
    redrawCanvas();
  }
  //Zoom
  static auto lastZoom = mCurrentZoom;
  mCurrentZoom = mGui.zoomScale->GetValue();
  if (lastZoom != mCurrentZoom)
  {
    auto cursorPos = mGui.zoomEntry->GetCursorPosition();
    mGui.zoomEntry->SetText(std::to_string(static_cast<int>(mCurrentZoom * 100)) + "%");
    mGui.zoomEntry->SetCursorPosition(cursorPos);
    redrawCanvas();
    lastZoom = mCurrentZoom;
  }
  //Size
  static auto lastSize = mGui.notebook->GetAllocation();
  auto currentSize = mGui.notebook->GetAllocation();
  if (lastSize.width != currentSize.width || lastSize.height != currentSize.height)
  {
    lastSize = currentSize;
    redrawCanvas();
  }
}

void TilesetController::redrawCanvas()
{
  if (mGui.tilesetPages.size() != 0)
  {
    std::cout << "Redraw, canvas: " << mGui.activePage->texName << std::endl;
    const sf::Texture &tex = mTilesetManager.getTileset(mGui.activePage->canvas->GetId());
    if (mRenderTex.getSize() != sf::Vector2u(static_cast<unsigned>(mGui.activePage->canvas->GetAllocation().width),
      static_cast<unsigned>(mGui.activePage->canvas->GetAllocation().height)))
    {
      std::cout << "Recreated texture" << std::endl;
      mRenderTex.create(static_cast<unsigned>(mGui.activePage->canvas->GetAllocation().width),
        static_cast<unsigned>(mGui.activePage->canvas->GetAllocation().height));
    }

    sf::Sprite sprite(tex);
    sprite.scale({ mCurrentZoom, mCurrentZoom });
    auto view = mRenderTex.getDefaultView();
    view.setCenter({ mCurrentOffset.x + sprite.getGlobalBounds().width / 2.f, mCurrentOffset.y + sprite.getGlobalBounds().height / 2.f });
    mRenderTex.setView(view);
    mRenderTex.clear();
    mRenderTex.draw(sprite);
    mRenderTex.display();
    sf::Sprite sprite2(mRenderTex.getTexture());
    std::cout << "Draw" << std::endl;
    mGui.activePage->canvas->Clear();
    mGui.activePage->canvas->Draw(sprite2);
    mGui.activePage->canvas->Display();
    std::cout << "Offset: " << mCurrentOffset.x << " | " << mCurrentOffset.y << std::endl;
    auto difference_x = sprite.getGlobalBounds().width - mRenderTex.getSize().x;
    if (difference_x > 0)
    {
      mGui.activePage->hScrollbar->Show(true);
      auto adj = mGui.activePage->hScrollbar->GetAdjustment();
      adj->Configure(mCurrentOffset.x, -difference_x / 2.f, difference_x / 2.f, difference_x / 100.f, difference_x / 5.f, 1);
    }
    else
    {
      mGui.activePage->hScrollbar->Show(false);
      mGui.activePage->hScrollbar->SetValue(0);
    }
    auto difference_y = sprite.getGlobalBounds().height - mRenderTex.getSize().y;
    if (difference_y > 0)
    {
      mGui.activePage->vScrollbar->Show(true);
      auto adj = mGui.activePage->vScrollbar->GetAdjustment();
      adj->Configure(mCurrentOffset.y, -difference_y / 2.f, difference_y / 2.f, difference_y / 100.f, difference_y / 5.f, 1.f);
    }
    else
    {
      mGui.activePage->vScrollbar->Show(false);
      mGui.activePage->vScrollbar->SetValue(0);
    }
  }
}

void TilesetController::openLoadTilesetDialog()
{
  mGui.loadTilesetName->SetText("tileset.png");

  mGui.loadTilesetDialog->Show(true);
  mGui.loadTilesetDialog->GrabFocus();
}

void TilesetController::loadNewTileset()
{
  auto name = mGui.loadTilesetName->GetText();
  if (mTilesetManager.loadTileset(name))
  {
    addTilesetToView(name);
    mGui.loadTilesetDialog->Show(false);
    mGui.notebook->SetCurrentPage(mGui.notebook->GetPageCount() - 1);
    updateActiveCanvas();
  }
  else
  {

  }
}

void TilesetController::updateActiveCanvas()
{
  auto activePage = mGui.notebook->GetCurrentPage();
  if (mGui.tilesetPages.size() != 0)
  {
    auto ptr = &mGui.tilesetPages[activePage];
    if (ptr != mGui.activePage)
    {
      mGui.activePage = ptr;
      redrawCanvas();
    }
  }
}

void TilesetController::updateZoom()
{
  std::string text = mGui.zoomEntry->GetText();
  if (text.size() > 0)
  {
    if (text.back() == '%')
      text.pop_back();
    mCurrentZoom = static_cast<float>(std::atof(text.c_str()));
    if (mCurrentZoom <= 0)
      mCurrentZoom = 1;
    else
      mCurrentZoom /= 100;

    mGui.zoomScale->SetValue(mCurrentZoom);
  }
}

void TilesetController::updateOffset()
{
  mCurrentOffset.x = mGui.activePage->hScrollbar->GetValue();
  mCurrentOffset.y = mGui.activePage->vScrollbar->GetValue();
}

void TilesetController::addTilesetToView(const std::string &name)
{
  auto label = sfg::Label::Create(name);
  auto box = sfg::Box::Create(sfg::Box::Orientation::VERTICAL);
  auto subBox = sfg::Box::Create();
  auto canvas = sfg::Canvas::Create();
  canvas->SetId(name);
  canvas->SetRequisition({ 200, 200 });
  subBox->Pack(canvas);
  auto vScrollbar = sfg::Scrollbar::Create(sfg::Scrollbar::Orientation::VERTICAL);
  vScrollbar->SetRequisition({ 25, 0 });
  vScrollbar->SetRange(0, 100);
  vScrollbar->SetIncrements(1, 5);
  vScrollbar->GetAdjustment()->GetSignal(sfg::Adjustment::OnChange).Connect(std::bind(&TilesetController::updateOffset, this));
  subBox->Pack(vScrollbar, false);
  auto hScrollbar = sfg::Scrollbar::Create();
  hScrollbar->SetRequisition({ 0, 25 });
  hScrollbar->SetIncrements(1, 5);
  hScrollbar->SetRange(0, 100);
  hScrollbar->GetAdjustment()->GetSignal(sfg::Adjustment::OnChange).Connect(std::bind(&TilesetController::updateOffset, this));
  box->Pack(subBox);
  box->Pack(hScrollbar, false);
  mGui.notebook->AppendPage(box, label);
  mGui.tilesetPages.push_back({ canvas, hScrollbar, vScrollbar, name });

  //Check if the preview page is still there, delete if so
  if (mGui.notebook->GetNthPage(0)->GetId() == "preview")
  {
    mGui.notebook->RemovePage(0);
  }
}

void TilesetController::initGui()
{
  initTilesetWindow();
  initLoadTilesetDialog();
}

void TilesetController::initTilesetWindow()
{
  auto box = sfg::Box::Create(sfg::Box::Orientation::VERTICAL);

  //TILESET view
  mGui.notebook = sfg::Notebook::Create();
  mGui.notebook->GetSignal(sfg::Notebook::OnLeftClick).Connect(std::bind(&TilesetController::updateActiveCanvas, this));
  mGui.notebook->GetSignal(sfg::Notebook::OnSizeAllocate).Connect(std::bind(&TilesetController::redrawCanvas, this));

  auto label = sfg::Label::Create("No tileset loaded");
  auto canvas = sfg::Canvas::Create();
  canvas->SetRequisition({ 50.f, 50.f });
  canvas->SetId("preview");
  mGui.notebook->AppendPage(canvas, label);

  box->Pack(mGui.notebook);

  //CONTROLS
  auto subBox = sfg::Box::Create();
  box->Pack(subBox, false);

  auto bt = sfg::Button::Create("Add");
  bt->GetSignal(sfg::Button::OnLeftClick).Connect(std::bind(&TilesetController::openLoadTilesetDialog, this));
  subBox->Pack(bt, false);
  bt = sfg::Button::Create("Remove");
  subBox->Pack(bt, false);
  mGui.zoomEntry = sfg::Entry::Create("100%");
  mGui.zoomEntry->SetRequisition({ 50.f, 0.f });
  mGui.zoomEntry->GetSignal(sfg::Entry::OnTextChanged).Connect(std::bind(&TilesetController::updateZoom, this));
  subBox->Pack(mGui.zoomEntry, false);
  mGui.zoomScale = sfg::Scale::Create(0, 5, 0.1f);
  mGui.zoomScale->SetValue(1.f);
  mGui.zoomScale->SetRequisition({ 0, 10 });
  subBox->Pack(mGui.zoomScale);

  auto window = sfg::Window::Create(sfg::Window::Style::TOPLEVEL | sfg::Window::Style::SHADOW);
  window->SetTitle("Tilemaps");
  window->Add(box);
  mDesktop.Add(window);
}

void TilesetController::initLoadTilesetDialog()
{
  mGui.loadTilesetDialog = sfg::Window::Create(sfg::Window::Style::BACKGROUND |
    sfg::Window::Style::TITLEBAR);
  mGui.loadTilesetDialog->SetTitle("Load new Tileset");

  auto box = sfg::Box::Create(sfg::Box::Orientation::VERTICAL, 5.f);

  auto frame = sfg::Frame::Create("Enter tileset name with extension");
  mGui.loadTilesetName = sfg::Entry::Create("tileset.png");
  frame->Add(mGui.loadTilesetName);
  box->Pack(frame);

  auto subBox = sfg::Box::Create(sfg::Box::Orientation::HORIZONTAL, 5.f);
  auto bt = sfg::Button::Create("Load");
  bt->GetSignal(sfg::Button::OnLeftClick).Connect(std::bind(&TilesetController::loadNewTileset, this));
  subBox->Pack(bt);
  bt = sfg::Button::Create("Cancel");
  bt->GetSignal(sfg::Button::OnLeftClick).Connect([this](){mGui.loadTilesetDialog->Show(false); });
  subBox->Pack(bt);

  box->Pack(subBox);

  mGui.loadTilesetDialog->Add(box);
  mGui.loadTilesetDialog->Show(false);
  //mLoadTilesetDialog.window->SetZOrder(5);
  mDesktop.Add(mGui.loadTilesetDialog);
}<commit_msg>Error handling when the tileset could not be loaded<commit_after>#include "tilesetController.hpp"

#include "tilesetManager.hpp"

#include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/Sprite.hpp>

#include <SFGUI/Adjustment.hpp>
#include <SFGUI/Box.hpp>
#include <SFGUI/Button.hpp>
#include <SFGUI/Desktop.hpp>
#include <SFGUI/Frame.hpp>
#include <SFGUI/Image.hpp>
#include <SFGUI/Label.hpp>
#include <SFGUI/Scale.hpp>

TilesetController::TilesetController(TilesetManager &tilesetManager, sfg::Desktop &desktop) :
  mTilesetManager(tilesetManager),
  mDesktop(desktop)
{
  initGui();
}

void TilesetController::update()
{
  //Offset
  static auto lastOffset = mCurrentOffset;
  if (lastOffset != mCurrentOffset)
  {
    lastOffset = mCurrentOffset;
    redrawCanvas();
  }
  //Zoom
  static auto lastZoom = mCurrentZoom;
  mCurrentZoom = mGui.zoomScale->GetValue();
  if (lastZoom != mCurrentZoom)
  {
    auto cursorPos = mGui.zoomEntry->GetCursorPosition();
    mGui.zoomEntry->SetText(std::to_string(static_cast<int>(mCurrentZoom * 100)) + "%");
    mGui.zoomEntry->SetCursorPosition(cursorPos);
    redrawCanvas();
    lastZoom = mCurrentZoom;
  }
  //Size
  static auto lastSize = mGui.notebook->GetAllocation();
  auto currentSize = mGui.notebook->GetAllocation();
  if (lastSize.width != currentSize.width || lastSize.height != currentSize.height)
  {
    lastSize = currentSize;
    redrawCanvas();
  }
}

void TilesetController::redrawCanvas()
{
  if (mGui.tilesetPages.size() != 0)
  {
    std::cout << "Redraw, canvas: " << mGui.activePage->texName << std::endl;
    const sf::Texture &tex = mTilesetManager.getTileset(mGui.activePage->canvas->GetId());
    if (mRenderTex.getSize() != sf::Vector2u(static_cast<unsigned>(mGui.activePage->canvas->GetAllocation().width),
      static_cast<unsigned>(mGui.activePage->canvas->GetAllocation().height)))
    {
      std::cout << "Recreated texture" << std::endl;
      mRenderTex.create(static_cast<unsigned>(mGui.activePage->canvas->GetAllocation().width),
        static_cast<unsigned>(mGui.activePage->canvas->GetAllocation().height));
    }

    sf::Sprite sprite(tex);
    sprite.scale({ mCurrentZoom, mCurrentZoom });
    auto view = mRenderTex.getDefaultView();
    view.setCenter({ mCurrentOffset.x + sprite.getGlobalBounds().width / 2.f, mCurrentOffset.y + sprite.getGlobalBounds().height / 2.f });
    mRenderTex.setView(view);
    mRenderTex.clear();
    mRenderTex.draw(sprite);
    mRenderTex.display();
    sf::Sprite sprite2(mRenderTex.getTexture());
    std::cout << "Draw" << std::endl;
    mGui.activePage->canvas->Clear();
    mGui.activePage->canvas->Draw(sprite2);
    mGui.activePage->canvas->Display();
    std::cout << "Offset: " << mCurrentOffset.x << " | " << mCurrentOffset.y << std::endl;
    auto difference_x = sprite.getGlobalBounds().width - mRenderTex.getSize().x;
    if (difference_x > 0)
    {
      mGui.activePage->hScrollbar->Show(true);
      auto adj = mGui.activePage->hScrollbar->GetAdjustment();
      adj->Configure(mCurrentOffset.x, -difference_x / 2.f, difference_x / 2.f, difference_x / 100.f, difference_x / 5.f, 1);
    }
    else
    {
      mGui.activePage->hScrollbar->Show(false);
      mGui.activePage->hScrollbar->SetValue(0);
    }
    auto difference_y = sprite.getGlobalBounds().height - mRenderTex.getSize().y;
    if (difference_y > 0)
    {
      mGui.activePage->vScrollbar->Show(true);
      auto adj = mGui.activePage->vScrollbar->GetAdjustment();
      adj->Configure(mCurrentOffset.y, -difference_y / 2.f, difference_y / 2.f, difference_y / 100.f, difference_y / 5.f, 1.f);
    }
    else
    {
      mGui.activePage->vScrollbar->Show(false);
      mGui.activePage->vScrollbar->SetValue(0);
    }
  }
}

void TilesetController::openLoadTilesetDialog()
{
  mGui.loadTilesetName->SetText("tileset.png");

  mGui.loadTilesetDialog->Show(true);
  mGui.loadTilesetDialog->GrabFocus();
}

void TilesetController::loadNewTileset()
{
  auto name = mGui.loadTilesetName->GetText();
  if (mTilesetManager.loadTileset(name))
  {
    addTilesetToView(name);
    mGui.loadTilesetDialog->Show(false);
    mGui.notebook->SetCurrentPage(mGui.notebook->GetPageCount() - 1);
    updateActiveCanvas();
  }
  else
  {
    mGui.loadTilesetName->SetText("Could not load the file");
  }
}

void TilesetController::updateActiveCanvas()
{
  auto activePage = mGui.notebook->GetCurrentPage();
  if (mGui.tilesetPages.size() != 0)
  {
    auto ptr = &mGui.tilesetPages[activePage];
    if (ptr != mGui.activePage)
    {
      mGui.activePage = ptr;
      redrawCanvas();
    }
  }
}

void TilesetController::updateZoom()
{
  std::string text = mGui.zoomEntry->GetText();
  if (text.size() > 0)
  {
    if (text.back() == '%')
      text.pop_back();
    mCurrentZoom = static_cast<float>(std::atof(text.c_str()));
    if (mCurrentZoom <= 0)
      mCurrentZoom = 1;
    else
      mCurrentZoom /= 100;

    mGui.zoomScale->SetValue(mCurrentZoom);
  }
}

void TilesetController::updateOffset()
{
  mCurrentOffset.x = mGui.activePage->hScrollbar->GetValue();
  mCurrentOffset.y = mGui.activePage->vScrollbar->GetValue();
}

void TilesetController::addTilesetToView(const std::string &name)
{
  auto label = sfg::Label::Create(name);
  auto box = sfg::Box::Create(sfg::Box::Orientation::VERTICAL);
  auto subBox = sfg::Box::Create();
  auto canvas = sfg::Canvas::Create();
  canvas->SetId(name);
  canvas->SetRequisition({ 200, 200 });
  subBox->Pack(canvas);
  auto vScrollbar = sfg::Scrollbar::Create(sfg::Scrollbar::Orientation::VERTICAL);
  vScrollbar->SetRequisition({ 25, 0 });
  vScrollbar->SetRange(0, 100);
  vScrollbar->SetIncrements(1, 5);
  vScrollbar->GetAdjustment()->GetSignal(sfg::Adjustment::OnChange).Connect(std::bind(&TilesetController::updateOffset, this));
  subBox->Pack(vScrollbar, false);
  auto hScrollbar = sfg::Scrollbar::Create();
  hScrollbar->SetRequisition({ 0, 25 });
  hScrollbar->SetIncrements(1, 5);
  hScrollbar->SetRange(0, 100);
  hScrollbar->GetAdjustment()->GetSignal(sfg::Adjustment::OnChange).Connect(std::bind(&TilesetController::updateOffset, this));
  box->Pack(subBox);
  box->Pack(hScrollbar, false);
  mGui.notebook->AppendPage(box, label);
  mGui.tilesetPages.push_back({ canvas, hScrollbar, vScrollbar, name });

  //Check if the preview page is still there, delete if so
  if (mGui.notebook->GetNthPage(0)->GetId() == "preview")
  {
    mGui.notebook->RemovePage(0);
  }
}

void TilesetController::initGui()
{
  initTilesetWindow();
  initLoadTilesetDialog();
}

void TilesetController::initTilesetWindow()
{
  auto box = sfg::Box::Create(sfg::Box::Orientation::VERTICAL);

  //TILESET view
  mGui.notebook = sfg::Notebook::Create();
  mGui.notebook->GetSignal(sfg::Notebook::OnLeftClick).Connect(std::bind(&TilesetController::updateActiveCanvas, this));
  mGui.notebook->GetSignal(sfg::Notebook::OnSizeAllocate).Connect(std::bind(&TilesetController::redrawCanvas, this));

  auto label = sfg::Label::Create("No tileset loaded");
  auto canvas = sfg::Canvas::Create();
  canvas->SetRequisition({ 50.f, 50.f });
  canvas->SetId("preview");
  mGui.notebook->AppendPage(canvas, label);

  box->Pack(mGui.notebook);

  //CONTROLS
  auto subBox = sfg::Box::Create();
  box->Pack(subBox, false);

  auto bt = sfg::Button::Create("Add");
  bt->GetSignal(sfg::Button::OnLeftClick).Connect(std::bind(&TilesetController::openLoadTilesetDialog, this));
  subBox->Pack(bt, false);
  bt = sfg::Button::Create("Remove");
  subBox->Pack(bt, false);
  mGui.zoomEntry = sfg::Entry::Create("100%");
  mGui.zoomEntry->SetRequisition({ 50.f, 0.f });
  mGui.zoomEntry->GetSignal(sfg::Entry::OnTextChanged).Connect(std::bind(&TilesetController::updateZoom, this));
  subBox->Pack(mGui.zoomEntry, false);
  mGui.zoomScale = sfg::Scale::Create(0, 5, 0.1f);
  mGui.zoomScale->SetValue(1.f);
  mGui.zoomScale->SetRequisition({ 0, 10 });
  subBox->Pack(mGui.zoomScale);

  auto window = sfg::Window::Create(sfg::Window::Style::TOPLEVEL | sfg::Window::Style::SHADOW);
  window->SetTitle("Tilemaps");
  window->Add(box);
  mDesktop.Add(window);
}

void TilesetController::initLoadTilesetDialog()
{
  mGui.loadTilesetDialog = sfg::Window::Create(sfg::Window::Style::BACKGROUND |
    sfg::Window::Style::TITLEBAR);
  mGui.loadTilesetDialog->SetTitle("Load new Tileset");

  auto box = sfg::Box::Create(sfg::Box::Orientation::VERTICAL, 5.f);

  auto frame = sfg::Frame::Create("Enter tileset name with extension");
  mGui.loadTilesetName = sfg::Entry::Create("tileset.png");
  frame->Add(mGui.loadTilesetName);
  box->Pack(frame);

  auto subBox = sfg::Box::Create(sfg::Box::Orientation::HORIZONTAL, 5.f);
  auto bt = sfg::Button::Create("Load");
  bt->GetSignal(sfg::Button::OnLeftClick).Connect(std::bind(&TilesetController::loadNewTileset, this));
  subBox->Pack(bt);
  bt = sfg::Button::Create("Cancel");
  bt->GetSignal(sfg::Button::OnLeftClick).Connect([this](){mGui.loadTilesetDialog->Show(false); });
  subBox->Pack(bt);

  box->Pack(subBox);

  mGui.loadTilesetDialog->Add(box);
  mGui.loadTilesetDialog->Show(false);
  //mLoadTilesetDialog.window->SetZOrder(5);
  mDesktop.Add(mGui.loadTilesetDialog);
}<|endoftext|>