<commit_before>/*******************************************************************************

Copyright The University of Auckland

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.

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

//==============================================================================
// Editor find/replace widget
//==============================================================================

#include "coreguiutils.h"
#include "editorwidgetfindreplacewidget.h"
#include "i18ninterface.h"

//==============================================================================

#include "ui_editorwidgetfindreplacewidget.h"

//==============================================================================

#include <Qt>

//==============================================================================

#include <QAction>
#include <QKeyEvent>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QPainter>
#include <QPixmap>
#include <QSize>
#include <QToolButton>

//==============================================================================

namespace OpenCOR {
namespace EditorWidget {

//==============================================================================

EditorWidgetFindReplaceWidget::EditorWidgetFindReplaceWidget(QWidget *pParent) :
    Core::Widget(pParent),
    mGui(new Ui::EditorWidgetFindReplaceWidget),
    mActive(false)
{
    // Set up the GUI

    mGui->setupUi(this);

#ifdef Q_OS_MAC
    mGui->findEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
    mGui->replaceEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
    // Note: the above remove the focus border since it messes up the look of
    //       our edit widgets...
#endif

    // Create and handle our drop-down menu action

    mDropDownAction = Core::newAction(this);

    mCaseSensitiveAction = Core::newAction(true, this);
    mWholeWordsOnlyAction = Core::newAction(true, this);
    mRegularExpressionAction = Core::newAction(true, this);

    QMenu *dropDownMenu = new QMenu(this);

    dropDownMenu->addAction(mCaseSensitiveAction);
    dropDownMenu->addAction(mWholeWordsOnlyAction);
    dropDownMenu->addAction(mRegularExpressionAction);

    mDropDownAction->setMenu(dropDownMenu);

    mGui->findEdit->addAction(mDropDownAction, QLineEdit::LeadingPosition);

    connect(mCaseSensitiveAction, SIGNAL(toggled(bool)),
            this, SLOT(searchOptionChanged()));
    connect(mWholeWordsOnlyAction, SIGNAL(toggled(bool)),
            this, SLOT(searchOptionChanged()));
    connect(mRegularExpressionAction, SIGNAL(toggled(bool)),
            this, SLOT(searchOptionChanged()));

    // Create and handle our clear find and replace text actions

    mClearFindTextAction = Core::newAction(QIcon(":/EditorWidget/qtCreator/src/plugins/coreplugin/images/editclear.png"), this);
    mClearReplaceTextAction = Core::newAction(QIcon(":/EditorWidget/qtCreator/src/plugins/coreplugin/images/editclear.png"), this);

    connect(mClearFindTextAction, SIGNAL(triggered(bool)),
            mGui->findEdit, SLOT(clear()));

    connect(mClearReplaceTextAction, SIGNAL(triggered(bool)),
            mGui->replaceEdit, SLOT(clear()));

    // Make our find edit widget our focus proxy

    setFocusProxy(mGui->findEdit);

    // Some connections for our find-related widgets

    connect(mGui->findEdit, SIGNAL(textChanged(const QString &)),
            this, SLOT(updateClearFindTextAction(const QString &)));

    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->findPreviousButton, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->findNextButton, SLOT(setEnabled(bool)));

    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->replaceButton, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->replaceAndFindButton, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->replaceAllButton, SLOT(setEnabled(bool)));

    // A connection for our replace widget

    connect(mGui->replaceEdit, SIGNAL(textChanged(const QString &)),
            this, SLOT(updateClearReplaceTextAction(const QString &)));

    // A few more things , so that we are properly initialised

    retranslateUi();

    searchOptionChanged();

    setActive(true);

    updateStyleSheet();
    updateHeight();
    // Note: just to be safe, we update our height after updating our style
    //       sheet since we change the size of our tool buttons...

    mGui->findPreviousButton->setEnabled(false);
    mGui->findNextButton->setEnabled(false);

    mGui->replaceButton->setEnabled(false);
    mGui->replaceAndFindButton->setEnabled(false);
    mGui->replaceAllButton->setEnabled(false);
}

//==============================================================================

EditorWidgetFindReplaceWidget::~EditorWidgetFindReplaceWidget()
{
    // Delete the GUI

    delete mGui;
}

//==============================================================================

void EditorWidgetFindReplaceWidget::retranslateUi()
{
    // Retranslate our GUI

    mGui->retranslateUi(this);

    // Retranslate our actions

    I18nInterface::retranslateAction(mCaseSensitiveAction, tr("Case Sensitive"),
                                     tr("The search is case sensitive"));
    I18nInterface::retranslateAction(mWholeWordsOnlyAction, tr("Whole Words Only"),
                                     tr("The search is done on whole words only"));
    I18nInterface::retranslateAction(mRegularExpressionAction, tr("Regular Expression"),
                                     tr("The search uses a regular expression"));

    I18nInterface::retranslateAction(mClearFindTextAction, tr("Clear Text"),
                                     tr("Clear the text"));
    I18nInterface::retranslateAction(mClearReplaceTextAction, tr("Clear Text"),
                                     tr("Clear the text"));
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::isCaseSensitive() const
{
    // Return whether the search is to be case sensitive

    return mCaseSensitiveAction->isChecked();
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::searchWholeWordsOnly() const
{
    // Return whether we search whole words only

    return mWholeWordsOnlyAction->isChecked();
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::useRegularExpression() const
{
    // Return whether we use a regular expression

    return mRegularExpressionAction->isChecked();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::setReadOnly(const bool &pReadOnly)
{
    // Show/hide our replace-related widgets based on whether we are in
    // read-only mode

    Core::showEnableWidget(mGui->replaceLabel, !pReadOnly);
    Core::showEnableWidget(mGui->replaceEdit, !pReadOnly);
    Core::showEnableWidget(mGui->replaceButton, !pReadOnly);
    Core::showEnableWidget(mGui->replaceAndFindButton, !pReadOnly);
    Core::showEnableWidget(mGui->replaceAllButton, !pReadOnly);

    // Enable/disable our find spacer

    mGui->findLayout->setStretch(2, !pReadOnly);

    // Disable our replace-related buttons, if needed

    if (findText().isEmpty()) {
        mGui->replaceButton->setEnabled(false);
        mGui->replaceAndFindButton->setEnabled(false);
        mGui->replaceAllButton->setEnabled(false);
    }

    // Update our height

    updateHeight();
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::isFindPreviousNextAvailable() const
{
    // Return whether the find previous/next actions are available

    return !findText().isEmpty();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::selectFindText() const
{
    // Select our find text

    mGui->findEdit->selectAll();
}

//==============================================================================

QString EditorWidgetFindReplaceWidget::findText() const
{
    // Return our find text

    return mGui->findEdit->text();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::setFindText(const QString &pFindText)
{
    // Set our find text and select it

    mGui->findEdit->setText(pFindText);

    selectFindText();
}

//==============================================================================

QString EditorWidgetFindReplaceWidget::replaceText() const
{
    // Return our replace text

    return mGui->replaceEdit->text();
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::findEditHasFocus() const
{
    // Return whether our find edit has the focus

    return mGui->findEdit->hasFocus();
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::replaceEditHasFocus() const
{
    // Return whether our replace edit has the focus

    return mGui->replaceEdit->hasFocus();
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::isActive() const
{
    // Return whether we are active

    return mActive;
}

//==============================================================================

void EditorWidgetFindReplaceWidget::setActive(const bool &pActive)
{
    if (pActive == mActive)
        return;

    // Set our active state

    mActive = pActive;

    if (pActive)
        connect(mGui->findEdit, SIGNAL(textChanged(const QString &)),
                this, SIGNAL(findTextChanged(const QString &)));
    else
        disconnect(mGui->findEdit, SIGNAL(textChanged(const QString &)),
                   this, SIGNAL(findTextChanged(const QString &)));
}

//==============================================================================

void EditorWidgetFindReplaceWidget::updateFrom(EditorWidgetFindReplaceWidget *pFindReplace)
{
    // Update our find and replace texts from the given find/replace widget

    mGui->findEdit->setText(pFindReplace->findText());
    mGui->replaceEdit->setText(pFindReplace->replaceText());
}

//==============================================================================

void EditorWidgetFindReplaceWidget::updateHeight()
{
    // Update our layout
    // Note: we shouldn't have to do this, but if the user opens a read-only and
    //       shows ourselves, then the find-related widgets will be too 'low'.
    //       This is because the replace-related widgets get hidden/disabled as
    //       expected, but the layout doesn't get updated before we fix our
    //       height, so we update our layout here and in all cases...

    mGui->layout->update();

    // Update our height

    setFixedHeight(mGui->layout->sizeHint().height());
}

//==============================================================================

void EditorWidgetFindReplaceWidget::updateStyleSheet()
{
    // Change the style of our tool buttons

    QColor shadowColor = Core::shadowColor();

    setStyleSheet(QString("QToolButton {"
                          "    border: 0px;"
                          "    border-radius: 3px;"
                          "    padding: 1px;"
                          "}"
                          ""
                          "QToolButton:focus {"
                          "    background: rgba(%1, %2, %3, 0.13);"
                          "    border: 1px solid rgba(%1, %2, %3, 0.39);"
                          "}"
                          ""
                          "QToolButton:hover {"
                          "    background: rgba(%1, %2, %3, 0.39);"
                          "}"
                          ""
                          "QToolButton:pressed {"
                          "    background: rgba(%1, %2, %3, 0.79);"
                          "}").arg(QString::number(shadowColor.red()),
                                   QString::number(shadowColor.green()),
                                   QString::number(shadowColor.blue())));
}

//==============================================================================

void EditorWidgetFindReplaceWidget::changeEvent(QEvent *pEvent)
{
    // Check whether the palette has changed and if so then update our style
    // sheet

    if (pEvent->type() == QEvent::PaletteChange)
        updateStyleSheet();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::keyPressEvent(QKeyEvent *pEvent)
{
    // Let people know that a key has been pressed

    bool handled = false;

    emit keyPressed(pEvent, handled);

    // Carry on as normal, if the event wasn't handled

    if (handled)
        // Accept the event

        pEvent->accept();
    else
        // Default handling of the event

        Core::Widget::keyPressEvent(pEvent);
}

//==============================================================================

void EditorWidgetFindReplaceWidget::resizeEvent(QResizeEvent *pEvent)
{
    // Default handling of the event

    Core::Widget::resizeEvent(pEvent);

    // Update our height

    updateHeight();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::on_findPreviousButton_clicked()
{
    // Let people know that we want to find the previous occurrence of the text

    emit findPreviousRequested();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::on_findNextButton_clicked()
{
    // Let people know that we want to find the next occurrence of the text

    emit findNextRequested();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::on_replaceButton_clicked()
{
    // Let people know that we want to replace the current text

    emit replaceRequested();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::on_replaceAndFindButton_clicked()
{
    // Let people know that we want to replace the current text and the find the
    // next occurence of the text

    emit replaceAndFindRequested();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::on_replaceAllButton_clicked()
{
    // Let people know that we want to replace all the occurences of the text

    emit replaceAllRequested();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::searchOptionChanged()
{
    // Update the icon used for the leading position of our find widget

    static const QIcon DefaultIcon           = QIcon(":/EditorWidget/qtCreator/src/plugins/coreplugin/images/magnifier.png");
    static const QIcon CaseSensitiveIcon     = QIcon(":/EditorWidget/qtCreator/src/plugins/coreplugin/find/images/casesensitively.png");
    static const QIcon WholeWordsOnlyIcon    = QIcon(":/EditorWidget/qtCreator/src/plugins/coreplugin/find/images/wholewords.png");
    static const QIcon RegularExpressionIcon = QIcon(":/EditorWidget/qtCreator/src/plugins/coreplugin/find/images/regexp.png");

    int nbOfOptions =  mCaseSensitiveAction->isChecked()
                      +mWholeWordsOnlyAction->isChecked()
                      +mRegularExpressionAction->isChecked();

    if (nbOfOptions) {
        static const int IconSize = 16;
        static const int IconWidth = 6;

        QPixmap dropDownPixmap = QPixmap(nbOfOptions*IconWidth-mRegularExpressionAction->isChecked(),
                                         IconSize);
        // Note: -mRegularExpressionAction->isChecked(), because
        //       regularExpressionIcon is effectively one pixel narrower than
        //       caseSensitiveIcon and wholeWordsOnlyIcon...

        dropDownPixmap.fill(Qt::transparent);

        QPainter dropDownPixmapPainter(&dropDownPixmap);

        int left = -IconWidth;

        if (mCaseSensitiveAction->isChecked()) {
            CaseSensitiveIcon.paint(&dropDownPixmapPainter, left, 0, IconSize, IconSize);

            left += IconWidth;
        }

        if (mWholeWordsOnlyAction->isChecked()) {
            WholeWordsOnlyIcon.paint(&dropDownPixmapPainter, left, 0, IconSize, IconSize);

            left += IconWidth;
        }

        if (mRegularExpressionAction->isChecked())
            RegularExpressionIcon.paint(&dropDownPixmapPainter, left-1, 0, IconSize, IconSize);

        mDropDownAction->setIcon(dropDownPixmap);
    } else {
        // No options are set, so use our default icon

        mDropDownAction->setIcon(DefaultIcon);
    }
}

//==============================================================================

void EditorWidgetFindReplaceWidget::updateClearFindTextAction(const QString &pText)
{
    // Show/hide our clear text action, based on whether our find widget
    // contains some text

    if (pText.isEmpty())
        mGui->findEdit->removeAction(mClearFindTextAction);
    else
        mGui->findEdit->addAction(mClearFindTextAction, QLineEdit::TrailingPosition);

    // Let people know whether we can find/replace

    emit canFindReplace(!findText().isEmpty());
}

//==============================================================================

void EditorWidgetFindReplaceWidget::updateClearReplaceTextAction(const QString &pText)
{
    // Show/hide our clear text action, based on whether our replace widget
    // contains some text

    if (pText.isEmpty())
        mGui->replaceEdit->removeAction(mClearReplaceTextAction);
    else
        mGui->replaceEdit->addAction(mClearReplaceTextAction, QLineEdit::TrailingPosition);
}

//==============================================================================

}   // namespace EditorWidget
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Editor (find/replace widget): fixed a problem with the icon for the search options / magnifier looking wrong (closes #1026).<commit_after>/*******************************************************************************

Copyright The University of Auckland

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.

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

//==============================================================================
// Editor find/replace widget
//==============================================================================

#include "coreguiutils.h"
#include "editorwidgetfindreplacewidget.h"
#include "i18ninterface.h"

//==============================================================================

#include "ui_editorwidgetfindreplacewidget.h"

//==============================================================================

#include <Qt>

//==============================================================================

#include <QAction>
#include <QKeyEvent>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QPainter>
#include <QPixmap>
#include <QSize>
#include <QToolButton>

//==============================================================================

namespace OpenCOR {
namespace EditorWidget {

//==============================================================================

EditorWidgetFindReplaceWidget::EditorWidgetFindReplaceWidget(QWidget *pParent) :
    Core::Widget(pParent),
    mGui(new Ui::EditorWidgetFindReplaceWidget),
    mActive(false)
{
    // Set up the GUI

    mGui->setupUi(this);

#ifdef Q_OS_MAC
    mGui->findEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
    mGui->replaceEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
    // Note: the above remove the focus border since it messes up the look of
    //       our edit widgets...
#endif

    // Create and handle our drop-down menu action

    mDropDownAction = Core::newAction(this);

    mCaseSensitiveAction = Core::newAction(true, this);
    mWholeWordsOnlyAction = Core::newAction(true, this);
    mRegularExpressionAction = Core::newAction(true, this);

    QMenu *dropDownMenu = new QMenu(this);

    dropDownMenu->addAction(mCaseSensitiveAction);
    dropDownMenu->addAction(mWholeWordsOnlyAction);
    dropDownMenu->addAction(mRegularExpressionAction);

    mDropDownAction->setMenu(dropDownMenu);

    mGui->findEdit->addAction(mDropDownAction, QLineEdit::LeadingPosition);

    connect(mCaseSensitiveAction, SIGNAL(toggled(bool)),
            this, SLOT(searchOptionChanged()));
    connect(mWholeWordsOnlyAction, SIGNAL(toggled(bool)),
            this, SLOT(searchOptionChanged()));
    connect(mRegularExpressionAction, SIGNAL(toggled(bool)),
            this, SLOT(searchOptionChanged()));

    // Create and handle our clear find and replace text actions

    mClearFindTextAction = Core::newAction(QIcon(":/EditorWidget/qtCreator/src/plugins/coreplugin/images/editclear.png"), this);
    mClearReplaceTextAction = Core::newAction(QIcon(":/EditorWidget/qtCreator/src/plugins/coreplugin/images/editclear.png"), this);

    connect(mClearFindTextAction, SIGNAL(triggered(bool)),
            mGui->findEdit, SLOT(clear()));

    connect(mClearReplaceTextAction, SIGNAL(triggered(bool)),
            mGui->replaceEdit, SLOT(clear()));

    // Make our find edit widget our focus proxy

    setFocusProxy(mGui->findEdit);

    // Some connections for our find-related widgets

    connect(mGui->findEdit, SIGNAL(textChanged(const QString &)),
            this, SLOT(updateClearFindTextAction(const QString &)));

    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->findPreviousButton, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->findNextButton, SLOT(setEnabled(bool)));

    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->replaceButton, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->replaceAndFindButton, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->replaceAllButton, SLOT(setEnabled(bool)));

    // A connection for our replace widget

    connect(mGui->replaceEdit, SIGNAL(textChanged(const QString &)),
            this, SLOT(updateClearReplaceTextAction(const QString &)));

    // A few more things , so that we are properly initialised

    retranslateUi();

    searchOptionChanged();

    setActive(true);

    updateStyleSheet();
    updateHeight();
    // Note: just to be safe, we update our height after updating our style
    //       sheet since we change the size of our tool buttons...

    mGui->findPreviousButton->setEnabled(false);
    mGui->findNextButton->setEnabled(false);

    mGui->replaceButton->setEnabled(false);
    mGui->replaceAndFindButton->setEnabled(false);
    mGui->replaceAllButton->setEnabled(false);
}

//==============================================================================

EditorWidgetFindReplaceWidget::~EditorWidgetFindReplaceWidget()
{
    // Delete the GUI

    delete mGui;
}

//==============================================================================

void EditorWidgetFindReplaceWidget::retranslateUi()
{
    // Retranslate our GUI

    mGui->retranslateUi(this);

    // Retranslate our actions

    I18nInterface::retranslateAction(mCaseSensitiveAction, tr("Case Sensitive"),
                                     tr("The search is case sensitive"));
    I18nInterface::retranslateAction(mWholeWordsOnlyAction, tr("Whole Words Only"),
                                     tr("The search is done on whole words only"));
    I18nInterface::retranslateAction(mRegularExpressionAction, tr("Regular Expression"),
                                     tr("The search uses a regular expression"));

    I18nInterface::retranslateAction(mClearFindTextAction, tr("Clear Text"),
                                     tr("Clear the text"));
    I18nInterface::retranslateAction(mClearReplaceTextAction, tr("Clear Text"),
                                     tr("Clear the text"));
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::isCaseSensitive() const
{
    // Return whether the search is to be case sensitive

    return mCaseSensitiveAction->isChecked();
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::searchWholeWordsOnly() const
{
    // Return whether we search whole words only

    return mWholeWordsOnlyAction->isChecked();
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::useRegularExpression() const
{
    // Return whether we use a regular expression

    return mRegularExpressionAction->isChecked();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::setReadOnly(const bool &pReadOnly)
{
    // Show/hide our replace-related widgets based on whether we are in
    // read-only mode

    Core::showEnableWidget(mGui->replaceLabel, !pReadOnly);
    Core::showEnableWidget(mGui->replaceEdit, !pReadOnly);
    Core::showEnableWidget(mGui->replaceButton, !pReadOnly);
    Core::showEnableWidget(mGui->replaceAndFindButton, !pReadOnly);
    Core::showEnableWidget(mGui->replaceAllButton, !pReadOnly);

    // Enable/disable our find spacer

    mGui->findLayout->setStretch(2, !pReadOnly);

    // Disable our replace-related buttons, if needed

    if (findText().isEmpty()) {
        mGui->replaceButton->setEnabled(false);
        mGui->replaceAndFindButton->setEnabled(false);
        mGui->replaceAllButton->setEnabled(false);
    }

    // Update our height

    updateHeight();
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::isFindPreviousNextAvailable() const
{
    // Return whether the find previous/next actions are available

    return !findText().isEmpty();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::selectFindText() const
{
    // Select our find text

    mGui->findEdit->selectAll();
}

//==============================================================================

QString EditorWidgetFindReplaceWidget::findText() const
{
    // Return our find text

    return mGui->findEdit->text();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::setFindText(const QString &pFindText)
{
    // Set our find text and select it

    mGui->findEdit->setText(pFindText);

    selectFindText();
}

//==============================================================================

QString EditorWidgetFindReplaceWidget::replaceText() const
{
    // Return our replace text

    return mGui->replaceEdit->text();
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::findEditHasFocus() const
{
    // Return whether our find edit has the focus

    return mGui->findEdit->hasFocus();
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::replaceEditHasFocus() const
{
    // Return whether our replace edit has the focus

    return mGui->replaceEdit->hasFocus();
}

//==============================================================================

bool EditorWidgetFindReplaceWidget::isActive() const
{
    // Return whether we are active

    return mActive;
}

//==============================================================================

void EditorWidgetFindReplaceWidget::setActive(const bool &pActive)
{
    if (pActive == mActive)
        return;

    // Set our active state

    mActive = pActive;

    if (pActive)
        connect(mGui->findEdit, SIGNAL(textChanged(const QString &)),
                this, SIGNAL(findTextChanged(const QString &)));
    else
        disconnect(mGui->findEdit, SIGNAL(textChanged(const QString &)),
                   this, SIGNAL(findTextChanged(const QString &)));
}

//==============================================================================

void EditorWidgetFindReplaceWidget::updateFrom(EditorWidgetFindReplaceWidget *pFindReplace)
{
    // Update our find and replace texts from the given find/replace widget

    mGui->findEdit->setText(pFindReplace->findText());
    mGui->replaceEdit->setText(pFindReplace->replaceText());
}

//==============================================================================

void EditorWidgetFindReplaceWidget::updateHeight()
{
    // Update our layout
    // Note: we shouldn't have to do this, but if the user opens a read-only and
    //       shows ourselves, then the find-related widgets will be too 'low'.
    //       This is because the replace-related widgets get hidden/disabled as
    //       expected, but the layout doesn't get updated before we fix our
    //       height, so we update our layout here and in all cases...

    mGui->layout->update();

    // Update our height

    setFixedHeight(mGui->layout->sizeHint().height());
}

//==============================================================================

void EditorWidgetFindReplaceWidget::updateStyleSheet()
{
    // Change the style of our tool buttons

    QColor shadowColor = Core::shadowColor();

    setStyleSheet(QString("QToolButton {"
                          "    border: 0px;"
                          "    border-radius: 3px;"
                          "    padding: 1px;"
                          "}"
                          ""
                          "QToolButton:focus {"
                          "    background: rgba(%1, %2, %3, 0.13);"
                          "    border: 1px solid rgba(%1, %2, %3, 0.39);"
                          "}"
                          ""
                          "QToolButton:hover {"
                          "    background: rgba(%1, %2, %3, 0.39);"
                          "}"
                          ""
                          "QToolButton:pressed {"
                          "    background: rgba(%1, %2, %3, 0.79);"
                          "}").arg(QString::number(shadowColor.red()),
                                   QString::number(shadowColor.green()),
                                   QString::number(shadowColor.blue())));
}

//==============================================================================

void EditorWidgetFindReplaceWidget::changeEvent(QEvent *pEvent)
{
    // Check whether the palette has changed and if so then update our style
    // sheet

    if (pEvent->type() == QEvent::PaletteChange)
        updateStyleSheet();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::keyPressEvent(QKeyEvent *pEvent)
{
    // Let people know that a key has been pressed

    bool handled = false;

    emit keyPressed(pEvent, handled);

    // Carry on as normal, if the event wasn't handled

    if (handled)
        // Accept the event

        pEvent->accept();
    else
        // Default handling of the event

        Core::Widget::keyPressEvent(pEvent);
}

//==============================================================================

void EditorWidgetFindReplaceWidget::resizeEvent(QResizeEvent *pEvent)
{
    // Default handling of the event

    Core::Widget::resizeEvent(pEvent);

    // Update our height

    updateHeight();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::on_findPreviousButton_clicked()
{
    // Let people know that we want to find the previous occurrence of the text

    emit findPreviousRequested();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::on_findNextButton_clicked()
{
    // Let people know that we want to find the next occurrence of the text

    emit findNextRequested();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::on_replaceButton_clicked()
{
    // Let people know that we want to replace the current text

    emit replaceRequested();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::on_replaceAndFindButton_clicked()
{
    // Let people know that we want to replace the current text and the find the
    // next occurence of the text

    emit replaceAndFindRequested();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::on_replaceAllButton_clicked()
{
    // Let people know that we want to replace all the occurences of the text

    emit replaceAllRequested();
}

//==============================================================================

void EditorWidgetFindReplaceWidget::searchOptionChanged()
{
    // Update the icon used for the leading position of our find widget

    static const QIcon MagnifierIcon         = QIcon(":/EditorWidget/qtCreator/src/plugins/coreplugin/images/magnifier.png");
    static const QIcon CaseSensitiveIcon     = QIcon(":/EditorWidget/qtCreator/src/plugins/coreplugin/find/images/casesensitively.png");
    static const QIcon WholeWordsOnlyIcon    = QIcon(":/EditorWidget/qtCreator/src/plugins/coreplugin/find/images/wholewords.png");
    static const QIcon RegularExpressionIcon = QIcon(":/EditorWidget/qtCreator/src/plugins/coreplugin/find/images/regexp.png");
    static const int IconSize                = 16;
    static const int MagnifierIconWidth      = 17;
    static const int MagnifierIconHeight     = 11;
    static const int CaseSensitiveIconShift  =  6;
    static const int WholeWordsOnlyIconShift =  6;
    static const int RegularExpressionShift  =  7;
    static const int CaseSensitiveIconWidth  =  5;
    static const int WholeWordsOnlyIconWidth =  5;
    static const int RegularExpressionWidth  =  4;

    int nbOfOptions =  mCaseSensitiveAction->isChecked()
                      +mWholeWordsOnlyAction->isChecked()
                      +mRegularExpressionAction->isChecked();
    QPixmap dropDownPixmap = QPixmap(IconSize, IconSize);

    dropDownPixmap.fill(Qt::transparent);

    QPainter dropDownPixmapPainter(&dropDownPixmap);

    if (nbOfOptions) {
        int left = ( IconSize-nbOfOptions+1
                    -mCaseSensitiveAction->isChecked()*CaseSensitiveIconWidth
                    -mWholeWordsOnlyAction->isChecked()*WholeWordsOnlyIconWidth
                    -mRegularExpressionAction->isChecked()*RegularExpressionWidth) >> 1;

        if (mCaseSensitiveAction->isChecked()) {
            CaseSensitiveIcon.paint(&dropDownPixmapPainter,
                                    left-CaseSensitiveIconShift, 0,
                                    IconSize, IconSize);

            left += CaseSensitiveIconWidth+1;
        }

        if (mWholeWordsOnlyAction->isChecked()) {
            WholeWordsOnlyIcon.paint(&dropDownPixmapPainter,
                                     left-WholeWordsOnlyIconShift, 0,
                                     IconSize, IconSize);

            left += WholeWordsOnlyIconWidth+1;
        }

        if (mRegularExpressionAction->isChecked()) {
            RegularExpressionIcon.paint(&dropDownPixmapPainter,
                                        left-RegularExpressionShift, 0,
                                        IconSize, IconSize);
        }
    } else {
        // We hack of magnifier icon away so that it ends up looking the way we
        // want it (since it's wider than 16 pixels)

        MagnifierIcon.paint(&dropDownPixmapPainter,
                            -1, ((IconSize-MagnifierIconHeight) >> 1)+1,
                            MagnifierIconWidth, MagnifierIconHeight);

        QPen pen = dropDownPixmapPainter.pen();

        pen.setColor(Qt::white);

        dropDownPixmapPainter.setPen(pen);

        dropDownPixmapPainter.drawPoint(0, 13);
    }

    mDropDownAction->setIcon(dropDownPixmap);
}

//==============================================================================

void EditorWidgetFindReplaceWidget::updateClearFindTextAction(const QString &pText)
{
    // Show/hide our clear text action, based on whether our find widget
    // contains some text

    if (pText.isEmpty())
        mGui->findEdit->removeAction(mClearFindTextAction);
    else
        mGui->findEdit->addAction(mClearFindTextAction, QLineEdit::TrailingPosition);

    // Let people know whether we can find/replace

    emit canFindReplace(!findText().isEmpty());
}

//==============================================================================

void EditorWidgetFindReplaceWidget::updateClearReplaceTextAction(const QString &pText)
{
    // Show/hide our clear text action, based on whether our replace widget
    // contains some text

    if (pText.isEmpty())
        mGui->replaceEdit->removeAction(mClearReplaceTextAction);
    else
        mGui->replaceEdit->addAction(mClearReplaceTextAction, QLineEdit::TrailingPosition);
}

//==============================================================================

}   // namespace EditorWidget
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/about_chrome_dialog.h"

#include <gtk/gtk.h>

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/file_version_info.h"
#include "base/gfx/gtk_util.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/profile.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/gtk_util.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "grit/theme_resources.h"
#include "webkit/glue/webkit_glue.h"

namespace {

// The URLs that you navigate to when clicking the links in the About dialog.
const char* const kAcknowledgements = "about:credits";
const char* const kTOS = "about:terms";

// Left or right margin.
const int kPanelHorizMargin = 13;

// Top or bottom margin.
const int kPanelVertMargin = 20;

// Extra spacing between product name and version number.
const int kExtraLineSpacing = 5;

// These are used as placeholder text around the links in the text in the about
// dialog.
const char* kBeginLinkChr = "BEGIN_LINK_CHR";
const char* kBeginLinkOss = "BEGIN_LINK_OSS";
// We don't actually use this one.
// const char* kEndLinkChr = "END_LINK_CHR";
const char* kEndLinkOss = "END_LINK_OSS";
const char* kBeginLink = "BEGIN_LINK";
const char* kEndLink = "END_LINK";

void OnDialogResponse(GtkDialog* dialog, int response_id) {
  // We're done.
  gtk_widget_destroy(GTK_WIDGET(dialog));
}

void FixLabelWrappingCallback(GtkWidget *label,
                              GtkAllocation *allocation,
                              gpointer data) {
  gtk_widget_set_size_request(label, allocation->width, -1);
}

GtkWidget* MakeMarkupLabel(const char* format, const std::string& str) {
  GtkWidget* label = gtk_label_new(NULL);
  char* markup = g_markup_printf_escaped(format, str.c_str());
  gtk_label_set_markup(GTK_LABEL(label), markup);
  g_free(markup);

  // Left align it.
  gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);

  return label;
}

void OnLinkButtonClick(GtkWidget* button, const char* url) {
  BrowserList::GetLastActive()->
      OpenURL(GURL(url), GURL(), NEW_WINDOW, PageTransition::LINK);
}

const char* GetChromiumUrl() {
  static std::string url(l10n_util::GetStringUTF8(IDS_CHROMIUM_PROJECT_URL));
  return url.c_str();
}

}  // namespace

void ShowAboutDialogForProfile(GtkWindow* parent, Profile* profile) {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  static GdkPixbuf* background = rb.GetPixbufNamed(IDR_ABOUT_BACKGROUND);
  scoped_ptr<FileVersionInfo> version_info(
      FileVersionInfo::CreateFileVersionInfoForCurrentModule());
  std::wstring current_version = version_info->file_version();
#if !defined(GOOGLE_CHROME_BUILD)
  current_version += L" (";
  current_version += version_info->last_change();
  current_version += L")";
#endif

  // Build the dialog.
  GtkWidget* dialog = gtk_dialog_new_with_buttons(
      l10n_util::GetStringUTF8(IDS_ABOUT_CHROME_TITLE).c_str(),
      parent,
      GTK_DIALOG_MODAL,
      GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
      NULL);
  // Pick up the style set in gtk_util.cc:InitRCStyles().
  // The layout of this dialog is special because the logo should be flush
  // with the edges of the window.
  gtk_widget_set_name(dialog, "about-dialog");
  gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);

  GtkWidget* content_area = GTK_DIALOG(dialog)->vbox;

  // Use an event box to get the background painting correctly
  GtkWidget* ebox = gtk_event_box_new();
  gtk_widget_modify_bg(ebox, GTK_STATE_NORMAL, &gfx::kGdkWhite);

  GtkWidget* hbox = gtk_hbox_new(FALSE, 0);

  GtkWidget* text_alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
  gtk_alignment_set_padding(GTK_ALIGNMENT(text_alignment),
                            kPanelVertMargin, kPanelVertMargin,
                            kPanelHorizMargin, kPanelHorizMargin);

  GtkWidget* text_vbox = gtk_vbox_new(FALSE, kExtraLineSpacing);

  GtkWidget* product_label = MakeMarkupLabel(
      "%s",
      l10n_util::GetStringUTF8(IDS_PRODUCT_NAME));
  gtk_box_pack_start(GTK_BOX(text_vbox), product_label, FALSE, FALSE, 0);

  GtkWidget* version_label = gtk_label_new(WideToUTF8(current_version).c_str());
  gtk_misc_set_alignment(GTK_MISC(version_label), 0.0, 0.5);
  gtk_label_set_selectable(GTK_LABEL(version_label), TRUE);
  gtk_box_pack_start(GTK_BOX(text_vbox), version_label, FALSE, FALSE, 0);

  gtk_container_add(GTK_CONTAINER(text_alignment), text_vbox);
  gtk_box_pack_start(GTK_BOX(hbox), text_alignment, TRUE, TRUE, 0);

  GtkWidget* image_vbox = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_end(GTK_BOX(image_vbox),
                   gtk_image_new_from_pixbuf(background),
                   FALSE, FALSE, 0);

  gtk_box_pack_start(GTK_BOX(hbox), image_vbox, FALSE, FALSE, 0);
  gtk_container_add(GTK_CONTAINER(ebox), hbox);
  gtk_box_pack_start(GTK_BOX(content_area), ebox, TRUE, TRUE, 0);

  // We use a separate box for the licensing etc. text.  See the comment near
  // the top of this function about using a special layout for this dialog.
  GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
  gtk_container_set_border_width(GTK_CONTAINER(vbox),
                                 gtk_util::kContentAreaBorder);

  GtkWidget* copyright_label = MakeMarkupLabel(
      "%s",
      l10n_util::GetStringUTF8(IDS_ABOUT_VERSION_COPYRIGHT));
  gtk_box_pack_start(GTK_BOX(vbox), copyright_label, TRUE, TRUE, 5);

  std::string license = l10n_util::GetStringUTF8(IDS_ABOUT_VERSION_LICENSE);
  bool chromium_url_appears_first =
      license.find(kBeginLinkChr) < license.find(kBeginLinkOss);
  size_t link1 = license.find(kBeginLink);
  DCHECK(link1 != std::string::npos);
  size_t link1_end = license.find(kEndLink, link1);
  DCHECK(link1_end != std::string::npos);
  size_t link2 = license.find(kBeginLink, link1_end);
  DCHECK(link2 != std::string::npos);
  size_t link2_end = license.find(kEndLink, link2);
  DCHECK(link1_end != std::string::npos);

  GtkWidget* license_chunk1 = MakeMarkupLabel(
      "%s",
      license.substr(0, link1));
  GtkWidget* license_chunk2 = MakeMarkupLabel(
      "%s",
      license.substr(link1_end + strlen(kEndLinkOss),
                     link2 - link1_end - strlen(kEndLinkOss)));
  GtkWidget* license_chunk3 = MakeMarkupLabel(
      "%s",
      license.substr(link2_end + strlen(kEndLinkOss)));

  std::string first_link_text =
      std::string("") +
      license.substr(link1 + strlen(kBeginLinkOss),
                     link1_end - link1 - strlen(kBeginLinkOss)) +
      std::string("");
  std::string second_link_text =
      std::string("") +
      license.substr(link2 + strlen(kBeginLinkOss),
                     link2_end - link2 - strlen(kBeginLinkOss)) +
      std::string("");

  GtkWidget* first_link =
      gtk_chrome_link_button_new_with_markup(first_link_text.c_str());
  GtkWidget* second_link =
      gtk_chrome_link_button_new_with_markup(second_link_text.c_str());
  if (!chromium_url_appears_first) {
    GtkWidget* swap = second_link;
    second_link = first_link;
    first_link = swap;
  }

  g_signal_connect(chromium_url_appears_first ? first_link : second_link,
                   "clicked", G_CALLBACK(OnLinkButtonClick),
                   const_cast<char*>(GetChromiumUrl()));
  g_signal_connect(chromium_url_appears_first ? second_link : first_link,
                   "clicked", G_CALLBACK(OnLinkButtonClick),
                   const_cast<char*>(kAcknowledgements));

  GtkWidget* license_hbox = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_hbox), license_chunk1,
                     FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_hbox), first_link,
                     FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_hbox), license_chunk2,
                     FALSE, FALSE, 0);

  // Since there's no good way to dynamically wrap the license block, force
  // a line break right before the second link (which matches en-US Windows
  // chromium).
  GtkWidget* license_hbox2 = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_hbox2), second_link,
                     FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_hbox2), license_chunk3,
                     FALSE, FALSE, 0);

  GtkWidget* license_vbox = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_vbox), license_hbox, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_vbox), license_hbox2, FALSE, FALSE, 0);

  gtk_box_pack_start(GTK_BOX(vbox), license_vbox, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(content_area), vbox, TRUE, TRUE, 0);

  g_signal_connect(dialog, "response", G_CALLBACK(OnDialogResponse), NULL);
  gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
  gtk_widget_show_all(dialog);
}
<commit_msg>Make chrome version legible in about:chrome dialog for dark themes.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/about_chrome_dialog.h"

#include <gtk/gtk.h>

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/file_version_info.h"
#include "base/gfx/gtk_util.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/profile.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/gtk_util.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "grit/theme_resources.h"
#include "webkit/glue/webkit_glue.h"

namespace {

// The URLs that you navigate to when clicking the links in the About dialog.
const char* const kAcknowledgements = "about:credits";
const char* const kTOS = "about:terms";

// Left or right margin.
const int kPanelHorizMargin = 13;

// Top or bottom margin.
const int kPanelVertMargin = 20;

// Extra spacing between product name and version number.
const int kExtraLineSpacing = 5;

// These are used as placeholder text around the links in the text in the about
// dialog.
const char* kBeginLinkChr = "BEGIN_LINK_CHR";
const char* kBeginLinkOss = "BEGIN_LINK_OSS";
// We don't actually use this one.
// const char* kEndLinkChr = "END_LINK_CHR";
const char* kEndLinkOss = "END_LINK_OSS";
const char* kBeginLink = "BEGIN_LINK";
const char* kEndLink = "END_LINK";

const char* kSmaller = "%s";

void OnDialogResponse(GtkDialog* dialog, int response_id) {
  // We're done.
  gtk_widget_destroy(GTK_WIDGET(dialog));
}

void FixLabelWrappingCallback(GtkWidget *label,
                              GtkAllocation *allocation,
                              gpointer data) {
  gtk_widget_set_size_request(label, allocation->width, -1);
}

GtkWidget* MakeMarkupLabel(const char* format, const std::string& str) {
  GtkWidget* label = gtk_label_new(NULL);
  char* markup = g_markup_printf_escaped(format, str.c_str());
  gtk_label_set_markup(GTK_LABEL(label), markup);
  g_free(markup);

  // Left align it.
  gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);

  return label;
}

void OnLinkButtonClick(GtkWidget* button, const char* url) {
  BrowserList::GetLastActive()->
      OpenURL(GURL(url), GURL(), NEW_WINDOW, PageTransition::LINK);
}

const char* GetChromiumUrl() {
  static std::string url(l10n_util::GetStringUTF8(IDS_CHROMIUM_PROJECT_URL));
  return url.c_str();
}

std::string Smaller(const std::string& text) {
  return std::string("") + text + std::string("");
}

}  // namespace

void ShowAboutDialogForProfile(GtkWindow* parent, Profile* profile) {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  static GdkPixbuf* background = rb.GetPixbufNamed(IDR_ABOUT_BACKGROUND);
  scoped_ptr<FileVersionInfo> version_info(
      FileVersionInfo::CreateFileVersionInfoForCurrentModule());
  std::wstring current_version = version_info->file_version();
#if !defined(GOOGLE_CHROME_BUILD)
  current_version += L" (";
  current_version += version_info->last_change();
  current_version += L")";
#endif

  // Build the dialog.
  GtkWidget* dialog = gtk_dialog_new_with_buttons(
      l10n_util::GetStringUTF8(IDS_ABOUT_CHROME_TITLE).c_str(),
      parent,
      GTK_DIALOG_MODAL,
      GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
      NULL);
  // Pick up the style set in gtk_util.cc:InitRCStyles().
  // The layout of this dialog is special because the logo should be flush
  // with the edges of the window.
  gtk_widget_set_name(dialog, "about-dialog");
  gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);

  GtkWidget* content_area = GTK_DIALOG(dialog)->vbox;

  // Use an event box to get the background painting correctly
  GtkWidget* ebox = gtk_event_box_new();
  gtk_widget_modify_bg(ebox, GTK_STATE_NORMAL, &gfx::kGdkWhite);

  GtkWidget* hbox = gtk_hbox_new(FALSE, 0);

  GtkWidget* text_alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
  gtk_alignment_set_padding(GTK_ALIGNMENT(text_alignment),
                            kPanelVertMargin, kPanelVertMargin,
                            kPanelHorizMargin, kPanelHorizMargin);

  GtkWidget* text_vbox = gtk_vbox_new(FALSE, kExtraLineSpacing);

  GdkColor black = gfx::kGdkBlack;
  GtkWidget* product_label = MakeMarkupLabel(
      "%s",
      l10n_util::GetStringUTF8(IDS_PRODUCT_NAME));
  gtk_widget_modify_fg(product_label, GTK_STATE_NORMAL, &black);
  gtk_box_pack_start(GTK_BOX(text_vbox), product_label, FALSE, FALSE, 0);

  GtkWidget* version_label = gtk_label_new(WideToUTF8(current_version).c_str());
  gtk_misc_set_alignment(GTK_MISC(version_label), 0.0, 0.5);
  gtk_label_set_selectable(GTK_LABEL(version_label), TRUE);
  gtk_widget_modify_fg(version_label, GTK_STATE_NORMAL, &black);
  gtk_box_pack_start(GTK_BOX(text_vbox), version_label, FALSE, FALSE, 0);

  gtk_container_add(GTK_CONTAINER(text_alignment), text_vbox);
  gtk_box_pack_start(GTK_BOX(hbox), text_alignment, TRUE, TRUE, 0);

  GtkWidget* image_vbox = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_end(GTK_BOX(image_vbox),
                   gtk_image_new_from_pixbuf(background),
                   FALSE, FALSE, 0);

  gtk_box_pack_start(GTK_BOX(hbox), image_vbox, FALSE, FALSE, 0);
  gtk_container_add(GTK_CONTAINER(ebox), hbox);
  gtk_box_pack_start(GTK_BOX(content_area), ebox, TRUE, TRUE, 0);

  // We use a separate box for the licensing etc. text.  See the comment near
  // the top of this function about using a special layout for this dialog.
  GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
  gtk_container_set_border_width(GTK_CONTAINER(vbox),
                                 gtk_util::kContentAreaBorder);

  GtkWidget* copyright_label = MakeMarkupLabel(
      kSmaller, l10n_util::GetStringUTF8(IDS_ABOUT_VERSION_COPYRIGHT));
  gtk_box_pack_start(GTK_BOX(vbox), copyright_label, TRUE, TRUE, 5);

  std::string license = l10n_util::GetStringUTF8(IDS_ABOUT_VERSION_LICENSE);
  bool chromium_url_appears_first =
      license.find(kBeginLinkChr) < license.find(kBeginLinkOss);
  size_t link1 = license.find(kBeginLink);
  DCHECK(link1 != std::string::npos);
  size_t link1_end = license.find(kEndLink, link1);
  DCHECK(link1_end != std::string::npos);
  size_t link2 = license.find(kBeginLink, link1_end);
  DCHECK(link2 != std::string::npos);
  size_t link2_end = license.find(kEndLink, link2);
  DCHECK(link1_end != std::string::npos);

  GtkWidget* license_chunk1 = MakeMarkupLabel(
      kSmaller, license.substr(0, link1));
  GtkWidget* license_chunk2 = MakeMarkupLabel(
      kSmaller,
      license.substr(link1_end + strlen(kEndLinkOss),
                     link2 - link1_end - strlen(kEndLinkOss)));
  GtkWidget* license_chunk3 = MakeMarkupLabel(
      kSmaller, license.substr(link2_end + strlen(kEndLinkOss)));

  std::string first_link_text = Smaller(
      license.substr(link1 + strlen(kBeginLinkOss),
                     link1_end - link1 - strlen(kBeginLinkOss)));
  std::string second_link_text = Smaller(
      license.substr(link2 + strlen(kBeginLinkOss),
                     link2_end - link2 - strlen(kBeginLinkOss)));

  GtkWidget* first_link =
      gtk_chrome_link_button_new_with_markup(first_link_text.c_str());
  GtkWidget* second_link =
      gtk_chrome_link_button_new_with_markup(second_link_text.c_str());
  if (!chromium_url_appears_first) {
    GtkWidget* swap = second_link;
    second_link = first_link;
    first_link = swap;
  }

  g_signal_connect(chromium_url_appears_first ? first_link : second_link,
                   "clicked", G_CALLBACK(OnLinkButtonClick),
                   const_cast<char*>(GetChromiumUrl()));
  g_signal_connect(chromium_url_appears_first ? second_link : first_link,
                   "clicked", G_CALLBACK(OnLinkButtonClick),
                   const_cast<char*>(kAcknowledgements));

  GtkWidget* license_hbox = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_hbox), license_chunk1,
                     FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_hbox), first_link,
                     FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_hbox), license_chunk2,
                     FALSE, FALSE, 0);

  // Since there's no good way to dynamically wrap the license block, force
  // a line break right before the second link (which matches en-US Windows
  // chromium).
  GtkWidget* license_hbox2 = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_hbox2), second_link,
                     FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_hbox2), license_chunk3,
                     FALSE, FALSE, 0);

  GtkWidget* license_vbox = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_vbox), license_hbox, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(license_vbox), license_hbox2, FALSE, FALSE, 0);

#if defined(GOOGLE_CHROME_BUILD)
  std::vector<size_t> url_offsets;
  std::wstring text = l10n_util::GetStringF(IDS_ABOUT_TERMS_OF_SERVICE,
                                            std::wstring(),
                                            std::wstring(),
                                            &url_offsets);

  std::string tos_link_text = Smaller(
      l10n_util::GetStringUTF8(IDS_TERMS_OF_SERVICE));
  GtkWidget* tos_chunk1 = MakeMarkupLabel(
      kSmaller, WideToUTF8(text.substr(0, url_offsets[0])).c_str());
  GtkWidget* tos_link =
      gtk_chrome_link_button_new_with_markup(tos_link_text.c_str());
  GtkWidget* tos_chunk2 = MakeMarkupLabel(
      kSmaller, WideToUTF8(text.substr(url_offsets[0])).c_str());

  GtkWidget* tos_hbox = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(tos_hbox), tos_chunk1, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(tos_hbox), tos_link, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(tos_hbox), tos_chunk2, FALSE, FALSE, 0);

  g_signal_connect(tos_link, "clicked", G_CALLBACK(OnLinkButtonClick),
                   const_cast<char*>(kTOS));
#endif

  gtk_box_pack_start(GTK_BOX(vbox), license_vbox, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(vbox), tos_hbox, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(content_area), vbox, TRUE, TRUE, 0);

  g_signal_connect(dialog, "response", G_CALLBACK(OnDialogResponse), NULL);
  gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
  gtk_widget_show_all(dialog);
}
<|endoftext|>


<commit_before>// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"
#if defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) ||                        \
    defined(HOST_OS_ANDROID) || defined(HOST_OS_FUCHSIA)

#include "bin/console.h"

#include <errno.h>
#include <sys/ioctl.h>
#include <termios.h>

#include "bin/fdutils.h"
#include "platform/signal_blocker.h"

namespace dart {
namespace bin {

class PosixConsole {
 public:
  static const tcflag_t kInvalidFlag = -1;

  static void Initialize() {
    SaveMode(STDOUT_FILENO, &stdout_initial_c_lflag_);
    SaveMode(STDERR_FILENO, &stderr_initial_c_lflag_);
    SaveMode(STDIN_FILENO, &stdin_initial_c_lflag_);
  }

  static void Cleanup() {
    RestoreMode(STDOUT_FILENO, stdout_initial_c_lflag_);
    RestoreMode(STDERR_FILENO, stderr_initial_c_lflag_);
    RestoreMode(STDIN_FILENO, stdin_initial_c_lflag_);
    ClearLFlags();
  }

 private:
  static tcflag_t stdout_initial_c_lflag_;
  static tcflag_t stderr_initial_c_lflag_;
  static tcflag_t stdin_initial_c_lflag_;

  static void ClearLFlags() {
    stdout_initial_c_lflag_ = kInvalidFlag;
    stderr_initial_c_lflag_ = kInvalidFlag;
    stdin_initial_c_lflag_ = kInvalidFlag;
  }

  static void SaveMode(intptr_t fd, tcflag_t* flag) {
    ASSERT(flag != NULL);
    struct termios term;
    int status = NO_RETRY_EXPECTED(tcgetattr(fd, &term));
    if (status != 0) {
      return;
    }
    *flag = term.c_lflag;
  }

  static void RestoreMode(intptr_t fd, tcflag_t flag) {
    if (flag == kInvalidFlag) {
      return;
    }
    struct termios term;
    int status = NO_RETRY_EXPECTED(tcgetattr(fd, &term));
    if (status != 0) {
      return;
    }
    term.c_lflag = flag;
    NO_RETRY_EXPECTED(tcsetattr(fd, TCSANOW, &term));
  }

  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(PosixConsole);
};

tcflag_t PosixConsole::stdout_initial_c_lflag_ = PosixConsole::kInvalidFlag;
tcflag_t PosixConsole::stderr_initial_c_lflag_ = PosixConsole::kInvalidFlag;
tcflag_t PosixConsole::stdin_initial_c_lflag_ = PosixConsole::kInvalidFlag;

void Console::SaveConfig() {
  PosixConsole::Initialize();
}

void Console::RestoreConfig() {
  PosixConsole::Cleanup();
}

}  // namespace bin
}  // namespace dart

#endif  // defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) ||                 \
        // defined(HOST_OS_ANDROID) || defined(HOST_OS_FUCHSIA)
<commit_msg>[ VM / Flutter ] Replaced NO_RETRY_EXPECTED with VOID_TEMP_FAILURE_RETRY in console_posix.cc:69.<commit_after>// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"
#if defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) ||                        \
    defined(HOST_OS_ANDROID) || defined(HOST_OS_FUCHSIA)

#include "bin/console.h"

#include <errno.h>
#include <sys/ioctl.h>
#include <termios.h>

#include "bin/fdutils.h"
#include "platform/signal_blocker.h"

namespace dart {
namespace bin {

class PosixConsole {
 public:
  static const tcflag_t kInvalidFlag = -1;

  static void Initialize() {
    SaveMode(STDOUT_FILENO, &stdout_initial_c_lflag_);
    SaveMode(STDERR_FILENO, &stderr_initial_c_lflag_);
    SaveMode(STDIN_FILENO, &stdin_initial_c_lflag_);
  }

  static void Cleanup() {
    RestoreMode(STDOUT_FILENO, stdout_initial_c_lflag_);
    RestoreMode(STDERR_FILENO, stderr_initial_c_lflag_);
    RestoreMode(STDIN_FILENO, stdin_initial_c_lflag_);
    ClearLFlags();
  }

 private:
  static tcflag_t stdout_initial_c_lflag_;
  static tcflag_t stderr_initial_c_lflag_;
  static tcflag_t stdin_initial_c_lflag_;

  static void ClearLFlags() {
    stdout_initial_c_lflag_ = kInvalidFlag;
    stderr_initial_c_lflag_ = kInvalidFlag;
    stdin_initial_c_lflag_ = kInvalidFlag;
  }

  static void SaveMode(intptr_t fd, tcflag_t* flag) {
    ASSERT(flag != NULL);
    struct termios term;
    int status = TEMP_FAILURE_RETRY(tcgetattr(fd, &term));
    if (status != 0) {
      return;
    }
    *flag = term.c_lflag;
  }

  static void RestoreMode(intptr_t fd, tcflag_t flag) {
    if (flag == kInvalidFlag) {
      return;
    }
    struct termios term;
    int status = TEMP_FAILURE_RETRY(tcgetattr(fd, &term));
    if (status != 0) {
      return;
    }
    term.c_lflag = flag;
    VOID_TEMP_FAILURE_RETRY(tcsetattr(fd, TCSANOW, &term));
  }

  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(PosixConsole);
};

tcflag_t PosixConsole::stdout_initial_c_lflag_ = PosixConsole::kInvalidFlag;
tcflag_t PosixConsole::stderr_initial_c_lflag_ = PosixConsole::kInvalidFlag;
tcflag_t PosixConsole::stdin_initial_c_lflag_ = PosixConsole::kInvalidFlag;

void Console::SaveConfig() {
  PosixConsole::Initialize();
}

void Console::RestoreConfig() {
  PosixConsole::Cleanup();
}

}  // namespace bin
}  // namespace dart

#endif  // defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) ||                 \
        // defined(HOST_OS_ANDROID) || defined(HOST_OS_FUCHSIA)
<|endoftext|>


<commit_before>#include <sirius.h>

using namespace sirius;

void test_unit_cell()
{
    Simulation_context ctx("sirius.json", mpi_comm_world());
    ctx.unit_cell().initialize();

    vector3d<int> k_grid(2, 2, 1);
    vector3d<int> k_shift(1, 1, 0);

    mdarray<double, 2> kp;
    std::vector<double> wk;
    int nk = ctx.unit_cell().symmetry()->get_irreducible_reciprocal_mesh(k_grid, k_shift, kp, wk);

    printf("number of k-points: %i\n", nk);
    for (int ik = 0; ik < nk; ik++)
    {
        printf("kp: %f %f %f\n", kp(0, ik), kp(1, ik), kp(2, ik));
    }
}

int main(int argn, char** argv)
{
    cmd_args args;

    args.parse_args(argn, argv);
    if (args.exist("help"))
    {
        printf("Usage: %s [options]\n", argv[0]);
        args.print_help();
        return 0;
    }

    sirius::initialize(1);
    test_unit_cell();
    sirius::finalize();
}
<commit_msg>update test<commit_after>#include <sirius.h>

using namespace sirius;

void test1()
{
    Simulation_context ctx(mpi_comm_world(), "pseudopotential");
    ctx.set_processing_unit("cpu");

    int N = 7;
    double a{4};
    ctx.unit_cell().set_lattice_vectors({{N*a,0,0}, {0,N*a,0}, {0,0,N*a}});

    ctx.unit_cell().add_atom_type("A");

    auto& atype = ctx.unit_cell().atom_type(0);

    ctx.unit_cell().atom_type(0).zn(1);
    ctx.unit_cell().atom_type(0).set_radial_grid(radial_grid_t::lin_exp_grid, 1000, 0, 2);

    std::vector<double> beta(ctx.unit_cell().atom_type(0).num_mt_points());
    for (int i = 0; i < atype.num_mt_points(); i++) {
        double x = atype.radial_grid(i);
        beta[i] = std::exp(-x) * (4 - x * x);
    }
    ctx.unit_cell().atom_type(0).add_beta_radial_function(0, beta);
    ctx.unit_cell().atom_type(0).add_beta_radial_function(1, beta);
    ctx.unit_cell().atom_type(0).add_beta_radial_function(2, beta);

    for (int i1 = 0; i1 < N; i1++) {
        for (int i2 = 0; i2 < N; i2++) {
            for (int i3 = 0; i3 < N; i3++) {
                ctx.unit_cell().add_atom("A", {1.0 * i1 / N, 1.0 * i2 / N, 1.0 * i3 / N});
            }
        }
    }

    ctx.initialize();

    ctx.print_info();

    double vk[] = {0, 0, 0};
    K_point kp(ctx, vk, 1.0);

    kp.initialize();

    printf("num_gkvec: %i\n", kp.num_gkvec());

    auto& bp_chunks = ctx.beta_projector_chunks();

    for (int k = 0; k < 10; k++) {
        kp.beta_projectors().prepare();
        for (int ichunk = 0; ichunk < bp_chunks.num_chunks(); ichunk++) {
            kp.beta_projectors().generate(ichunk);
        }
        kp.beta_projectors().dismiss();
    }
}

int main(int argn, char** argv)
{
    cmd_args args;

    args.parse_args(argn, argv);
    if (args.exist("help")) {
        printf("Usage: %s [options]\n", argv[0]);
        args.print_help();
        return 0;
    }

    sirius::initialize();

    test1();

    if (mpi_comm_world().rank() == 0) {
        sddk::timer::print();
    }

    sirius::finalize();
}
<|endoftext|>


<commit_before>/*****************************************************************************/
/**
 *  @file   ScreenBase.cpp
 *  @author Naohisa Sakamoto
 */
