<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "projectwindow.h"

#include "doubletabwidget.h"

#include "project.h"
#include "projectexplorer.h"
#include "projectexplorerconstants.h"
#include "session.h"
#include "projecttreewidget.h"
#include "iprojectproperties.h"
#include "targetsettingspanel.h"
#include "target.h"

#include <coreplugin/icore.h>
#include <coreplugin/idocument.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
#include <utils/stylehelper.h>

#include <QApplication>
#include <QGridLayout>
#include <QLabel>
#include <QPainter>
#include <QStackedWidget>

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

namespace {
const int ICON_SIZE(64);

const int ABOVE_HEADING_MARGIN(10);
const int ABOVE_CONTENTS_MARGIN(4);
const int BELOW_CONTENTS_MARGIN(16);

} // anonymous namespace

///
// OnePixelBlackLine
///

class OnePixelBlackLine : public QWidget
{
public:
    OnePixelBlackLine(QWidget *parent)
        : QWidget(parent)
    {
        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
        setMinimumHeight(1);
        setMaximumHeight(1);
    }
    void paintEvent(QPaintEvent *e)
    {
        Q_UNUSED(e);
        QPainter p(this);
        QColor fillColor = Utils::StyleHelper::mergedColors(
                palette().button().color(), Qt::black, 80);
        p.fillRect(contentsRect(), fillColor);
    }
};

class RootWidget : public QWidget
{
public:
    RootWidget(QWidget *parent) : QWidget(parent) {
        setFocusPolicy(Qt::NoFocus);
    }
    void paintEvent(QPaintEvent *);
};

void RootWidget::paintEvent(QPaintEvent *e)
{
    QWidget::paintEvent(e);

    QPainter painter(this);
    QColor light = Utils::StyleHelper::mergedColors(
            palette().button().color(), Qt::white, 30);
    QColor dark = Utils::StyleHelper::mergedColors(
            palette().button().color(), Qt::black, 85);

    painter.setPen(light);
    painter.drawLine(rect().topRight(), rect().bottomRight());
    painter.setPen(dark);
    painter.drawLine(rect().topRight() - QPoint(1,0), rect().bottomRight() - QPoint(1,0));
}

///
// PanelsWidget
///

PanelsWidget::PanelsWidget(QWidget *parent) :
    QScrollArea(parent),
    m_root(new RootWidget(this))
{
    // We want a 900px wide widget with and the scrollbar at the
    // side of the screen.
    m_root->setFixedWidth(900);
    m_root->setContentsMargins(0, 0, 40, 0);

    QPalette pal = m_root->palette();
    QColor background = Utils::StyleHelper::mergedColors(
            palette().window().color(), Qt::white, 85);
    pal.setColor(QPalette::All, QPalette::Window, background.darker(102));
    setPalette(pal);
    pal.setColor(QPalette::All, QPalette::Window, background);
    m_root->setPalette(pal);
    // The layout holding the individual panels:
    m_layout = new QGridLayout(m_root);
    m_layout->setColumnMinimumWidth(0, ICON_SIZE + 4);
    m_layout->setSpacing(0);

    setWidget(m_root);
    setFrameStyle(QFrame::NoFrame);
    setWidgetResizable(true);
    setFocusPolicy(Qt::NoFocus);
}

PanelsWidget::~PanelsWidget()
{
    qDeleteAll(m_panels);
}

/*
 * Add a widget with heading information into the grid
 * layout of the PanelsWidget.
 *
 *     ...
 * +--------+-------------------------------------------+ ABOVE_HEADING_MARGIN
 * | icon   | name                                      |
 * +        +-------------------------------------------+
 * |        | line                                      |
 * +--------+-------------------------------------------+ ABOVE_CONTENTS_MARGIN
 * |          widget (with contentsmargins adjusted!)   |
 * +--------+-------------------------------------------+ BELOW_CONTENTS_MARGIN
 */
void PanelsWidget::addPropertiesPanel(PropertiesPanel *panel)
{
    QTC_ASSERT(panel, return);

    const int headerRow(m_layout->rowCount() - 1);

    // icon:
    if (!panel->icon().isNull()) {
        QLabel *iconLabel = new QLabel(m_root);
        iconLabel->setPixmap(panel->icon().pixmap(ICON_SIZE, ICON_SIZE));
        iconLabel->setContentsMargins(0, ABOVE_HEADING_MARGIN, 0, 0);
        m_layout->addWidget(iconLabel, headerRow, 0, 3, 1, Qt::AlignTop | Qt::AlignHCenter);
    }

    // name:
    QLabel *nameLabel = new QLabel(m_root);
    nameLabel->setText(panel->displayName());
    QPalette palette = nameLabel->palette();
    palette.setBrush(QPalette::All, QPalette::Foreground, QColor(0, 0, 0, 110));
    nameLabel->setPalette(palette);
    nameLabel->setContentsMargins(0, ABOVE_HEADING_MARGIN, 0, 0);
    QFont f = nameLabel->font();
    f.setBold(true);
    f.setPointSizeF(f.pointSizeF() * 1.6);
    nameLabel->setFont(f);
    m_layout->addWidget(nameLabel, headerRow, 1, 1, 1, Qt::AlignVCenter | Qt::AlignLeft);

    // line:
    const int lineRow(headerRow + 1);
    QWidget *line = new OnePixelBlackLine(m_root);
    m_layout->addWidget(line, lineRow, 1, 1, -1, Qt::AlignTop);

    // add the widget:
    const int widgetRow(lineRow + 1);
    addPanelWidget(panel, widgetRow);
}

void PanelsWidget::addPanelWidget(PropertiesPanel *panel, int row)
{
    QWidget *widget = panel->widget();
    widget->setContentsMargins(Constants::PANEL_LEFT_MARGIN,
                               ABOVE_CONTENTS_MARGIN, 0,
                               BELOW_CONTENTS_MARGIN);
    widget->setParent(m_root);
    m_layout->addWidget(widget, row, 0, 1, 2);

    m_panels.append(panel);
}

///
// ProjectWindow
///

ProjectWindow::ProjectWindow(QWidget *parent)
    : QWidget(parent),
      m_currentWidget(0),
      m_previousTargetSubIndex(-1)
{
    ProjectExplorer::SessionManager *session = ProjectExplorerPlugin::instance()->session();

    // Setup overall layout:
    QVBoxLayout *viewLayout = new QVBoxLayout(this);
    viewLayout->setMargin(0);
    viewLayout->setSpacing(0);

    m_tabWidget = new DoubleTabWidget(this);
    viewLayout->addWidget(m_tabWidget);

    // Setup our container for the contents:
    m_centralWidget = new QStackedWidget(this);
    viewLayout->addWidget(m_centralWidget);

    // connects:
    connect(m_tabWidget, SIGNAL(currentIndexChanged(int,int)),
            this, SLOT(showProperties(int,int)));

    connect(session, SIGNAL(sessionLoaded(QString)), this, SLOT(restoreStatus()));
    connect(session, SIGNAL(aboutToSaveSession()), this, SLOT(saveStatus()));

    connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
            this, SLOT(registerProject(ProjectExplorer::Project*)));
    connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)),
            this, SLOT(deregisterProject(ProjectExplorer::Project*)));

    connect(session, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
            this, SLOT(startupProjectChanged(ProjectExplorer::Project*)));

    connect(session, SIGNAL(projectDisplayNameChanged(ProjectExplorer::Project*)),
            this, SLOT(projectUpdated(ProjectExplorer::Project*)));

    // Update properties to empty project for now:
    showProperties(-1, -1);
}

ProjectWindow::~ProjectWindow()
{
}

void ProjectWindow::extensionsInitialized()
{
    foreach (ITargetFactory *fac, ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>())
        connect(fac, SIGNAL(canCreateTargetIdsChanged()),
                this, SLOT(targetFactoriesChanged()));

    QList<IProjectPanelFactory *> list = ExtensionSystem::PluginManager::instance()->getObjects<IProjectPanelFactory>();
    qSort(list.begin(), list.end(), &IPanelFactory::prioritySort);
}

void ProjectWindow::aboutToShutdown()
{
    showProperties(-1, -1); // that's a bit stupid, but otherwise stuff is still
                            // connected to the session
    disconnect(ProjectExplorerPlugin::instance()->session(), 0, this, 0);
}

void ProjectWindow::projectUpdated(Project *p)
{
    // Called after a project was configured
    int index = m_tabWidget->currentIndex();
    deregisterProject(p);
    registerProject(p);
    m_tabWidget->setCurrentIndex(index);
}

void ProjectWindow::targetFactoriesChanged()
{
    bool changed = false;
    int index = m_tabWidget->currentIndex();
    QList<Project *> projects = m_tabIndexToProject;
    foreach (ProjectExplorer::Project *project, projects) {
        if (m_usesTargetPage.value(project) != useTargetPage(project)) {
            changed = true;
            deregisterProject(project);
            registerProject(project);
        }
    }
    if (changed)
        m_tabWidget->setCurrentIndex(index);
}

bool ProjectWindow::useTargetPage(ProjectExplorer::Project *project)
{
    if (project->targets().isEmpty())
        return false;
    if (project->targets().size() > 1)
        return true;
    int count = 0;
    foreach (ITargetFactory *fac, ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>()) {
        foreach (Core::Id targetId, fac->supportedTargetIds()) {
            if (fac->canCreate(project, targetId))
                ++count;
            if (count > 1)
                return true;
        }
    }
    return false;
}

void ProjectWindow::registerProject(ProjectExplorer::Project *project)
{
    if (!project || m_tabIndexToProject.contains(project))
        return;

    // find index to insert:
    int index = -1;
    for (int i = 0; i <= m_tabIndexToProject.count(); ++i) {
        if (i == m_tabIndexToProject.count() ||
            m_tabIndexToProject.at(i)->displayName() > project->displayName()) {
            index = i;
            break;
        }
    }

    QStringList subtabs;

    bool usesTargetPage = useTargetPage(project);
    m_usesTargetPage.insert(project, usesTargetPage);

    if (!usesTargetPage){
        // Show the target specific pages directly
        if (project->activeTarget()) {
            QList<ITargetPanelFactory *> factories =
                    ExtensionSystem::PluginManager::instance()->getObjects<ITargetPanelFactory>();

            qSort(factories.begin(), factories.end(), &IPanelFactory::prioritySort);

            foreach (ITargetPanelFactory *factory, factories)
                if (factory->supports(project->activeTarget()))
                    subtabs << factory->displayName();
        }
    } else {
        // Use the Targets page
        subtabs << QCoreApplication::translate("TargetSettingsPanelFactory", "Targets");
    }

    // Add the project specific pages
    QList<IProjectPanelFactory *> factories = ExtensionSystem::PluginManager::instance()->getObjects<IProjectPanelFactory>();
    qSort(factories.begin(), factories.end(), &IPanelFactory::prioritySort);
    foreach (IProjectPanelFactory *panelFactory, factories) {
        if (panelFactory->supports(project))
            subtabs << panelFactory->displayName();
    }

    m_tabIndexToProject.insert(index, project);
    m_tabWidget->insertTab(index, project->displayName(), project->document()->fileName(), subtabs);
}

