<commit_before>/***********************************************************************
    filename:   FalSlider.cpp
    created:    Sun Jul 3 2005
    author:     Paul D Turner <paul@cegui.org.uk>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "FalSlider.h"
#include "falagard/CEGUIFalWidgetLookManager.h"
#include "falagard/CEGUIFalWidgetLookFeel.h"
#include "CEGUIWindowManager.h"
#include "elements/CEGUIThumb.h"

// Start of CEGUI namespace section
namespace CEGUI
{
    const utf8 FalagardSlider::TypeName[] = "Falagard/Slider";
    FalagardSliderProperties::VerticalSlider FalagardSlider::d_verticalProperty;
    FalagardSliderProperties::ReversedDirection FalagardSlider::d_reversedProperty;

    FalagardSlider::FalagardSlider(const String& type) :
        SliderWindowRenderer(type),
        d_vertical(false),
        d_reversed(false)
    {
        registerProperty(&d_verticalProperty);
        registerProperty(&d_reversedProperty);
    }

    void FalagardSlider::render()
    {
        const StateImagery* imagery;

        // get WidgetLookFeel for the assigned look.
        const WidgetLookFeel& wlf = getLookNFeel();
        // try and get imagery for our current state
        imagery = &wlf.getStateImagery(d_window->isDisabled() ? "Disabled" : "Enabled");
        // peform the rendering operation.
        imagery->render(*d_window);
    }

    void FalagardSlider::performChildWindowLayout()
    {
        updateThumb();
    }

    void FalagardSlider::updateThumb(void)
    {
        Slider* w = (Slider*)d_window;
        // get area the thumb is supposed to use as it's area.
        const WidgetLookFeel& wlf = getLookNFeel();
        Rect area(wlf.getNamedArea("ThumbTrackArea").getArea().getPixelRect(*w));
        // get accesss to the thumb
        Thumb* theThumb = w->getThumb();

        const Size w_pixel_size(w->getPixelSize());

        // get base location for thumb widget
        UVector2 thumbPosition(cegui_reldim(area.d_left / w_pixel_size.d_width),
                               cegui_reldim(area.d_top / w_pixel_size.d_height));

        // Is this a vertical slider
        if (d_vertical)
        {
            // pixel extent of total available area the thumb moves in
            float slideExtent = area.getHeight() - theThumb->getPixelSize().d_height;

            // Set range of motion for the thumb widget
            if (w_pixel_size.d_height != 0.0f)
                theThumb->setVertRange(area.d_top  / w_pixel_size.d_height,
                                       (area.d_top + slideExtent) / w_pixel_size.d_height);
            else
                theThumb->setVertRange(0.0f, 0.0f);

            // calculate vertical positon for thumb
            float thumbOffset = w->getCurrentValue() * (slideExtent / w->getMaxValue());

            if (w_pixel_size.d_height != 0.0f)
                thumbPosition.d_y.d_scale +=
                    (d_reversed ? thumbOffset : slideExtent - thumbOffset) / w_pixel_size.d_height;
        }
        // Horizontal slider
        else
        {
            // pixel extent of total available area the thumb moves in
            float slideExtent = area.getWidth() - theThumb->getPixelSize().d_width;

            // Set range of motion for the thumb widget
            if (w_pixel_size.d_width != 0.0f)
                theThumb->setHorzRange(area.d_left / w_pixel_size.d_width,
                                       (area.d_left + slideExtent) / w_pixel_size.d_width);
            else
                theThumb->setHorzRange(0.0f, 0.0f);

            // calculate horizontal positon for thumb
            float thumbOffset = w->getCurrentValue() * (slideExtent / w->getMaxValue());

            if (w_pixel_size.d_width != 0.0f)
                thumbPosition.d_x.d_scale +=
                    (d_reversed ? slideExtent - thumbOffset : thumbOffset)  / w_pixel_size.d_width;
        }

        // set new position for thumb.
        theThumb->setPosition(thumbPosition);
    }

    float FalagardSlider::getValueFromThumb(void) const
    {
        Slider* w = (Slider*)d_window;
        // get area the thumb is supposed to use as it's area.
        const WidgetLookFeel& wlf = getLookNFeel();
        Rect area(wlf.getNamedArea("ThumbTrackArea").getArea().getPixelRect(*w));
        // get accesss to the thumb
        Thumb* theThumb = w->getThumb();

        // slider is vertical
        if (d_vertical)
        {
            // pixel extent of total available area the thumb moves in
            float slideExtent = area.getHeight() - theThumb->getPixelSize().d_height;
            // calculate value represented by current thumb position
            float thumbValue = (theThumb->getYPosition().asAbsolute(w->getPixelSize().d_height) - area.d_top) / (slideExtent / w->getMaxValue());
            // return final thumb value according to slider settings
            return d_reversed ? thumbValue : w->getMaxValue() - thumbValue;
        }
        // slider is horizontal
        else
        {
            // pixel extent of total available area the thumb moves in
            float slideExtent = area.getWidth() - theThumb->getPixelSize().d_width;
            // calculate value represented by current thumb position
            float thumbValue = (theThumb->getXPosition().asAbsolute(w->getPixelSize().d_width) - area.d_left) / (slideExtent / w->getMaxValue());
            // return final thumb value according to slider settings
            return d_reversed ? w->getMaxValue() - thumbValue : thumbValue;
        }
    }

    float FalagardSlider::getAdjustDirectionFromPoint(const Point& pt) const
    {
        Slider* w = (Slider*)d_window;
        Rect absrect(w->getThumb()->getUnclippedOuterRect());

        if ((d_vertical && (pt.d_y < absrect.d_top)) ||
            (!d_vertical && (pt.d_x > absrect.d_right)))
        {
            return d_reversed ? -1.0f : 1.0f;
        }
        else if ((d_vertical && (pt.d_y > absrect.d_bottom)) ||
            (!d_vertical && (pt.d_x < absrect.d_left)))
        {
            return d_reversed ? 1.0f : -1.0f;
        }
        else
        {
            return 0;
        }
    }

    bool FalagardSlider::isVertical() const
    {
        return d_vertical;
    }

    void FalagardSlider::setVertical(bool setting)
    {
        d_vertical = setting;
    }

    bool FalagardSlider::isReversedDirection() const
    {
        return d_reversed;
    }

    void FalagardSlider::setReversedDirection(bool setting)
    {
        d_reversed = setting;
    }

} // End of  CEGUI namespace section
<commit_msg>FIX: Divisoin by zero / NaN issue with slider where the thumb would end up never getting a correct position.  Thanks to Erik Hjortsberg.<commit_after>/***********************************************************************
    filename:   FalSlider.cpp
    created:    Sun Jul 3 2005
    author:     Paul D Turner <paul@cegui.org.uk>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "FalSlider.h"
#include "falagard/CEGUIFalWidgetLookManager.h"
#include "falagard/CEGUIFalWidgetLookFeel.h"
#include "CEGUIWindowManager.h"
#include "elements/CEGUIThumb.h"

// Start of CEGUI namespace section
namespace CEGUI
{
    const utf8 FalagardSlider::TypeName[] = "Falagard/Slider";
    FalagardSliderProperties::VerticalSlider FalagardSlider::d_verticalProperty;
    FalagardSliderProperties::ReversedDirection FalagardSlider::d_reversedProperty;

    FalagardSlider::FalagardSlider(const String& type) :
        SliderWindowRenderer(type),
        d_vertical(false),
        d_reversed(false)
    {
        registerProperty(&d_verticalProperty);
        registerProperty(&d_reversedProperty);
    }

    void FalagardSlider::render()
    {
        const StateImagery* imagery;

        // get WidgetLookFeel for the assigned look.
        const WidgetLookFeel& wlf = getLookNFeel();
        // try and get imagery for our current state
        imagery = &wlf.getStateImagery(d_window->isDisabled() ? "Disabled" : "Enabled");
        // peform the rendering operation.
        imagery->render(*d_window);
    }

    void FalagardSlider::performChildWindowLayout()
    {
        updateThumb();
    }

    void FalagardSlider::updateThumb(void)
    {
        Slider* w = (Slider*)d_window;
        // get area the thumb is supposed to use as it's area.
        const WidgetLookFeel& wlf = getLookNFeel();
        Rect area(wlf.getNamedArea("ThumbTrackArea").getArea().getPixelRect(*w));
        // get accesss to the thumb
        Thumb* theThumb = w->getThumb();

        const Size w_pixel_size(w->getPixelSize());

        float thumbRelXPos = w_pixel_size.d_width == 0.0f ? 0.0f : (area.d_left / w_pixel_size.d_width);
        float thumbRelYPos = w_pixel_size.d_height == 0.0f ? 0.0f : (area.d_top / w_pixel_size.d_height);
        // get base location for thumb widget
        UVector2 thumbPosition(cegui_reldim(thumbRelXPos), cegui_reldim(thumbRelYPos));

        // Is this a vertical slider
        if (d_vertical)
        {
            // pixel extent of total available area the thumb moves in
            float slideExtent = area.getHeight() - theThumb->getPixelSize().d_height;

            // Set range of motion for the thumb widget
            if (w_pixel_size.d_height != 0.0f)
                theThumb->setVertRange(area.d_top  / w_pixel_size.d_height,
                                       (area.d_top + slideExtent) / w_pixel_size.d_height);
            else
                theThumb->setVertRange(0.0f, 0.0f);

            // calculate vertical positon for thumb
            float thumbOffset = w->getCurrentValue() * (slideExtent / w->getMaxValue());

            if (w_pixel_size.d_height != 0.0f)
                thumbPosition.d_y.d_scale +=
                    (d_reversed ? thumbOffset : slideExtent - thumbOffset) / w_pixel_size.d_height;
        }
        // Horizontal slider
        else
        {
            // pixel extent of total available area the thumb moves in
            float slideExtent = area.getWidth() - theThumb->getPixelSize().d_width;

            // Set range of motion for the thumb widget
            if (w_pixel_size.d_width != 0.0f)
                theThumb->setHorzRange(area.d_left / w_pixel_size.d_width,
                                       (area.d_left + slideExtent) / w_pixel_size.d_width);
            else
                theThumb->setHorzRange(0.0f, 0.0f);

            // calculate horizontal positon for thumb
            float thumbOffset = w->getCurrentValue() * (slideExtent / w->getMaxValue());

            if (w_pixel_size.d_width != 0.0f)
                thumbPosition.d_x.d_scale +=
                    (d_reversed ? slideExtent - thumbOffset : thumbOffset)  / w_pixel_size.d_width;
        }

        // set new position for thumb.
        theThumb->setPosition(thumbPosition);
    }

    float FalagardSlider::getValueFromThumb(void) const
    {
        Slider* w = (Slider*)d_window;
        // get area the thumb is supposed to use as it's area.
        const WidgetLookFeel& wlf = getLookNFeel();
        Rect area(wlf.getNamedArea("ThumbTrackArea").getArea().getPixelRect(*w));
        // get accesss to the thumb
        Thumb* theThumb = w->getThumb();

        // slider is vertical
        if (d_vertical)
        {
            // pixel extent of total available area the thumb moves in
            float slideExtent = area.getHeight() - theThumb->getPixelSize().d_height;
            // calculate value represented by current thumb position
            float thumbValue = (theThumb->getYPosition().asAbsolute(w->getPixelSize().d_height) - area.d_top) / (slideExtent / w->getMaxValue());
            // return final thumb value according to slider settings
            return d_reversed ? thumbValue : w->getMaxValue() - thumbValue;
        }
        // slider is horizontal
        else
        {
            // pixel extent of total available area the thumb moves in
            float slideExtent = area.getWidth() - theThumb->getPixelSize().d_width;
            // calculate value represented by current thumb position
            float thumbValue = (theThumb->getXPosition().asAbsolute(w->getPixelSize().d_width) - area.d_left) / (slideExtent / w->getMaxValue());
            // return final thumb value according to slider settings
            return d_reversed ? w->getMaxValue() - thumbValue : thumbValue;
        }
    }

    float FalagardSlider::getAdjustDirectionFromPoint(const Point& pt) const
    {
        Slider* w = (Slider*)d_window;
        Rect absrect(w->getThumb()->getUnclippedOuterRect());

        if ((d_vertical && (pt.d_y < absrect.d_top)) ||
            (!d_vertical && (pt.d_x > absrect.d_right)))
        {
            return d_reversed ? -1.0f : 1.0f;
        }
        else if ((d_vertical && (pt.d_y > absrect.d_bottom)) ||
            (!d_vertical && (pt.d_x < absrect.d_left)))
        {
            return d_reversed ? 1.0f : -1.0f;
        }
        else
        {
            return 0;
        }
    }

    bool FalagardSlider::isVertical() const
    {
        return d_vertical;
    }

    void FalagardSlider::setVertical(bool setting)
    {
        d_vertical = setting;
    }

    bool FalagardSlider::isReversedDirection() const
    {
        return d_reversed;
    }

    void FalagardSlider::setReversedDirection(bool setting)
    {
        d_reversed = setting;
    }

} // End of  CEGUI namespace section
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */
#ifndef INCLUDED_CHART2_SOURCE_INC_CHARTVIEW_EXPLICITSCALEVALUES_HXX
#define INCLUDED_CHART2_SOURCE_INC_CHARTVIEW_EXPLICITSCALEVALUES_HXX

