<commit_before>#include "SentenceStateBuilder.h"

#include <vector>

#include "Sysout.h"

#include "../language/Grammar.h"
#include "../language/Dictionary.h"

gmr::SentenceState* SentenceStateBuilder::processStatement(std::vector<std::string>* statement)
{
    // Make a new builder
    SentenceStateBuilder* ssbuilder = new SentenceStateBuilder();

    // Loop through all the words
    for(std::vector<std::string>::iterator wordPtr = statement->begin(); wordPtr != statement->end(); ++ wordPtr)
    {
    /* === Testing for nouns === */

        // Remembers if this word is a noun
        bool isNoun = false;

        // Test for nouns
        for(gmr::NounId possiblyMatchingNounId = 0; possiblyMatchingNounId < Dictionary::numNouns(); ++ possiblyMatchingNounId)
        {
            // Does it match the singular form?
            if(*wordPtr == Dictionary::getNoun(possiblyMatchingNounId)->getSingularForm())
            {
                // Process it
                ssbuilder->processNoun(possiblyMatchingNounId, gmr::singular);

                // It is a noun
                isNoun = true;

                // Do not test for the other nouns
                break;
            }

            // Does it match the plural form?
            else if(*wordPtr == Dictionary::getNoun(possiblyMatchingNounId)->getPluralForm())
            {
                // Process it
                ssbuilder->processNoun(possiblyMatchingNounId, gmr::plural);

                // It is a noun
                isNoun = true;

                // Do not test for the other nouns
                break;
            }
        }

        // If it is a noun, then obviously it can't be anything else,
        // So stop analyzing this word and look at the next word
        if(isNoun) { continue; }

    /* === Testing for articles === */

        // Test for articles
        gmr::ArticleProperties testArticleProperties = Dictionary::getArticle(*wordPtr);

        // If this article type is not erroneous
        if(testArticleProperties.type != gmr::undefinite)
        {
            ssbuilder->processArticle(testArticleProperties);

            // Continue to next word
            continue;
        }

    /* === Testing for modifiers === */

        // Remembers if this word is a noun
        bool isModifier = false;

        //
        gmr::ModifierId possiblyMatchingModifierId = Dictionary::getModifierId(*wordPtr);

        // Test for modifiers
        Sysout::println(possiblyMatchingModifierId);
        if(possiblyMatchingModifierId != Dictionary::getErroneousModifierId())
        {
            // Process it
        Sysout::println("notatnererr");
        Sysout::println(Dictionary::getModifier(possiblyMatchingModifierId)->getForm());
            ssbuilder->processModifier(possiblyMatchingModifierId);

            // It is a modifier
            isModifier = true;

            // Do not test for the other nouns
            break;
        }

        // If it is a noun, then obviously it can't be anything else,
        // So stop analyzing this word and look at the next word
        if(isModifier) { continue; }

    /* === Testing for adjuncts === */

        // Put something here
    }

    gmr::SentenceState* sntcState = ssbuilder->finish();

    delete ssbuilder;

    return sntcState;
}

gmr::SentenceState* SentenceStateBuilder::finish()
{
    return new gmr::SentenceState(completedNouns);
}

void SentenceStateBuilder::publishNoun()
{
    // Add the workspace address to the collection of addresses of completed nouns
    completedNouns->push_back(wipNoun);

    // Make a new workspace
    wipNoun = new gmr::NounState();
}

void SentenceStateBuilder::processNoun(gmr::NounId id, gmr::Plurality plurality)
{
    // If we can tell the difference between plural and singular
    if(!Dictionary::getNoun(id)->hasAmbiguousPlurality())
    {
        wipNoun->plurality = plurality;
    }

    // Set the id
    wipNoun->id = id;

    // Publish the noun
    publishNoun();
}

void SentenceStateBuilder::processArticle(gmr::ArticleProperties properties)
{
    // If we do not already know the plurality for the noun
    if(wipNoun->plurality == gmr::ambiguous)
    {
        // Set it to be this one
        wipNoun->plurality = properties.plurality;
    }

    // Set its definity
    wipNoun->definity = properties.type;
}

void SentenceStateBuilder::processModifier(gmr::ModifierId modifierId)
{
    bool alreadyHas = false;
    for(unsigned int indexOffset = 0; indexOffset < wipNoun->modifiers->size(); ++ indexOffset)
    {
        if(wipNoun->modifiers->at(indexOffset) == modifierId)
        {
            alreadyHas = true;
            break;
        }
    }

    if(!alreadyHas)
    {
        wipNoun->modifiers->push_back(modifierId);
    }
}

SentenceStateBuilder::SentenceStateBuilder()
{
    wipNoun = new gmr::NounState(); // The space we will build our work in progress (WIP) noun
    completedNouns = new std::vector<gmr::NounState*>(); // All of our completed nouns
}
<commit_msg>Fixed modifier recognition<commit_after>#include "SentenceStateBuilder.h"

#include <vector>

#include "../language/Grammar.h"
#include "../language/Dictionary.h"

gmr::SentenceState* SentenceStateBuilder::processStatement(std::vector<std::string>* statement)
{
    // Make a new builder
    SentenceStateBuilder* ssbuilder = new SentenceStateBuilder();

    // Loop through all the words
    for(std::vector<std::string>::iterator wordPtr = statement->begin(); wordPtr != statement->end(); ++ wordPtr)
    {
    /* === Testing for nouns === */

        // Remembers if this word is a noun
        bool isNoun = false;

        // Test for nouns
        for(gmr::NounId possiblyMatchingNounId = 0; possiblyMatchingNounId < Dictionary::numNouns(); ++ possiblyMatchingNounId)
        {
            // Does it match the singular form?
            if(*wordPtr == Dictionary::getNoun(possiblyMatchingNounId)->getSingularForm())
            {
                // Process it
                ssbuilder->processNoun(possiblyMatchingNounId, gmr::singular);

                // It is a noun
                isNoun = true;

                // Do not test for the other nouns
                break;
            }

            // Does it match the plural form?
            else if(*wordPtr == Dictionary::getNoun(possiblyMatchingNounId)->getPluralForm())
            {
                // Process it
                ssbuilder->processNoun(possiblyMatchingNounId, gmr::plural);

                // It is a noun
                isNoun = true;

                // Do not test for the other nouns
                break;
            }
        }

        // If it is a noun, then obviously it can't be anything else,
        // So stop analyzing this word and look at the next word
        if(isNoun) { continue; }

    /* === Testing for articles === */

        // Test for articles
        gmr::ArticleProperties testArticleProperties = Dictionary::getArticle(*wordPtr);

        // If this article type is not erroneous
        if(testArticleProperties.type != gmr::undefinite)
        {
            ssbuilder->processArticle(testArticleProperties);

            // Continue to next word
            continue;
        }

    /* === Testing for modifiers === */

        //
        gmr::ModifierId possiblyMatchingModifierId = Dictionary::getModifierId(*wordPtr);

        // Test for modifiers
        if(possiblyMatchingModifierId != Dictionary::getErroneousModifierId())
        {
            // Process it
            ssbuilder->processModifier(possiblyMatchingModifierId);

            // If it is a modifier, then obviously it can't be anything else,
            // So stop analyzing this word and look at the next word
            continue;
        }

    /* === Testing for adjuncts === */

        // Put something here
    }

    gmr::SentenceState* sntcState = ssbuilder->finish();

    delete ssbuilder;

    return sntcState;
}

gmr::SentenceState* SentenceStateBuilder::finish()
{
    return new gmr::SentenceState(completedNouns);
}

void SentenceStateBuilder::publishNoun()
{
    // Add the workspace address to the collection of addresses of completed nouns
    completedNouns->push_back(wipNoun);

    // Make a new workspace
    wipNoun = new gmr::NounState();
}

void SentenceStateBuilder::processNoun(gmr::NounId id, gmr::Plurality plurality)
{
    // If we can tell the difference between plural and singular
    if(!Dictionary::getNoun(id)->hasAmbiguousPlurality())
    {
        wipNoun->plurality = plurality;
    }

    // Set the id
    wipNoun->id = id;

    // Publish the noun
    publishNoun();
}

void SentenceStateBuilder::processArticle(gmr::ArticleProperties properties)
{
    // If we do not already know the plurality for the noun
    if(wipNoun->plurality == gmr::ambiguous)
    {
        // Set it to be this one
        wipNoun->plurality = properties.plurality;
    }

    // Set its definity
    wipNoun->definity = properties.type;
}

void SentenceStateBuilder::processModifier(gmr::ModifierId modifierId)
{
    bool alreadyHas = false;
    for(unsigned int indexOffset = 0; indexOffset < wipNoun->modifiers->size(); ++ indexOffset)
    {
        if(wipNoun->modifiers->at(indexOffset) == modifierId)
        {
            alreadyHas = true;
            break;
        }
    }

    if(!alreadyHas)
    {
        wipNoun->modifiers->push_back(modifierId);
    }
}

SentenceStateBuilder::SentenceStateBuilder()
{
    wipNoun = new gmr::NounState(); // The space we will build our work in progress (WIP) noun
    completedNouns = new std::vector<gmr::NounState*>(); // All of our completed nouns
}
<|endoftext|>


<commit_before>#include "glyphcellrenderer.h"

#include <wx/dcclient.h>
#include <wx/graphics.h>

#include <memory>

GlyphCellRenderer::GlyphCellRenderer(const std::map<wxString, SvgGlyph> &glyphs, int fontSize): glyphs(glyphs), fontSize(fontSize)
{

}

wxGridCellRenderer *GlyphCellRenderer::Clone() const
{
	return nullptr;
}