void ProjectWindow::deregisterProject(ProjectExplorer::Project *project)
{
    int index = m_tabIndexToProject.indexOf(project);
    if (index < 0)
        return;

    m_tabIndexToProject.removeAt(index);
    m_tabWidget->removeTab(index);
}

void ProjectWindow::startupProjectChanged(ProjectExplorer::Project *p)
{
    int index = m_tabIndexToProject.indexOf(p);
    if (index != -1)
        m_tabWidget->setCurrentIndex(index);
}

void ProjectWindow::showProperties(int index, int subIndex)
{
    if (index < 0 || index >= m_tabIndexToProject.count()) {
        removeCurrentWidget();
        return;
    }

    Project *project = m_tabIndexToProject.at(index);

    // Set up custom panels again:
    int pos = 0;
    IPanelFactory *fac = 0;
    // remember previous sub index state of target settings page
    if (TargetSettingsPanelWidget *previousPanelWidget
            = qobject_cast<TargetSettingsPanelWidget*>(m_currentWidget)) {
        m_previousTargetSubIndex = previousPanelWidget->currentSubIndex();
    }

    if (m_usesTargetPage.value(project)) {
        if (subIndex == 0) {
            // Targets page
            removeCurrentWidget();
            TargetSettingsPanelWidget *panelWidget = new TargetSettingsPanelWidget(project);
            if (m_previousTargetSubIndex >= 0)
                panelWidget->setCurrentSubIndex(m_previousTargetSubIndex);
            m_currentWidget = panelWidget;
            m_centralWidget->addWidget(m_currentWidget);
            m_centralWidget->setCurrentWidget(m_currentWidget);
        }
        ++pos;
    } else if (project->activeTarget()) {
        // No Targets page, target specific pages are first in the list
        QList<ITargetPanelFactory *> factories = ExtensionSystem::PluginManager::instance()->getObjects<ITargetPanelFactory>();
        qSort(factories.begin(), factories.end(), &ITargetPanelFactory::prioritySort);
        foreach (ITargetPanelFactory *panelFactory, factories) {
            if (panelFactory->supports(project->activeTarget())) {
                if (subIndex == pos) {
                    fac = panelFactory;
                    break;
                }
                ++pos;
            }
        }
    }

    if (!fac) {
        QList<IProjectPanelFactory *> factories = ExtensionSystem::PluginManager::instance()->getObjects<IProjectPanelFactory>();
        qSort(factories.begin(), factories.end(), &IPanelFactory::prioritySort);
        foreach (IProjectPanelFactory *panelFactory, factories) {
            if (panelFactory->supports(project)) {
                if (subIndex == pos) {
                    fac = panelFactory;
                    break;
                }
                ++pos;
            }
        }
    }

    if (fac) {
        removeCurrentWidget();

        PropertiesPanel *panel = 0;
        if (ITargetPanelFactory *ipf = qobject_cast<ITargetPanelFactory *>(fac))
            panel = ipf->createPanel(project->activeTarget());
        else if (IProjectPanelFactory *ipf = qobject_cast<IProjectPanelFactory *>(fac))
            panel = ipf->createPanel(project);
        Q_ASSERT(panel);

        PanelsWidget *panelsWidget = new PanelsWidget(m_centralWidget);
        panelsWidget->addPropertiesPanel(panel);
        m_currentWidget = panelsWidget;
        m_centralWidget->addWidget(m_currentWidget);
        m_centralWidget->setCurrentWidget(m_currentWidget);

    }

    ProjectExplorerPlugin::instance()->session()->setStartupProject(project);
}

void ProjectWindow::removeCurrentWidget()
{
    if (m_currentWidget) {
        m_centralWidget->removeWidget(m_currentWidget);
        if (m_currentWidget) {
            delete m_currentWidget;
            m_currentWidget = 0;
        }
    }
}
<commit_msg>Remove connections to removed functions<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "projectwindow.h"

#include "doubletabwidget.h"

#include "project.h"
#include "projectexplorer.h"
#include "projectexplorerconstants.h"
#include "session.h"
#include "projecttreewidget.h"
#include "iprojectproperties.h"
#include "targetsettingspanel.h"
#include "target.h"

#include <coreplugin/icore.h>
#include <coreplugin/idocument.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
#include <utils/stylehelper.h>

#include <QApplication>
#include <QGridLayout>
#include <QLabel>
#include <QPainter>
#include <QStackedWidget>

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

namespace {
const int ICON_SIZE(64);

const int ABOVE_HEADING_MARGIN(10);
const int ABOVE_CONTENTS_MARGIN(4);
const int BELOW_CONTENTS_MARGIN(16);

} // anonymous namespace

///
// OnePixelBlackLine
///

class OnePixelBlackLine : public QWidget
{
public:
    OnePixelBlackLine(QWidget *parent)
        : QWidget(parent)
    {
        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
        setMinimumHeight(1);
        setMaximumHeight(1);
    }
    void paintEvent(QPaintEvent *e)
    {
        Q_UNUSED(e);
        QPainter p(this);
        QColor fillColor = Utils::StyleHelper::mergedColors(
                palette().button().color(), Qt::black, 80);
        p.fillRect(contentsRect(), fillColor);
    }
};

class RootWidget : public QWidget
{
public:
    RootWidget(QWidget *parent) : QWidget(parent) {
        setFocusPolicy(Qt::NoFocus);
    }
    void paintEvent(QPaintEvent *);
};

void RootWidget::paintEvent(QPaintEvent *e)
{
    QWidget::paintEvent(e);

    QPainter painter(this);
    QColor light = Utils::StyleHelper::mergedColors(
            palette().button().color(), Qt::white, 30);
    QColor dark = Utils::StyleHelper::mergedColors(
            palette().button().color(), Qt::black, 85);

    painter.setPen(light);
    painter.drawLine(rect().topRight(), rect().bottomRight());
    painter.setPen(dark);
    painter.drawLine(rect().topRight() - QPoint(1,0), rect().bottomRight() - QPoint(1,0));
}

///
// PanelsWidget
///

PanelsWidget::PanelsWidget(QWidget *parent) :
    QScrollArea(parent),
    m_root(new RootWidget(this))
{
    // We want a 900px wide widget with and the scrollbar at the
    // side of the screen.
    m_root->setFixedWidth(900);
    m_root->setContentsMargins(0, 0, 40, 0);

    QPalette pal = m_root->palette();
    QColor background = Utils::StyleHelper::mergedColors(
            palette().window().color(), Qt::white, 85);
    pal.setColor(QPalette::All, QPalette::Window, background.darker(102));
    setPalette(pal);
    pal.setColor(QPalette::All, QPalette::Window, background);
    m_root->setPalette(pal);
    // The layout holding the individual panels:
    m_layout = new QGridLayout(m_root);
    m_layout->setColumnMinimumWidth(0, ICON_SIZE + 4);
    m_layout->setSpacing(0);

    setWidget(m_root);
    setFrameStyle(QFrame::NoFrame);
    setWidgetResizable(true);
    setFocusPolicy(Qt::NoFocus);
}

PanelsWidget::~PanelsWidget()
{
    qDeleteAll(m_panels);
}

/*
 * Add a widget with heading information into the grid
 * layout of the PanelsWidget.
 *
 *     ...
 * +--------+-------------------------------------------+ ABOVE_HEADING_MARGIN
 * | icon   | name                                      |
 * +        +-------------------------------------------+
 * |        | line                                      |
 * +--------+-------------------------------------------+ ABOVE_CONTENTS_MARGIN
 * |          widget (with contentsmargins adjusted!)   |
 * +--------+-------------------------------------------+ BELOW_CONTENTS_MARGIN
 */
void PanelsWidget::addPropertiesPanel(PropertiesPanel *panel)
{
    QTC_ASSERT(panel, return);

    const int headerRow(m_layout->rowCount() - 1);

    // icon:
    if (!panel->icon().isNull()) {
        QLabel *iconLabel = new QLabel(m_root);
        iconLabel->setPixmap(panel->icon().pixmap(ICON_SIZE, ICON_SIZE));
        iconLabel->setContentsMargins(0, ABOVE_HEADING_MARGIN, 0, 0);
        m_layout->addWidget(iconLabel, headerRow, 0, 3, 1, Qt::AlignTop | Qt::AlignHCenter);
    }

    // name:
    QLabel *nameLabel = new QLabel(m_root);
    nameLabel->setText(panel->displayName());
    QPalette palette = nameLabel->palette();
    palette.setBrush(QPalette::All, QPalette::Foreground, QColor(0, 0, 0, 110));
    nameLabel->setPalette(palette);
    nameLabel->setContentsMargins(0, ABOVE_HEADING_MARGIN, 0, 0);
    QFont f = nameLabel->font();
    f.setBold(true);
    f.setPointSizeF(f.pointSizeF() * 1.6);
    nameLabel->setFont(f);
    m_layout->addWidget(nameLabel, headerRow, 1, 1, 1, Qt::AlignVCenter | Qt::AlignLeft);

    // line:
    const int lineRow(headerRow + 1);
    QWidget *line = new OnePixelBlackLine(m_root);
    m_layout->addWidget(line, lineRow, 1, 1, -1, Qt::AlignTop);

    // add the widget:
    const int widgetRow(lineRow + 1);
    addPanelWidget(panel, widgetRow);
}

void PanelsWidget::addPanelWidget(PropertiesPanel *panel, int row)
{
    QWidget *widget = panel->widget();
    widget->setContentsMargins(Constants::PANEL_LEFT_MARGIN,
                               ABOVE_CONTENTS_MARGIN, 0,
                               BELOW_CONTENTS_MARGIN);
    widget->setParent(m_root);
    m_layout->addWidget(widget, row, 0, 1, 2);

    m_panels.append(panel);
}

///
// ProjectWindow
///

ProjectWindow::ProjectWindow(QWidget *parent)
    : QWidget(parent),
      m_currentWidget(0),
      m_previousTargetSubIndex(-1)
{
    ProjectExplorer::SessionManager *session = ProjectExplorerPlugin::instance()->session();

    // Setup overall layout:
    QVBoxLayout *viewLayout = new QVBoxLayout(this);
    viewLayout->setMargin(0);
    viewLayout->setSpacing(0);

    m_tabWidget = new DoubleTabWidget(this);
    viewLayout->addWidget(m_tabWidget);

    // Setup our container for the contents:
    m_centralWidget = new QStackedWidget(this);
    viewLayout->addWidget(m_centralWidget);

    // connects:
    connect(m_tabWidget, SIGNAL(currentIndexChanged(int,int)),
            this, SLOT(showProperties(int,int)));

    connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
            this, SLOT(registerProject(ProjectExplorer::Project*)));
    connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)),
            this, SLOT(deregisterProject(ProjectExplorer::Project*)));

    connect(session, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
            this, SLOT(startupProjectChanged(ProjectExplorer::Project*)));

    connect(session, SIGNAL(projectDisplayNameChanged(ProjectExplorer::Project*)),
            this, SLOT(projectUpdated(ProjectExplorer::Project*)));

    // Update properties to empty project for now:
    showProperties(-1, -1);
}