#include "chartviewdllapi.hxx"
#include <com/sun/star/chart/TimeInterval.hpp>
#include <com/sun/star/chart/TimeUnit.hpp>
#include <com/sun/star/chart2/AxisOrientation.hpp>
#include <com/sun/star/chart2/AxisType.hpp>
#include <com/sun/star/chart2/XScaling.hpp>
#include <tools/date.hxx>
#include <vector>
namespace chart
{

/** This structure contains the explicit values for a scale like Minimum and Maximum.
    See also ::com::sun::star::chart2::ScaleData.
*/

struct OOO_DLLPUBLIC_CHARTVIEW ExplicitScaleData
{
    ExplicitScaleData();

    double Minimum;
    double Maximum;
    double Origin;

    ::com::sun::star::chart2::AxisOrientation     Orientation;

    ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XScaling > Scaling;

    sal_Int32   AxisType;//see ::com::sun::star::chart2::AxisType
    bool        ShiftedCategoryPosition;
    sal_Int32   TimeResolution; //constant of type <type>::com::sun::star::chart::TimeUnit</type>
    Date        NullDate;
};

struct OOO_DLLPUBLIC_CHARTVIEW ExplicitSubIncrement
{
    ExplicitSubIncrement();

    /** Numbers of intervals between two superior ticks.  For an axis
        this usually means, that IntervalCount - 1
        sub-tick-marks are displayed between two superior ticks.

     */
    sal_Int32 IntervalCount;

    /** If <TRUE/>, the distance between two sub-tick-marks on the
        screen is always the same.  If <FALSE/>, the distances may
        differ depending on the <type>XScaling</type>.
     */
    bool PostEquidistant;
};

/** describes how tickmarks are positioned on the scale of an axis.
*/
struct OOO_DLLPUBLIC_CHARTVIEW ExplicitIncrementData
{
    ExplicitIncrementData();

    /** the following two members are only for date-time axis
    */
    ::com::sun::star::chart::TimeInterval   MajorTimeInterval;
    ::com::sun::star::chart::TimeInterval   MinorTimeInterval;

    /** the other members are for *not* date-time axis
    */

    /** <member>Distance</member> describes the distance between two
    neighboring main tickmarks on a <type>Scale</type> of an axis.
    All neighboring main tickmarks have the same constant distance.

If the Scale has a <type>XScaling</type> the <member>Distance</member>
    may be measured in two different ways - that is - before or after the
    scaling is applied.

On a logarithmic scale for example the distance between two main
    tickmarks is typically measured after the scaling is applied:
    Distance = log(tick2)-log(tick1)
    ( log(1000)-log(100)==log(100)-log(10)==log(10)-log(1)==1==Distance ).
    The resulting tickmarks will always look equidistant on the screen.
    The other possibility is to have a Distance = tick2-tick1 measured constant
    before a scaling is applied, which may lead to non equidistant tickmarks
    on the screen.

<member>PostEquidistant</member> rules whether the <member>Distance</member>
    is meant to be a value before or after scaling.

    */
    double      Distance;

    /**
    <member>PostEquidistant</member> rules whether the member <member>Distance</member>
    describes a distance before or after the scaling is applied.

If <member>PostEquidistant</member> equals <TRUE/> <member>Distance</member>
    is given in values after <type>XScaling</type> is applied, thus resulting
    main tickmarks will always look equidistant on the screen.
    If <member>PostEquidistant</member> equals <FALSE/> <member>Distance</member>
    is given in values before <type>XScaling</type> is applied.

    */
    bool        PostEquidistant;

    /** The <member>BaseValue</member> gives a starting point on the scale
    to which all further main tickmarks are relatively positioned.

The <member>BaseValue</member> is always a value on the scale before
    a possible scaling is applied. If the given value is not valid in the
    associated scaling the minimum of the scaling is assumed,
    if there is no minimum any other obvious value will be assumed.

E.g.: assume a scale from 0 to 6 with identical scaling.
    Further assume this Increment to have Distance==2 and PostEquidistant==false.
    Setting BaseValue=0 would lead to main tickmarks 0; 2; 4; 6;
    Setting BaseValue=1,3 would lead to main tickmarks 1,3; 3,3; 5,3;
    Setting BaseValue=-0,7 would also lead to main tickmarks 1,3; 3,3; 5,3;
    And setting BaseValue to 2, -2, 4, -4 etc. in this example
    leads to the same result as BaseValue=0.

    */
    double      BaseValue;

    /** <member>SubIncrements</member> describes the positioning of further
    sub tickmarks on the scale of an axis.

The first SubIncrement in this sequence determines how the
    distance between two neighboring main tickmarks is divided for positioning
    of further sub tickmarks. Every following SubIncrement determines the
    positions of subsequent tickmarks in relation to their parent tickmarks
    iven by the preceding SubIncrement.

    */
    ::std::vector< ExplicitSubIncrement > SubIncrements;
};

} //namespace chart
#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>remove whitespace<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */
#ifndef INCLUDED_CHART2_SOURCE_INC_CHARTVIEW_EXPLICITSCALEVALUES_HXX
#define INCLUDED_CHART2_SOURCE_INC_CHARTVIEW_EXPLICITSCALEVALUES_HXX

#include "chartviewdllapi.hxx"
#include <com/sun/star/chart/TimeInterval.hpp>
#include <com/sun/star/chart/TimeUnit.hpp>
#include <com/sun/star/chart2/AxisOrientation.hpp>
#include <com/sun/star/chart2/AxisType.hpp>
#include <com/sun/star/chart2/XScaling.hpp>
#include <tools/date.hxx>
#include <vector>
namespace chart
{

/** This structure contains the explicit values for a scale like Minimum and Maximum.
    See also ::com::sun::star::chart2::ScaleData.
*/
struct OOO_DLLPUBLIC_CHARTVIEW ExplicitScaleData
{
    ExplicitScaleData();

    double Minimum;
    double Maximum;
    double Origin;

    ::com::sun::star::chart2::AxisOrientation     Orientation;

    ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XScaling > Scaling;

    sal_Int32   AxisType;//see ::com::sun::star::chart2::AxisType
    bool        ShiftedCategoryPosition;
    sal_Int32   TimeResolution; //constant of type <type>::com::sun::star::chart::TimeUnit</type>
    Date        NullDate;
};

struct OOO_DLLPUBLIC_CHARTVIEW ExplicitSubIncrement
{
    ExplicitSubIncrement();

    /** Numbers of intervals between two superior ticks.  For an axis
        this usually means, that IntervalCount - 1
        sub-tick-marks are displayed between two superior ticks.

     */
    sal_Int32 IntervalCount;

    /** If <TRUE/>, the distance between two sub-tick-marks on the
        screen is always the same.  If <FALSE/>, the distances may
        differ depending on the <type>XScaling</type>.
     */
    bool PostEquidistant;
};

/** describes how tickmarks are positioned on the scale of an axis.
*/
struct OOO_DLLPUBLIC_CHARTVIEW ExplicitIncrementData
{
    ExplicitIncrementData();

    /** the following two members are only for date-time axis
    */
    ::com::sun::star::chart::TimeInterval   MajorTimeInterval;
    ::com::sun::star::chart::TimeInterval   MinorTimeInterval;

    /** the other members are for *not* date-time axis
    */

    /** <member>Distance</member> describes the distance between two
    neighboring main tickmarks on a <type>Scale</type> of an axis.
    All neighboring main tickmarks have the same constant distance.

If the Scale has a <type>XScaling</type> the <member>Distance</member>
    may be measured in two different ways - that is - before or after the
    scaling is applied.

On a logarithmic scale for example the distance between two main
    tickmarks is typically measured after the scaling is applied:
    Distance = log(tick2)-log(tick1)
    ( log(1000)-log(100)==log(100)-log(10)==log(10)-log(1)==1==Distance ).
    The resulting tickmarks will always look equidistant on the screen.
    The other possibility is to have a Distance = tick2-tick1 measured constant
    before a scaling is applied, which may lead to non equidistant tickmarks
    on the screen.

<member>PostEquidistant</member> rules whether the <member>Distance</member>
    is meant to be a value before or after scaling.

    */
    double      Distance;