void GlyphCellRenderer::Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, const wxRect &rect, int row, int col, bool isSelected)
{
    wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);

	wxString value = grid.GetTable()->GetValue(row, col);

	auto it = glyphs.find(value);
	if (it == glyphs.end()) return;

    const SvgGlyph &glyph = it->second;

    if (!glyph.isOk())
        return;

    // Oh, crap
    wxRect newRect = rect;
    newRect.x += dc.GetDeviceOrigin().x;
    newRect.y += dc.GetDeviceOrigin().y;

    std::unique_ptr<wxGraphicsContext> gc(wxGraphicsContext::Create(static_cast<wxPaintDC&>(dc)));
	gc->SetBrush(wxBrush(*wxBLACK));

    SvgPath path(glyph.data.ToStdString());
    SvgGlyphCtrl::RenderGlyph(gc.get(), newRect, path, glyph, fontSize);
}

wxSize GlyphCellRenderer::GetBestSize(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, int row, int col)
{
    return wxSize(fontSize + 4, fontSize + 4);
}
<commit_msg>do not set device origins for GDI+ graphics context<commit_after>#include "glyphcellrenderer.h"

#include <wx/dcclient.h>
#include <wx/graphics.h>

#include <memory>

GlyphCellRenderer::GlyphCellRenderer(const std::map<wxString, SvgGlyph> &glyphs, int fontSize): glyphs(glyphs), fontSize(fontSize)
{

}

wxGridCellRenderer *GlyphCellRenderer::Clone() const
{
	return nullptr;
}

void GlyphCellRenderer::Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, const wxRect &rect, int row, int col, bool isSelected)
{
    wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);

	wxString value = grid.GetTable()->GetValue(row, col);

	auto it = glyphs.find(value);
	if (it == glyphs.end()) return;

    const SvgGlyph &glyph = it->second;

    if (!glyph.isOk())
        return;

    std::unique_ptr<wxGraphicsContext> gc(wxGraphicsContext::Create(static_cast<wxPaintDC&>(dc)));
	gc->SetBrush(wxBrush(*wxBLACK));

    wxRect newRect = rect;

    // Oh, crap
    if (gc->GetRenderer()->GetName() == L"cairo")
    {
        newRect.x += dc.GetDeviceOrigin().x;
        newRect.y += dc.GetDeviceOrigin().y;
    }

    SvgPath path(glyph.data.ToStdString());
    SvgGlyphCtrl::RenderGlyph(gc.get(), newRect, path, glyph, fontSize);
}

wxSize GlyphCellRenderer::GetBestSize(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, int row, int col)
{
    return wxSize(fontSize + 4, fontSize + 4);
}
<|endoftext|>


<commit_before>#include "archivestabwidget.h"

WARNINGS_DISABLE
#include <QAction>
#include <QComboBox>
#include <QCoreApplication>
#include <QCursor>
#include <QEvent>
#include <QEventLoop>
#include <QKeyEvent>
#include <QKeySequence>
#include <QMenu>
#include <QWidget>
#include <Qt>

#include "ui_archivestabwidget.h"
WARNINGS_ENABLE

#include "archivelistwidget.h"
#include "archivewidget.h"
#include "basetask.h"
#include "persistentmodel/archive.h"

ArchivesTabWidget::ArchivesTabWidget(QWidget *parent)
    : QWidget(parent), _ui(new Ui::ArchivesTabWidget)
{
    // Ui initialization
    _ui->setupUi(this);
    updateUi();

    // Basic UI setup.
    _ui->archiveListWidget->setAttribute(Qt::WA_MacShowFocusRect, false);
    _ui->archiveDetailsWidget->hide();
    _ui->archivesFilterFrame->hide();

    // Context menu.
    _archiveListMenu = new QMenu(_ui->archiveListWidget);
    connect(_ui->archiveListWidget,
            &ArchiveListWidget::customContextMenuRequested, this,
            &ArchivesTabWidget::showArchiveListMenu);

    // Context menu actions.
    _ui->archiveListWidget->addAction(_ui->actionRefresh);
    _ui->archiveListWidget->addAction(_ui->actionInspect);
    _ui->archiveListWidget->addAction(_ui->actionDelete);
    _ui->archiveListWidget->addAction(_ui->actionRestore);
    connect(_ui->actionInspect, &QAction::triggered, _ui->archiveListWidget,
            &ArchiveListWidget::inspectSelectedItem);
    connect(_ui->actionDelete, &QAction::triggered, _ui->archiveListWidget,
            &ArchiveListWidget::deleteSelectedItems);
    connect(_ui->actionRestore, &QAction::triggered, _ui->archiveListWidget,
            &ArchiveListWidget::restoreSelectedItem);

    // Connections from the ArchiveListWidget.
    connect(_ui->archiveListWidget, &ArchiveListWidget::inspectArchive, this,
            &ArchivesTabWidget::displayInspectArchive);
    connect(_ui->archiveListWidget, &ArchiveListWidget::clearInspectArchive,
            this, &ArchivesTabWidget::hideInspectArchive);
    connect(_ui->archiveListWidget, &ArchiveListWidget::deleteArchives, this,
            &ArchivesTabWidget::deleteArchives);
    connect(_ui->archiveListWidget, &ArchiveListWidget::restoreArchive, this,
            &ArchivesTabWidget::restoreArchive);
    connect(_ui->archiveListWidget, &ArchiveListWidget::displayJobDetails,
            [this](const QString &jobRef) { emit displayJobDetails(jobRef); });
    connect(_ui->archiveListWidget, &ArchiveListWidget::countChanged,
            [this](int total, int visible) {
                _ui->archivesCountLabel->setText(
                    tr("Archives (%1/%2)").arg(visible).arg(total));
            });

    // Connections to the ArchiveListWidget.
    connect(this, &ArchivesTabWidget::archiveList, _ui->archiveListWidget,
            &ArchiveListWidget::setArchives);
    connect(this, &ArchivesTabWidget::addArchive, _ui->archiveListWidget,
            &ArchiveListWidget::addArchive);

    // Connections from the ArchiveDetailsWidget.
    connect(_ui->archiveDetailsWidget, &ArchiveDetailsWidget::restoreArchive,
            this, &ArchivesTabWidget::restoreArchive);
    connect(_ui->archiveDetailsWidget, &ArchiveDetailsWidget::hidden,
            _ui->archiveListWidget, &ArchiveListWidget::noInspect);
    connect(_ui->archiveDetailsWidget, &ArchiveDetailsWidget::taskRequested,
            this, &ArchivesTabWidget::taskRequested);
    connect(_ui->archiveDetailsWidget, &ArchiveDetailsWidget::jobClicked,
            [this](const QString &jobRef) { emit jobClicked(jobRef); });

    // Filtering.
    _ui->archiveListWidget->addAction(_ui->actionFilterArchives);
    _ui->archivesFilterButton->setDefaultAction(_ui->actionFilterArchives);
    connect(_ui->archivesFilter, &QComboBox::editTextChanged,
            _ui->archiveListWidget, &ArchiveListWidget::setFilter);
    connect(_ui->actionFilterArchives, &QAction::triggered, [this]() {
        _ui->archivesFilterFrame->setVisible(
            !_ui->archivesFilterFrame->isVisible());
        if(_ui->archivesFilter->isVisible())
            _ui->archivesFilter->setFocus();
        else
            _ui->archivesFilter->clearEditText();
    });
    connect(_ui->archivesFilter, &QComboBox::editTextChanged,
            _ui->archiveListWidget, &ArchiveListWidget::setFilter);
    connect(_ui->archivesFilter,
            static_cast<void (QComboBox::*)(int)>(
                &QComboBox::currentIndexChanged),
            [this]() { _ui->archiveListWidget->setFocus(); });
}

ArchivesTabWidget::~ArchivesTabWidget()
{
    delete _ui;
}

void ArchivesTabWidget::changeEvent(QEvent *event)
{
    if(event->type() == QEvent::LanguageChange)
    {
        _ui->retranslateUi(this);
        updateUi();
    }
    QWidget::changeEvent(event);
}

void ArchivesTabWidget::keyPressEvent(QKeyEvent *event)
{
    switch(event->key())
    {
    case Qt::Key_Escape:
        // Apply to the ArchiveDetailsWidget, if possible...
        if(_ui->archiveDetailsWidget->isVisible())
        {
            _ui->archiveDetailsWidget->close();
            return;
        }
        // ... otherwise, apply the archive filter, if possible...
        if(_ui->archivesFilter->isVisible())
        {
            if(_ui->archivesFilter->currentText().isEmpty())
            {
                _ui->actionFilterArchives->trigger();
            }
            else
            {
                _ui->archivesFilter->clearEditText();
                _ui->archivesFilter->setFocus();
            }
            return;
        }
        // ... otherwise, use the default handling.
        break;
    default:
        QWidget::keyPressEvent(event);
    }
}

void ArchivesTabWidget::hideInspectArchive()
{
    _ui->archiveDetailsWidget->hide();
}

void ArchivesTabWidget::displayInspectArchive(ArchivePtr archive)
{
    // Get the size.
    if(archive->sizeTotal() == 0)
        emit loadArchiveStats(archive);

    // Get the file list.
    if(archive->contents().count() == 0)
        emit loadArchiveContents(archive);

    // Highlight the row in the ArchiveListWidget.
    _ui->archiveListWidget->selectArchive(archive);

    // Display Archive details.
    _ui->archiveDetailsWidget->setArchive(archive);
    if(!_ui->archiveDetailsWidget->isVisible())
    {
        _ui->archiveDetailsWidget->show();
        // Allow the event loop to update the geometry of the scroll area.
        // I haven't found a way to fix this without dropping back to the
        // main event loop.  :(
        QCoreApplication::processEvents(QEventLoop::AllEvents, 10);
    }

    // Make sure we can see it in the Archive List.  Must be after showing
    // the ArchiveDetailsWidget, otherwise the highlighted row might be
    // "visible" underneath the newly-expanded ArchiveDetailsWidget.
    _ui->archiveListWidget->ensureCurrentItemVisible();
}