ProjectWindow::~ProjectWindow()
{
}

void ProjectWindow::extensionsInitialized()
{
    foreach (ITargetFactory *fac, ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>())
        connect(fac, SIGNAL(canCreateTargetIdsChanged()),
                this, SLOT(targetFactoriesChanged()));

    QList<IProjectPanelFactory *> list = ExtensionSystem::PluginManager::instance()->getObjects<IProjectPanelFactory>();
    qSort(list.begin(), list.end(), &IPanelFactory::prioritySort);
}

void ProjectWindow::aboutToShutdown()
{
    showProperties(-1, -1); // that's a bit stupid, but otherwise stuff is still
                            // connected to the session
    disconnect(ProjectExplorerPlugin::instance()->session(), 0, this, 0);
}

void ProjectWindow::projectUpdated(Project *p)
{
    // Called after a project was configured
    int index = m_tabWidget->currentIndex();
    deregisterProject(p);
    registerProject(p);
    m_tabWidget->setCurrentIndex(index);
}

void ProjectWindow::targetFactoriesChanged()
{
    bool changed = false;
    int index = m_tabWidget->currentIndex();
    QList<Project *> projects = m_tabIndexToProject;
    foreach (ProjectExplorer::Project *project, projects) {
        if (m_usesTargetPage.value(project) != useTargetPage(project)) {
            changed = true;
            deregisterProject(project);
            registerProject(project);
        }
    }
    if (changed)
        m_tabWidget->setCurrentIndex(index);
}

bool ProjectWindow::useTargetPage(ProjectExplorer::Project *project)
{
    if (project->targets().isEmpty())
        return false;
    if (project->targets().size() > 1)
        return true;
    int count = 0;
    foreach (ITargetFactory *fac, ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>()) {
        foreach (Core::Id targetId, fac->supportedTargetIds()) {
            if (fac->canCreate(project, targetId))
                ++count;
            if (count > 1)
                return true;
        }
    }
    return false;
}

void ProjectWindow::registerProject(ProjectExplorer::Project *project)
{
    if (!project || m_tabIndexToProject.contains(project))
        return;

    // find index to insert:
    int index = -1;
    for (int i = 0; i <= m_tabIndexToProject.count(); ++i) {
        if (i == m_tabIndexToProject.count() ||
            m_tabIndexToProject.at(i)->displayName() > project->displayName()) {
            index = i;
            break;
        }
    }

    QStringList subtabs;

    bool usesTargetPage = useTargetPage(project);
    m_usesTargetPage.insert(project, usesTargetPage);

    if (!usesTargetPage){
        // Show the target specific pages directly
        if (project->activeTarget()) {
            QList<ITargetPanelFactory *> factories =
                    ExtensionSystem::PluginManager::instance()->getObjects<ITargetPanelFactory>();

            qSort(factories.begin(), factories.end(), &IPanelFactory::prioritySort);

            foreach (ITargetPanelFactory *factory, factories)
                if (factory->supports(project->activeTarget()))
                    subtabs << factory->displayName();
        }
    } else {
        // Use the Targets page
        subtabs << QCoreApplication::translate("TargetSettingsPanelFactory", "Targets");
    }

    // Add the project specific pages
    QList<IProjectPanelFactory *> factories = ExtensionSystem::PluginManager::instance()->getObjects<IProjectPanelFactory>();
    qSort(factories.begin(), factories.end(), &IPanelFactory::prioritySort);
    foreach (IProjectPanelFactory *panelFactory, factories) {
        if (panelFactory->supports(project))
            subtabs << panelFactory->displayName();
    }

    m_tabIndexToProject.insert(index, project);
    m_tabWidget->insertTab(index, project->displayName(), project->document()->fileName(), subtabs);
}

void ProjectWindow::deregisterProject(ProjectExplorer::Project *project)
{
    int index = m_tabIndexToProject.indexOf(project);
    if (index < 0)
        return;

    m_tabIndexToProject.removeAt(index);
    m_tabWidget->removeTab(index);
}

void ProjectWindow::startupProjectChanged(ProjectExplorer::Project *p)
{
    int index = m_tabIndexToProject.indexOf(p);
    if (index != -1)
        m_tabWidget->setCurrentIndex(index);
}

void ProjectWindow::showProperties(int index, int subIndex)
{
    if (index < 0 || index >= m_tabIndexToProject.count()) {
        removeCurrentWidget();
        return;
    }

    Project *project = m_tabIndexToProject.at(index);

    // Set up custom panels again:
    int pos = 0;
    IPanelFactory *fac = 0;
    // remember previous sub index state of target settings page
    if (TargetSettingsPanelWidget *previousPanelWidget
            = qobject_cast<TargetSettingsPanelWidget*>(m_currentWidget)) {
        m_previousTargetSubIndex = previousPanelWidget->currentSubIndex();
    }

    if (m_usesTargetPage.value(project)) {
        if (subIndex == 0) {
            // Targets page
            removeCurrentWidget();
            TargetSettingsPanelWidget *panelWidget = new TargetSettingsPanelWidget(project);
            if (m_previousTargetSubIndex >= 0)
                panelWidget->setCurrentSubIndex(m_previousTargetSubIndex);
            m_currentWidget = panelWidget;
            m_centralWidget->addWidget(m_currentWidget);
            m_centralWidget->setCurrentWidget(m_currentWidget);
        }
        ++pos;
    } else if (project->activeTarget()) {
        // No Targets page, target specific pages are first in the list
        QList<ITargetPanelFactory *> factories = ExtensionSystem::PluginManager::instance()->getObjects<ITargetPanelFactory>();
        qSort(factories.begin(), factories.end(), &ITargetPanelFactory::prioritySort);
        foreach (ITargetPanelFactory *panelFactory, factories) {
            if (panelFactory->supports(project->activeTarget())) {
                if (subIndex == pos) {
                    fac = panelFactory;
                    break;
                }
                ++pos;
            }
        }
    }

    if (!fac) {
        QList<IProjectPanelFactory *> factories = ExtensionSystem::PluginManager::instance()->getObjects<IProjectPanelFactory>();
        qSort(factories.begin(), factories.end(), &IPanelFactory::prioritySort);
        foreach (IProjectPanelFactory *panelFactory, factories) {
            if (panelFactory->supports(project)) {
                if (subIndex == pos) {
                    fac = panelFactory;
                    break;
                }
                ++pos;
            }
        }
    }

    if (fac) {
        removeCurrentWidget();

        PropertiesPanel *panel = 0;
        if (ITargetPanelFactory *ipf = qobject_cast<ITargetPanelFactory *>(fac))
            panel = ipf->createPanel(project->activeTarget());
        else if (IProjectPanelFactory *ipf = qobject_cast<IProjectPanelFactory *>(fac))
            panel = ipf->createPanel(project);
        Q_ASSERT(panel);

        PanelsWidget *panelsWidget = new PanelsWidget(m_centralWidget);
        panelsWidget->addPropertiesPanel(panel);
        m_currentWidget = panelsWidget;
        m_centralWidget->addWidget(m_currentWidget);
        m_centralWidget->setCurrentWidget(m_currentWidget);

    }

    ProjectExplorerPlugin::instance()->session()->setStartupProject(project);
}

void ProjectWindow::removeCurrentWidget()
{
    if (m_currentWidget) {
        m_centralWidget->removeWidget(m_currentWidget);
        if (m_currentWidget) {
            delete m_currentWidget;
            m_currentWidget = 0;
        }
    }
}
<|endoftext|>


<commit_before>#include "AbstractCameraQueue.hpp"

#include <ros/console.h>

void AbstractCameraQueue::enqueue(std::vector<CameraData> data)
{
	for (std::vector<CameraData>::iterator it = data.begin(); it != data.end(); it++) {
		enqueue(*it);
	}
}

void AbstractCameraQueue::enqueue(CameraData data)
{
	enqueueInternal(data);

	if (getSize() > 15) {
		ROS_WARN("Camera queue running full. Quadcopter id: %d", data.quadcopterId);
	}
}

std::vector<CameraData> AbstractCameraQueue::toVector(CameraData data)
{
	std::vector<CameraData> result;
	result.push_back(data);
	return result;
}<commit_msg>More info of camera queue is running full.<commit_after>#include "AbstractCameraQueue.hpp"

#include <ros/console.h>

void AbstractCameraQueue::enqueue(std::vector<CameraData> data)
{
	for (std::vector<CameraData>::iterator it = data.begin(); it != data.end(); it++) {
		enqueue(*it);
	}
}

void AbstractCameraQueue::enqueue(CameraData data)
{
	enqueueInternal(data);

	if (getSize() > 25) {
		ROS_WARN("Camera queue running full. Quadcopter id: %d. Entries: %ld", data.quadcopterId, getSize());
	}
}

std::vector<CameraData> AbstractCameraQueue::toVector(CameraData data)
{
	std::vector<CameraData> result;
	result.push_back(data);
	return result;
}<|endoftext|>


<commit_before>#include <gtest/gtest.h>

#include "Addition.h"

class AdditionTest : public ::testing::Test
{
    virtual void SetUp() {}
    virtual void TearDown() {}

};

TEST_F(AdditionTest, twoValues)
{
    const int x = 2;
    const int y = 3;
    Addition addition;
    EXPECT_EQ(5, addition.twoValues(x, y));
    EXPECT_EQ(10, addition.twoValues(5, 6));
}

<commit_msg>Fixed failing test.<commit_after>#include <gtest/gtest.h>

#include "Addition.h"

class AdditionTest : public ::testing::Test
{
    virtual void SetUp() {}
    virtual void TearDown() {}

};

TEST_F(AdditionTest, twoValues)
{
    const int x = 2;
    const int y = 3;
    Addition addition;
    EXPECT_EQ(5, addition.twoValues(x, y));
    EXPECT_EQ(10, addition.twoValues(5, 5));
}

<|endoftext|>


<commit_before>#include "code_generator.h"

#include <unordered_map>
using namespace std;

struct code_generation_context
{
    code_generation_context();
    ~code_generation_context();
    unordered_map<string, instruction_sequence> functions;
    unordered_map<string, label_instruction*> function_labels;
    unordered_map<string, int> variables;
    label_instruction* epilog_label;
    int tempUsed;
    int expressionTarget;
};