    /**
    <member>PostEquidistant</member> rules whether the member <member>Distance</member>
    describes a distance before or after the scaling is applied.

If <member>PostEquidistant</member> equals <TRUE/> <member>Distance</member>
    is given in values after <type>XScaling</type> is applied, thus resulting
    main tickmarks will always look equidistant on the screen.
    If <member>PostEquidistant</member> equals <FALSE/> <member>Distance</member>
    is given in values before <type>XScaling</type> is applied.

    */
    bool        PostEquidistant;

    /** The <member>BaseValue</member> gives a starting point on the scale
    to which all further main tickmarks are relatively positioned.

The <member>BaseValue</member> is always a value on the scale before
    a possible scaling is applied. If the given value is not valid in the
    associated scaling the minimum of the scaling is assumed,
    if there is no minimum any other obvious value will be assumed.

E.g.: assume a scale from 0 to 6 with identical scaling.
    Further assume this Increment to have Distance==2 and PostEquidistant==false.
    Setting BaseValue=0 would lead to main tickmarks 0; 2; 4; 6;
    Setting BaseValue=1,3 would lead to main tickmarks 1,3; 3,3; 5,3;
    Setting BaseValue=-0,7 would also lead to main tickmarks 1,3; 3,3; 5,3;
    And setting BaseValue to 2, -2, 4, -4 etc. in this example
    leads to the same result as BaseValue=0.

    */
    double      BaseValue;

    /** <member>SubIncrements</member> describes the positioning of further
    sub tickmarks on the scale of an axis.

The first SubIncrement in this sequence determines how the
    distance between two neighboring main tickmarks is divided for positioning
    of further sub tickmarks. Every following SubIncrement determines the
    positions of subsequent tickmarks in relation to their parent tickmarks
    iven by the preceding SubIncrement.

    */
    ::std::vector< ExplicitSubIncrement > SubIncrements;
};

} //namespace chart
#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: RegressionCalculationHelper.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: ihi $ $Date: 2007-11-23 12:07:00 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef CHART2_REGRESSIONCALCULATIONHELPER_HXX
#define CHART2_REGRESSIONCALCULATIONHELPER_HXX

#ifndef INCLUDED_RTL_MATH_HXX
#include <rtl/math.hxx>
#endif

#include <utility>
#include <functional>
#include <vector>

#ifndef INCLUDED_RTL_MATH_HXX
#include <rtl/math.hxx>
#endif

#define NUMBER_TO_STR(number) (::rtl::OStringToOUString(::rtl::math::doubleToString( \
          number, rtl_math_StringFormat_G, 4, '.', true ),RTL_TEXTENCODING_ASCII_US ))

#define UC_SPACE (sal_Unicode(' '))
#define UC_MINUS_SIGN (sal_Unicode('-'))
// #define UC_MINUS_SIGN (sal_Unicode(0x2212))

namespace chart
{
namespace RegressionCalculationHelper
{

typedef ::std::pair< ::std::vector< double >, ::std::vector< double > > tDoubleVectorPair;

/** takes the given x- and y-values and copyies them into the resulting pair,
    which contains x-values in the first element and the y-values in the second
    one.  All tuples for which aPred is false are not copied.

The functors below provide a set of useful predicates that can be
    used to pass as parameter aPred.

 */
template< class Pred >
tDoubleVectorPair
    cleanup( const ::com::sun::star::uno::Sequence< double > & rXValues,
             const ::com::sun::star::uno::Sequence< double > & rYValues,
             Pred aPred )
{
    tDoubleVectorPair aResult;
    sal_Int32 nSize = ::std::min( rXValues.getLength(), rYValues.getLength());
    for( sal_Int32 i=0; i<nSize; ++i )
    {
        if( aPred( rXValues[i], rYValues[i] ))
        {
            aResult.first.push_back( rXValues[i] );
            aResult.second.push_back( rYValues[i] );
        }
    }

    return aResult;
}

class isValid : public ::std::binary_function< double, double, bool >
{
public:
    inline bool operator()( double x, double y )
    { return ! ( ::rtl::math::isNan( x ) ||
                 ::rtl::math::isNan( y ) ||
                 ::rtl::math::isInf( x ) ||
                 ::rtl::math::isInf( y ) );
    }
};

class isValidAndXPositive : public ::std::binary_function< double, double, bool >
{
public:
    inline bool operator()( double x, double y )
    { return ! ( ::rtl::math::isNan( x ) ||
                 ::rtl::math::isNan( y ) ||
                 ::rtl::math::isInf( x ) ||
                 ::rtl::math::isInf( y ) ||
                 x <= 0.0 );
    }
};

class isValidAndYPositive : public ::std::binary_function< double, double, bool >
{
public:
    inline bool operator()( double x, double y )
    { return ! ( ::rtl::math::isNan( x ) ||
                 ::rtl::math::isNan( y ) ||
                 ::rtl::math::isInf( x ) ||
                 ::rtl::math::isInf( y ) ||
                 y <= 0.0 );
    }
};

class isValidAndBothPositive : public ::std::binary_function< double, double, bool >
{
public:
    inline bool operator()( double x, double y )
    { return ! ( ::rtl::math::isNan( x ) ||
                 ::rtl::math::isNan( y ) ||
                 ::rtl::math::isInf( x ) ||
                 ::rtl::math::isInf( y ) ||
                 x <= 0.0 ||
                 y <= 0.0 );
    }
};

} //  namespace RegressionCalculationHelper
} //  namespace chart

// CHART2_REGRESSIONCALCULATIONHELPER_HXX
#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.5.60); FILE MERGED 2008/04/01 15:04:23 thb 1.5.60.2: #i85898# Stripping all external header guards 2008/03/28 16:44:24 rt 1.5.60.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: RegressionCalculationHelper.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef CHART2_REGRESSIONCALCULATIONHELPER_HXX
#define CHART2_REGRESSIONCALCULATIONHELPER_HXX

#include <rtl/math.hxx>

#include <utility>
#include <functional>
#include <vector>
#include <rtl/math.hxx>

#define NUMBER_TO_STR(number) (::rtl::OStringToOUString(::rtl::math::doubleToString( \
          number, rtl_math_StringFormat_G, 4, '.', true ),RTL_TEXTENCODING_ASCII_US ))

#define UC_SPACE (sal_Unicode(' '))
#define UC_MINUS_SIGN (sal_Unicode('-'))
// #define UC_MINUS_SIGN (sal_Unicode(0x2212))

namespace chart
{
namespace RegressionCalculationHelper
{

typedef ::std::pair< ::std::vector< double >, ::std::vector< double > > tDoubleVectorPair;

/** takes the given x- and y-values and copyies them into the resulting pair,
    which contains x-values in the first element and the y-values in the second
    one.  All tuples for which aPred is false are not copied.

The functors below provide a set of useful predicates that can be
    used to pass as parameter aPred.

 */
template< class Pred >
tDoubleVectorPair
    cleanup( const ::com::sun::star::uno::Sequence< double > & rXValues,
             const ::com::sun::star::uno::Sequence< double > & rYValues,
             Pred aPred )
{
    tDoubleVectorPair aResult;
    sal_Int32 nSize = ::std::min( rXValues.getLength(), rYValues.getLength());
    for( sal_Int32 i=0; i<nSize; ++i )
    {
        if( aPred( rXValues[i], rYValues[i] ))
        {
            aResult.first.push_back( rXValues[i] );
            aResult.second.push_back( rYValues[i] );
        }
    }

    return aResult;
}

class isValid : public ::std::binary_function< double, double, bool >
{
public:
    inline bool operator()( double x, double y )
    { return ! ( ::rtl::math::isNan( x ) ||
                 ::rtl::math::isNan( y ) ||
                 ::rtl::math::isInf( x ) ||
                 ::rtl::math::isInf( y ) );
    }
};

class isValidAndXPositive : public ::std::binary_function< double, double, bool >
{
public:
    inline bool operator()( double x, double y )
    { return ! ( ::rtl::math::isNan( x ) ||
                 ::rtl::math::isNan( y ) ||
                 ::rtl::math::isInf( x ) ||
                 ::rtl::math::isInf( y ) ||
                 x <= 0.0 );
    }
};

class isValidAndYPositive : public ::std::binary_function< double, double, bool >
{
public:
    inline bool operator()( double x, double y )
    { return ! ( ::rtl::math::isNan( x ) ||
                 ::rtl::math::isNan( y ) ||
                 ::rtl::math::isInf( x ) ||
                 ::rtl::math::isInf( y ) ||
                 y <= 0.0 );
    }
};

class isValidAndBothPositive : public ::std::binary_function< double, double, bool >
{
public:
    inline bool operator()( double x, double y )
    { return ! ( ::rtl::math::isNan( x ) ||
                 ::rtl::math::isNan( y ) ||
                 ::rtl::math::isInf( x ) ||
                 ::rtl::math::isInf( y ) ||
                 x <= 0.0 ||
                 y <= 0.0 );
    }
};

} //  namespace RegressionCalculationHelper
} //  namespace chart

// CHART2_REGRESSIONCALCULATIONHELPER_HXX
#endif
<|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 "build/build_config.h"

#if defined(TOOLKIT_GTK)
#include <gtk/gtk.h>
#endif

#include "base/gfx/rect.h"
#include "base/gfx/size.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/browser_action_test_util.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/extensions/extension_action.h"
#include "chrome/test/ui_test_utils.h"

static const int kTimeoutMs = 60 * 1000;  // 1 minute

class BrowserActionApiTest : public ExtensionApiTest {
 public:
  BrowserActionApiTest() {}
  virtual ~BrowserActionApiTest() {}

 protected:
  BrowserActionTestUtil GetBrowserActionsBar() {
    return BrowserActionTestUtil(browser());
  }

  gfx::Rect OpenPopup(int index) {
    {
      NotificationRegistrar registrar;
      registrar.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
                    NotificationService::AllSources());
      GetBrowserActionsBar().Press(index);
      // If the popup is already showing then we needn't wait for the
      // notification before proceeding.
      if (!GetBrowserActionsBar().HasPopup()) {
        MessageLoop::current()->PostDelayedTask(
            FROM_HERE, new MessageLoop::QuitTask, kTimeoutMs);
      }
      ui_test_utils::RunMessageLoop();
    }
    EXPECT_TRUE(GetBrowserActionsBar().HasPopup());
    return GetBrowserActionsBar().GetPopupBounds();
  }
};

IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, Basic) {
  StartHTTPServer();
  ASSERT_TRUE(RunExtensionTest("browser_action/basics")) << message_;

  // Test that there is a browser action in the toolbar.
  ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());

  // Tell the extension to update the browser action state.
  ResultCatcher catcher;
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  Extension* extension = service->extensions()->at(0);
  ui_test_utils::NavigateToURL(browser(),
      GURL(extension->GetResourceURL("update.html")));
  ASSERT_TRUE(catcher.GetNextResult());

  // Test that we received the changes.
  ExtensionAction* action = extension->browser_action();
  ASSERT_EQ("Modified", action->GetTitle(ExtensionAction::kDefaultTabId));
  ASSERT_EQ("badge", action->GetBadgeText(ExtensionAction::kDefaultTabId));
  ASSERT_EQ(SkColorSetARGB(255, 255, 255, 255),
            action->GetBadgeBackgroundColor(ExtensionAction::kDefaultTabId));

  // Simulate the browser action being clicked.
  ui_test_utils::NavigateToURL(browser(),
      GURL("http://localhost:1337/files/extensions/test_file.txt"));

  ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
      browser()->profile(), action->extension_id(), browser());

  // Verify the command worked.
  TabContents* tab = browser()->GetSelectedTabContents();
  bool result = false;
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      tab->render_view_host(), L"",
      L"setInterval(function(){"
      L"  if(document.body.bgColor == 'red'){"
      L"    window.domAutomationController.send(true)}}, 100)",
      &result);
  ASSERT_TRUE(result);
}

IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, DynamicBrowserAction) {
  ASSERT_TRUE(RunExtensionTest("browser_action/no_icon")) << message_;

  // Test that there is a browser action in the toolbar and that it has no icon.
  ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());
  EXPECT_FALSE(GetBrowserActionsBar().HasIcon(0));

  // Tell the extension to update the icon using setIcon({imageData:...}).
  ResultCatcher catcher;
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  Extension* extension = service->extensions()->at(0);
  ui_test_utils::NavigateToURL(browser(),
      GURL(extension->GetResourceURL("update.html")));
  ASSERT_TRUE(catcher.GetNextResult());

  // Test that we received the changes.
  EXPECT_TRUE(GetBrowserActionsBar().HasIcon(0));

  // Tell the extension to update using setIcon({path:...});
  ui_test_utils::NavigateToURL(browser(),
      GURL(extension->GetResourceURL("update2.html")));
  ASSERT_TRUE(catcher.GetNextResult());

  // Test that we received the changes.
  EXPECT_TRUE(GetBrowserActionsBar().HasIcon(0));

  // TODO(aa): Would be nice here to actually compare that the pixels change.
}

IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, TabSpecificBrowserActionState) {
  ASSERT_TRUE(RunExtensionTest("browser_action/tab_specific_state")) <<
      message_;

  // Test that there is a browser action in the toolbar and that it has an icon.
  ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());
  EXPECT_TRUE(GetBrowserActionsBar().HasIcon(0));

  // Execute the action, its title should change.
  ResultCatcher catcher;
  GetBrowserActionsBar().Press(0);
  ASSERT_TRUE(catcher.GetNextResult());
  EXPECT_EQ("Showing icon 2", GetBrowserActionsBar().GetTooltip(0));

  // Open a new tab, the title should go back.
  browser()->NewTab();
  EXPECT_EQ("hi!", GetBrowserActionsBar().GetTooltip(0));

  // Go back to first tab, changed title should reappear.
  browser()->SelectTabContentsAt(0, true);
  EXPECT_EQ("Showing icon 2", GetBrowserActionsBar().GetTooltip(0));

  // Reload that tab, default title should come back.
  ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
  EXPECT_EQ("hi!", GetBrowserActionsBar().GetTooltip(0));
}

IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, BrowserActionPopup) {
  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
      "browser_action/popup")));

  // The extension's popup's size grows by |growFactor| each click.
  const int growFactor = 500;
  gfx::Size minSize = BrowserActionTestUtil::GetMinPopupSize();
  gfx::Size maxSize = BrowserActionTestUtil::GetMaxPopupSize();

  // Ensure that two clicks will exceed the maximum allowed size.
  ASSERT_GT(minSize.height() + growFactor * 2, maxSize.height());
  ASSERT_GT(minSize.width() + growFactor * 2, maxSize.width());

  // Simulate a click on the browser action and verify the size of the resulting
  // popup.  The first one tries to be 0x0, so it should be the min values.
  gfx::Rect bounds = OpenPopup(0);
  EXPECT_EQ(minSize, bounds.size());
  EXPECT_TRUE(GetBrowserActionsBar().HidePopup());

  bounds = OpenPopup(0);
  EXPECT_EQ(gfx::Size(growFactor, growFactor), bounds.size());
  EXPECT_TRUE(GetBrowserActionsBar().HidePopup());

  // One more time, but this time it should be constrained by the max values.
  bounds = OpenPopup(0);
  EXPECT_EQ(maxSize, bounds.size());
  EXPECT_TRUE(GetBrowserActionsBar().HidePopup());
}
<commit_msg>Mark ExtensionApiTest.BrowserActionPopup as flaky.<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 "build/build_config.h"

#if defined(TOOLKIT_GTK)
#include <gtk/gtk.h>
#endif

#include "base/gfx/rect.h"
#include "base/gfx/size.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/browser_action_test_util.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/extensions/extension_action.h"
#include "chrome/test/ui_test_utils.h"

static const int kTimeoutMs = 60 * 1000;  // 1 minute

class BrowserActionApiTest : public ExtensionApiTest {
 public:
  BrowserActionApiTest() {}
  virtual ~BrowserActionApiTest() {}

 protected:
  BrowserActionTestUtil GetBrowserActionsBar() {
    return BrowserActionTestUtil(browser());
  }

  gfx::Rect OpenPopup(int index) {
    {
      NotificationRegistrar registrar;
      registrar.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
                    NotificationService::AllSources());
      GetBrowserActionsBar().Press(index);
      // If the popup is already showing then we needn't wait for the
      // notification before proceeding.
      if (!GetBrowserActionsBar().HasPopup()) {
        MessageLoop::current()->PostDelayedTask(
            FROM_HERE, new MessageLoop::QuitTask, kTimeoutMs);
      }
      ui_test_utils::RunMessageLoop();
    }
    EXPECT_TRUE(GetBrowserActionsBar().HasPopup());
    return GetBrowserActionsBar().GetPopupBounds();
  }
};

IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, Basic) {
  StartHTTPServer();
  ASSERT_TRUE(RunExtensionTest("browser_action/basics")) << message_;

  // Test that there is a browser action in the toolbar.
  ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());

  // Tell the extension to update the browser action state.
  ResultCatcher catcher;
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  Extension* extension = service->extensions()->at(0);
  ui_test_utils::NavigateToURL(browser(),
      GURL(extension->GetResourceURL("update.html")));
  ASSERT_TRUE(catcher.GetNextResult());

  // Test that we received the changes.
  ExtensionAction* action = extension->browser_action();
  ASSERT_EQ("Modified", action->GetTitle(ExtensionAction::kDefaultTabId));
  ASSERT_EQ("badge", action->GetBadgeText(ExtensionAction::kDefaultTabId));
  ASSERT_EQ(SkColorSetARGB(255, 255, 255, 255),
            action->GetBadgeBackgroundColor(ExtensionAction::kDefaultTabId));

  // Simulate the browser action being clicked.
  ui_test_utils::NavigateToURL(browser(),
      GURL("http://localhost:1337/files/extensions/test_file.txt"));

  ExtensionBrowserEventRouter::GetInstance()->BrowserActionExecuted(
      browser()->profile(), action->extension_id(), browser());

  // Verify the command worked.
  TabContents* tab = browser()->GetSelectedTabContents();
  bool result = false;
  ui_test_utils::ExecuteJavaScriptAndExtractBool(
      tab->render_view_host(), L"",
      L"setInterval(function(){"
      L"  if(document.body.bgColor == 'red'){"
      L"    window.domAutomationController.send(true)}}, 100)",
      &result);
  ASSERT_TRUE(result);
}

IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, DynamicBrowserAction) {
  ASSERT_TRUE(RunExtensionTest("browser_action/no_icon")) << message_;

  // Test that there is a browser action in the toolbar and that it has no icon.
  ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());
  EXPECT_FALSE(GetBrowserActionsBar().HasIcon(0));

  // Tell the extension to update the icon using setIcon({imageData:...}).
  ResultCatcher catcher;
  ExtensionsService* service = browser()->profile()->GetExtensionsService();
  Extension* extension = service->extensions()->at(0);
  ui_test_utils::NavigateToURL(browser(),
      GURL(extension->GetResourceURL("update.html")));
  ASSERT_TRUE(catcher.GetNextResult());

  // Test that we received the changes.
  EXPECT_TRUE(GetBrowserActionsBar().HasIcon(0));

  // Tell the extension to update using setIcon({path:...});
  ui_test_utils::NavigateToURL(browser(),
      GURL(extension->GetResourceURL("update2.html")));
  ASSERT_TRUE(catcher.GetNextResult());

  // Test that we received the changes.
  EXPECT_TRUE(GetBrowserActionsBar().HasIcon(0));

  // TODO(aa): Would be nice here to actually compare that the pixels change.
}

IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, TabSpecificBrowserActionState) {
  ASSERT_TRUE(RunExtensionTest("browser_action/tab_specific_state")) <<
      message_;

  // Test that there is a browser action in the toolbar and that it has an icon.
  ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());
  EXPECT_TRUE(GetBrowserActionsBar().HasIcon(0));

  // Execute the action, its title should change.
  ResultCatcher catcher;
  GetBrowserActionsBar().Press(0);
  ASSERT_TRUE(catcher.GetNextResult());
  EXPECT_EQ("Showing icon 2", GetBrowserActionsBar().GetTooltip(0));

  // Open a new tab, the title should go back.
  browser()->NewTab();
  EXPECT_EQ("hi!", GetBrowserActionsBar().GetTooltip(0));

  // Go back to first tab, changed title should reappear.
  browser()->SelectTabContentsAt(0, true);
  EXPECT_EQ("Showing icon 2", GetBrowserActionsBar().GetTooltip(0));

  // Reload that tab, default title should come back.
  ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
  EXPECT_EQ("hi!", GetBrowserActionsBar().GetTooltip(0));
}

IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, FLAKY_BrowserActionPopup) {
  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
      "browser_action/popup")));

  // The extension's popup's size grows by |growFactor| each click.
  const int growFactor = 500;
  gfx::Size minSize = BrowserActionTestUtil::GetMinPopupSize();
  gfx::Size maxSize = BrowserActionTestUtil::GetMaxPopupSize();

  // Ensure that two clicks will exceed the maximum allowed size.
  ASSERT_GT(minSize.height() + growFactor * 2, maxSize.height());
  ASSERT_GT(minSize.width() + growFactor * 2, maxSize.width());

  // Simulate a click on the browser action and verify the size of the resulting
  // popup.  The first one tries to be 0x0, so it should be the min values.
  gfx::Rect bounds = OpenPopup(0);
  EXPECT_EQ(minSize, bounds.size());
  EXPECT_TRUE(GetBrowserActionsBar().HidePopup());

  bounds = OpenPopup(0);
  EXPECT_EQ(gfx::Size(growFactor, growFactor), bounds.size());
  EXPECT_TRUE(GetBrowserActionsBar().HidePopup());

  // One more time, but this time it should be constrained by the max values.
  bounds = OpenPopup(0);
  EXPECT_EQ(maxSize, bounds.size());
  EXPECT_TRUE(GetBrowserActionsBar().HidePopup());
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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/extensions/extension_apitest.h"
#include "net/base/mock_host_resolver.h"