void ArchivesTabWidget::showArchiveListMenu()
{
    // Construct menu.
    _archiveListMenu->clear();
    if(!_ui->archiveListWidget->selectedItems().isEmpty())
    {
        if(_ui->archiveListWidget->selectedItems().count() == 1)
        {
            _archiveListMenu->addAction(_ui->actionInspect);
            _archiveListMenu->addAction(_ui->actionRestore);
        }
        _archiveListMenu->addAction(_ui->actionDelete);
    }
    _archiveListMenu->addAction(_ui->actionRefresh);

    // Display menu.
    _archiveListMenu->popup(QCursor::pos());
}

void ArchivesTabWidget::updateUi()
{
    _ui->actionFilterArchives->setToolTip(
        _ui->actionFilterArchives->toolTip().arg(
            _ui->actionFilterArchives->shortcut().toString(
                QKeySequence::NativeText)));
    _ui->archivesFilter->setToolTip(_ui->archivesFilter->toolTip().arg(
        _ui->actionFilterArchives->shortcut().toString(
            QKeySequence::NativeText)));
}

void ArchivesTabWidget::displayInspectArchiveByRef(QString archiveName)
{
    ArchivePtr archive = _ui->archiveListWidget->findArchiveByName(archiveName);
    displayInspectArchive(archive);
}
<commit_msg>ArchivesTabWidget: use default key handling<commit_after>#include "archivestabwidget.h"

WARNINGS_DISABLE
#include <QAction>
#include <QComboBox>
#include <QCoreApplication>
#include <QCursor>
#include <QEvent>
#include <QEventLoop>
#include <QKeyEvent>
#include <QKeySequence>
#include <QMenu>
#include <QWidget>
#include <Qt>

#include "ui_archivestabwidget.h"
WARNINGS_ENABLE

#include "archivelistwidget.h"
#include "archivewidget.h"
#include "basetask.h"
#include "persistentmodel/archive.h"

ArchivesTabWidget::ArchivesTabWidget(QWidget *parent)
    : QWidget(parent), _ui(new Ui::ArchivesTabWidget)
{
    // Ui initialization
    _ui->setupUi(this);
    updateUi();

    // Basic UI setup.
    _ui->archiveListWidget->setAttribute(Qt::WA_MacShowFocusRect, false);
    _ui->archiveDetailsWidget->hide();
    _ui->archivesFilterFrame->hide();

    // Context menu.
    _archiveListMenu = new QMenu(_ui->archiveListWidget);
    connect(_ui->archiveListWidget,
            &ArchiveListWidget::customContextMenuRequested, this,
            &ArchivesTabWidget::showArchiveListMenu);

    // Context menu actions.
    _ui->archiveListWidget->addAction(_ui->actionRefresh);
    _ui->archiveListWidget->addAction(_ui->actionInspect);
    _ui->archiveListWidget->addAction(_ui->actionDelete);
    _ui->archiveListWidget->addAction(_ui->actionRestore);
    connect(_ui->actionInspect, &QAction::triggered, _ui->archiveListWidget,
            &ArchiveListWidget::inspectSelectedItem);
    connect(_ui->actionDelete, &QAction::triggered, _ui->archiveListWidget,
            &ArchiveListWidget::deleteSelectedItems);
    connect(_ui->actionRestore, &QAction::triggered, _ui->archiveListWidget,
            &ArchiveListWidget::restoreSelectedItem);

    // Connections from the ArchiveListWidget.
    connect(_ui->archiveListWidget, &ArchiveListWidget::inspectArchive, this,
            &ArchivesTabWidget::displayInspectArchive);
    connect(_ui->archiveListWidget, &ArchiveListWidget::clearInspectArchive,
            this, &ArchivesTabWidget::hideInspectArchive);
    connect(_ui->archiveListWidget, &ArchiveListWidget::deleteArchives, this,
            &ArchivesTabWidget::deleteArchives);
    connect(_ui->archiveListWidget, &ArchiveListWidget::restoreArchive, this,
            &ArchivesTabWidget::restoreArchive);
    connect(_ui->archiveListWidget, &ArchiveListWidget::displayJobDetails,
            [this](const QString &jobRef) { emit displayJobDetails(jobRef); });
    connect(_ui->archiveListWidget, &ArchiveListWidget::countChanged,
            [this](int total, int visible) {
                _ui->archivesCountLabel->setText(
                    tr("Archives (%1/%2)").arg(visible).arg(total));
            });

    // Connections to the ArchiveListWidget.
    connect(this, &ArchivesTabWidget::archiveList, _ui->archiveListWidget,
            &ArchiveListWidget::setArchives);
    connect(this, &ArchivesTabWidget::addArchive, _ui->archiveListWidget,
            &ArchiveListWidget::addArchive);

    // Connections from the ArchiveDetailsWidget.
    connect(_ui->archiveDetailsWidget, &ArchiveDetailsWidget::restoreArchive,
            this, &ArchivesTabWidget::restoreArchive);
    connect(_ui->archiveDetailsWidget, &ArchiveDetailsWidget::hidden,
            _ui->archiveListWidget, &ArchiveListWidget::noInspect);
    connect(_ui->archiveDetailsWidget, &ArchiveDetailsWidget::taskRequested,
            this, &ArchivesTabWidget::taskRequested);
    connect(_ui->archiveDetailsWidget, &ArchiveDetailsWidget::jobClicked,
            [this](const QString &jobRef) { emit jobClicked(jobRef); });

    // Filtering.
    _ui->archiveListWidget->addAction(_ui->actionFilterArchives);
    _ui->archivesFilterButton->setDefaultAction(_ui->actionFilterArchives);
    connect(_ui->archivesFilter, &QComboBox::editTextChanged,
            _ui->archiveListWidget, &ArchiveListWidget::setFilter);
    connect(_ui->actionFilterArchives, &QAction::triggered, [this]() {
        _ui->archivesFilterFrame->setVisible(
            !_ui->archivesFilterFrame->isVisible());
        if(_ui->archivesFilter->isVisible())
            _ui->archivesFilter->setFocus();
        else
            _ui->archivesFilter->clearEditText();
    });
    connect(_ui->archivesFilter, &QComboBox::editTextChanged,
            _ui->archiveListWidget, &ArchiveListWidget::setFilter);
    connect(_ui->archivesFilter,
            static_cast<void (QComboBox::*)(int)>(
                &QComboBox::currentIndexChanged),
            [this]() { _ui->archiveListWidget->setFocus(); });
}

ArchivesTabWidget::~ArchivesTabWidget()
{
    delete _ui;
}

void ArchivesTabWidget::changeEvent(QEvent *event)
{
    if(event->type() == QEvent::LanguageChange)
    {
        _ui->retranslateUi(this);
        updateUi();
    }
    QWidget::changeEvent(event);
}

void ArchivesTabWidget::keyPressEvent(QKeyEvent *event)
{
    switch(event->key())
    {
    case Qt::Key_Escape:
        // Apply to the ArchiveDetailsWidget, if possible...
        if(_ui->archiveDetailsWidget->isVisible())
        {
            _ui->archiveDetailsWidget->close();
            return;
        }
        // ... otherwise, apply the archive filter, if possible...
        if(_ui->archivesFilter->isVisible())
        {
            if(_ui->archivesFilter->currentText().isEmpty())
            {
                _ui->actionFilterArchives->trigger();
            }
            else
            {
                _ui->archivesFilter->clearEditText();
                _ui->archivesFilter->setFocus();
            }
            return;
        }
        // ... otherwise, use the default handling.
        break;
    }
    QWidget::keyPressEvent(event);
}

void ArchivesTabWidget::hideInspectArchive()
{
    _ui->archiveDetailsWidget->hide();
}

void ArchivesTabWidget::displayInspectArchive(ArchivePtr archive)
{
    // Get the size.
    if(archive->sizeTotal() == 0)
        emit loadArchiveStats(archive);

    // Get the file list.
    if(archive->contents().count() == 0)
        emit loadArchiveContents(archive);

    // Highlight the row in the ArchiveListWidget.
    _ui->archiveListWidget->selectArchive(archive);

    // Display Archive details.
    _ui->archiveDetailsWidget->setArchive(archive);
    if(!_ui->archiveDetailsWidget->isVisible())
    {
        _ui->archiveDetailsWidget->show();
        // Allow the event loop to update the geometry of the scroll area.
        // I haven't found a way to fix this without dropping back to the
        // main event loop.  :(
        QCoreApplication::processEvents(QEventLoop::AllEvents, 10);
    }

    // Make sure we can see it in the Archive List.  Must be after showing
    // the ArchiveDetailsWidget, otherwise the highlighted row might be
    // "visible" underneath the newly-expanded ArchiveDetailsWidget.
    _ui->archiveListWidget->ensureCurrentItemVisible();
}

void ArchivesTabWidget::showArchiveListMenu()
{
    // Construct menu.
    _archiveListMenu->clear();
    if(!_ui->archiveListWidget->selectedItems().isEmpty())
    {
        if(_ui->archiveListWidget->selectedItems().count() == 1)
        {
            _archiveListMenu->addAction(_ui->actionInspect);
            _archiveListMenu->addAction(_ui->actionRestore);
        }
        _archiveListMenu->addAction(_ui->actionDelete);
    }
    _archiveListMenu->addAction(_ui->actionRefresh);

    // Display menu.
    _archiveListMenu->popup(QCursor::pos());
}

void ArchivesTabWidget::updateUi()
{
    _ui->actionFilterArchives->setToolTip(
        _ui->actionFilterArchives->toolTip().arg(
            _ui->actionFilterArchives->shortcut().toString(
                QKeySequence::NativeText)));
    _ui->archivesFilter->setToolTip(_ui->archivesFilter->toolTip().arg(
        _ui->actionFilterArchives->shortcut().toString(
            QKeySequence::NativeText)));
}

void ArchivesTabWidget::displayInspectArchiveByRef(QString archiveName)
{
    ArchivePtr archive = _ui->archiveListWidget->findArchiveByName(archiveName);
    displayInspectArchive(archive);
}
<|endoftext|>


<commit_before>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/fastos/fastos.h>
#include <iostream>
#include <string>
#include <cstdlib>

#include <boost/program_options.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/noncopyable.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <boost/scope_exit.hpp>