class code_generator_impl
{
public:
    code_generator_impl();
    ~code_generator_impl();
    instruction_sequence generate_code(program_node* program);
private:
    instruction_sequence generate_code(program_node* program, code_generation_context* context);
    instruction_sequence generate_code(function_node* function, code_generation_context* context);
    instruction_sequence generate_code(statement_node* statement, code_generation_context* context);
    instruction_sequence generate_code(if_statement_node* if_statement, code_generation_context* context);
    instruction_sequence generate_code(return_statement_node* return_statement, code_generation_context* context);
    instruction_sequence generate_code(call_statement_node* call_statement, code_generation_context* context);
    instruction_sequence generate_code(expression_node* expression_statement, code_generation_context* context);
    instruction_sequence generate_code(literal_node* literal, code_generation_context* context);
    instruction_sequence generate_code(identifier_node* variable, code_generation_context* context);
    instruction_sequence generate_code(call_node* call, code_generation_context* context);
    instruction_sequence generate_code(plus_node* plus, code_generation_context* context);
    instruction_sequence generate_code(minus_node* minus, code_generation_context* context);
    instruction_sequence generate_code(condition_node* condition, code_generation_context* context);
};

void concatenate(instruction* prev, instruction* next)
{
    prev->next = next;
    next->prev = prev;
}

void concatenate(instruction_sequence prev, instruction* next)
{
    prev.tail->next = next;
    next->prev = prev.tail;
}

void concatenate(instruction* prev, instruction_sequence next)
{
    prev->next = next.head;
    next.head->prev = prev;
}

void concatenate(instruction_sequence prev, instruction_sequence next)
{
    prev.tail->next = next.head;
    next.head->prev = prev.tail;
}

code_generator::code_generator()
{
    this->impl = new code_generator_impl();
}

code_generator::~code_generator()
{
    delete this->impl;
}

instruction_sequence code_generator::generate_code(program_node* program)
{
    return this->impl->generate_code(program);
}

code_generator_impl::code_generator_impl()
{
}

code_generator_impl::~code_generator_impl()
{
}

instruction_sequence code_generator_impl::generate_code(program_node* program)
{
    code_generation_context context;
    return this->generate_code(program, &context);
}

instruction_sequence code_generator_impl::generate_code(program_node* program, code_generation_context* context)
{
    instruction_sequence result;
    function_node* function = program->function;
    while (function != nullptr)
    {
        label_instruction* label = new label_instruction();
        context->function_labels.insert(make_pair(function->function_name, label));
    }
    function = program->function;
    while (function != nullptr)
    {
        instruction_sequence function_body = this->generate_code(function, context);
        context->functions.insert(make_pair(function->function_name, function_body));
        function = function->next_function;
    }

    // TODO: Layout and linking
    return result;
}

instruction_sequence code_generator_impl::generate_code(function_node* function, code_generation_context* context)
{
    instruction_sequence result;
    label_instruction* epilog_label = new label_instruction();
    context->epilog_label = epilog_label;
    context->tempUsed = 0;
    if (function->argument_name != nullptr)
    {
        /* The stack pointer is pointing at empty, before it is the return address, before it is the argument! */
        context->variables.insert(make_pair(function->argument_name, -2));
    }
    instruction_sequence statement_body = generate_code(function->statement, context);

    // TODO: Generate prolog and epilog
    return result;
}

instruction_sequence code_generator_impl::generate_code(statement_node* statement, code_generation_context* context)
{
    switch (statement->get_statement_node_type())
    {
    case if_statement:
        return this->generate_code((if_statement_node*)statement, context);
    case return_statement:
        return this->generate_code((return_statement_node*)statement, context);
    case call_statement:
        return this->generate_code((call_statement_node*)statement, context);
    default:
        instruction_sequence result;
        return result;
    }
}

instruction_sequence code_generator_impl::generate_code(if_statement_node* if_statement, code_generation_context* context)
{
    instruction_sequence result;
    int condition_target = ++context->tempUsed;
    instruction_sequence condition_code = this->generate_code(if_statement->condition, context);

    label_instruction* false_label = new label_instruction();
    label_instruction* complete_label = new label_instruction();

    // condition code
    // load r3, condition_target
    // beqz r3, false_label
    // true code
    // b complete
    // false_label
    // false code
    // complete_label
    load_instruction* load_condition = new load_instruction();
    load_condition->destination_register = 3;
    load_condition->location = condition_target;

    branch_on_zero_instruction* branch_to_false = new branch_on_zero_instruction();
    branch_to_false->operand = 3;
    branch_to_false->branchTo = false_label;

    instruction_sequence true_code = this->generate_code(if_statement->true_statement, context);

    branch_instruction* branch_to_complete = new branch_instruction();
    branch_to_complete->branchTo = complete_label;

    instruction_sequence false_code = this->generate_code(if_statement->false_statement, context);

    result.head = condition_code.head;
    concatenate(condition_code, load_condition);
    concatenate(load_condition, branch_to_false);
    concatenate(branch_to_false, true_code);
    concatenate(true_code, branch_to_complete);
    concatenate(branch_to_complete, false_label);
    concatenate(false_label, false_code);
    concatenate(false_code, complete_label);
    result.tail = complete_label;

    return result;
}

instruction_sequence code_generator_impl::generate_code(return_statement_node* return_statement, code_generation_context* context)
{
    instruction_sequence result;
    int value_target = ++context->tempUsed;
    context->expressionTarget = value_target;
    instruction_sequence value_code = this->generate_code(return_statement->value, context);

    // load r2, expression_target
    load_instruction* load_value = new load_instruction();
    load_value->destination_register = 2;
    load_value->location = value_target;

    // jump epilog
    branch_instruction* branch_to_epilog = new branch_instruction();
    branch_to_epilog->branchTo = context->epilog_label;

    result.head = value_code.head;
    concatenate(value_code, load_value);
    concatenate(load_value, branch_to_epilog);
    result.tail = branch_to_epilog;

    return result;
}

instruction_sequence code_generator_impl::generate_code(call_statement_node* call_statement, code_generation_context* context)
{
    instruction_sequence result;
    return result;
}

instruction_sequence code_generator_impl::generate_code(expression_node* expression, code_generation_context* context)
{
    switch (expression->get_expression_node_type())
    {
    case literal:
        return this->generate_code((literal_node*)expression, context);
    case variable:
        return this->generate_code((identifier_node*)expression, context);
    case call:
        return this->generate_code((call_node*)expression, context);
    case plus_node_type:
        return this->generate_code((plus_node*)expression, context);
    case minus_node_type:
        return this->generate_code((minus_node*)expression, context);
    default:
        instruction_sequence result;
        return result;
    }
}

instruction_sequence code_generator_impl::generate_code(literal_node* literal, code_generation_context* context)
{
    instruction_sequence result;

    load_immediate_instruction* load_literal = new load_immediate_instruction();
    load_literal->destination_register = 4;
    load_literal->value = literal->value;

    store_instruction* store = new store_instruction();
    store->location = context->expressionTarget;
    store->source_register = 4;

    result.head = load_literal;
    concatenate(load_literal, store);
    result.tail = store;

    return result;
}

instruction_sequence code_generator_impl::generate_code(identifier_node* variable, code_generation_context* context)
{
    instruction_sequence result;
    return result;
}

instruction_sequence code_generator_impl::generate_code(call_node* call, code_generation_context* context)
{
    instruction_sequence result;
    int expressionTarget = context->expressionTarget;
    int argumentTarget = ++context->tempUsed;
    context->expressionTarget = argumentTarget;
    instruction_sequence argument_code = this->generate_code(call->argument, context);
    load_instruction* load_argument = new load_instruction();
    load_argument->location = argumentTarget;
    load_argument->destination_register = 1;
    call_instruction* call_op = new call_instruction();
    call_op->target = context->function_labels[call->function_name];
    store_instruction* store = new store_instruction();
    store->source_register = 2;
    store->location = expressionTarget;

    result.head = argument_code.head;
    concatenate(argument_code, load_argument);
    concatenate(load_argument, call_op);
    concatenate(call_op, store);
    result.tail = store;

    return result;
}

instruction_sequence code_generator_impl::generate_code(plus_node* plus, code_generation_context* context)
{
    instruction_sequence result;
    int expressionTarget = context->expressionTarget;
    int left_target = ++context->tempUsed;
    int right_target = ++context->tempUsed;
    context->expressionTarget = left_target;
    instruction_sequence left_code = this->generate_code(plus->left, context);
    context->expressionTarget = right_target;
    instruction_sequence right_code = this->generate_code(plus->left, context);
    load_instruction* load_left = new load_instruction();
    load_left->destination_register = 3;
    load_left->location = left_target;
    load_instruction* load_right = new load_instruction();
    load_right->destination_register = 4;
    load_right->location = right_target;
    plus_instruction* plus_op = new plus_instruction();
    plus_op->destination_register = 2;
    plus_op->operand1 = 3;
    plus_op->operand2 = 4;
    store_instruction* store = new store_instruction();
    store->source_register = 2;
    store->location = expressionTarget;
    result.head = left_code.head;
    concatenate(left_code, right_code);
    concatenate(right_code, load_left);
    concatenate(load_left, load_right);
    concatenate(load_right, plus_op);
    concatenate(plus_op, store);
    result.tail = store;
    return result;
}

instruction_sequence code_generator_impl::generate_code(minus_node* minus, code_generation_context* context)
{
    instruction_sequence result;
    int expressionTarget = context->expressionTarget;
    int left_target = ++context->tempUsed;
    int right_target = ++context->tempUsed;
    context->expressionTarget = left_target;
    instruction_sequence left_code = this->generate_code(minus->left, context);
    context->expressionTarget = right_target;
    instruction_sequence right_code = this->generate_code(minus->left, context);
    load_instruction* load_left = new load_instruction();
    load_left->destination_register = 3;
    load_left->location = left_target;
    load_instruction* load_right = new load_instruction();
    load_right->destination_register = 4;
    load_right->location = right_target;
    minus_instruction* minus_op = new minus_instruction();
    minus_op->destination_register = 2;
    minus_op->operand1 = 3;
    minus_op->operand2 = 4;
    store_instruction* store = new store_instruction();
    store->source_register = 2;
    store->location = expressionTarget;
    result.head = left_code.head;
    concatenate(left_code, right_code);
    concatenate(right_code, load_left);
    concatenate(load_left, load_right);
    concatenate(load_right, minus_op);
    concatenate(minus_op, store);
    result.tail = store;
    return result;
}

instruction_sequence code_generator_impl::generate_code(condition_node* condition, code_generation_context* context)
{
    instruction_sequence result;
    int variable_location = context->variables[condition->variable_name];
    int literal = condition->value;
    // load r3, variable_location
    load_instruction* load_variable = new load_instruction();
    load_variable->destination_register = 3;
    load_variable->location = variable_location;

    // loadimm r4, literal
    load_immediate_instruction* load_literal = new load_immediate_instruction();
    load_literal->destination_register = 4;
    load_literal->value = literal;

    // cmp r2, r3, r4
    compare_instruction* compare = new compare_instruction();
    compare->destination_register = 2;
    compare->operand1 = 3;
    compare->operand2 = 4;

    // store target, r2
    store_instruction* store = new store_instruction();
    store->location = context->expressionTarget;
    store->source_register = 2;

    result.head = load_variable;
    concatenate(load_variable, load_literal);
    concatenate(load_literal, compare);
    concatenate(compare, store);
    result.tail = store;

    return result;
}