/*****************************************************************************/
#include "ScreenBase.h"
#include "Application.h"
#include "KVSMouseButton.h"
#include "KVSKey.h"
#include <kvs/Message>
#include <kvs/TimerEventListener>

namespace
{

/*===========================================================================*/
/**
 *  @brief  Returns pointer to the screen.
 *  @param  handler [in] the window handler
 *  @return pointer to the screen
 */
/*===========================================================================*/
kvs::glfw::ScreenBase* ThisScreen( GLFWwindow* handler )
{
    return static_cast<kvs::glfw::ScreenBase*>( glfwGetWindowUserPointer( handler ) );
}

}

namespace kvs
{

namespace glfw
{

/*===========================================================================*/
/**
 *  @brief  Returns the pointer to the glfw screen base downcasted from the screen base.
 *  @param  screen [in] the screen base.
 *  @return pointer to the glfw screen base
 */
/*===========================================================================*/
ScreenBase* ScreenBase::DownCast( kvs::ScreenBase* screen )
{
    return dynamic_cast<ScreenBase*>( screen );
}

/*===========================================================================*/
/**
 *  @brief  Returns the const pointer to the glfw screen base downcasted from the screen base.
 *  @param  screen [in] the screen base.
 *  @return const pointer to the glfw screen base
 */
/*===========================================================================*/
const ScreenBase* ScreenBase::DownCast( const kvs::ScreenBase* screen )
{
    return dynamic_cast<ScreenBase*>( const_cast<kvs::ScreenBase*>( screen ) );
}

/*===========================================================================*/
/**
 *  @brief  Callback function, which is called when the window is resized.
 *  @param  handler [in] the window handler
 *  @param  width [in] the window width
 *  @param  height [in] the window height
 */
/*===========================================================================*/
void WindowSizeCallback( GLFWwindow* handler, int width, int height )
{
    auto* this_screen = ::ThisScreen( handler );
    this_screen->aquireContext();

    const auto vp = kvs::OpenGL::Viewport();
    this_screen->resizeEvent( width, height );
    if ( this_screen->width() != ( vp[2] - vp[0] ) ) // device_pixel_ratio != 1.0
    {
        kvs::OpenGL::SetViewport( vp );
    }

    this_screen->releaseContext();
    this_screen->redraw();
}

/*===========================================================================*/
/**
 *  @brief  Callback function, which is called when a mouse button is pressed or released.
 *  @param  handler [in] the window handler
 *  @param  button [in] the mouse button
 *  @param  action [in] the action (GLFW_PRESS or GLFW_RELEASE)
 *  @param  mods [in] the modifier keys
 */
/*===========================================================================*/
void MouseButtonCallback( GLFWwindow* handler, int button, int action, int mods )
{
    auto* this_screen = ::ThisScreen( handler );
    this_screen->aquireContext();

    double x = 0.0;
    double y = 0.0;
    glfwGetCursorPos( handler, &x, &y );

    this_screen->m_mouse_event->setPosition( int( x ), int( y ) );
    this_screen->m_mouse_event->setButton( kvs::glfw::KVSMouseButton::Button( button ) );
    this_screen->m_mouse_event->setState( kvs::glfw::KVSMouseButton::State( action ) );
    this_screen->m_mouse_event->setModifiers( kvs::glfw::KVSKey::Modifier( mods ) );

    switch ( action )
    {
    case GLFW_PRESS:
    {
        this_screen->m_elapse_time_counter.stop();
        if ( this_screen->m_elapse_time_counter.sec() < 0.2f )
        {
            this_screen->m_mouse_event->setAction( kvs::MouseButton::DoubleClicked );
            this_screen->mouseDoubleClickEvent( this_screen->m_mouse_event );
        }
        else
        {
            this_screen->m_mouse_event->setAction( kvs::MouseButton::Pressed );
            this_screen->mousePressEvent( this_screen->m_mouse_event );
        }
        this_screen->m_elapse_time_counter.start();
        break;
    }
    case GLFW_RELEASE:
    {
        this_screen->m_mouse_event->setAction( kvs::MouseButton::Released );
        this_screen->mouseReleaseEvent( this_screen->m_mouse_event );
        break;
    }
    default: break;
    }

    this_screen->releaseContext();
}

/*===========================================================================*/
/**
 *  @brief  Callback function, which is called when the cursor is moved.
 *  @param  handler [in] the window handler
 *  @param  x [in] the x-coordinate of the cursor
 *  @param  y [in] the y-coordinate of the cursor
 */
/*===========================================================================*/
void CursorPosCallback( GLFWwindow* handler, double x, double y )
{
    auto* this_screen = ::ThisScreen( handler );
    this_screen->aquireContext();

    if ( this_screen->m_mouse_event->state() == kvs::MouseButton::Down )
    {
        this_screen->m_mouse_event->setPosition( x, y );
        this_screen->m_mouse_event->setAction( kvs::MouseButton::Moved );
        this_screen->mouseMoveEvent( this_screen->m_mouse_event );
    }

    this_screen->releaseContext();
}

/*===========================================================================*/
/**
 *  @brief  Callback function, which is called when the scrolling device is used.
 *  @param  handler [in] the window handler
 *  @param  x [in] the scroll offset along the x-axis
 *  @param  y [in] the scroll offset along the y-axis
 */
/*===========================================================================*/
void ScrollCallback( GLFWwindow* handler, double x, double y )
{
    auto* this_screen = ::ThisScreen( handler );
    this_screen->aquireContext();

    this_screen->m_wheel_event->setPosition( x, y );
    this_screen->m_wheel_event->setDirection( y > 0.0 ? 1 : -1 );
    this_screen->wheelEvent( this_screen->m_wheel_event );

    this_screen->releaseContext();
}

/*===========================================================================*/
/**
 *  @brief  Callback function, which is called when a key is pressed, repeated or released.
 *  @param  handler [in] the window handler
 *  @param  key [in] the key that was pressed or released
 *  @param  scancode [in] the system-specific scancode of the key
 *  @param  action [in] the action (GLFW_PRESS, GLFW_RELEASE or GLFW_REPEAT)
 *  @param  mods [in] the modifier keys
 */
/*===========================================================================*/
void KeyCallback( GLFWwindow* handler, int key, int scancode, int action, int mods )
{
    auto* this_screen = ::ThisScreen( handler );
    this_screen->aquireContext();

    double x = 0.0;
    double y = 0.0;
    glfwGetCursorPos( handler, &x, &y );

    this_screen->m_key_event->setPosition( int( x ), int( y ) );
    this_screen->m_key_event->setModifiers( kvs::glfw::KVSKey::Modifier( mods ) );
    this_screen->m_key_event->setKey( kvs::glfw::KVSKey::Code( key, mods ) );
    switch ( action )
    {
    case GLFW_PRESS:
        this_screen->keyPressEvent( this_screen->m_key_event );
        break;
    default:
        break;
    }

    this_screen->releaseContext();
}

/*===========================================================================*/
/**
 *  @brief  Constructs a ScreenBase class.
 *  @param  application [in] the application
 */
/*===========================================================================*/
ScreenBase::ScreenBase( kvs::glfw::Application* application ):
    m_handler( 0 ),
    m_id( -1 ),
    m_mouse_event( 0 ),
    m_key_event( 0 ),
    m_wheel_event( 0 ),
    m_is_fullscreen( false )
{
    if ( application ) application->attach( this );

    m_mouse_event = new kvs::MouseEvent();
    m_key_event = new kvs::KeyEvent();
    m_wheel_event = new kvs::WheelEvent();

    m_elapse_time_counter.start();
}

/*===========================================================================*/
/**
 *  @brief  Destroys the ScreenBase class.
 */
/*===========================================================================*/
ScreenBase::~ScreenBase()
{
    if ( m_mouse_event ) { delete m_mouse_event; }
    if ( m_key_event ) { delete m_key_event; }
    if ( m_wheel_event ) { delete m_wheel_event; }
    if ( m_handler ) { glfwDestroyWindow( m_handler ); }
}

/*===========================================================================*/
/**
 *  @brief  Creates a screen.
 */
/*===========================================================================*/
void ScreenBase::create()
{
    KVS_ASSERT( m_id == -1 );

    // Create window.
    m_handler = glfwCreateWindow(
        BaseClass::width(),
        BaseClass::height(),
        BaseClass::title().c_str(),
        NULL, NULL );
    if ( !m_handler )
    {
        kvsMessageError() << "Cannot create GLFW screen." << std::endl;
        return;
    }

    glfwMakeContextCurrent( m_handler );
    glfwSwapInterval(1);

    // Set callback functions.
    glfwSetWindowUserPointer( m_handler, this );
    glfwSetWindowSizeCallback( m_handler, WindowSizeCallback );
    glfwSetMouseButtonCallback( m_handler, MouseButtonCallback );
    glfwSetCursorPosCallback( m_handler, CursorPosCallback );
    glfwSetScrollCallback( m_handler, ScrollCallback );
    glfwSetKeyCallback( m_handler, KeyCallback );

    // Initialize GLEW. (Before glfwMakeContextCurrent)
#if defined( KVS_ENABLE_GLEW )
    GLenum result = glewInit();
    if ( result != GLEW_OK )
    {
        const std::string error( glewGetErrorString( result ) );
        kvsMessageError() << "GLEW initialization failed: " << error << "." << std::endl;
    }
#endif

    // Create paint device.
    BaseClass::paintDevice()->create();

    // Generate window ID.
    static int counter = 0;
    m_id = counter++;

    glfwMakeContextCurrent( NULL );
}

/*===========================================================================*/
/**
 *  @brief  Shows the screen.
 */
/*===========================================================================*/
void ScreenBase::show()
{
#if 1 // KVS_ENABLE_DEPRECATED
    if ( m_id == -1 ) { this->create(); }
#endif
    glfwShowWindow( m_handler );
}

/*===========================================================================*/
/**
 *  @brief  Hides the screen.
 */
/*===========================================================================*/
void ScreenBase::hide()
{
    glfwHideWindow( m_handler );
}

/*===========================================================================*/
/**
 *  @brief  Shows the screen as fullscreen size.
 */
/*===========================================================================*/
void ScreenBase::showFullScreen()
{
    if ( m_is_fullscreen ) return;
    m_is_fullscreen = true;

    int x = 0, y = 0;
    glfwGetWindowPos( m_handler, &x, &y );
    BaseClass::setPosition( x, y );

    auto* monitor = glfwGetPrimaryMonitor();
    const auto* mode = glfwGetVideoMode( monitor );
    glfwSetWindowMonitor( m_handler, monitor, 0, 0, mode->width, mode->height, 0 );
}

/*===========================================================================*/
/**
 *  @brief  Shows the screen as normal size.
 */
/*===========================================================================*/
void ScreenBase::showNormal()
{
    if ( !m_is_fullscreen ) return;
    m_is_fullscreen = false;

    const int x = BaseClass::x();
    const int y = BaseClass::y();
    const int w = BaseClass::width();
    const int h = BaseClass::height();
    glfwSetWindowMonitor( m_handler, nullptr, x, y, w, h, 0 );
}

/*===========================================================================*/
/**
 *  @brief  Pop up the screen.
 */
/*===========================================================================*/
void ScreenBase::popUp()
{
    glfwFocusWindow( m_handler );
}

/*===========================================================================*/
/**
 *  @brief  Push down the screen. (not yet implemented)
 */
/*===========================================================================*/
void ScreenBase::pushDown()
{
    // To-Do
}

/*===========================================================================*/
/**
 *  @brief  Redraw the screen.
 */
/*===========================================================================*/
void ScreenBase::redraw()
{
    this->aquireContext();
    this->paintEvent();
    this->releaseContext();
}

/*===========================================================================*/
/**
 *  @brief  Resize the screen.
 *  @param  width [in] the window width
 *  @param  height [in] the window height
 */
/*===========================================================================*/
void ScreenBase::resize( int width, int height )
{
    glfwSetWindowSize( m_handler, width, height );
}

/*===========================================================================*/
/**
 *  @brief  Returns true if the screen is shown as fullscreen size.
 *  @return true if the screen is fullscreen.
 */
/*===========================================================================*/
bool ScreenBase::isFullScreen() const
{
    return m_is_fullscreen;
}

void ScreenBase::enable() {}
void ScreenBase::disable() {}
void ScreenBase::reset() {}

void ScreenBase::initializeEvent(){}
void ScreenBase::paintEvent(){}
void ScreenBase::resizeEvent( int, int ){}
void ScreenBase::mousePressEvent( kvs::MouseEvent* ){}
void ScreenBase::mouseMoveEvent( kvs::MouseEvent* ){}
void ScreenBase::mouseReleaseEvent( kvs::MouseEvent* ){}
void ScreenBase::mouseDoubleClickEvent( kvs::MouseEvent* ){}
void ScreenBase::wheelEvent( kvs::WheelEvent* ){}
void ScreenBase::keyPressEvent( kvs::KeyEvent* ){}

std::list<kvs::glfw::Timer*>& ScreenBase::timerEventHandler()
{
    return m_timer_event_handler;
}

void ScreenBase::addTimerEvent( kvs::TimerEventListener* event, kvs::glfw::Timer* timer )
{
    event->setScreen( this );
    timer->setEventListener( event );
    m_timer_event_handler.push_back( timer );
}

} // end of namespace glfw

} // end of namespace kvs
<commit_msg>Update ScreenBase.cpp<commit_after>/*****************************************************************************/
/**
 *  @file   ScreenBase.cpp
 *  @author Naohisa Sakamoto
 */