#include <vespa/fastos/app.h>
#include <vespa/config-zookeepers.h>

#include <vespa/fileacquirer/config-filedistributorrpc.h>
#include <vespa/filedistribution/distributor/config-filedistributor.h>
#include <vespa/filedistribution/model/config-filereferences.h>

#include <vespa/filedistribution/distributor/filedistributortrackerimpl.h>
#include <vespa/filedistribution/distributor/filedownloadermanager.h>
#include <vespa/filedistribution/distributor/filedownloader.h>
#include <vespa/filedistribution/distributor/signalhandling.h>
#include <vespa/filedistribution/distributor/state_server_impl.h>

#include <vespa/filedistribution/model/filedistributionmodelimpl.h>
#include <vespa/filedistribution/rpc/filedistributorrpc.h>
#include <vespa/filedistribution/common/exception.h>
#include <vespa/filedistribution/common/componentsdeleter.h>

namespace {
const char* programName = "filedistributor";
}

#include <vespa/log/log.h>
LOG_SETUP(programName);

namespace ll = boost::lambda;

using namespace filedistribution;
using cloud::config::ZookeepersConfig;
using cloud::config::filedistribution::FiledistributorConfig;
using cloud::config::filedistribution::FiledistributorrpcConfig;

class FileDistributor : public config::IFetcherCallback<ZookeepersConfig>,
                        public config::IFetcherCallback<FiledistributorConfig>,
                        public config::IFetcherCallback<FiledistributorrpcConfig>,
                        public config::IGenerationCallback,
                        boost::noncopyable
{
    class Components : boost::noncopyable {
        ComponentsDeleter _componentsDeleter;
    public:
        const boost::shared_ptr<ZKFacade> _zk;
        const boost::shared_ptr<FileDistributionModelImpl> _model;
        const boost::shared_ptr<FileDistributorTrackerImpl> _tracker;
        const boost::shared_ptr<FileDownloader> _downloader;
        const boost::shared_ptr<FileDownloaderManager> _manager;
        const boost::shared_ptr<FileDistributorRPC> _rpcHandler;
        const boost::shared_ptr<StateServerImpl> _stateServer;

    private:
        boost::thread _downloaderEventLoopThread;
        config::ConfigFetcher _configFetcher;

        template <class T>
        typename boost::shared_ptr<T> track(T* component) {
            return _componentsDeleter.track(component);
        }

    public:

        Components(const boost::shared_ptr<ExceptionRethrower>& exceptionRethrower,
                   const config::ConfigUri & configUri,
                   const ZookeepersConfig& zooKeepersConfig,
                   const FiledistributorConfig& fileDistributorConfig,
                   const FiledistributorrpcConfig& rpcConfig)
            :_zk(track(new ZKFacade(zooKeepersConfig.zookeeperserverlist, exceptionRethrower))),
             _model(track(new FileDistributionModelImpl(
                                     fileDistributorConfig.hostname,
                                     fileDistributorConfig.torrentport,
                                     _zk,
                                     exceptionRethrower))),
             _tracker(track(new FileDistributorTrackerImpl(_model, exceptionRethrower))),
             _downloader(track(new FileDownloader(
                                     _tracker,
                                     fileDistributorConfig.hostname,
                                     fileDistributorConfig.torrentport,
                                     boost::filesystem::path(fileDistributorConfig.filedbpath),
                                     exceptionRethrower))),
             _manager(track(new FileDownloaderManager(_downloader, _model))),
             _rpcHandler(track(new FileDistributorRPC(rpcConfig.connectionspec, _manager))),
             _stateServer(track(new StateServerImpl(fileDistributorConfig.stateport))),
             _downloaderEventLoopThread(
                    ll::bind(&FileDownloader::runEventLoop, _downloader.get())),
             _configFetcher(configUri.getContext())

        {
            _manager->start();
            _rpcHandler->start();

            _tracker->setDownloader(_downloader);
            _configFetcher.subscribe<FilereferencesConfig>(configUri.getConfigId(), _model.get());
            _configFetcher.start();
            updatedConfig(_configFetcher.getGeneration());
        }

        void updatedConfig(int64_t generation) {
            vespalib::ComponentConfigProducer::Config curr("filedistributor", generation);
            _stateServer->myComponents.addConfig(curr);
        }

        ~Components() {
            _configFetcher.close();
            //Do not waste time retrying zookeeper operations when going down.
            _zk->disableRetries();

            _downloaderEventLoopThread.interrupt();
            _downloaderEventLoopThread.join();
        }

    };

    typedef boost::lock_guard<boost::mutex> LockGuard;
    boost::mutex _configMutex;

    bool _completeReconfigurationNeeded;
    std::unique_ptr<ZookeepersConfig> _zooKeepersConfig;
    std::unique_ptr<FiledistributorConfig> _fileDistributorConfig;
    std::unique_ptr<FiledistributorrpcConfig> _rpcConfig;

    boost::shared_ptr<ExceptionRethrower> _exceptionRethrower;
    std::unique_ptr<Components> _components;
public:
    FileDistributor()
        : _configMutex(),
          _completeReconfigurationNeeded(false),
          _zooKeepersConfig(),
          _fileDistributorConfig(),
          _rpcConfig(),
          _exceptionRethrower(),
          _components()
    { }

    void notifyGenerationChange(int64_t generation) {
        if (_components && ! completeReconfigurationNeeded()) {
            _components->updatedConfig(generation);
        }
    }

    //configure overrides
    void configure(std::unique_ptr<ZookeepersConfig> config) {
        LockGuard guard(_configMutex);
        _zooKeepersConfig = std::move(config);
        _completeReconfigurationNeeded = true;
    }

    void configure(std::unique_ptr<FiledistributorConfig> config) {
        LockGuard guard(_configMutex);
        if (_fileDistributorConfig.get() != NULL &&
            (config->torrentport != _fileDistributorConfig->torrentport ||
             config->stateport   != _fileDistributorConfig->stateport ||
             config->hostname    != _fileDistributorConfig->hostname ||
             config->filedbpath  != _fileDistributorConfig->filedbpath))
        {
            _completeReconfigurationNeeded = true;
        } else if (_components.get()) {
            configureSpeedLimits(*config);
        }
        _fileDistributorConfig = std::move(config);

    }

    void configure(std::unique_ptr<FiledistributorrpcConfig> config) {
        LockGuard guard(_configMutex);
        _rpcConfig = std::move(config);
        _completeReconfigurationNeeded = true;
    }

    void run(const config::ConfigUri & configUri) {
        while (!askedToShutDown()) {
            clearReinitializeFlag();
            _exceptionRethrower.reset(new ExceptionRethrower());
            runImpl(configUri);

            if (_exceptionRethrower->exceptionStored())
                _exceptionRethrower->rethrow();
        }
    }

    static void ensureExceptionsStored(const boost::shared_ptr<ExceptionRethrower>& exceptionRethrower) {
        //TODO: this is somewhat hackish, refactor to eliminate this later.
        LOG(debug, "Waiting for shutdown");
        for (int i=0;
             i<50 && !exceptionRethrower.unique();
                ++i) {
            boost::this_thread::sleep(boost::posix_time::milliseconds(100));
        }
        LOG(debug, "Done waiting for shutdown");

        if (!exceptionRethrower.unique()) {
            EV_STOPPING(programName, "Forced termination");
            kill(getpid(), SIGKILL);
        }
    }

    void createComponents(const boost::shared_ptr<ExceptionRethrower>& exceptionRethrower, const config::ConfigUri & configUri) {
        LockGuard guard(_configMutex);
        _components.reset(
                new Components(exceptionRethrower,
                        configUri,
                        *_zooKeepersConfig,
                        *_fileDistributorConfig,
                        *_rpcConfig));

        configureSpeedLimits(*_fileDistributorConfig);
        _completeReconfigurationNeeded = false;
    }

    bool completeReconfigurationNeeded() {
        LockGuard guard(_configMutex);
        if (_completeReconfigurationNeeded) {
            LOG(debug, "Complete reconfiguration needed");
        }
        return _completeReconfigurationNeeded;
    }

    void configureSpeedLimits(const FiledistributorConfig& config) {
        FileDownloader& downloader = *_components->_downloader;
        downloader.setMaxDownloadSpeed(config.maxdownloadspeed);
        downloader.setMaxUploadSpeed(config.maxuploadspeed);
    }

    //avoid warning due to scope exit macro
#pragma GCC diagnostic ignored "-Wshadow"
    void runImpl(const config::ConfigUri & configUri) {

        BOOST_SCOPE_EXIT((&_components)(&_exceptionRethrower)) {
            _components.reset();
            //Ensures that any exception stored during destruction will be available when returning.
            ensureExceptionsStored(_exceptionRethrower);
        } BOOST_SCOPE_EXIT_END

        createComponents(_exceptionRethrower, configUri);

        // We do not want back to back reinitializing as it gives zero time for serving
        // some torrents.
        int postPoneAskedToReinitializedSecs = 50;

        while (!askedToShutDown() &&
	       (postPoneAskedToReinitializedSecs > 0 || !askedToReinitialize()) &&
	       !completeReconfigurationNeeded() &&
	       !_exceptionRethrower->exceptionStored()) {
	  postPoneAskedToReinitializedSecs--;
	  boost::this_thread::sleep(boost::posix_time::seconds(1));
        }
    }
};

//TODO: use pop in gcc 4.6
#pragma GCC diagnostic warning "-Wshadow"

class FileDistributorApplication : public FastOS_Application {
    const config::ConfigUri _configUri;
public:
    FileDistributorApplication(const config::ConfigUri & configUri);

    //overrides
    int Main();
};

namespace {

struct ProgramOptionException {
    std::string _msg;
    ProgramOptionException(const std::string & msg)
        : _msg(msg)
    {}
};

bool exists(const std::string& optionName, const boost::program_options::variables_map& map) {
    return map.find(optionName) != map.end();
}

void ensureExists(const std::string& optionName, const boost::program_options::variables_map& map \
                  ) {
    if (!exists(optionName, map)) {
        throw ProgramOptionException("Error: Missing option " + optionName);
    }
}

} //anonymous namespace