code_generation_context::code_generation_context()
{
    this->epilog_label = nullptr;
    this->tempUsed = 0;
}

code_generation_context::~code_generation_context()
{
    if (this->epilog_label != nullptr)
    {
        delete this->epilog_label;
    }
}
<commit_msg>Fix a simple bug in CodeGenerator<commit_after>#include "code_generator.h"

#include <unordered_map>
using namespace std;

struct code_generation_context
{
    code_generation_context();
    ~code_generation_context();
    unordered_map<string, instruction_sequence> functions;
    unordered_map<string, label_instruction*> function_labels;
    unordered_map<string, int> variables;
    label_instruction* epilog_label;
    int tempUsed;
    int expressionTarget;
};

class code_generator_impl
{
public:
    code_generator_impl();
    ~code_generator_impl();
    instruction_sequence generate_code(program_node* program);
private:
    instruction_sequence generate_code(program_node* program, code_generation_context* context);
    instruction_sequence generate_code(function_node* function, code_generation_context* context);
    instruction_sequence generate_code(statement_node* statement, code_generation_context* context);
    instruction_sequence generate_code(if_statement_node* if_statement, code_generation_context* context);
    instruction_sequence generate_code(return_statement_node* return_statement, code_generation_context* context);
    instruction_sequence generate_code(call_statement_node* call_statement, code_generation_context* context);
    instruction_sequence generate_code(expression_node* expression_statement, code_generation_context* context);
    instruction_sequence generate_code(literal_node* literal, code_generation_context* context);
    instruction_sequence generate_code(identifier_node* variable, code_generation_context* context);
    instruction_sequence generate_code(call_node* call, code_generation_context* context);
    instruction_sequence generate_code(plus_node* plus, code_generation_context* context);
    instruction_sequence generate_code(minus_node* minus, code_generation_context* context);
    instruction_sequence generate_code(condition_node* condition, code_generation_context* context);
};

void concatenate(instruction* prev, instruction* next)
{
    prev->next = next;
    next->prev = prev;
}

void concatenate(instruction_sequence prev, instruction* next)
{
    prev.tail->next = next;
    next->prev = prev.tail;
}

void concatenate(instruction* prev, instruction_sequence next)
{
    prev->next = next.head;
    next.head->prev = prev;
}

void concatenate(instruction_sequence prev, instruction_sequence next)
{
    prev.tail->next = next.head;
    next.head->prev = prev.tail;
}

code_generator::code_generator()
{
    this->impl = new code_generator_impl();
}

code_generator::~code_generator()
{
    delete this->impl;
}

instruction_sequence code_generator::generate_code(program_node* program)
{
    return this->impl->generate_code(program);
}

code_generator_impl::code_generator_impl()
{
}

code_generator_impl::~code_generator_impl()
{
}

instruction_sequence code_generator_impl::generate_code(program_node* program)
{
    code_generation_context context;
    return this->generate_code(program, &context);
}

instruction_sequence code_generator_impl::generate_code(program_node* program, code_generation_context* context)
{
    instruction_sequence result;
    function_node* function = program->function;
    while (function != nullptr)
    {
        label_instruction* label = new label_instruction();
        context->function_labels.insert(make_pair(function->function_name, label));
        function = function->next_function;
    }
    function = program->function;
    while (function != nullptr)
    {
        instruction_sequence function_body = this->generate_code(function, context);
        context->functions.insert(make_pair(function->function_name, function_body));
        function = function->next_function;
    }

    // TODO: Layout and linking
    return result;
}

instruction_sequence code_generator_impl::generate_code(function_node* function, code_generation_context* context)
{
    instruction_sequence result;
    label_instruction* epilog_label = new label_instruction();
    context->epilog_label = epilog_label;
    context->tempUsed = 0;
    if (function->argument_name != nullptr)
    {
        /* The stack pointer is pointing at empty, before it is the return address, before it is the argument! */
        context->variables.insert(make_pair(function->argument_name, -2));
    }
    instruction_sequence statement_body = generate_code(function->statement, context);

    // TODO: Generate prolog and epilog
    return result;
}

instruction_sequence code_generator_impl::generate_code(statement_node* statement, code_generation_context* context)
{
    switch (statement->get_statement_node_type())
    {
    case if_statement:
        return this->generate_code((if_statement_node*)statement, context);
    case return_statement:
        return this->generate_code((return_statement_node*)statement, context);
    case call_statement:
        return this->generate_code((call_statement_node*)statement, context);
    default:
        instruction_sequence result;
        return result;
    }
}

instruction_sequence code_generator_impl::generate_code(if_statement_node* if_statement, code_generation_context* context)
{
    instruction_sequence result;
    int condition_target = ++context->tempUsed;
    instruction_sequence condition_code = this->generate_code(if_statement->condition, context);

    label_instruction* false_label = new label_instruction();
    label_instruction* complete_label = new label_instruction();

    // condition code
    // load r3, condition_target
    // beqz r3, false_label
    // true code
    // b complete
    // false_label
    // false code
    // complete_label
    load_instruction* load_condition = new load_instruction();
    load_condition->destination_register = 3;
    load_condition->location = condition_target;

    branch_on_zero_instruction* branch_to_false = new branch_on_zero_instruction();
    branch_to_false->operand = 3;
    branch_to_false->branchTo = false_label;

    instruction_sequence true_code = this->generate_code(if_statement->true_statement, context);

    branch_instruction* branch_to_complete = new branch_instruction();
    branch_to_complete->branchTo = complete_label;

    instruction_sequence false_code = this->generate_code(if_statement->false_statement, context);

    result.head = condition_code.head;
    concatenate(condition_code, load_condition);
    concatenate(load_condition, branch_to_false);
    concatenate(branch_to_false, true_code);
    concatenate(true_code, branch_to_complete);
    concatenate(branch_to_complete, false_label);
    concatenate(false_label, false_code);
    concatenate(false_code, complete_label);
    result.tail = complete_label;

    return result;
}

instruction_sequence code_generator_impl::generate_code(return_statement_node* return_statement, code_generation_context* context)
{
    instruction_sequence result;
    int value_target = ++context->tempUsed;
    context->expressionTarget = value_target;
    instruction_sequence value_code = this->generate_code(return_statement->value, context);

    // load r2, expression_target
    load_instruction* load_value = new load_instruction();
    load_value->destination_register = 2;
    load_value->location = value_target;

    // jump epilog
    branch_instruction* branch_to_epilog = new branch_instruction();
    branch_to_epilog->branchTo = context->epilog_label;

    result.head = value_code.head;
    concatenate(value_code, load_value);
    concatenate(load_value, branch_to_epilog);
    result.tail = branch_to_epilog;

    return result;
}

instruction_sequence code_generator_impl::generate_code(call_statement_node* call_statement, code_generation_context* context)
{
    instruction_sequence result;
    return result;
}

instruction_sequence code_generator_impl::generate_code(expression_node* expression, code_generation_context* context)
{
    switch (expression->get_expression_node_type())
    {
    case literal:
        return this->generate_code((literal_node*)expression, context);
    case variable:
        return this->generate_code((identifier_node*)expression, context);
    case call:
        return this->generate_code((call_node*)expression, context);
    case plus_node_type:
        return this->generate_code((plus_node*)expression, context);
    case minus_node_type:
        return this->generate_code((minus_node*)expression, context);
    default:
        instruction_sequence result;
        return result;
    }
}

instruction_sequence code_generator_impl::generate_code(literal_node* literal, code_generation_context* context)
{
    instruction_sequence result;

    load_immediate_instruction* load_literal = new load_immediate_instruction();
    load_literal->destination_register = 4;
    load_literal->value = literal->value;

    store_instruction* store = new store_instruction();
    store->location = context->expressionTarget;
    store->source_register = 4;

    result.head = load_literal;
    concatenate(load_literal, store);
    result.tail = store;

    return result;
}

instruction_sequence code_generator_impl::generate_code(identifier_node* variable, code_generation_context* context)
{
    instruction_sequence result;
    return result;
}

instruction_sequence code_generator_impl::generate_code(call_node* call, code_generation_context* context)
{
    instruction_sequence result;
    int expressionTarget = context->expressionTarget;
    int argumentTarget = ++context->tempUsed;
    context->expressionTarget = argumentTarget;
    instruction_sequence argument_code = this->generate_code(call->argument, context);
    load_instruction* load_argument = new load_instruction();
    load_argument->location = argumentTarget;
    load_argument->destination_register = 1;
    call_instruction* call_op = new call_instruction();
    call_op->target = context->function_labels[call->function_name];
    store_instruction* store = new store_instruction();
    store->source_register = 2;
    store->location = expressionTarget;

    result.head = argument_code.head;
    concatenate(argument_code, load_argument);
    concatenate(load_argument, call_op);
    concatenate(call_op, store);
    result.tail = store;

    return result;
}

instruction_sequence code_generator_impl::generate_code(plus_node* plus, code_generation_context* context)
{
    instruction_sequence result;
    int expressionTarget = context->expressionTarget;
    int left_target = ++context->tempUsed;
    int right_target = ++context->tempUsed;
    context->expressionTarget = left_target;
    instruction_sequence left_code = this->generate_code(plus->left, context);
    context->expressionTarget = right_target;
    instruction_sequence right_code = this->generate_code(plus->left, context);
    load_instruction* load_left = new load_instruction();
    load_left->destination_register = 3;
    load_left->location = left_target;
    load_instruction* load_right = new load_instruction();
    load_right->destination_register = 4;
    load_right->location = right_target;
    plus_instruction* plus_op = new plus_instruction();
    plus_op->destination_register = 2;
    plus_op->operand1 = 3;
    plus_op->operand2 = 4;
    store_instruction* store = new store_instruction();
    store->source_register = 2;
    store->location = expressionTarget;
    result.head = left_code.head;
    concatenate(left_code, right_code);
    concatenate(right_code, load_left);
    concatenate(load_left, load_right);
    concatenate(load_right, plus_op);
    concatenate(plus_op, store);
    result.tail = store;
    return result;
}

instruction_sequence code_generator_impl::generate_code(minus_node* minus, code_generation_context* context)
{
    instruction_sequence result;
    int expressionTarget = context->expressionTarget;
    int left_target = ++context->tempUsed;
    int right_target = ++context->tempUsed;
    context->expressionTarget = left_target;
    instruction_sequence left_code = this->generate_code(minus->left, context);
    context->expressionTarget = right_target;
    instruction_sequence right_code = this->generate_code(minus->left, context);
    load_instruction* load_left = new load_instruction();
    load_left->destination_register = 3;
    load_left->location = left_target;
    load_instruction* load_right = new load_instruction();
    load_right->destination_register = 4;
    load_right->location = right_target;
    minus_instruction* minus_op = new minus_instruction();
    minus_op->destination_register = 2;
    minus_op->operand1 = 3;
    minus_op->operand2 = 4;
    store_instruction* store = new store_instruction();
    store->source_register = 2;
    store->location = expressionTarget;
    result.head = left_code.head;
    concatenate(left_code, right_code);
    concatenate(right_code, load_left);
    concatenate(load_left, load_right);
    concatenate(load_right, minus_op);
    concatenate(minus_op, store);
    result.tail = store;
    return result;
}