class ExecuteScriptApiTest : public ExtensionApiTest {
 protected:
  void SetupDelayedHostResolver() {
    // We need a.com to be a little bit slow to trigger a race condition.
    host_resolver()->AddRuleWithLatency("a.com", "127.0.0.1", 500);
    host_resolver()->AddRule("b.com", "127.0.0.1");
    host_resolver()->AddRule("c.com", "127.0.0.1");
  }
};

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, ExecuteScriptBasic) {
  SetupDelayedHostResolver();
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionTest("executescript/basic")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, ExecuteScriptInFrame) {
  SetupDelayedHostResolver();
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionTest("executescript/in_frame")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, ExecuteScriptPermissions) {
  SetupDelayedHostResolver();
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionTest("executescript/permissions")) << message_;
}

// http://crbug.com/84760
#if defined(OS_CHROMEOS)
#define MAYBE_ExecuteScriptFileAfterClose DISABLED_ExecuteScriptFileAfterClose
#else
#define MAYBE_ExecuteScriptFileAfterClose ExecuteScriptFileAfterClose
#endif  // defined(OS_CHROMEOS)

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest,
                       MAYBE_ExecuteScriptFileAfterClose) {
  host_resolver()->AddRule("b.com", "127.0.0.1");
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionTest("executescript/file_after_close")) << message_;
}

// Crashy, http://crbug.com/67774.
IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest,
                       DISABLED_ExecuteScriptFragmentNavigation) {
  ASSERT_TRUE(StartTestServer());
  const char* extension_name = "executescript/fragment";
  ASSERT_TRUE(RunExtensionTest(extension_name)) << message_;
}

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, NavigationRaceExecuteScript) {
  host_resolver()->AddRule("a.com", "127.0.0.1");
  host_resolver()->AddRule("b.com", "127.0.0.1");
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionSubtest("executescript/navigation_race",
                                  "execute_script.html")) << message_;
}

#if defined(OS_LINUX)
// Fails on Linux.  http://crbug.com/89731
#define MAYBE_NavigationRaceJavaScriptUrl DISABLED_NavigationRaceJavaScriptUrl
#else
#define MAYBE_NavigationRaceJavaScriptUrl NavigationRaceJavaScriptUrl
#endif

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest,
                       MAYBE_NavigationRaceJavaScriptUrl) {
  host_resolver()->AddRule("a.com", "127.0.0.1");
  host_resolver()->AddRule("b.com", "127.0.0.1");
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionSubtest("executescript/navigation_race",
                                  "javascript_url.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, ExecuteScriptFrameAfterLoad) {
  SetupDelayedHostResolver();
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionTest("executescript/frame_after_load")) << message_;
}
<commit_msg>Disable cros tests on trunk.<commit_after>// Copyright (c) 2011 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/extensions/extension_apitest.h"
#include "net/base/mock_host_resolver.h"

class ExecuteScriptApiTest : public ExtensionApiTest {
 protected:
  void SetupDelayedHostResolver() {
    // We need a.com to be a little bit slow to trigger a race condition.
    host_resolver()->AddRuleWithLatency("a.com", "127.0.0.1", 500);
    host_resolver()->AddRule("b.com", "127.0.0.1");
    host_resolver()->AddRule("c.com", "127.0.0.1");
  }
};

// DISABLED http://crbug.com/92105
#if defined(OS_CHROMEOS)
#define MAYBE_ExecuteScriptBasic DISABLED_ExecuteScriptBasic
#else
#define MAYBE_ExecuteScriptBasic ExecuteScriptBasic
#endif  // defined(OS_CHROMEOS)

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, MAYBE_ExecuteScriptBasic) {
  SetupDelayedHostResolver();
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionTest("executescript/basic")) << message_;
}

// DISABLED http://crbug.com/92105
#if defined(OS_CHROMEOS)
#define MAYBE_ExecuteScriptInFrame DISABLED_ExecuteScriptInFrame
#else
#define MAYBE_ExecuteScriptInFrame ExecuteScriptInFrame
#endif  // defined(OS_CHROMEOS)

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, MAYBE_ExecuteScriptInFrame) {
  SetupDelayedHostResolver();
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionTest("executescript/in_frame")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, ExecuteScriptPermissions) {
  SetupDelayedHostResolver();
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionTest("executescript/permissions")) << message_;
}

// http://crbug.com/84760
#if defined(OS_CHROMEOS)
#define MAYBE_ExecuteScriptFileAfterClose DISABLED_ExecuteScriptFileAfterClose
#else
#define MAYBE_ExecuteScriptFileAfterClose ExecuteScriptFileAfterClose
#endif  // defined(OS_CHROMEOS)

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest,
                       MAYBE_ExecuteScriptFileAfterClose) {
  host_resolver()->AddRule("b.com", "127.0.0.1");
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionTest("executescript/file_after_close")) << message_;
}

// Crashy, http://crbug.com/67774.
IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest,
                       DISABLED_ExecuteScriptFragmentNavigation) {
  ASSERT_TRUE(StartTestServer());
  const char* extension_name = "executescript/fragment";
  ASSERT_TRUE(RunExtensionTest(extension_name)) << message_;
}

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, NavigationRaceExecuteScript) {
  host_resolver()->AddRule("a.com", "127.0.0.1");
  host_resolver()->AddRule("b.com", "127.0.0.1");
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionSubtest("executescript/navigation_race",
                                  "execute_script.html")) << message_;
}

#if defined(OS_LINUX)
// Fails on Linux.  http://crbug.com/89731
#define MAYBE_NavigationRaceJavaScriptUrl DISABLED_NavigationRaceJavaScriptUrl
#else
#define MAYBE_NavigationRaceJavaScriptUrl NavigationRaceJavaScriptUrl
#endif

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest,
                       MAYBE_NavigationRaceJavaScriptUrl) {
  host_resolver()->AddRule("a.com", "127.0.0.1");
  host_resolver()->AddRule("b.com", "127.0.0.1");
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionSubtest("executescript/navigation_race",
                                  "javascript_url.html")) << message_;
}

// DISABLED http://crbug.com/92105
#if defined(OS_CHROMEOS)
#define MAYBE_ExecuteScriptFrameAfterLoad DISABLED_ExecuteScriptFrameAfterLoad
#else
#define MAYBE_ExecuteScriptFrameAfterLoad ExecuteScriptFrameAfterLoad
#endif  // defined(OS_CHROMEOS)

IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest,
                       MAYBE_ExecuteScriptFrameAfterLoad) {
  SetupDelayedHostResolver();
  ASSERT_TRUE(StartTestServer());
  ASSERT_TRUE(RunExtensionTest("executescript/frame_after_load")) << message_;
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-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/sync/engine/change_reorder_buffer.h"

#include <limits>
#include <queue>
#include <set>
#include <utility>  // for pair<>
#include <vector>

#include "chrome/browser/sync/syncable/syncable.h"

using std::numeric_limits;
using std::pair;
using std::queue;
using std::set;
using std::vector;

namespace sync_api {

// Traversal provides a way to collect a set of nodes from the syncable
// directory structure and then traverse them, along with any intermediate
// nodes, in a top-down fashion, starting from a single common ancestor.  A
// Traversal starts out empty and is grown by means of the ExpandToInclude
// method.  Once constructed, the top(), begin_children(), and end_children()
// methods can be used to explore the nodes in root-to-leaf order.
class ChangeReorderBuffer::Traversal {
 public:
  typedef pair<int64, int64> ParentChildLink;
  typedef set<ParentChildLink> LinkSet;

  Traversal() : top_(kInvalidId) { }

  // Expand the traversal so that it includes the node indicated by
  // |child_handle|.
  void ExpandToInclude(syncable::BaseTransaction* trans,
                       int64 child_handle) {
    // If |top_| is invalid, this is the first insertion -- easy.
    if (top_ == kInvalidId) {
      top_ = child_handle;
      return;
    }

    int64 node_to_include = child_handle;
    while (node_to_include != kInvalidId && node_to_include != top_) {
      int64 node_parent = 0;

      syncable::Entry node(trans, syncable::GET_BY_HANDLE, node_to_include);
      CHECK(node.good());
      if (node.Get(syncable::ID).IsRoot()) {
        // If we've hit the root, and the root isn't already in the tree
        // (it would have to be |top_| if it were), start a new expansion
        // upwards from |top_| to unite the original traversal with the
        // path we just added that goes from |child_handle| to the root.
        node_to_include = top_;
        top_ = node.Get(syncable::META_HANDLE);
      } else {
        // Otherwise, get the parent ID so that we can add a ParentChildLink.
        syncable::Entry parent(trans, syncable::GET_BY_ID,
                             node.Get(syncable::PARENT_ID));
        CHECK(parent.good());
        node_parent = parent.Get(syncable::META_HANDLE);

        ParentChildLink link(node_parent, node_to_include);

        // If the link exists in the LinkSet |links_|, we don't need to search
        // any higher; we are done.
        if (links_.find(link) != links_.end())
          return;

        // Otherwise, extend |links_|, and repeat on the parent.
        links_.insert(link);
        node_to_include = node_parent;
      }
    }
  }

  // Return the top node of the traversal.  Use this as a starting point
  // for walking the tree.
  int64 top() const { return top_; }

  // Return an iterator corresponding to the first child (in the traversal)
  // of the node specified by |parent_id|.  Iterate this return value until
  // it is equal to the value returned by end_children(parent_id).  The
  // enumeration thus provided is unordered.
  LinkSet::const_iterator begin_children(int64 parent_id) const {
    return links_.upper_bound(
        ParentChildLink(parent_id, numeric_limits<int64>::min()));
  }

  // Return an iterator corresponding to the last child in the traversal
  // of the node specified by |parent_id|.
  LinkSet::const_iterator end_children(int64 parent_id) const {
    return begin_children(parent_id + 1);
  }

 private:
  // The topmost point in the directory hierarchy that is in the traversal,
  // and thus the first node to be traversed.  If the traversal is empty,
  // this is kInvalidId.  If the traversal contains exactly one member, |top_|
  // will be the solitary member, and |links_| will be empty.
  int64 top_;
  // A set of single-level links that compose the traversal below |top_|.  The
  // (parent, child) ordering of values enables efficient lookup of children
  // given the parent handle, which is used for top-down traversal.  |links_|
  // is expected to be connected -- every node that appears as a parent in a
  // link must either appear as a child of another link, or else be the
  // topmost node, |top_|.
  LinkSet links_;

  DISALLOW_COPY_AND_ASSIGN(Traversal);
};

ChangeReorderBuffer::ChangeReorderBuffer() {
}

ChangeReorderBuffer::~ChangeReorderBuffer() {
}

void ChangeReorderBuffer::GetAllChangesInTreeOrder(
    const BaseTransaction* sync_trans,
    vector<ChangeRecord>* changelist) {
  syncable::BaseTransaction* trans = sync_trans->GetWrappedTrans();

  // Step 1: Iterate through the operations, doing three things:
  // (a) Push deleted items straight into the |changelist|.
  // (b) Construct a traversal spanning all non-deleted items.
  // (c) Construct a set of all parent nodes of any position changes.
  set<int64> parents_of_position_changes;
  Traversal traversal;

  OperationMap::const_iterator i;
  for (i = operations_.begin(); i != operations_.end(); ++i) {
    if (i->second == OP_DELETE) {
      ChangeRecord record;
      record.id = i->first;
      record.action = ChangeRecord::ACTION_DELETE;
      if (specifics_.find(record.id) != specifics_.end())
        record.specifics = specifics_[record.id];
      if (extra_data_.find(record.id) != extra_data_.end())
        record.extra = extra_data_[record.id];
      changelist->push_back(record);
    } else {
      traversal.ExpandToInclude(trans, i->first);
      if (i->second == OP_ADD ||
          i->second == OP_UPDATE_POSITION_AND_PROPERTIES) {
        ReadNode node(sync_trans);
        CHECK(node.InitByIdLookup(i->first));
        parents_of_position_changes.insert(node.GetParentId());
      }
    }
  }

  // Step 2: Breadth-first expansion of the traversal, enumerating children in
  // the syncable sibling order if there were any position updates.
  queue<int64> to_visit;
  to_visit.push(traversal.top());
  while (!to_visit.empty()) {
    int64 next = to_visit.front();
    to_visit.pop();

    // If the node has an associated action, output a change record.
    i = operations_.find(next);
    if (i != operations_.end()) {
      ChangeRecord record;
      record.id = next;
      if (i->second == OP_ADD)
        record.action = ChangeRecord::ACTION_ADD;
      else
        record.action = ChangeRecord::ACTION_UPDATE;
      if (specifics_.find(record.id) != specifics_.end())
        record.specifics = specifics_[record.id];
      if (extra_data_.find(record.id) != extra_data_.end())
        record.extra = extra_data_[record.id];
      changelist->push_back(record);
    }

    // Now add the children of |next| to |to_visit|.
    if (parents_of_position_changes.find(next) ==
        parents_of_position_changes.end()) {
        // No order changes on this parent -- traverse only the nodes listed
        // in the traversal (and not in sibling order).
        Traversal::LinkSet::const_iterator j = traversal.begin_children(next);
        Traversal::LinkSet::const_iterator end = traversal.end_children(next);
        for (; j != end; ++j) {
          CHECK(j->first == next);
          to_visit.push(j->second);
        }
    } else {
      // There were ordering changes on the children of this parent, so
      // enumerate all the children in the sibling order.
      syncable::Entry parent(trans, syncable::GET_BY_HANDLE, next);
      syncable::Id id = trans->directory()->
          GetFirstChildId(trans, parent.Get(syncable::ID));
      while (!id.IsRoot()) {
        syncable::Entry child(trans, syncable::GET_BY_ID, id);
        CHECK(child.good());
        int64 handle = child.Get(syncable::META_HANDLE);
        to_visit.push(handle);
        // If there is no operation on this child node, record it as as an
        // update, so that the listener gets notified of all nodes in the new
        // ordering.
        if (operations_.find(handle) == operations_.end())
          operations_[handle] = OP_UPDATE_POSITION_AND_PROPERTIES;
        id = child.Get(syncable::NEXT_ID);
      }
    }
  }
}

}  // namespace sync_api
<commit_msg>[SYNC] Check if a change's entry is for a position-sensitive model before traversing its parents.<commit_after>// Copyright (c) 2006-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/sync/engine/change_reorder_buffer.h"

#include <limits>
#include <queue>
#include <set>
#include <utility>  // for pair<>
#include <vector>

#include "chrome/browser/sync/syncable/syncable.h"

using std::numeric_limits;
using std::pair;
using std::queue;
using std::set;
using std::vector;

namespace sync_api {

// Traversal provides a way to collect a set of nodes from the syncable
// directory structure and then traverse them, along with any intermediate
// nodes, in a top-down fashion, starting from a single common ancestor.  A
// Traversal starts out empty and is grown by means of the ExpandToInclude
// method.  Once constructed, the top(), begin_children(), and end_children()
// methods can be used to explore the nodes in root-to-leaf order.
class ChangeReorderBuffer::Traversal {
 public:
  typedef pair<int64, int64> ParentChildLink;
  typedef set<ParentChildLink> LinkSet;

  Traversal() : top_(kInvalidId) { }

  // Expand the traversal so that it includes the node indicated by
  // |child_handle|.
  void ExpandToInclude(syncable::BaseTransaction* trans,
                       int64 child_handle) {
    // If |top_| is invalid, this is the first insertion -- easy.
    if (top_ == kInvalidId) {
      top_ = child_handle;
      return;
    }

    int64 node_to_include = child_handle;
    while (node_to_include != kInvalidId && node_to_include != top_) {
      int64 node_parent = 0;

      syncable::Entry node(trans, syncable::GET_BY_HANDLE, node_to_include);
      CHECK(node.good());
      if (node.Get(syncable::ID).IsRoot()) {
        // If we've hit the root, and the root isn't already in the tree
        // (it would have to be |top_| if it were), start a new expansion
        // upwards from |top_| to unite the original traversal with the
        // path we just added that goes from |child_handle| to the root.
        node_to_include = top_;
        top_ = node.Get(syncable::META_HANDLE);
      } else {
        // Otherwise, get the parent ID so that we can add a ParentChildLink.
        syncable::Entry parent(trans, syncable::GET_BY_ID,
                             node.Get(syncable::PARENT_ID));
        CHECK(parent.good());
        node_parent = parent.Get(syncable::META_HANDLE);

        ParentChildLink link(node_parent, node_to_include);

        // If the link exists in the LinkSet |links_|, we don't need to search
        // any higher; we are done.
        if (links_.find(link) != links_.end())
          return;

        // Otherwise, extend |links_|, and repeat on the parent.
        links_.insert(link);
        node_to_include = node_parent;
      }
    }
  }

  // Return the top node of the traversal.  Use this as a starting point
  // for walking the tree.
  int64 top() const { return top_; }

  // Return an iterator corresponding to the first child (in the traversal)
  // of the node specified by |parent_id|.  Iterate this return value until
  // it is equal to the value returned by end_children(parent_id).  The
  // enumeration thus provided is unordered.
  LinkSet::const_iterator begin_children(int64 parent_id) const {
    return links_.upper_bound(
        ParentChildLink(parent_id, numeric_limits<int64>::min()));
  }

  // Return an iterator corresponding to the last child in the traversal
  // of the node specified by |parent_id|.
  LinkSet::const_iterator end_children(int64 parent_id) const {
    return begin_children(parent_id + 1);
  }

 private:
  // The topmost point in the directory hierarchy that is in the traversal,
  // and thus the first node to be traversed.  If the traversal is empty,
  // this is kInvalidId.  If the traversal contains exactly one member, |top_|
  // will be the solitary member, and |links_| will be empty.
  int64 top_;
  // A set of single-level links that compose the traversal below |top_|.  The
  // (parent, child) ordering of values enables efficient lookup of children
  // given the parent handle, which is used for top-down traversal.  |links_|
  // is expected to be connected -- every node that appears as a parent in a
  // link must either appear as a child of another link, or else be the
  // topmost node, |top_|.
  LinkSet links_;

  DISALLOW_COPY_AND_ASSIGN(Traversal);
};

ChangeReorderBuffer::ChangeReorderBuffer() {
}

ChangeReorderBuffer::~ChangeReorderBuffer() {
}

void ChangeReorderBuffer::GetAllChangesInTreeOrder(
    const BaseTransaction* sync_trans,
    vector<ChangeRecord>* changelist) {
  syncable::BaseTransaction* trans = sync_trans->GetWrappedTrans();

  // Step 1: Iterate through the operations, doing three things:
  // (a) Push deleted items straight into the |changelist|.
  // (b) Construct a traversal spanning all non-deleted items.
  // (c) Construct a set of all parent nodes of any position changes.
  set<int64> parents_of_position_changes;
  Traversal traversal;

  OperationMap::const_iterator i;
  for (i = operations_.begin(); i != operations_.end(); ++i) {
    if (i->second == OP_DELETE) {
      ChangeRecord record;
      record.id = i->first;
      record.action = ChangeRecord::ACTION_DELETE;
      if (specifics_.find(record.id) != specifics_.end())
        record.specifics = specifics_[record.id];
      if (extra_data_.find(record.id) != extra_data_.end())
        record.extra = extra_data_[record.id];
      changelist->push_back(record);
    } else {
      traversal.ExpandToInclude(trans, i->first);
      if (i->second == OP_ADD ||
          i->second == OP_UPDATE_POSITION_AND_PROPERTIES) {
        ReadNode node(sync_trans);
        CHECK(node.InitByIdLookup(i->first));

        // We only care about parents of entry's with position-sensitive models.
        if (node.GetEntry()->ShouldMaintainPosition())
          parents_of_position_changes.insert(node.GetParentId());
      }
    }
  }

  // Step 2: Breadth-first expansion of the traversal, enumerating children in
  // the syncable sibling order if there were any position updates.
  queue<int64> to_visit;
  to_visit.push(traversal.top());
  while (!to_visit.empty()) {
    int64 next = to_visit.front();
    to_visit.pop();

    // If the node has an associated action, output a change record.
    i = operations_.find(next);
    if (i != operations_.end()) {
      ChangeRecord record;
      record.id = next;
      if (i->second == OP_ADD)
        record.action = ChangeRecord::ACTION_ADD;
      else
        record.action = ChangeRecord::ACTION_UPDATE;
      if (specifics_.find(record.id) != specifics_.end())
        record.specifics = specifics_[record.id];
      if (extra_data_.find(record.id) != extra_data_.end())
        record.extra = extra_data_[record.id];
      changelist->push_back(record);
    }

    // Now add the children of |next| to |to_visit|.
    if (parents_of_position_changes.find(next) ==
        parents_of_position_changes.end()) {
        // No order changes on this parent -- traverse only the nodes listed
        // in the traversal (and not in sibling order).
        Traversal::LinkSet::const_iterator j = traversal.begin_children(next);
        Traversal::LinkSet::const_iterator end = traversal.end_children(next);
        for (; j != end; ++j) {
          CHECK(j->first == next);
          to_visit.push(j->second);
        }
    } else {
      // There were ordering changes on the children of this parent, so
      // enumerate all the children in the sibling order.
      syncable::Entry parent(trans, syncable::GET_BY_HANDLE, next);
      syncable::Id id = trans->directory()->
          GetFirstChildId(trans, parent.Get(syncable::ID));
      while (!id.IsRoot()) {
        syncable::Entry child(trans, syncable::GET_BY_ID, id);
        CHECK(child.good());
        int64 handle = child.Get(syncable::META_HANDLE);
        to_visit.push(handle);
        // If there is no operation on this child node, record it as as an
        // update, so that the listener gets notified of all nodes in the new
        // ordering.
        if (operations_.find(handle) == operations_.end())
          operations_[handle] = OP_UPDATE_POSITION_AND_PROPERTIES;
        id = child.Get(syncable::NEXT_ID);
      }
    }
  }
}

}  // namespace sync_api
<|endoftext|>


<commit_before>// Copyright (c) 2011 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/ui/gtk/fullscreen_exit_bubble_gtk.h"

#include "base/utf_string_conversions.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "chrome/browser/ui/gtk/rounded_window.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "grit/generated_resources.h"
#include "grit/ui_strings.h"
#include "ui/base/gtk/gtk_floating_container.h"
#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/l10n/l10n_util.h"

namespace {
const GdkColor kFrameColor = GDK_COLOR_RGB(0x63, 0x63, 0x63);
const int kMiddlePaddingPx = 30;
}  // namespace

FullscreenExitBubbleGtk::FullscreenExitBubbleGtk(
    GtkFloatingContainer* container,
    Browser* browser,
    const GURL& url,
    FullscreenExitBubbleType bubble_type)
  : FullscreenExitBubble(browser, url, bubble_type),
      container_(container),
      render_widget_host_view_widget_(browser->GetSelectedTabContents()->
          GetRenderWidgetHostView()->GetNativeView()) {
  InitWidgets();
}

FullscreenExitBubbleGtk::~FullscreenExitBubbleGtk() {
}

void FullscreenExitBubbleGtk::UpdateContent(
    const GURL& url,
    FullscreenExitBubbleType bubble_type) {
  if (bubble_type == FEB_TYPE_NONE) {
    NOTREACHED();
    bubble_type = FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION;
  }

  url_ = url;
  bubble_type_ = bubble_type;

  gtk_label_set_text(GTK_LABEL(message_label_),
                     UTF16ToUTF8(GetCurrentMessageText()).c_str());
  if (fullscreen_bubble::ShowButtonsForType(bubble_type)) {
    gtk_widget_hide(link_);
    gtk_widget_hide(instruction_label_);
    gtk_widget_show(allow_button_);
    gtk_button_set_label(GTK_BUTTON(deny_button_),
                         UTF16ToUTF8(GetCurrentDenyButtonText()).c_str());
    gtk_widget_show(deny_button_);
  } else {
    if (bubble_type == FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION) {
      gtk_widget_show(link_);
      gtk_widget_hide(instruction_label_);
    } else {
      gtk_widget_hide(link_);
      gtk_widget_show(instruction_label_);
    }
    gtk_widget_hide(allow_button_);
    gtk_widget_hide(deny_button_);
  }

  Show();
  StopWatchingMouse();
  StartWatchingMouseIfNecessary();
}

void FullscreenExitBubbleGtk::InitWidgets() {
  // The exit bubble is a gtk_chrome_link_button inside a gtk event box and gtk
  // alignment (these provide the background color).  This is then made rounded
  // and put into a slide widget.

  // The Windows code actually looks up the accelerator key in the accelerator
  // table and then converts the key to a string (in a switch statement). This
  // doesn't seem to be implemented for Gtk, so we just use F11 directly.
  std::string exit_text_utf8(l10n_util::GetStringFUTF8(
      IDS_EXIT_FULLSCREEN_MODE, l10n_util::GetStringUTF16(IDS_APP_F11_KEY)));

  hbox_ = gtk_hbox_new(false, ui::kControlSpacing);

  message_label_ = gtk_label_new(GetMessage(url_).c_str());
  gtk_box_pack_start(GTK_BOX(hbox_), message_label_, FALSE, FALSE, 0);

  allow_button_ = gtk_button_new_with_label(
      l10n_util::GetStringUTF8(IDS_FULLSCREEN_ALLOW).c_str());
  gtk_widget_set_no_show_all(allow_button_, FALSE);
  gtk_box_pack_start(GTK_BOX(hbox_), allow_button_, FALSE, FALSE, 0);

  deny_button_ = gtk_button_new_with_label(
      l10n_util::GetStringUTF8(IDS_FULLSCREEN_DENY).c_str());
  gtk_widget_set_no_show_all(deny_button_, FALSE);
  gtk_box_pack_start(GTK_BOX(hbox_), deny_button_, FALSE, FALSE, 0);

  link_ = gtk_chrome_link_button_new(exit_text_utf8.c_str());
  gtk_widget_set_no_show_all(link_, FALSE);
  gtk_chrome_link_button_set_use_gtk_theme(GTK_CHROME_LINK_BUTTON(link_),
                                           FALSE);
  gtk_box_pack_start(GTK_BOX(hbox_), link_, FALSE, FALSE, 0);

  instruction_label_ = gtk_label_new(UTF16ToUTF8(GetInstructionText()).c_str());
  gtk_widget_set_no_show_all(instruction_label_, FALSE);
  gtk_box_pack_start(GTK_BOX(hbox_), instruction_label_, FALSE, FALSE, 0);

  GtkWidget* bubble = gtk_util::CreateGtkBorderBin(
      hbox_, &ui::kGdkWhite,
      kPaddingPx, kPaddingPx, kPaddingPx, kPaddingPx);
  gtk_util::ActAsRoundedWindow(bubble, kFrameColor, 3,
      gtk_util::ROUNDED_ALL, gtk_util::BORDER_ALL);
  GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
  gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 5, 0, 0, 0);
  gtk_container_add(GTK_CONTAINER(alignment), bubble);
  ui_container_.Own(alignment);

  slide_widget_.reset(new SlideAnimatorGtk(ui_container_.get(),
      SlideAnimatorGtk::DOWN, kSlideOutDurationMs, false, false, NULL));
  gtk_widget_set_name(widget(), "exit-fullscreen-bubble");
  gtk_widget_show_all(ui_container_.get());
  gtk_widget_show(widget());
  slide_widget_->OpenWithoutAnimation();

  gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(container_),
                                      widget());

  signals_.Connect(container_, "set-floating-position",
                   G_CALLBACK(OnSetFloatingPositionThunk), this);
  signals_.Connect(link_, "clicked", G_CALLBACK(OnLinkClickedThunk), this);
  signals_.Connect(allow_button_, "clicked",
                   G_CALLBACK(&OnAllowClickedThunk), this);
  signals_.Connect(deny_button_, "clicked",
                   G_CALLBACK(&OnDenyClickedThunk), this);

  UpdateContent(url_, bubble_type_);
}