FileDistributorApplication::FileDistributorApplication(const config::ConfigUri & configUri)
    :_configUri(configUri) {
}

int
FileDistributorApplication::Main() {
    try {
        FileDistributor distributor;

        config::ConfigFetcher configFetcher(_configUri.getContext());
        configFetcher.subscribe<ZookeepersConfig>(_configUri.getConfigId(), &distributor);
        configFetcher.subscribe<FiledistributorConfig>(_configUri.getConfigId(), &distributor);
        configFetcher.subscribe<FiledistributorrpcConfig>(_configUri.getConfigId(), &distributor);
        configFetcher.subscribeGenerationChanges(&distributor);
        configFetcher.start();

        distributor.run(_configUri);

        EV_STOPPING(programName, "Clean exit");
        return 0;
    } catch(const FileDoesNotExistException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 1;
    } catch(const ZKNodeDoesNotExistsException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 2;
    } catch(const ZKSessionExpired & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 3;
    } catch(const config::ConfigTimeoutException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 4;
    } catch(const FailedListeningException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 5;
    } catch(const ZKGenericException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 99;
    } catch(const boost::unknown_exception & e) {
        std::string s = boost::diagnostic_information(e);
        LOG(warning, "Caught '%s'", s.c_str());
        EV_STOPPING(programName, s.c_str());
        return 255;
#if 0
    /*
     These are kept hanging around for reference as to how it was when we just held our ears
     singing "na, na, na, na..." no matter if the sun was shining or if the world imploded.
    */
    } catch(const boost::exception& e) {
        std::string s = boost::diagnostic_information(e);
        LOG(error, "Caught '%s'", s.c_str());
        EV_STOPPING(programName, s.c_str());
        return -1;
    } catch(const std::string& msg) {
        std::string s = "Error: " + msg;
        LOG(error, "Caught '%s'", s.c_str());
        EV_STOPPING(programName, s.c_str());
        return -1;
#endif
    }
}

int
executeApplication(int argc, char** argv) {
    const char
        *configId("configid"),
        *help("help");

    namespace po = boost::program_options;
    po::options_description description;
    description.add_options()
        (configId, po::value<std::string > (), "id to request config for")
        (help, "help");

    try {
        po::variables_map values;
        po::store(
                po::parse_command_line(argc, argv, description),
                values);

        if (exists(help, values)) {
            std::cout <<description;
            return 0;
        }
        ensureExists(configId, values);

        FileDistributorApplication application(
                values[configId].as<std::string > ());
        return application.Entry(argc, argv);

    } catch(ProgramOptionException& e) {
        std::cerr <<e._msg <<std::endl;
        return -1;
    }
}

int
main(int argc, char** argv) {
    EV_STARTED(programName);
    initSignals();

    std::srand(std::time(0));
    filedistribution::ZKLogging loggingGuard;

    return executeApplication(argc, argv);
}
<commit_msg>Install signals very early.<commit_after>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/fastos/fastos.h>
#include <iostream>
#include <string>
#include <cstdlib>

#include <boost/program_options.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/noncopyable.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <boost/scope_exit.hpp>

#include <vespa/fastos/app.h>
#include <vespa/config-zookeepers.h>

#include <vespa/fileacquirer/config-filedistributorrpc.h>
#include <vespa/filedistribution/distributor/config-filedistributor.h>
#include <vespa/filedistribution/model/config-filereferences.h>

#include <vespa/filedistribution/distributor/filedistributortrackerimpl.h>
#include <vespa/filedistribution/distributor/filedownloadermanager.h>
#include <vespa/filedistribution/distributor/filedownloader.h>
#include <vespa/filedistribution/distributor/signalhandling.h>
#include <vespa/filedistribution/distributor/state_server_impl.h>

#include <vespa/filedistribution/model/filedistributionmodelimpl.h>
#include <vespa/filedistribution/rpc/filedistributorrpc.h>
#include <vespa/filedistribution/common/exception.h>
#include <vespa/filedistribution/common/componentsdeleter.h>

namespace {
const char* programName = "filedistributor";
}

#include <vespa/log/log.h>
LOG_SETUP(programName);

namespace ll = boost::lambda;

using namespace filedistribution;
using cloud::config::ZookeepersConfig;
using cloud::config::filedistribution::FiledistributorConfig;
using cloud::config::filedistribution::FiledistributorrpcConfig;

class FileDistributor : public config::IFetcherCallback<ZookeepersConfig>,
                        public config::IFetcherCallback<FiledistributorConfig>,
                        public config::IFetcherCallback<FiledistributorrpcConfig>,
                        public config::IGenerationCallback,
                        boost::noncopyable
{
    class Components : boost::noncopyable {
        ComponentsDeleter _componentsDeleter;
    public:
        const boost::shared_ptr<ZKFacade> _zk;
        const boost::shared_ptr<FileDistributionModelImpl> _model;
        const boost::shared_ptr<FileDistributorTrackerImpl> _tracker;
        const boost::shared_ptr<FileDownloader> _downloader;
        const boost::shared_ptr<FileDownloaderManager> _manager;
        const boost::shared_ptr<FileDistributorRPC> _rpcHandler;
        const boost::shared_ptr<StateServerImpl> _stateServer;

    private:
        boost::thread _downloaderEventLoopThread;
        config::ConfigFetcher _configFetcher;

        template <class T>
        typename boost::shared_ptr<T> track(T* component) {
            return _componentsDeleter.track(component);
        }

    public:

        Components(const boost::shared_ptr<ExceptionRethrower>& exceptionRethrower,
                   const config::ConfigUri & configUri,
                   const ZookeepersConfig& zooKeepersConfig,
                   const FiledistributorConfig& fileDistributorConfig,
                   const FiledistributorrpcConfig& rpcConfig)
            :_zk(track(new ZKFacade(zooKeepersConfig.zookeeperserverlist, exceptionRethrower))),
             _model(track(new FileDistributionModelImpl(
                                     fileDistributorConfig.hostname,
                                     fileDistributorConfig.torrentport,
                                     _zk,
                                     exceptionRethrower))),
             _tracker(track(new FileDistributorTrackerImpl(_model, exceptionRethrower))),
             _downloader(track(new FileDownloader(
                                     _tracker,
                                     fileDistributorConfig.hostname,
                                     fileDistributorConfig.torrentport,
                                     boost::filesystem::path(fileDistributorConfig.filedbpath),
                                     exceptionRethrower))),
             _manager(track(new FileDownloaderManager(_downloader, _model))),
             _rpcHandler(track(new FileDistributorRPC(rpcConfig.connectionspec, _manager))),
             _stateServer(track(new StateServerImpl(fileDistributorConfig.stateport))),
             _downloaderEventLoopThread(
                    ll::bind(&FileDownloader::runEventLoop, _downloader.get())),
             _configFetcher(configUri.getContext())

        {
            _manager->start();
            _rpcHandler->start();

            _tracker->setDownloader(_downloader);
            _configFetcher.subscribe<FilereferencesConfig>(configUri.getConfigId(), _model.get());
            _configFetcher.start();
            updatedConfig(_configFetcher.getGeneration());
        }

        void updatedConfig(int64_t generation) {
            vespalib::ComponentConfigProducer::Config curr("filedistributor", generation);
            _stateServer->myComponents.addConfig(curr);
        }

        ~Components() {
            _configFetcher.close();
            //Do not waste time retrying zookeeper operations when going down.
            _zk->disableRetries();

            _downloaderEventLoopThread.interrupt();
            _downloaderEventLoopThread.join();
        }

    };

    typedef boost::lock_guard<boost::mutex> LockGuard;
    boost::mutex _configMutex;

    bool _completeReconfigurationNeeded;
    std::unique_ptr<ZookeepersConfig> _zooKeepersConfig;
    std::unique_ptr<FiledistributorConfig> _fileDistributorConfig;
    std::unique_ptr<FiledistributorrpcConfig> _rpcConfig;

    boost::shared_ptr<ExceptionRethrower> _exceptionRethrower;
    std::unique_ptr<Components> _components;
public:
    FileDistributor()
        : _configMutex(),
          _completeReconfigurationNeeded(false),
          _zooKeepersConfig(),
          _fileDistributorConfig(),
          _rpcConfig(),
          _exceptionRethrower(),
          _components()
    { }

    void notifyGenerationChange(int64_t generation) {
        if (_components && ! completeReconfigurationNeeded()) {
            _components->updatedConfig(generation);
        }
    }

    //configure overrides
    void configure(std::unique_ptr<ZookeepersConfig> config) {
        LockGuard guard(_configMutex);
        _zooKeepersConfig = std::move(config);
        _completeReconfigurationNeeded = true;
    }

    void configure(std::unique_ptr<FiledistributorConfig> config) {
        LockGuard guard(_configMutex);
        if (_fileDistributorConfig.get() != NULL &&
            (config->torrentport != _fileDistributorConfig->torrentport ||
             config->stateport   != _fileDistributorConfig->stateport ||
             config->hostname    != _fileDistributorConfig->hostname ||
             config->filedbpath  != _fileDistributorConfig->filedbpath))
        {
            _completeReconfigurationNeeded = true;
        } else if (_components.get()) {
            configureSpeedLimits(*config);
        }
        _fileDistributorConfig = std::move(config);

    }

    void configure(std::unique_ptr<FiledistributorrpcConfig> config) {
        LockGuard guard(_configMutex);
        _rpcConfig = std::move(config);
        _completeReconfigurationNeeded = true;
    }

    void run(const config::ConfigUri & configUri) {
        while (!askedToShutDown()) {
            clearReinitializeFlag();
            _exceptionRethrower.reset(new ExceptionRethrower());
            runImpl(configUri);

            if (_exceptionRethrower->exceptionStored())
                _exceptionRethrower->rethrow();
        }
    }

    static void ensureExceptionsStored(const boost::shared_ptr<ExceptionRethrower>& exceptionRethrower) {
        //TODO: this is somewhat hackish, refactor to eliminate this later.
        LOG(debug, "Waiting for shutdown");
        for (int i=0;
             i<50 && !exceptionRethrower.unique();
                ++i) {
            boost::this_thread::sleep(boost::posix_time::milliseconds(100));
        }
        LOG(debug, "Done waiting for shutdown");

        if (!exceptionRethrower.unique()) {
            EV_STOPPING(programName, "Forced termination");
            kill(getpid(), SIGKILL);
        }
    }

    void createComponents(const boost::shared_ptr<ExceptionRethrower>& exceptionRethrower, const config::ConfigUri & configUri) {
        LockGuard guard(_configMutex);
        _components.reset(
                new Components(exceptionRethrower,
                        configUri,
                        *_zooKeepersConfig,
                        *_fileDistributorConfig,
                        *_rpcConfig));

        configureSpeedLimits(*_fileDistributorConfig);
        _completeReconfigurationNeeded = false;
    }

    bool completeReconfigurationNeeded() {
        LockGuard guard(_configMutex);
        if (_completeReconfigurationNeeded) {
            LOG(debug, "Complete reconfiguration needed");
        }
        return _completeReconfigurationNeeded;
    }

    void configureSpeedLimits(const FiledistributorConfig& config) {
        FileDownloader& downloader = *_components->_downloader;
        downloader.setMaxDownloadSpeed(config.maxdownloadspeed);
        downloader.setMaxUploadSpeed(config.maxuploadspeed);
    }

    //avoid warning due to scope exit macro
#pragma GCC diagnostic ignored "-Wshadow"
    void runImpl(const config::ConfigUri & configUri) {

        BOOST_SCOPE_EXIT((&_components)(&_exceptionRethrower)) {
            _components.reset();
            //Ensures that any exception stored during destruction will be available when returning.
            ensureExceptionsStored(_exceptionRethrower);
        } BOOST_SCOPE_EXIT_END

        createComponents(_exceptionRethrower, configUri);

        // We do not want back to back reinitializing as it gives zero time for serving
        // some torrents.
        int postPoneAskedToReinitializedSecs = 50;

        while (!askedToShutDown() &&
	       (postPoneAskedToReinitializedSecs > 0 || !askedToReinitialize()) &&
	       !completeReconfigurationNeeded() &&
	       !_exceptionRethrower->exceptionStored()) {
	  postPoneAskedToReinitializedSecs--;
	  boost::this_thread::sleep(boost::posix_time::seconds(1));
        }
    }
};