instruction_sequence code_generator_impl::generate_code(condition_node* condition, code_generation_context* context)
{
    instruction_sequence result;
    int variable_location = context->variables[condition->variable_name];
    int literal = condition->value;
    // load r3, variable_location
    load_instruction* load_variable = new load_instruction();
    load_variable->destination_register = 3;
    load_variable->location = variable_location;

    // loadimm r4, literal
    load_immediate_instruction* load_literal = new load_immediate_instruction();
    load_literal->destination_register = 4;
    load_literal->value = literal;

    // cmp r2, r3, r4
    compare_instruction* compare = new compare_instruction();
    compare->destination_register = 2;
    compare->operand1 = 3;
    compare->operand2 = 4;

    // store target, r2
    store_instruction* store = new store_instruction();
    store->location = context->expressionTarget;
    store->source_register = 2;

    result.head = load_variable;
    concatenate(load_variable, load_literal);
    concatenate(load_literal, compare);
    concatenate(compare, store);
    result.tail = store;

    return result;
}

code_generation_context::code_generation_context()
{
    this->epilog_label = nullptr;
    this->tempUsed = 0;
}

code_generation_context::~code_generation_context()
{
    if (this->epilog_label != nullptr)
    {
        delete this->epilog_label;
    }
}
<|endoftext|>


<commit_before>// Screen.hh for fluxbox
// Copyright (c) 2001 Henrik Kinnunen (fluxgen@linuxmail.org)
//
// Screen.hh for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.	IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

#ifndef	 _SCREEN_HH_
#define	 _SCREEN_HH_

#include <X11/Xlib.h>
#include <X11/Xresource.h>

#ifdef		TIME_WITH_SYS_TIME
#	include <sys/time.h>
#	include <time.h>
#else // !TIME_WITH_SYS_TIME
#	ifdef		HAVE_SYS_TIME_H
#		include <sys/time.h>
#	else // !HAVE_SYS_TIME_H
#		include <time.h>
#	endif // HAVE_SYS_TIME_H
#endif // TIME_WITH_SYS_TIME

#include <stdio.h>

#include "Theme.hh"

// forward declaration
class BScreen;
#ifndef _BASEDISPLAY_HH_
#include "BaseDisplay.hh"
#endif
#ifndef _CONFIGMENU_HH_
#include "Configmenu.hh"
#endif
#ifndef _ICON_HH_
#include "Icon.hh"
#endif
#ifndef _LINKEDLIST_HH_
#include "LinkedList.hh"
#endif
#ifndef _NETIZEN_HH_
#include "Netizen.hh"
#endif
#ifndef _ROOTMENU_HH_
#include "Rootmenu.hh"
#endif
#ifndef _TIMER_HH_
#include "Timer.hh"
#endif
#ifndef _WORKSPACE_HH_
#include "Workspace.hh"
#endif
#ifndef _WORKSPACEMENU_HH_
#include "Workspacemenu.hh"
#endif
#ifndef _FLUXBOX_HH_
#include "fluxbox.hh"
#endif

#ifdef		SLIT
#	include "Slit.hh"
#endif // SLIT

class BScreen : public ScreenInfo {
public:
	BScreen(Fluxbox *, int);
	~BScreen(void);

	inline const Bool &isToolbarOnTop(void) const
	{ return resource.toolbar_on_top; }
	inline const Bool &doToolbarAutoHide(void) const
	{ return resource.toolbar_auto_hide; }
	inline const Bool &isSloppyFocus(void) const
	{ return resource.sloppy_focus; }
	inline const Bool &isSemiSloppyFocus(void) const
	{ return resource.semi_sloppy_focus; }
	inline const Bool &isRootColormapInstalled(void) const
	{ return root_colormap_installed; }
	inline const Bool &isScreenManaged(void) const { return managed; }
	inline const Bool &isTabRotateVertical(void) const
	{ return resource.tab_rotate_vertical; }
	inline const Bool &isSloppyWindowGrouping(void) const
	{ return resource.sloppy_window_grouping; }
	inline const Bool &doAutoRaise(void) const { return resource.auto_raise; }
	inline const Bool &doImageDither(void) const
	{ return resource.image_dither; }
	inline const Bool &doOrderedDither(void) const
	{ return resource.ordered_dither; }
	inline const Bool &doOpaqueMove(void) const { return resource.opaque_move; }
	inline const Bool &doFullMax(void) const { return resource.full_max; }
	inline const Bool &doFocusNew(void) const { return resource.focus_new; }
	inline const Bool &doFocusLast(void) const { return resource.focus_last; }

	inline const GC &getOpGC() const { return theme->getOpGC(); }

	inline const BColor *getBorderColor(void) { return &theme->getBorderColor(); }
	inline BImageControl *getImageControl(void) { return image_control; }
	inline Rootmenu *getRootmenu(void) { return rootmenu; }

#ifdef	 SLIT
	inline const Bool &isSlitOnTop(void) const { return resource.slit_on_top; }
	inline const Bool &doSlitAutoHide(void) const
	{ return resource.slit_auto_hide; }
	inline Slit *getSlit(void) { return slit; }
	inline const int &getSlitPlacement(void) const
	{ return resource.slit_placement; }
	inline const int &getSlitDirection(void) const
	{ return resource.slit_direction; }
	inline void saveSlitPlacement(int p) { resource.slit_placement = p; }
	inline void saveSlitDirection(int d) { resource.slit_direction = d; }
	inline void saveSlitOnTop(Bool t)		{ resource.slit_on_top = t; }
	inline void saveSlitAutoHide(Bool t) { resource.slit_auto_hide = t; }
#endif // SLIT

	inline Toolbar *getToolbar(void) { return toolbar; }

	inline Workspace *getWorkspace(int w) { return workspacesList->find(w); }
	inline Workspace *getCurrentWorkspace(void) { return current_workspace; }

	inline Workspacemenu *getWorkspacemenu(void) { return workspacemenu; }

	inline const unsigned int getHandleWidth(void) const
	{ return theme->getHandleWidth(); }
	inline const unsigned int getBevelWidth(void) const
	{ return theme->getBevelWidth(); }
	inline const unsigned int getFrameWidth(void) const
	{ return theme->getFrameWidth(); }
	inline const unsigned int getBorderWidth(void) const
	{ return theme->getBorderWidth(); }
	inline const unsigned int getBorderWidth2x(void) const
	{ return theme->getBorderWidth()*2; }

	inline const int getCurrentWorkspaceID()
	{ return current_workspace->getWorkspaceID(); }
	inline const int getCount(void) { return workspacesList->count(); }
	inline const int getIconCount(void) { return iconList->count(); }
	inline LinkedList<FluxboxWindow> *getIconList(void) { return iconList; }
	inline const int &getNumberOfWorkspaces(void) const
	{ return resource.workspaces; }
	inline const int &getToolbarPlacement(void) const
	{ return resource.toolbar_placement; }
	inline const int &getToolbarWidthPercent(void) const
	{ return resource.toolbar_width_percent; }
	inline const int &getPlacementPolicy(void) const
	{ return resource.placement_policy; }
	inline const int &getEdgeSnapThreshold(void) const
	{ return resource.edge_snap_threshold; }
	inline const int &getRowPlacementDirection(void) const
	{ return resource.row_direction; }
	inline const int &getColPlacementDirection(void) const
	{ return resource.col_direction; }
	inline const unsigned int &getTabWidth(void) const
	{ return resource.tab_width; }
	inline const unsigned int &getTabHeight(void) const
	{ return resource.tab_height; }
	inline const int getTabPlacement(void)
	{ return resource.tab_placement; }
	inline const int getTabAlignment(void)
	{ return resource.tab_alignment; }

	inline void setRootColormapInstalled(Bool r) { root_colormap_installed = r; }
	inline void saveSloppyFocus(Bool s) { resource.sloppy_focus = s; }
	inline void saveSemiSloppyFocus(Bool s) { resource.semi_sloppy_focus = s; }
	inline void saveAutoRaise(Bool a) { resource.auto_raise = a; }
	inline void saveWorkspaces(int w) { resource.workspaces = w; }
	inline void saveToolbarOnTop(Bool r) { resource.toolbar_on_top = r; }
	inline void saveToolbarAutoHide(Bool r) { resource.toolbar_auto_hide = r; }
	inline void saveToolbarWidthPercent(int w)
	{ resource.toolbar_width_percent = w; }
	inline void saveToolbarPlacement(int p) { resource.toolbar_placement = p; }
	inline void savePlacementPolicy(int p) { resource.placement_policy = p; }
	inline void saveRowPlacementDirection(int d) { resource.row_direction = d; }
	inline void saveColPlacementDirection(int d) { resource.col_direction = d; }
	inline void saveEdgeSnapThreshold(int t)
	{ resource.edge_snap_threshold = t; }
	inline void saveImageDither(Bool d) { resource.image_dither = d; }
	inline void saveOpaqueMove(Bool o) { resource.opaque_move = o; }
	inline void saveFullMax(Bool f) { resource.full_max = f; }
	inline void saveFocusNew(Bool f) { resource.focus_new = f; }
	inline void saveFocusLast(Bool f) { resource.focus_last = f; }
	inline void saveTabWidth(unsigned int w) { resource.tab_width = w; }
	inline void saveTabHeight(unsigned int h) { resource.tab_height = h; }
	inline void saveTabPlacement(unsigned int p) { resource.tab_placement = p; }
	inline void saveTabAlignment(unsigned int a) { resource.tab_alignment = a; }
	inline void saveTabRotateVertical(Bool r)
	{ resource.tab_rotate_vertical = r; }
	inline void saveSloppyWindowGrouping(Bool s)
	{ resource.sloppy_window_grouping = s; }
	inline void iconUpdate(void) { iconmenu->update(); }
	inline Iconmenu *getIconmenu(void) { return iconmenu; }

#ifdef		HAVE_STRFTIME
	inline char *getStrftimeFormat(void) { return resource.strftime_format; }
	void saveStrftimeFormat(char *);
#else // !HAVE_STRFTIME
	inline int getDateFormat(void) { return resource.date_format; }
	inline void saveDateFormat(int f) { resource.date_format = f; }
	inline Bool isClock24Hour(void) { return resource.clock24hour; }
	inline void saveClock24Hour(Bool c) { resource.clock24hour = c; }
#endif // HAVE_STRFTIME