std::string FullscreenExitBubbleGtk::GetMessage(const GURL& url) {
  if (url.is_empty()) {
    return l10n_util::GetStringUTF8(
        IDS_FULLSCREEN_USER_ENTERED_FULLSCREEN);
  }
  if (url.SchemeIsFile())
    return l10n_util::GetStringUTF8(IDS_FULLSCREEN_ENTERED_FULLSCREEN);
  return l10n_util::GetStringFUTF8(IDS_FULLSCREEN_SITE_ENTERED_FULLSCREEN,
      UTF8ToUTF16(url.host()));
}

gfx::Rect FullscreenExitBubbleGtk::GetPopupRect(
    bool ignore_animation_state) const {
  GtkRequisition bubble_size;
  if (ignore_animation_state) {
    gtk_widget_size_request(ui_container_.get(), &bubble_size);
  } else {
    gtk_widget_size_request(widget(), &bubble_size);
  }
  return gfx::Rect(bubble_size.width, bubble_size.height);
}

gfx::Point FullscreenExitBubbleGtk::GetCursorScreenPoint() {
  GdkDisplay* display = gtk_widget_get_display(widget());

  // Get cursor position.
  // TODO: this hits the X server, so we may want to consider decreasing
  // kPositionCheckHz if we detect that we're running remotely.
  int x, y;
  gdk_display_get_pointer(display, NULL, &x, &y, NULL);

  return gfx::Point(x, y);
}

bool FullscreenExitBubbleGtk::WindowContainsPoint(gfx::Point pos) {
  GtkWindow* window = GTK_WINDOW(
      gtk_widget_get_ancestor(widget(), GTK_TYPE_WINDOW));
  int width, height, x, y;
  gtk_window_get_size(window, &width, &height);
  gtk_window_get_position(window, &x, &y);
  return gfx::Rect(x, y, width, height).Contains(pos);
}

bool FullscreenExitBubbleGtk::IsWindowActive() {
  if (!widget()->parent)
    return false;
  GtkWindow* window = GTK_WINDOW(
      gtk_widget_get_ancestor(widget(), GTK_TYPE_WINDOW));
  return gtk_window_is_active(window);
}

void FullscreenExitBubbleGtk::Hide() {
  slide_widget_->Close();
}

void FullscreenExitBubbleGtk::Show() {
  slide_widget_->Open();
}

bool FullscreenExitBubbleGtk::IsAnimating() {
  return slide_widget_->IsAnimating();
}

void FullscreenExitBubbleGtk::StartWatchingMouseIfNecessary() {
  if (!fullscreen_bubble::ShowButtonsForType(bubble_type_))
    StartWatchingMouse();
}

void FullscreenExitBubbleGtk::OnSetFloatingPosition(
    GtkWidget* floating_container,
    GtkAllocation* allocation) {
  GtkRequisition bubble_size;
  gtk_widget_size_request(widget(), &bubble_size);

  // Position the bubble at the top center of the screen.
  GValue value = { 0, };
  g_value_init(&value, G_TYPE_INT);
  g_value_set_int(&value, (allocation->width - bubble_size.width) / 2);
  gtk_container_child_set_property(GTK_CONTAINER(floating_container),
                                   widget(), "x", &value);

  g_value_set_int(&value, 0);
  gtk_container_child_set_property(GTK_CONTAINER(floating_container),
                                   widget(), "y", &value);
  g_value_unset(&value);
}