//TODO: use pop in gcc 4.6
#pragma GCC diagnostic warning "-Wshadow"

class FileDistributorApplication : public FastOS_Application {
    const config::ConfigUri _configUri;
public:
    FileDistributorApplication(const config::ConfigUri & configUri);

    //overrides
    int Main();
};

namespace {

struct ProgramOptionException {
    std::string _msg;
    ProgramOptionException(const std::string & msg)
        : _msg(msg)
    {}
};

bool exists(const std::string& optionName, const boost::program_options::variables_map& map) {
    return map.find(optionName) != map.end();
}

void ensureExists(const std::string& optionName, const boost::program_options::variables_map& map \
                  ) {
    if (!exists(optionName, map)) {
        throw ProgramOptionException("Error: Missing option " + optionName);
    }
}

} //anonymous namespace

FileDistributorApplication::FileDistributorApplication(const config::ConfigUri & configUri)
    :_configUri(configUri) {
}

int
FileDistributorApplication::Main() {
    try {
        FileDistributor distributor;

        config::ConfigFetcher configFetcher(_configUri.getContext());
        configFetcher.subscribe<ZookeepersConfig>(_configUri.getConfigId(), &distributor);
        configFetcher.subscribe<FiledistributorConfig>(_configUri.getConfigId(), &distributor);
        configFetcher.subscribe<FiledistributorrpcConfig>(_configUri.getConfigId(), &distributor);
        configFetcher.subscribeGenerationChanges(&distributor);
        configFetcher.start();

        distributor.run(_configUri);

        EV_STOPPING(programName, "Clean exit");
        return 0;
    } catch(const FileDoesNotExistException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 1;
    } catch(const ZKNodeDoesNotExistsException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 2;
    } catch(const ZKSessionExpired & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 3;
    } catch(const config::ConfigTimeoutException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 4;
    } catch(const FailedListeningException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 5;
    } catch(const ZKGenericException & e) {
        std::string s = boost::diagnostic_information(e);
        EV_STOPPING(programName, s.c_str());
        return 99;
    } catch(const boost::unknown_exception & e) {
        std::string s = boost::diagnostic_information(e);
        LOG(warning, "Caught '%s'", s.c_str());
        EV_STOPPING(programName, s.c_str());
        return 255;
#if 0
    /*
     These are kept hanging around for reference as to how it was when we just held our ears
     singing "na, na, na, na..." no matter if the sun was shining or if the world imploded.
    */
    } catch(const boost::exception& e) {
        std::string s = boost::diagnostic_information(e);
        LOG(error, "Caught '%s'", s.c_str());
        EV_STOPPING(programName, s.c_str());
        return -1;
    } catch(const std::string& msg) {
        std::string s = "Error: " + msg;
        LOG(error, "Caught '%s'", s.c_str());
        EV_STOPPING(programName, s.c_str());
        return -1;
#endif
    }
}

int
executeApplication(int argc, char** argv) {
    const char
        *configId("configid"),
        *help("help");

    namespace po = boost::program_options;
    po::options_description description;
    description.add_options()
        (configId, po::value<std::string > (), "id to request config for")
        (help, "help");

    try {
        po::variables_map values;
        po::store(
                po::parse_command_line(argc, argv, description),
                values);

        if (exists(help, values)) {
            std::cout <<description;
            return 0;
        }
        ensureExists(configId, values);

        FileDistributorApplication application(
                values[configId].as<std::string > ());
        return application.Entry(argc, argv);

    } catch(ProgramOptionException& e) {
        std::cerr <<e._msg <<std::endl;
        return -1;
    }
}

namespace {

class InitSignals {
public:
    InitSignals() { initSignals(); }
};

InitSignals _G_initSignals;

}

int
main(int argc, char** argv) {
    if (askedToShutDown()) { return 0; }
    EV_STARTED(programName);

    std::srand(std::time(0));
    filedistribution::ZKLogging loggingGuard;

    return executeApplication(argc, argv);
}
<|endoftext|>


<commit_before>/*
* Copyright (C) 2007-2013 German Aerospace Center (DLR/SC)
*
* Created: 2013-12-17 Tobias Stollenwerk <Tobias.Stollenwerk@dlr.de>
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* @brief  Implementation of CPACS wing profile as a CST profile
*
* The wing profile is defined by the (C)lass function / (S)hape function (T)ransformation
* geometry representation method.
*/

#include "CCPACSWingProfileCST.h"

#include "CCSTCurveBuilder.h"

#include "CTiglError.h"
#include "CTiglTypeRegistry.h"
#include "CTiglLogging.h"
#include "CTiglTransformation.h"
#include "CWireToCurve.h"
#include "CCPACSWingProfileFactory.h"
#include "TixiSaveExt.h"
#include "math.h"

#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <Geom_BSplineCurve.hxx>