	inline Theme::WindowStyle *getWindowStyle(void) { return &theme->getWindowStyle(); }
	inline Theme::MenuStyle *getMenuStyle(void) { return &theme->getMenuStyle(); }
	inline Theme::ToolbarStyle *getToolbarStyle(void) { return &theme->getToolbarStyle(); }

	FluxboxWindow *getIcon(int);

	int addWorkspace(void);
	int removeLastWorkspace(void);
	//scroll workspaces
	void nextWorkspace();
	void prevWorkspace();

	void removeWorkspaceNames(void);
	void updateWorkspaceNamesAtom(void);

	void addWorkspaceName(char *);
	void addNetizen(Netizen *);
	void removeNetizen(Window);
	void addIcon(FluxboxWindow *);
	void removeIcon(FluxboxWindow *);
	void getNameOfWorkspace(int, char **);
	void changeWorkspaceID(int);
	void raiseWindows(Window *, int);
	void reassociateWindow(FluxboxWindow *, int, Bool);
	void prevFocus(void);
	void nextFocus(void);
	void raiseFocus(void);
	void reconfigure(void);
	void rereadMenu(void);
	void shutdown(void);
	void showPosition(int, int);
	void showGeometry(unsigned int, unsigned int);
	void hideGeometry(void);

	void updateNetizenCurrentWorkspace(void);
	void updateNetizenWorkspaceCount(void);
	void updateNetizenWindowFocus(void);
	void updateNetizenWindowAdd(Window, unsigned long);
	void updateNetizenWindowDel(Window);
	void updateNetizenConfigNotify(XEvent *);
	void updateNetizenWindowRaise(Window);
	void updateNetizenWindowLower(Window);

	enum { RowSmartPlacement = 1, ColSmartPlacement, CascadePlacement, LeftRight,
				 RightLeft, TopBottom, BottomTop };
	enum { LeftJustify = 1, RightJustify, CenterJustify };
	enum { RoundBullet = 1, TriangleBullet, SquareBullet, NoBullet };
	enum { Restart = 1, RestartOther, Exit, Shutdown, Execute, Reconfigure,
				 WindowShade, WindowIconify, WindowMaximize, WindowClose, WindowRaise,
				 WindowLower, WindowStick, WindowKill, SetStyle, WindowTab};

private:
	Theme *theme;

	Bool root_colormap_installed, managed, geom_visible;
	GC opGC;
	Pixmap geom_pixmap;
	Window geom_window;

	Fluxbox *fluxbox;
	BImageControl *image_control;
	Configmenu *configmenu;
	Iconmenu *iconmenu;

	Rootmenu *rootmenu;

	LinkedList<Rootmenu> *rootmenuList;
	LinkedList<Netizen> *netizenList;
	LinkedList<FluxboxWindow> *iconList;

#ifdef		SLIT
	Slit *slit;
#endif // SLIT

	Toolbar *toolbar;
	Workspace *current_workspace;
	Workspacemenu *workspacemenu;

	unsigned int geom_w, geom_h;
	unsigned long event_mask;

	LinkedList<char> *workspaceNames;
	LinkedList<Workspace> *workspacesList;

	struct resource {

		Bool toolbar_on_top, toolbar_auto_hide, sloppy_focus, auto_raise,
			auto_edge_balance, image_dither, ordered_dither, opaque_move, full_max,
			focus_new, focus_last, tab_rotate_vertical, semi_sloppy_focus,
			sloppy_window_grouping;

		int workspaces, toolbar_placement, toolbar_width_percent, placement_policy,
			edge_snap_threshold, row_direction, col_direction;

		unsigned int tab_placement, tab_alignment, tab_width, tab_height;

#ifdef		SLIT
		Bool slit_on_top, slit_auto_hide;
		int slit_placement, slit_direction;
#endif // SLIT

#ifdef		HAVE_STRFTIME
		char *strftime_format;
#else // !HAVE_STRFTIME
		Bool clock24hour;
		int date_format;
#endif // HAVE_STRFTIME

	} resource;

protected:
	Bool parseMenuFile(FILE *, Rootmenu *);

	bool readDatabaseTexture(char *, char *, BTexture *, unsigned long);
	bool readDatabaseColor(char *, char *, BColor *, unsigned long);

	void readDatabaseFontSet(char *, char *, XFontSet *);
	XFontSet createFontSet(char *);
	void readDatabaseFont(char *, char *, XFontStruct **);

	void InitMenu(void);

};

#endif // _SCREEN_HH_
<commit_msg>Added maximize over slit resource<commit_after>// Screen.hh for fluxbox
// Copyright (c) 2001 Henrik Kinnunen (fluxgen@linuxmail.org)
//
// Screen.hh for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.	IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

#ifndef	 _SCREEN_HH_
#define	 _SCREEN_HH_

#include <X11/Xlib.h>
#include <X11/Xresource.h>

#ifdef		TIME_WITH_SYS_TIME
#	include <sys/time.h>
#	include <time.h>
#else // !TIME_WITH_SYS_TIME
#	ifdef		HAVE_SYS_TIME_H
#		include <sys/time.h>
#	else // !HAVE_SYS_TIME_H
#		include <time.h>
#	endif // HAVE_SYS_TIME_H
#endif // TIME_WITH_SYS_TIME

#include <stdio.h>

#include "Theme.hh"

// forward declaration
class BScreen;
#ifndef _BASEDISPLAY_HH_
#include "BaseDisplay.hh"
#endif
#ifndef _CONFIGMENU_HH_
#include "Configmenu.hh"
#endif
#ifndef _ICON_HH_
#include "Icon.hh"
#endif
#ifndef _LINKEDLIST_HH_
#include "LinkedList.hh"
#endif
#ifndef _NETIZEN_HH_
#include "Netizen.hh"
#endif
#ifndef _ROOTMENU_HH_
#include "Rootmenu.hh"
#endif
#ifndef _TIMER_HH_
#include "Timer.hh"
#endif
#ifndef _WORKSPACE_HH_
#include "Workspace.hh"
#endif
#ifndef _WORKSPACEMENU_HH_
#include "Workspacemenu.hh"
#endif
#ifndef _FLUXBOX_HH_
#include "fluxbox.hh"
#endif

#ifdef		SLIT
#	include "Slit.hh"
#endif // SLIT

class BScreen : public ScreenInfo {
public:
	BScreen(Fluxbox *, int);
	~BScreen(void);

	inline const Bool &isToolbarOnTop(void) const
	{ return resource.toolbar_on_top; }
	inline const Bool &doToolbarAutoHide(void) const
	{ return resource.toolbar_auto_hide; }
	inline const Bool &isSloppyFocus(void) const
	{ return resource.sloppy_focus; }
	inline const Bool &isSemiSloppyFocus(void) const
	{ return resource.semi_sloppy_focus; }
	inline const Bool &isRootColormapInstalled(void) const
	{ return root_colormap_installed; }
	inline const Bool &isScreenManaged(void) const { return managed; }
	inline const Bool &isTabRotateVertical(void) const
	{ return resource.tab_rotate_vertical; }
	inline const Bool &isSloppyWindowGrouping(void) const
	{ return resource.sloppy_window_grouping; }
	inline const Bool &doAutoRaise(void) const { return resource.auto_raise; }
	inline const Bool &doImageDither(void) const
	{ return resource.image_dither; }
	inline const Bool &doOrderedDither(void) const
	{ return resource.ordered_dither; }
	inline const Bool &doMaxOverSlit(void) const { return resource.max_over_slit; }
	inline const Bool &doOpaqueMove(void) const { return resource.opaque_move; }
	inline const Bool &doFullMax(void) const { return resource.full_max; }
	inline const Bool &doFocusNew(void) const { return resource.focus_new; }
	inline const Bool &doFocusLast(void) const { return resource.focus_last; }

	inline const GC &getOpGC() const { return theme->getOpGC(); }

	inline const BColor *getBorderColor(void) { return &theme->getBorderColor(); }
	inline BImageControl *getImageControl(void) { return image_control; }
	inline Rootmenu *getRootmenu(void) { return rootmenu; }

#ifdef	 SLIT
	inline const Bool &isSlitOnTop(void) const { return resource.slit_on_top; }
	inline const Bool &doSlitAutoHide(void) const
	{ return resource.slit_auto_hide; }
	inline Slit *getSlit(void) { return slit; }
	inline const int &getSlitPlacement(void) const
	{ return resource.slit_placement; }
	inline const int &getSlitDirection(void) const
	{ return resource.slit_direction; }
	inline void saveSlitPlacement(int p) { resource.slit_placement = p; }
	inline void saveSlitDirection(int d) { resource.slit_direction = d; }
	inline void saveSlitOnTop(Bool t)		{ resource.slit_on_top = t; }
	inline void saveSlitAutoHide(Bool t) { resource.slit_auto_hide = t; }
#endif // SLIT

	inline Toolbar *getToolbar(void) { return toolbar; }

	inline Workspace *getWorkspace(int w) { return workspacesList->find(w); }
	inline Workspace *getCurrentWorkspace(void) { return current_workspace; }

	inline Workspacemenu *getWorkspacemenu(void) { return workspacemenu; }

	inline const unsigned int getHandleWidth(void) const
	{ return theme->getHandleWidth(); }
	inline const unsigned int getBevelWidth(void) const
	{ return theme->getBevelWidth(); }
	inline const unsigned int getFrameWidth(void) const
	{ return theme->getFrameWidth(); }
	inline const unsigned int getBorderWidth(void) const
	{ return theme->getBorderWidth(); }
	inline const unsigned int getBorderWidth2x(void) const
	{ return theme->getBorderWidth()*2; }

	inline const int getCurrentWorkspaceID()
	{ return current_workspace->getWorkspaceID(); }
	inline const int getCount(void) { return workspacesList->count(); }
	inline const int getIconCount(void) { return iconList->count(); }
	inline LinkedList<FluxboxWindow> *getIconList(void) { return iconList; }
	inline const int &getNumberOfWorkspaces(void) const
	{ return resource.workspaces; }
	inline const int &getToolbarPlacement(void) const
	{ return resource.toolbar_placement; }
	inline const int &getToolbarWidthPercent(void) const
	{ return resource.toolbar_width_percent; }
	inline const int &getPlacementPolicy(void) const
	{ return resource.placement_policy; }
	inline const int &getEdgeSnapThreshold(void) const
	{ return resource.edge_snap_threshold; }
	inline const int &getRowPlacementDirection(void) const
	{ return resource.row_direction; }
	inline const int &getColPlacementDirection(void) const
	{ return resource.col_direction; }
	inline const unsigned int &getTabWidth(void) const
	{ return resource.tab_width; }
	inline const unsigned int &getTabHeight(void) const
	{ return resource.tab_height; }
	inline const int getTabPlacement(void)
	{ return resource.tab_placement; }
	inline const int getTabAlignment(void)
	{ return resource.tab_alignment; }