void FullscreenExitBubbleGtk::OnLinkClicked(GtkWidget* link) {
  gtk_widget_grab_focus(render_widget_host_view_widget_);
  ToggleFullscreen();
}

void FullscreenExitBubbleGtk::OnAllowClicked(GtkWidget* button) {
  gtk_widget_grab_focus(render_widget_host_view_widget_);
  Accept();
  UpdateContent(url_, bubble_type_);
  StartWatchingMouse();
}
void FullscreenExitBubbleGtk::OnDenyClicked(GtkWidget* button) {
  gtk_widget_grab_focus(render_widget_host_view_widget_);
  Cancel();
}
<commit_msg>Remove extraneous StartWatchingMouse().<commit_after>// Copyright (c) 2011 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/ui/gtk/fullscreen_exit_bubble_gtk.h"

#include "base/utf_string_conversions.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "chrome/browser/ui/gtk/rounded_window.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "grit/generated_resources.h"
#include "grit/ui_strings.h"
#include "ui/base/gtk/gtk_floating_container.h"
#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/l10n/l10n_util.h"

namespace {
const GdkColor kFrameColor = GDK_COLOR_RGB(0x63, 0x63, 0x63);
const int kMiddlePaddingPx = 30;
}  // namespace

FullscreenExitBubbleGtk::FullscreenExitBubbleGtk(
    GtkFloatingContainer* container,
    Browser* browser,
    const GURL& url,
    FullscreenExitBubbleType bubble_type)
  : FullscreenExitBubble(browser, url, bubble_type),
      container_(container),
      render_widget_host_view_widget_(browser->GetSelectedTabContents()->
          GetRenderWidgetHostView()->GetNativeView()) {
  InitWidgets();
}

FullscreenExitBubbleGtk::~FullscreenExitBubbleGtk() {
}

void FullscreenExitBubbleGtk::UpdateContent(
    const GURL& url,
    FullscreenExitBubbleType bubble_type) {
  if (bubble_type == FEB_TYPE_NONE) {
    NOTREACHED();
    bubble_type = FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION;
  }

  url_ = url;
  bubble_type_ = bubble_type;

  gtk_label_set_text(GTK_LABEL(message_label_),
                     UTF16ToUTF8(GetCurrentMessageText()).c_str());
  if (fullscreen_bubble::ShowButtonsForType(bubble_type)) {
    gtk_widget_hide(link_);
    gtk_widget_hide(instruction_label_);
    gtk_widget_show(allow_button_);
    gtk_button_set_label(GTK_BUTTON(deny_button_),
                         UTF16ToUTF8(GetCurrentDenyButtonText()).c_str());
    gtk_widget_show(deny_button_);
  } else {
    if (bubble_type == FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION) {
      gtk_widget_show(link_);
      gtk_widget_hide(instruction_label_);
    } else {
      gtk_widget_hide(link_);
      gtk_widget_show(instruction_label_);
    }
    gtk_widget_hide(allow_button_);
    gtk_widget_hide(deny_button_);
  }

  Show();
  StopWatchingMouse();
  StartWatchingMouseIfNecessary();
}

void FullscreenExitBubbleGtk::InitWidgets() {
  // The exit bubble is a gtk_chrome_link_button inside a gtk event box and gtk
  // alignment (these provide the background color).  This is then made rounded
  // and put into a slide widget.

  // The Windows code actually looks up the accelerator key in the accelerator
  // table and then converts the key to a string (in a switch statement). This
  // doesn't seem to be implemented for Gtk, so we just use F11 directly.
  std::string exit_text_utf8(l10n_util::GetStringFUTF8(
      IDS_EXIT_FULLSCREEN_MODE, l10n_util::GetStringUTF16(IDS_APP_F11_KEY)));

  hbox_ = gtk_hbox_new(false, ui::kControlSpacing);

  message_label_ = gtk_label_new(GetMessage(url_).c_str());
  gtk_box_pack_start(GTK_BOX(hbox_), message_label_, FALSE, FALSE, 0);

  allow_button_ = gtk_button_new_with_label(
      l10n_util::GetStringUTF8(IDS_FULLSCREEN_ALLOW).c_str());
  gtk_widget_set_no_show_all(allow_button_, FALSE);
  gtk_box_pack_start(GTK_BOX(hbox_), allow_button_, FALSE, FALSE, 0);

  deny_button_ = gtk_button_new_with_label(
      l10n_util::GetStringUTF8(IDS_FULLSCREEN_DENY).c_str());
  gtk_widget_set_no_show_all(deny_button_, FALSE);
  gtk_box_pack_start(GTK_BOX(hbox_), deny_button_, FALSE, FALSE, 0);

  link_ = gtk_chrome_link_button_new(exit_text_utf8.c_str());
  gtk_widget_set_no_show_all(link_, FALSE);
  gtk_chrome_link_button_set_use_gtk_theme(GTK_CHROME_LINK_BUTTON(link_),
                                           FALSE);
  gtk_box_pack_start(GTK_BOX(hbox_), link_, FALSE, FALSE, 0);

  instruction_label_ = gtk_label_new(UTF16ToUTF8(GetInstructionText()).c_str());
  gtk_widget_set_no_show_all(instruction_label_, FALSE);
  gtk_box_pack_start(GTK_BOX(hbox_), instruction_label_, FALSE, FALSE, 0);

  GtkWidget* bubble = gtk_util::CreateGtkBorderBin(
      hbox_, &ui::kGdkWhite,
      kPaddingPx, kPaddingPx, kPaddingPx, kPaddingPx);
  gtk_util::ActAsRoundedWindow(bubble, kFrameColor, 3,
      gtk_util::ROUNDED_ALL, gtk_util::BORDER_ALL);
  GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
  gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 5, 0, 0, 0);
  gtk_container_add(GTK_CONTAINER(alignment), bubble);
  ui_container_.Own(alignment);

  slide_widget_.reset(new SlideAnimatorGtk(ui_container_.get(),
      SlideAnimatorGtk::DOWN, kSlideOutDurationMs, false, false, NULL));
  gtk_widget_set_name(widget(), "exit-fullscreen-bubble");
  gtk_widget_show_all(ui_container_.get());
  gtk_widget_show(widget());
  slide_widget_->OpenWithoutAnimation();

  gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(container_),
                                      widget());

  signals_.Connect(container_, "set-floating-position",
                   G_CALLBACK(OnSetFloatingPositionThunk), this);
  signals_.Connect(link_, "clicked", G_CALLBACK(OnLinkClickedThunk), this);
  signals_.Connect(allow_button_, "clicked",
                   G_CALLBACK(&OnAllowClickedThunk), this);
  signals_.Connect(deny_button_, "clicked",
                   G_CALLBACK(&OnDenyClickedThunk), this);

  UpdateContent(url_, bubble_type_);
}

std::string FullscreenExitBubbleGtk::GetMessage(const GURL& url) {
  if (url.is_empty()) {
    return l10n_util::GetStringUTF8(
        IDS_FULLSCREEN_USER_ENTERED_FULLSCREEN);
  }
  if (url.SchemeIsFile())
    return l10n_util::GetStringUTF8(IDS_FULLSCREEN_ENTERED_FULLSCREEN);
  return l10n_util::GetStringFUTF8(IDS_FULLSCREEN_SITE_ENTERED_FULLSCREEN,
      UTF8ToUTF16(url.host()));
}

gfx::Rect FullscreenExitBubbleGtk::GetPopupRect(
    bool ignore_animation_state) const {
  GtkRequisition bubble_size;
  if (ignore_animation_state) {
    gtk_widget_size_request(ui_container_.get(), &bubble_size);
  } else {
    gtk_widget_size_request(widget(), &bubble_size);
  }
  return gfx::Rect(bubble_size.width, bubble_size.height);
}

gfx::Point FullscreenExitBubbleGtk::GetCursorScreenPoint() {
  GdkDisplay* display = gtk_widget_get_display(widget());

  // Get cursor position.
  // TODO: this hits the X server, so we may want to consider decreasing
  // kPositionCheckHz if we detect that we're running remotely.
  int x, y;
  gdk_display_get_pointer(display, NULL, &x, &y, NULL);

  return gfx::Point(x, y);
}

bool FullscreenExitBubbleGtk::WindowContainsPoint(gfx::Point pos) {
  GtkWindow* window = GTK_WINDOW(
      gtk_widget_get_ancestor(widget(), GTK_TYPE_WINDOW));
  int width, height, x, y;
  gtk_window_get_size(window, &width, &height);
  gtk_window_get_position(window, &x, &y);
  return gfx::Rect(x, y, width, height).Contains(pos);
}

bool FullscreenExitBubbleGtk::IsWindowActive() {
  if (!widget()->parent)
    return false;
  GtkWindow* window = GTK_WINDOW(
      gtk_widget_get_ancestor(widget(), GTK_TYPE_WINDOW));
  return gtk_window_is_active(window);
}

void FullscreenExitBubbleGtk::Hide() {
  slide_widget_->Close();
}

void FullscreenExitBubbleGtk::Show() {
  slide_widget_->Open();
}

bool FullscreenExitBubbleGtk::IsAnimating() {
  return slide_widget_->IsAnimating();
}

void FullscreenExitBubbleGtk::StartWatchingMouseIfNecessary() {
  if (!fullscreen_bubble::ShowButtonsForType(bubble_type_))
    StartWatchingMouse();
}

void FullscreenExitBubbleGtk::OnSetFloatingPosition(
    GtkWidget* floating_container,
    GtkAllocation* allocation) {
  GtkRequisition bubble_size;
  gtk_widget_size_request(widget(), &bubble_size);

  // Position the bubble at the top center of the screen.
  GValue value = { 0, };
  g_value_init(&value, G_TYPE_INT);
  g_value_set_int(&value, (allocation->width - bubble_size.width) / 2);
  gtk_container_child_set_property(GTK_CONTAINER(floating_container),
                                   widget(), "x", &value);

  g_value_set_int(&value, 0);
  gtk_container_child_set_property(GTK_CONTAINER(floating_container),
                                   widget(), "y", &value);
  g_value_unset(&value);
}

void FullscreenExitBubbleGtk::OnLinkClicked(GtkWidget* link) {
  gtk_widget_grab_focus(render_widget_host_view_widget_);
  ToggleFullscreen();
}

void FullscreenExitBubbleGtk::OnAllowClicked(GtkWidget* button) {
  gtk_widget_grab_focus(render_widget_host_view_widget_);
  Accept();
  UpdateContent(url_, bubble_type_);
}
void FullscreenExitBubbleGtk::OnDenyClicked(GtkWidget* button) {
  gtk_widget_grab_focus(render_widget_host_view_widget_);
  Cancel();
}
<|endoftext|>