namespace tigl
{

namespace
{
    // helper function to read in tixi vector
    std::vector<double> readTixiVector (TixiDocumentHandle tixiHandle, const std::string& xpath, const std::string& name, const std::string& funcname)
    {
        std::string fullpath = xpath + name;
        int count;
        if (tixiGetVectorSize(tixiHandle, fullpath.c_str(), &count) != SUCCESS) {
            throw CTiglError("Error: XML error while reading vector <" + name + "> in " + funcname, TIGL_XML_ERROR);
        }
        double *tmp;
        if (tixiGetFloatVector(tixiHandle, fullpath.c_str(), &tmp, count) != SUCCESS)  {
            throw CTiglError("Error: XML error while reading vector <" + name + "> in " + funcname, TIGL_XML_ERROR);
        }
        std::vector<double> res(tmp, tmp+count);
        return res;
    }
    // helper function to read in tixi double
    double readTixiDouble (TixiDocumentHandle tixiHandle, const std::string& xpath, const std::string& name, const std::string& funcname)
    {
        std::string fullpath = xpath + name;
        double res;
        if (tixiGetDoubleElement(tixiHandle, fullpath.c_str(), &res) != SUCCESS) {
            throw CTiglError("Error: XML error while reading double <" + name + "> in " + funcname, TIGL_XML_ERROR);
        }
        return res;
    }
} // anonymous namespace

// register profile algo at factory
PTiglWingProfileAlgo CreateProfileCST(const CCPACSWingProfile& profile, const std::string& cpacsPath)
{
    return PTiglWingProfileAlgo(new CCPACSWingProfileCST(profile, cpacsPath));
}

AUTORUN(CCPACSWingProfileCST)
{
    return CCPACSWingProfileFactory::Instance().RegisterAlgo(CCPACSWingProfileCST::CPACSID(), CreateProfileCST);
}

// Constructor
CCPACSWingProfileCST::CCPACSWingProfileCST(const CCPACSWingProfile& profile, const std::string& path)
{
    ProfileDataXPath=path + "/" + CPACSID();
    trailingEdge.Nullify();
}

// Destructor
CCPACSWingProfileCST::~CCPACSWingProfileCST(void)
{
}

std::string CCPACSWingProfileCST::CPACSID()
{
    return "cst2D";
}

// Cleanup routine
void CCPACSWingProfileCST::Cleanup(void)
{
    upperB.clear();
    lowerB.clear();
    trailingEdge.Nullify();
}

void CCPACSWingProfileCST::Update(void)
{
    BuildWires();
}

// Read wing profile file
void CCPACSWingProfileCST::ReadCPACS(TixiDocumentHandle tixiHandle)
{
    upperB=readTixiVector(tixiHandle, ProfileDataXPath, "/upperB", "CCPACSWingProfileCST::ReadCPACS");
    lowerB=readTixiVector(tixiHandle, ProfileDataXPath, "/lowerB", "CCPACSWingProfileCST::ReadCPACS");
    upperN1=readTixiDouble(tixiHandle, ProfileDataXPath, "/upperN1", "CCPACSWingProfileCST::ReadCPACS");
    upperN2=readTixiDouble(tixiHandle, ProfileDataXPath, "/upperN2", "CCPACSWingProfileCST::ReadCPACS");
    lowerN1=readTixiDouble(tixiHandle, ProfileDataXPath, "/lowerN1", "CCPACSWingProfileCST::ReadCPACS");
    lowerN2=readTixiDouble(tixiHandle, ProfileDataXPath, "/lowerN2", "CCPACSWingProfileCST::ReadCPACS");
}

// Write CPACS wing profile
void CCPACSWingProfileCST::WriteCPACS(TixiDocumentHandle tixiHandle, const std::string& ProfileXPath)
{
    // Set the element "point"
    TixiSaveExt::TixiSaveElement(tixiHandle, ProfileXPath.c_str(), CPACSID().c_str() );

    std::string elementPath = ProfileXPath + "/" + CPACSID();

    TixiSaveExt::TixiSaveVector(tixiHandle, elementPath, "upperB", upperB);
    TixiSaveExt::TixiSaveVector(tixiHandle, elementPath, "lowerB", lowerB);
    TixiSaveExt::TixiSaveDoubleElement(tixiHandle, elementPath.c_str(), "upperN1", upperN1);
    TixiSaveExt::TixiSaveDoubleElement(tixiHandle, elementPath.c_str(), "upperN2", upperN2);
    TixiSaveExt::TixiSaveDoubleElement(tixiHandle, elementPath.c_str(), "lowerN1", lowerN1);
    TixiSaveExt::TixiSaveDoubleElement(tixiHandle, elementPath.c_str(), "lowerN2", lowerN2);

}

// Builds the wing profile wire. The returned wire is already transformed by the
// wing profile element transformation.
void CCPACSWingProfileCST::BuildWires()
{
    gp_Trsf yzSwitch;
    yzSwitch.SetMirror(gp_Ax2(gp_Pnt(0.,0.,0.), gp_Dir(0.,-1.,1.)));

    // Build upper wire
    CCSTCurveBuilder upperBuilder(upperN1, upperN2, upperB);
    Handle_Geom_BSplineCurve upperCurve = upperBuilder.Curve();
    upperCurve->Transform(yzSwitch);
    upperWire = BRepBuilderAPI_MakeEdge(upperCurve);

    // Build lower curve,
    std::vector<double> binv;
    for (unsigned int i = 0; i < lowerB.size(); ++i) {
        binv.push_back(-lowerB[i]);
    }

    CCSTCurveBuilder lowerBuilder(lowerN1, lowerN2, binv);
    Handle_Geom_BSplineCurve lowerCurve = lowerBuilder.Curve();
    lowerCurve->Transform(yzSwitch);
    lowerCurve->Reverse();
    lowerWire = BRepBuilderAPI_MakeEdge(lowerCurve);

    BRepBuilderAPI_MakeWire upperLowerWireMaker(lowerWire, upperWire);
    TopoDS_Wire upperLowerWire = upperLowerWireMaker.Wire();

    // conatenate wire
    Handle_Geom_Curve upperLowerCurve = CWireToCurve(upperLowerWire).curve();
    upperLowerEdge = BRepBuilderAPI_MakeEdge(upperLowerCurve);

    tePoint = gp_Pnt(1,0,0);
    lePoint = gp_Pnt(0,0,0);
}

// Returns sample points
std::vector<CTiglPoint*> CCPACSWingProfileCST::GetSamplePoints() const
{
    std::vector<CTiglPoint*> empty;
    return empty;
}

// get profiles CPACS XML path
const std::string & CCPACSWingProfileCST::GetProfileDataXPath() const
{
    return ProfileDataXPath;
}

// Getter for upper wire of closed profile
const TopoDS_Edge& CCPACSWingProfileCST::GetUpperWireClosed() const
{
    return upperWire;
}

// Getter for lower wire of closed profile
const TopoDS_Edge& CCPACSWingProfileCST::GetLowerWireClosed() const
{
    return lowerWire;
}

// Getter for upper wire of opened profile
const TopoDS_Edge& CCPACSWingProfileCST::GetUpperWireOpened() const
{
    throw CTiglError("ERROR: GetUpperWireOpened not implemented yet for CCPACSWingProfileCST!");
}

// Getter for lower wire of opened profile
const TopoDS_Edge& CCPACSWingProfileCST::GetLowerWireOpened() const
{
    throw CTiglError("ERROR: GetLowerWireOpened not implemented yet for CCPACSWingProfileCST!");
}

// get upper wing profile wire
const TopoDS_Edge & CCPACSWingProfileCST::GetUpperWire() const
{
    return upperWire;
}

// get lower wing profile wire
const TopoDS_Edge & CCPACSWingProfileCST::GetLowerWire() const
{
    return lowerWire;
}

// gets the upper and lower wing profile into on edge
const TopoDS_Edge & CCPACSWingProfileCST::GetUpperLowerWire() const
{
    return upperLowerEdge;
}

// get trailing edge
const TopoDS_Edge & CCPACSWingProfileCST::GetTrailingEdge() const
{
    return trailingEdge;
}

// get trailing edge
const TopoDS_Edge & CCPACSWingProfileCST::GetTrailingEdgeOpened() const
{
    throw CTiglError("ERROR: GetTrailingEdgeOpened not implemented yet for CCPACSWingProfileCST!");
}

// get leading edge point();
const gp_Pnt & CCPACSWingProfileCST::GetLEPoint() const
{
    return lePoint;
}

// get trailing edge point();
const gp_Pnt & CCPACSWingProfileCST::GetTEPoint() const
{
    return tePoint;
}

} // end namespace tigl
<commit_msg>Fix for build issue with OCE 17 by including Standard_Version.hxx<commit_after>/*
* Copyright (C) 2007-2013 German Aerospace Center (DLR/SC)
*
* Created: 2013-12-17 Tobias Stollenwerk <Tobias.Stollenwerk@dlr.de>
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* @brief  Implementation of CPACS wing profile as a CST profile
*
* The wing profile is defined by the (C)lass function / (S)hape function (T)ransformation
* geometry representation method.
*/

#include "CCPACSWingProfileCST.h"

#include "CCSTCurveBuilder.h"

#include "CTiglError.h"
#include "CTiglTypeRegistry.h"
#include "CTiglLogging.h"
#include "CTiglTransformation.h"
#include "CWireToCurve.h"
#include "CCPACSWingProfileFactory.h"
#include "TixiSaveExt.h"
#include "math.h"

#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Standard_Version.hxx>