	inline void setRootColormapInstalled(Bool r) { root_colormap_installed = r; }
	inline void saveSloppyFocus(Bool s) { resource.sloppy_focus = s; }
	inline void saveSemiSloppyFocus(Bool s) { resource.semi_sloppy_focus = s; }
	inline void saveAutoRaise(Bool a) { resource.auto_raise = a; }
	inline void saveWorkspaces(int w) { resource.workspaces = w; }
	inline void saveToolbarOnTop(Bool r) { resource.toolbar_on_top = r; }
	inline void saveToolbarAutoHide(Bool r) { resource.toolbar_auto_hide = r; }
	inline void saveToolbarWidthPercent(int w)
	{ resource.toolbar_width_percent = w; }
	inline void saveToolbarPlacement(int p) { resource.toolbar_placement = p; }
	inline void savePlacementPolicy(int p) { resource.placement_policy = p; }
	inline void saveRowPlacementDirection(int d) { resource.row_direction = d; }
	inline void saveColPlacementDirection(int d) { resource.col_direction = d; }
	inline void saveEdgeSnapThreshold(int t)
	{ resource.edge_snap_threshold = t; }
	inline void saveImageDither(Bool d) { resource.image_dither = d; }
	inline void saveMaxOverSlit(Bool m) { resource.max_over_slit = m; }
	inline void saveOpaqueMove(Bool o) { resource.opaque_move = o; }
	inline void saveFullMax(Bool f) { resource.full_max = f; }
	inline void saveFocusNew(Bool f) { resource.focus_new = f; }
	inline void saveFocusLast(Bool f) { resource.focus_last = f; }
	inline void saveTabWidth(unsigned int w) { resource.tab_width = w; }
	inline void saveTabHeight(unsigned int h) { resource.tab_height = h; }
	inline void saveTabPlacement(unsigned int p) { resource.tab_placement = p; }
	inline void saveTabAlignment(unsigned int a) { resource.tab_alignment = a; }
	inline void saveTabRotateVertical(Bool r)
	{ resource.tab_rotate_vertical = r; }
	inline void saveSloppyWindowGrouping(Bool s)
	{ resource.sloppy_window_grouping = s; }
	inline void iconUpdate(void) { iconmenu->update(); }
	inline Iconmenu *getIconmenu(void) { return iconmenu; }

#ifdef		HAVE_STRFTIME
	inline char *getStrftimeFormat(void) { return resource.strftime_format; }
	void saveStrftimeFormat(char *);
#else // !HAVE_STRFTIME
	inline int getDateFormat(void) { return resource.date_format; }
	inline void saveDateFormat(int f) { resource.date_format = f; }
	inline Bool isClock24Hour(void) { return resource.clock24hour; }
	inline void saveClock24Hour(Bool c) { resource.clock24hour = c; }
#endif // HAVE_STRFTIME

	inline Theme::WindowStyle *getWindowStyle(void) { return &theme->getWindowStyle(); }
	inline Theme::MenuStyle *getMenuStyle(void) { return &theme->getMenuStyle(); }
	inline Theme::ToolbarStyle *getToolbarStyle(void) { return &theme->getToolbarStyle(); }

	FluxboxWindow *getIcon(int);

	int addWorkspace(void);
	int removeLastWorkspace(void);
	//scroll workspaces
	void nextWorkspace();
	void prevWorkspace();

	void removeWorkspaceNames(void);
	void updateWorkspaceNamesAtom(void);

	void addWorkspaceName(char *);
	void addNetizen(Netizen *);
	void removeNetizen(Window);
	void addIcon(FluxboxWindow *);
	void removeIcon(FluxboxWindow *);
	void getNameOfWorkspace(int, char **);
	void changeWorkspaceID(int);
	void raiseWindows(Window *, int);
	void reassociateWindow(FluxboxWindow *, int, Bool);
	void prevFocus(void);
	void nextFocus(void);
	void raiseFocus(void);
	void reconfigure(void);
	void rereadMenu(void);
	void shutdown(void);
	void showPosition(int, int);
	void showGeometry(unsigned int, unsigned int);
	void hideGeometry(void);

	void updateNetizenCurrentWorkspace(void);
	void updateNetizenWorkspaceCount(void);
	void updateNetizenWindowFocus(void);
	void updateNetizenWindowAdd(Window, unsigned long);
	void updateNetizenWindowDel(Window);
	void updateNetizenConfigNotify(XEvent *);
	void updateNetizenWindowRaise(Window);
	void updateNetizenWindowLower(Window);

	enum { RowSmartPlacement = 1, ColSmartPlacement, CascadePlacement, LeftRight,
				 RightLeft, TopBottom, BottomTop };
	enum { LeftJustify = 1, RightJustify, CenterJustify };
	enum { RoundBullet = 1, TriangleBullet, SquareBullet, NoBullet };
	enum { Restart = 1, RestartOther, Exit, Shutdown, Execute, Reconfigure,
				 WindowShade, WindowIconify, WindowMaximize, WindowClose, WindowRaise,
				 WindowLower, WindowStick, WindowKill, SetStyle, WindowTab};

private:
	Theme *theme;

	Bool root_colormap_installed, managed, geom_visible;
	GC opGC;
	Pixmap geom_pixmap;
	Window geom_window;

	Fluxbox *fluxbox;
	BImageControl *image_control;
	Configmenu *configmenu;
	Iconmenu *iconmenu;

	Rootmenu *rootmenu;

	LinkedList<Rootmenu> *rootmenuList;
	LinkedList<Netizen> *netizenList;
	LinkedList<FluxboxWindow> *iconList;

#ifdef		SLIT
	Slit *slit;
#endif // SLIT

	Toolbar *toolbar;
	Workspace *current_workspace;
	Workspacemenu *workspacemenu;

	unsigned int geom_w, geom_h;
	unsigned long event_mask;

	LinkedList<char> *workspaceNames;
	LinkedList<Workspace> *workspacesList;

	struct resource {

		Bool toolbar_on_top, toolbar_auto_hide, sloppy_focus, auto_raise,
			auto_edge_balance, image_dither, ordered_dither, opaque_move, full_max,
			focus_new, focus_last, max_over_slit, tab_rotate_vertical, semi_sloppy_focus,
			sloppy_window_grouping;

		int workspaces, toolbar_placement, toolbar_width_percent, placement_policy,
			edge_snap_threshold, row_direction, col_direction;

		unsigned int tab_placement, tab_alignment, tab_width, tab_height;

#ifdef		SLIT
		Bool slit_on_top, slit_auto_hide;
		int slit_placement, slit_direction;
#endif // SLIT

#ifdef		HAVE_STRFTIME
		char *strftime_format;
#else // !HAVE_STRFTIME
		Bool clock24hour;
		int date_format;
#endif // HAVE_STRFTIME

	} resource;

protected:
	Bool parseMenuFile(FILE *, Rootmenu *);

	bool readDatabaseTexture(char *, char *, BTexture *, unsigned long);
	bool readDatabaseColor(char *, char *, BColor *, unsigned long);

	void readDatabaseFontSet(char *, char *, XFontSet *);
	XFontSet createFontSet(char *);
	void readDatabaseFont(char *, char *, XFontStruct **);

	void InitMenu(void);

};

#endif // _SCREEN_HH_
<|endoftext|>


<commit_before>// Copyright 2019 Netherlands eScience Center and Netherlands Institute for Radio Astronomy (ASTRON)
//
// 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.

#include <ReadData.hpp>
#include <ArgumentList.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <gtest/gtest.h>

std::string fileName;

int main(int argc, char * argv[])
{
    testing::InitGoogleTest(&argc, argv);
    isa::utils::ArgumentList arguments(argc, argv);
    try
    {
        fileName = arguments.getSwitchArgument<std::string>("-zapped_channels_file");
    }
    catch ( isa::utils::EmptyCommandLine & err )
    {
        std::cerr << "Required command line parameters:" << std::endl;
        std::cerr << "\t-zapped_channels_file <string>" << std::endl;
    }
    return RUN_ALL_TESTS();
}

TEST(ZappedChannels, FileError)
{
    AstroData::Observation observation;
    std::vector<unsigned int> channels;
    std::string wrongFileName = "zappred_channels.conf";
    ASSERT_THROW(AstroData::readZappedChannels(observation, wrongFileName, channels), AstroData::FileError);
}

TEST(ZappedChannels, MatchingChannels)
{
    AstroData::Observation observation;
    std::vector<unsigned int> channels;
    observation.setFrequencyRange(1, 1024, 0.0f, 0.0f);
    channels.resize(observation.getNrChannels());
    AstroData::readZappedChannels(observation, fileName, channels);
    EXPECT_EQ(channels.at(4), 1);
    EXPECT_EQ(channels.at(39), 1);
    EXPECT_EQ(channels.at(7), 1);
    EXPECT_EQ(channels.at(19), 1);
    EXPECT_EQ(channels.at(1023), 1);
    EXPECT_EQ(channels.at(0), 1);
    EXPECT_NE(channels.at(45), 1);
    EXPECT_NE(channels.at(128), 1);
}
<commit_msg>Added empty lines.<commit_after>// Copyright 2019 Netherlands eScience Center and Netherlands Institute for Radio Astronomy (ASTRON)
//
// 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.

#include <ReadData.hpp>
#include <ArgumentList.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <gtest/gtest.h>

std::string fileName;

int main(int argc, char * argv[])
{
    testing::InitGoogleTest(&argc, argv);
    isa::utils::ArgumentList arguments(argc, argv);
    try
    {
        fileName = arguments.getSwitchArgument<std::string>("-zapped_channels_file");
    }
    catch ( isa::utils::EmptyCommandLine & err )
    {
        std::cerr << std::endl;
        std::cerr << "Required command line parameters:" << std::endl;
        std::cerr << "\t-zapped_channels_file <string>" << std::endl;
        std::cerr << std::endl;
    }
    return RUN_ALL_TESTS();
}

TEST(ZappedChannels, FileError)
{
    AstroData::Observation observation;
    std::vector<unsigned int> channels;
    std::string wrongFileName = "zappred_channels.conf";
    ASSERT_THROW(AstroData::readZappedChannels(observation, wrongFileName, channels), AstroData::FileError);
}

TEST(ZappedChannels, MatchingChannels)
{
    AstroData::Observation observation;
    std::vector<unsigned int> channels;
    observation.setFrequencyRange(1, 1024, 0.0f, 0.0f);
    channels.resize(observation.getNrChannels());
    AstroData::readZappedChannels(observation, fileName, channels);
    EXPECT_EQ(channels.at(4), 1);
    EXPECT_EQ(channels.at(39), 1);
    EXPECT_EQ(channels.at(7), 1);
    EXPECT_EQ(channels.at(19), 1);
    EXPECT_EQ(channels.at(1023), 1);
    EXPECT_EQ(channels.at(0), 1);
    EXPECT_NE(channels.at(45), 1);
    EXPECT_NE(channels.at(128), 1);
}
<|endoftext|>