/*****************************************************************************/
#include "ScreenBase.h"
#include "Application.h"
#include "KVSMouseButton.h"
#include "KVSKey.h"
#include <kvs/Message>
#include <kvs/TimerEventListener>

namespace
{

/*===========================================================================*/
/**
 *  @brief  Returns pointer to the screen.
 *  @param  handler [in] the window handler
 *  @return pointer to the screen
 */
/*===========================================================================*/
kvs::glfw::ScreenBase* ThisScreen( GLFWwindow* handler )
{
    return static_cast<kvs::glfw::ScreenBase*>( glfwGetWindowUserPointer( handler ) );
}

}

namespace kvs
{

namespace glfw
{

/*===========================================================================*/
/**
 *  @brief  Returns the pointer to the glfw screen base downcasted from the screen base.
 *  @param  screen [in] the screen base.
 *  @return pointer to the glfw screen base
 */
/*===========================================================================*/
ScreenBase* ScreenBase::DownCast( kvs::ScreenBase* screen )
{
    return dynamic_cast<ScreenBase*>( screen );
}

/*===========================================================================*/
/**
 *  @brief  Returns the const pointer to the glfw screen base downcasted from the screen base.
 *  @param  screen [in] the screen base.
 *  @return const pointer to the glfw screen base
 */
/*===========================================================================*/
const ScreenBase* ScreenBase::DownCast( const kvs::ScreenBase* screen )
{
    return dynamic_cast<ScreenBase*>( const_cast<kvs::ScreenBase*>( screen ) );
}

/*===========================================================================*/
/**
 *  @brief  Callback function, which is called when the window is resized.
 *  @param  handler [in] the window handler
 *  @param  width [in] the window width
 *  @param  height [in] the window height
 */
/*===========================================================================*/
void WindowSizeCallback( GLFWwindow* handler, int width, int height )
{
    auto* this_screen = ::ThisScreen( handler );
    this_screen->aquireContext();
    this_screen->resizeEvent( width, height );
    this_screen->releaseContext();
    this_screen->redraw();
}

/*===========================================================================*/
/**
 *  @brief  Callback function, which is called when a mouse button is pressed or released.
 *  @param  handler [in] the window handler
 *  @param  button [in] the mouse button
 *  @param  action [in] the action (GLFW_PRESS or GLFW_RELEASE)
 *  @param  mods [in] the modifier keys
 */
/*===========================================================================*/
void MouseButtonCallback( GLFWwindow* handler, int button, int action, int mods )
{
    auto* this_screen = ::ThisScreen( handler );
    this_screen->aquireContext();

    double x = 0.0;
    double y = 0.0;
    glfwGetCursorPos( handler, &x, &y );

    this_screen->m_mouse_event->setPosition( int( x ), int( y ) );
    this_screen->m_mouse_event->setButton( kvs::glfw::KVSMouseButton::Button( button ) );
    this_screen->m_mouse_event->setState( kvs::glfw::KVSMouseButton::State( action ) );
    this_screen->m_mouse_event->setModifiers( kvs::glfw::KVSKey::Modifier( mods ) );

    switch ( action )
    {
    case GLFW_PRESS:
    {
        this_screen->m_elapse_time_counter.stop();
        if ( this_screen->m_elapse_time_counter.sec() < 0.2f )
        {
            this_screen->m_mouse_event->setAction( kvs::MouseButton::DoubleClicked );
            this_screen->mouseDoubleClickEvent( this_screen->m_mouse_event );
        }
        else
        {
            this_screen->m_mouse_event->setAction( kvs::MouseButton::Pressed );
            this_screen->mousePressEvent( this_screen->m_mouse_event );
        }
        this_screen->m_elapse_time_counter.start();
        break;
    }
    case GLFW_RELEASE:
    {
        this_screen->m_mouse_event->setAction( kvs::MouseButton::Released );
        this_screen->mouseReleaseEvent( this_screen->m_mouse_event );
        break;
    }
    default: break;
    }

    this_screen->releaseContext();
}

/*===========================================================================*/
/**
 *  @brief  Callback function, which is called when the cursor is moved.
 *  @param  handler [in] the window handler
 *  @param  x [in] the x-coordinate of the cursor
 *  @param  y [in] the y-coordinate of the cursor
 */
/*===========================================================================*/
void CursorPosCallback( GLFWwindow* handler, double x, double y )
{
    auto* this_screen = ::ThisScreen( handler );
    this_screen->aquireContext();

    if ( this_screen->m_mouse_event->state() == kvs::MouseButton::Down )
    {
        this_screen->m_mouse_event->setPosition( x, y );
        this_screen->m_mouse_event->setAction( kvs::MouseButton::Moved );
        this_screen->mouseMoveEvent( this_screen->m_mouse_event );
    }

    this_screen->releaseContext();
}

/*===========================================================================*/
/**
 *  @brief  Callback function, which is called when the scrolling device is used.
 *  @param  handler [in] the window handler
 *  @param  x [in] the scroll offset along the x-axis
 *  @param  y [in] the scroll offset along the y-axis
 */
/*===========================================================================*/
void ScrollCallback( GLFWwindow* handler, double x, double y )
{
    auto* this_screen = ::ThisScreen( handler );
    this_screen->aquireContext();

    this_screen->m_wheel_event->setPosition( x, y );
    this_screen->m_wheel_event->setDirection( y > 0.0 ? 1 : -1 );
    this_screen->wheelEvent( this_screen->m_wheel_event );

    this_screen->releaseContext();
}

/*===========================================================================*/
/**
 *  @brief  Callback function, which is called when a key is pressed, repeated or released.
 *  @param  handler [in] the window handler
 *  @param  key [in] the key that was pressed or released
 *  @param  scancode [in] the system-specific scancode of the key
 *  @param  action [in] the action (GLFW_PRESS, GLFW_RELEASE or GLFW_REPEAT)
 *  @param  mods [in] the modifier keys
 */
/*===========================================================================*/
void KeyCallback( GLFWwindow* handler, int key, int scancode, int action, int mods )
{
    auto* this_screen = ::ThisScreen( handler );
    this_screen->aquireContext();

    double x = 0.0;
    double y = 0.0;
    glfwGetCursorPos( handler, &x, &y );

    this_screen->m_key_event->setPosition( int( x ), int( y ) );
    this_screen->m_key_event->setModifiers( kvs::glfw::KVSKey::Modifier( mods ) );
    this_screen->m_key_event->setKey( kvs::glfw::KVSKey::Code( key, mods ) );
    switch ( action )
    {
    case GLFW_PRESS:
        this_screen->keyPressEvent( this_screen->m_key_event );
        break;
    default:
        break;
    }

    this_screen->releaseContext();
}

/*===========================================================================*/
/**
 *  @brief  Constructs a ScreenBase class.
 *  @param  application [in] the application
 */
/*===========================================================================*/
ScreenBase::ScreenBase( kvs::glfw::Application* application ):
    m_handler( 0 ),
    m_id( -1 ),
    m_mouse_event( 0 ),
    m_key_event( 0 ),
    m_wheel_event( 0 ),
    m_is_fullscreen( false )
{
    if ( application ) application->attach( this );

    m_mouse_event = new kvs::MouseEvent();
    m_key_event = new kvs::KeyEvent();
    m_wheel_event = new kvs::WheelEvent();

    m_elapse_time_counter.start();
}

/*===========================================================================*/
/**
 *  @brief  Destroys the ScreenBase class.
 */
/*===========================================================================*/
ScreenBase::~ScreenBase()
{
    if ( m_mouse_event ) { delete m_mouse_event; }
    if ( m_key_event ) { delete m_key_event; }
    if ( m_wheel_event ) { delete m_wheel_event; }
    if ( m_handler ) { glfwDestroyWindow( m_handler ); }
}

/*===========================================================================*/
/**
 *  @brief  Creates a screen.
 */
/*===========================================================================*/
void ScreenBase::create()
{
    KVS_ASSERT( m_id == -1 );

    // Create window.
    m_handler = glfwCreateWindow(
        BaseClass::width(),
        BaseClass::height(),
        BaseClass::title().c_str(),
        NULL, NULL );
    if ( !m_handler )
    {
        kvsMessageError() << "Cannot create GLFW screen." << std::endl;
        return;
    }

    glfwMakeContextCurrent( m_handler );
    glfwSwapInterval(1);

    // Set callback functions.
    glfwSetWindowUserPointer( m_handler, this );
    glfwSetWindowSizeCallback( m_handler, WindowSizeCallback );
    glfwSetMouseButtonCallback( m_handler, MouseButtonCallback );
    glfwSetCursorPosCallback( m_handler, CursorPosCallback );
    glfwSetScrollCallback( m_handler, ScrollCallback );
    glfwSetKeyCallback( m_handler, KeyCallback );

    // Initialize GLEW. (Before glfwMakeContextCurrent)
#if defined( KVS_ENABLE_GLEW )
    GLenum result = glewInit();
    if ( result != GLEW_OK )
    {
        const std::string error( glewGetErrorString( result ) );
        kvsMessageError() << "GLEW initialization failed: " << error << "." << std::endl;
    }
#endif

    // Create paint device.
    BaseClass::paintDevice()->create();

    // Set device pixel ratio.
    const kvs::Vec4 vp = kvs::OpenGL::Viewport();
    BaseClass::setDevicePixelRatio( vp[2] / BaseClass::width() );

    // Generate window ID.
    static int counter = 0;
    m_id = counter++;

    glfwMakeContextCurrent( NULL );
}

/*===========================================================================*/
/**
 *  @brief  Shows the screen.
 */
/*===========================================================================*/
void ScreenBase::show()
{
#if 1 // KVS_ENABLE_DEPRECATED
    if ( m_id == -1 ) { this->create(); }
#endif
    glfwShowWindow( m_handler );
}

/*===========================================================================*/
/**
 *  @brief  Hides the screen.
 */
/*===========================================================================*/
void ScreenBase::hide()
{
    glfwHideWindow( m_handler );
}

/*===========================================================================*/
/**
 *  @brief  Shows the screen as fullscreen size.
 */
/*===========================================================================*/
void ScreenBase::showFullScreen()
{
    if ( m_is_fullscreen ) return;
    m_is_fullscreen = true;

    int x = 0, y = 0;
    glfwGetWindowPos( m_handler, &x, &y );
    BaseClass::setPosition( x, y );

    auto* monitor = glfwGetPrimaryMonitor();
    const auto* mode = glfwGetVideoMode( monitor );
    glfwSetWindowMonitor( m_handler, monitor, 0, 0, mode->width, mode->height, 0 );
}

/*===========================================================================*/
/**
 *  @brief  Shows the screen as normal size.
 */
/*===========================================================================*/
void ScreenBase::showNormal()
{
    if ( !m_is_fullscreen ) return;
    m_is_fullscreen = false;

    const int x = BaseClass::x();
    const int y = BaseClass::y();
    const int w = BaseClass::width();
    const int h = BaseClass::height();
    glfwSetWindowMonitor( m_handler, nullptr, x, y, w, h, 0 );
}

/*===========================================================================*/
/**
 *  @brief  Pop up the screen.
 */
/*===========================================================================*/
void ScreenBase::popUp()
{
    glfwFocusWindow( m_handler );
}

/*===========================================================================*/
/**
 *  @brief  Push down the screen. (not yet implemented)
 */
/*===========================================================================*/
void ScreenBase::pushDown()
{
    // To-Do
}

/*===========================================================================*/
/**
 *  @brief  Redraw the screen.
 */
/*===========================================================================*/
void ScreenBase::redraw()
{
    this->aquireContext();
    this->paintEvent();
    this->releaseContext();
}

/*===========================================================================*/
/**
 *  @brief  Resize the screen.
 *  @param  width [in] the window width
 *  @param  height [in] the window height
 */
/*===========================================================================*/
void ScreenBase::resize( int width, int height )
{
    glfwSetWindowSize( m_handler, width, height );
}

/*===========================================================================*/
/**
 *  @brief  Returns true if the screen is shown as fullscreen size.
 *  @return true if the screen is fullscreen.
 */
/*===========================================================================*/
bool ScreenBase::isFullScreen() const
{
    return m_is_fullscreen;
}

void ScreenBase::enable() {}
void ScreenBase::disable() {}
void ScreenBase::reset() {}

void ScreenBase::initializeEvent(){}
void ScreenBase::paintEvent(){}
void ScreenBase::resizeEvent( int, int ){}
void ScreenBase::mousePressEvent( kvs::MouseEvent* ){}
void ScreenBase::mouseMoveEvent( kvs::MouseEvent* ){}
void ScreenBase::mouseReleaseEvent( kvs::MouseEvent* ){}
void ScreenBase::mouseDoubleClickEvent( kvs::MouseEvent* ){}
void ScreenBase::wheelEvent( kvs::WheelEvent* ){}
void ScreenBase::keyPressEvent( kvs::KeyEvent* ){}

std::list<kvs::glfw::Timer*>& ScreenBase::timerEventHandler()
{
    return m_timer_event_handler;
}

void ScreenBase::addTimerEvent( kvs::TimerEventListener* event, kvs::glfw::Timer* timer )
{
    event->setScreen( this );
    timer->setEventListener( event );
    m_timer_event_handler.push_back( timer );
}

} // end of namespace glfw

} // end of namespace kvs
<|endoftext|>