namespace tigl
{

namespace
{
    // helper function to read in tixi vector
    std::vector<double> readTixiVector (TixiDocumentHandle tixiHandle, const std::string& xpath, const std::string& name, const std::string& funcname)
    {
        std::string fullpath = xpath + name;
        int count;
        if (tixiGetVectorSize(tixiHandle, fullpath.c_str(), &count) != SUCCESS) {
            throw CTiglError("Error: XML error while reading vector <" + name + "> in " + funcname, TIGL_XML_ERROR);
        }
        double *tmp;
        if (tixiGetFloatVector(tixiHandle, fullpath.c_str(), &tmp, count) != SUCCESS)  {
            throw CTiglError("Error: XML error while reading vector <" + name + "> in " + funcname, TIGL_XML_ERROR);
        }
        std::vector<double> res(tmp, tmp+count);
        return res;
    }
    // helper function to read in tixi double
    double readTixiDouble (TixiDocumentHandle tixiHandle, const std::string& xpath, const std::string& name, const std::string& funcname)
    {
        std::string fullpath = xpath + name;
        double res;
        if (tixiGetDoubleElement(tixiHandle, fullpath.c_str(), &res) != SUCCESS) {
            throw CTiglError("Error: XML error while reading double <" + name + "> in " + funcname, TIGL_XML_ERROR);
        }
        return res;
    }
} // anonymous namespace

// register profile algo at factory
PTiglWingProfileAlgo CreateProfileCST(const CCPACSWingProfile& profile, const std::string& cpacsPath)
{
    return PTiglWingProfileAlgo(new CCPACSWingProfileCST(profile, cpacsPath));
}

AUTORUN(CCPACSWingProfileCST)
{
    return CCPACSWingProfileFactory::Instance().RegisterAlgo(CCPACSWingProfileCST::CPACSID(), CreateProfileCST);
}

// Constructor
CCPACSWingProfileCST::CCPACSWingProfileCST(const CCPACSWingProfile& profile, const std::string& path)
{
    ProfileDataXPath=path + "/" + CPACSID();
    trailingEdge.Nullify();
}

// Destructor
CCPACSWingProfileCST::~CCPACSWingProfileCST(void)
{
}

std::string CCPACSWingProfileCST::CPACSID()
{
    return "cst2D";
}

// Cleanup routine
void CCPACSWingProfileCST::Cleanup(void)
{
    upperB.clear();
    lowerB.clear();
    trailingEdge.Nullify();
}

void CCPACSWingProfileCST::Update(void)
{
    BuildWires();
}

// Read wing profile file
void CCPACSWingProfileCST::ReadCPACS(TixiDocumentHandle tixiHandle)
{
    upperB=readTixiVector(tixiHandle, ProfileDataXPath, "/upperB", "CCPACSWingProfileCST::ReadCPACS");
    lowerB=readTixiVector(tixiHandle, ProfileDataXPath, "/lowerB", "CCPACSWingProfileCST::ReadCPACS");
    upperN1=readTixiDouble(tixiHandle, ProfileDataXPath, "/upperN1", "CCPACSWingProfileCST::ReadCPACS");
    upperN2=readTixiDouble(tixiHandle, ProfileDataXPath, "/upperN2", "CCPACSWingProfileCST::ReadCPACS");
    lowerN1=readTixiDouble(tixiHandle, ProfileDataXPath, "/lowerN1", "CCPACSWingProfileCST::ReadCPACS");
    lowerN2=readTixiDouble(tixiHandle, ProfileDataXPath, "/lowerN2", "CCPACSWingProfileCST::ReadCPACS");
}

// Write CPACS wing profile
void CCPACSWingProfileCST::WriteCPACS(TixiDocumentHandle tixiHandle, const std::string& ProfileXPath)
{
    // Set the element "point"
    TixiSaveExt::TixiSaveElement(tixiHandle, ProfileXPath.c_str(), CPACSID().c_str() );

    std::string elementPath = ProfileXPath + "/" + CPACSID();

    TixiSaveExt::TixiSaveVector(tixiHandle, elementPath, "upperB", upperB);
    TixiSaveExt::TixiSaveVector(tixiHandle, elementPath, "lowerB", lowerB);
    TixiSaveExt::TixiSaveDoubleElement(tixiHandle, elementPath.c_str(), "upperN1", upperN1);
    TixiSaveExt::TixiSaveDoubleElement(tixiHandle, elementPath.c_str(), "upperN2", upperN2);
    TixiSaveExt::TixiSaveDoubleElement(tixiHandle, elementPath.c_str(), "lowerN1", lowerN1);
    TixiSaveExt::TixiSaveDoubleElement(tixiHandle, elementPath.c_str(), "lowerN2", lowerN2);

}

// Builds the wing profile wire. The returned wire is already transformed by the
// wing profile element transformation.
void CCPACSWingProfileCST::BuildWires()
{
    gp_Trsf yzSwitch;
    yzSwitch.SetMirror(gp_Ax2(gp_Pnt(0.,0.,0.), gp_Dir(0.,-1.,1.)));

    // Build upper wire
    CCSTCurveBuilder upperBuilder(upperN1, upperN2, upperB);
    Handle_Geom_BSplineCurve upperCurve = upperBuilder.Curve();
    upperCurve->Transform(yzSwitch);
    upperWire = BRepBuilderAPI_MakeEdge(upperCurve);

    // Build lower curve,
    std::vector<double> binv;
    for (unsigned int i = 0; i < lowerB.size(); ++i) {
        binv.push_back(-lowerB[i]);
    }

    CCSTCurveBuilder lowerBuilder(lowerN1, lowerN2, binv);
    Handle_Geom_BSplineCurve lowerCurve = lowerBuilder.Curve();
    lowerCurve->Transform(yzSwitch);
    lowerCurve->Reverse();
    lowerWire = BRepBuilderAPI_MakeEdge(lowerCurve);

    BRepBuilderAPI_MakeWire upperLowerWireMaker(lowerWire, upperWire);
    TopoDS_Wire upperLowerWire = upperLowerWireMaker.Wire();

    // conatenate wire
    Handle_Geom_Curve upperLowerCurve = CWireToCurve(upperLowerWire).curve();
    upperLowerEdge = BRepBuilderAPI_MakeEdge(upperLowerCurve);

    tePoint = gp_Pnt(1,0,0);
    lePoint = gp_Pnt(0,0,0);
}

// Returns sample points
std::vector<CTiglPoint*> CCPACSWingProfileCST::GetSamplePoints() const
{
    std::vector<CTiglPoint*> empty;
    return empty;
}

// get profiles CPACS XML path
const std::string & CCPACSWingProfileCST::GetProfileDataXPath() const
{
    return ProfileDataXPath;
}

// Getter for upper wire of closed profile
const TopoDS_Edge& CCPACSWingProfileCST::GetUpperWireClosed() const
{
    return upperWire;
}

// Getter for lower wire of closed profile
const TopoDS_Edge& CCPACSWingProfileCST::GetLowerWireClosed() const
{
    return lowerWire;
}

// Getter for upper wire of opened profile
const TopoDS_Edge& CCPACSWingProfileCST::GetUpperWireOpened() const
{
    throw CTiglError("ERROR: GetUpperWireOpened not implemented yet for CCPACSWingProfileCST!");
}

// Getter for lower wire of opened profile
const TopoDS_Edge& CCPACSWingProfileCST::GetLowerWireOpened() const
{
    throw CTiglError("ERROR: GetLowerWireOpened not implemented yet for CCPACSWingProfileCST!");
}

// get upper wing profile wire
const TopoDS_Edge & CCPACSWingProfileCST::GetUpperWire() const
{
    return upperWire;
}

// get lower wing profile wire
const TopoDS_Edge & CCPACSWingProfileCST::GetLowerWire() const
{
    return lowerWire;
}

// gets the upper and lower wing profile into on edge
const TopoDS_Edge & CCPACSWingProfileCST::GetUpperLowerWire() const
{
    return upperLowerEdge;
}

// get trailing edge
const TopoDS_Edge & CCPACSWingProfileCST::GetTrailingEdge() const
{
    return trailingEdge;
}

// get trailing edge
const TopoDS_Edge & CCPACSWingProfileCST::GetTrailingEdgeOpened() const
{
    throw CTiglError("ERROR: GetTrailingEdgeOpened not implemented yet for CCPACSWingProfileCST!");
}

// get leading edge point();
const gp_Pnt & CCPACSWingProfileCST::GetLEPoint() const
{
    return lePoint;
}

// get trailing edge point();
const gp_Pnt & CCPACSWingProfileCST::GetTEPoint() const
{
    return tePoint;
}

} // end namespace tigl
<|endoftext|>


<commit_before>//=============================================================================================================
/**
* @file     informationwindow.h
* @author   Lorenz Esch <Lorenz.Esch@tu-ilmenau.de>
*           Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     August, 2014
*
* @section  LICENSE
*
* Copyright (C) 2014, Lorenz Esch, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Contains the implementation of the InformationWindow class.
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "informationwindow.h"

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace MNEBrowseRawQt;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

InformationWindow::InformationWindow(QWidget *parent) :
    QDockWidget(parent),
    ui(new Ui::InformationWindowWidget)
{
    ui->setupUi(this);

    m_pTextBrowser_Log = (QTextBrowser*)ui->tab_log->childAt(50,50);
}

//*************************************************************************************************************

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

//*************************************************************************************************************

void InformationWindow::writeToLog(const QString& logMsg, LogKind lgknd, LogLevel lglvl)
{
    if(lglvl<=m_eLogLevelCurrent) {
        if(lgknd == _LogKndError)
            m_pTextBrowser_Log->insertHtml("Error: "+logMsg+"");
        else if(lgknd == _LogKndWarning)
            m_pTextBrowser_Log->insertHtml("Warning: "+logMsg+"");
        else
            m_pTextBrowser_Log->insertHtml(logMsg);
        m_pTextBrowser_Log->insertPlainText("\n"); // new line
        //scroll down to the latest entry
        QTextCursor c = m_pTextBrowser_Log->textCursor();
        c.movePosition(QTextCursor::End);
        m_pTextBrowser_Log->setTextCursor(c);

        m_pTextBrowser_Log->verticalScrollBar()->setValue(m_pTextBrowser_Log->verticalScrollBar()->maximum());
    }
}

//*************************************************************************************************************

void InformationWindow::setLogLevel(LogLevel lvl)
{
    switch(lvl) {
    case _LogLvMin:
        writeToLog(tr("minimal log level set"), _LogKndMessage, _LogLvMin);
        break;
    case _LogLvNormal:
        writeToLog(tr("normal log level set"), _LogKndMessage, _LogLvMin);
        break;
    case _LogLvMax:
        writeToLog(tr("maximum log level set"), _LogKndMessage, _LogLvMin);
        break;
    }

    m_eLogLevelCurrent = lvl;
}
<commit_msg>initialize log level before writing to log<commit_after>//=============================================================================================================
/**
* @file     informationwindow.h
* @author   Lorenz Esch <Lorenz.Esch@tu-ilmenau.de>
*           Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     August, 2014
*
* @section  LICENSE
*
* Copyright (C) 2014, Lorenz Esch, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Contains the implementation of the InformationWindow class.
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "informationwindow.h"

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace MNEBrowseRawQt;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

InformationWindow::InformationWindow(QWidget *parent) :
    QDockWidget(parent),
    ui(new Ui::InformationWindowWidget)
{
    ui->setupUi(this);

    m_pTextBrowser_Log = (QTextBrowser*)ui->tab_log->childAt(50,50);
}

//*************************************************************************************************************

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

//*************************************************************************************************************

void InformationWindow::writeToLog(const QString& logMsg, LogKind lgknd, LogLevel lglvl)
{
    if(lglvl<=m_eLogLevelCurrent) {
        if(lgknd == _LogKndError)
            m_pTextBrowser_Log->insertHtml("Error: "+logMsg+"");
        else if(lgknd == _LogKndWarning)
            m_pTextBrowser_Log->insertHtml("Warning: "+logMsg+"");
        else
            m_pTextBrowser_Log->insertHtml(logMsg);
        m_pTextBrowser_Log->insertPlainText("\n"); // new line
        //scroll down to the latest entry
        QTextCursor c = m_pTextBrowser_Log->textCursor();
        c.movePosition(QTextCursor::End);
        m_pTextBrowser_Log->setTextCursor(c);

        m_pTextBrowser_Log->verticalScrollBar()->setValue(m_pTextBrowser_Log->verticalScrollBar()->maximum());
    }
}

//*************************************************************************************************************

void InformationWindow::setLogLevel(LogLevel lvl)
{
    m_eLogLevelCurrent = lvl;

    switch(lvl) {
    case _LogLvMin:
        writeToLog(tr("minimal log level set"), _LogKndMessage, _LogLvMin);
        break;
    case _LogLvNormal:
        writeToLog(tr("normal log level set"), _LogKndMessage, _LogLvMin);
        break;
    case _LogLvMax:
        writeToLog(tr("maximum log level set"), _LogKndMessage, _LogLvMin);
        break;
    }
}
<|endoftext|>