<commit_before>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2018 Intel Corporation. All Rights Reserved.

#include "../include/librealsense2/rs.hpp"
#include "../include/librealsense2/rsutil.h"
#include "proc/synthetic-stream.h"
#include "proc/occlusion-filter.h"
//#include  "../../common/tiny-profiler.h"
#include <vector>
#include <cmath>

namespace librealsense
{
    occlusion_filter::occlusion_filter() : _occlusion_filter(occlusion_monotonic_scan) , _occlusion_scanning(horizontal)
    {
    }

    void occlusion_filter::set_texel_intrinsics(const rs2_intrinsics& in)
    {
        _texels_intrinsics = in;
        _texels_depth.resize(_texels_intrinsics.value().width*_texels_intrinsics.value().height);
    }

   void occlusion_filter::process(float3* points, float2* uv_map, const std::vector<float2> & pix_coord, const rs2::depth_frame& depth) const
    {
        switch (_occlusion_filter)
        {
        case occlusion_none:
            break;
        case occlusion_monotonic_scan:
            monotonic_heuristic_invalidation(points, uv_map, pix_coord, depth);
            break;
        default:
            throw std::runtime_error(to_string() << "Unsupported occlusion filter type " << _occlusion_filter << " requested");
            break;
        }
    }
   int gcd(int a, int b) {
       if (b == 0)
           return a;
       return gcd(b, a % b);
   }
   // Return the greatest common divisor of a
   // and b which lie in the given range.
   int maxDivisorRange(int a, int b, int lo, int hi)
   {
       if (lo > hi)
       {
           int tmp = lo;
           lo = hi;
           hi = tmp;
       }
       int g = gcd(a, b);
       int res = g;

       // Loop from 1 to sqrt(GCD(a, b).
       for (int i = lo; i * i <= g && i <= hi; i++)

           if ((g % i == 0) && (g / i) < hi)
           {
               res = g / i;
               break;
           }

       return res;
   }
   template<size_t SIZE>
   void rotate_image_optimized(byte* dest[], const byte* source, int width, int height)
   {

       auto width_out = height;
       auto height_out = width;

       auto out = dest[0];
       auto buffer_size = maxDivisorRange(height, width, 1, ROTATION_BUFFER_SIZE);

       std::vector<byte> buffer(buffer_size * buffer_size * SIZE);
       for (int i = 0; i < height; i = i + buffer_size)
       {
           for (int j = 0; j < width; j = j + buffer_size)
           {
               for (int ii = 0; ii < buffer_size; ii++) {
                   for (int jj = 0; jj < buffer_size; jj++) {
                       auto source_index = (j + jj + (width * (i + ii))) * SIZE; // capture a buffer from source
                       memcpy((void*)&(buffer[buffer_size * (buffer_size - jj - 1) + (buffer_size - ii - 1) * SIZE]), &source[source_index], SIZE);
                   }
               }
               for (int ii = 0; ii < buffer_size; ii++) { // copy buffer to out
                   auto out_index = ((height - (i + buffer_size - 1) - 1) + (width - (j + buffer_size - 1) - 1 + ii) * height) * SIZE;
                   memcpy(&out[out_index], &(buffer[ii]), SIZE * buffer_size);
               }

           }
       }
   }
    // IMPORTANT! This implementation is based on the assumption that the RGB sensor is positioned strictly to the left of the depth sensor.
    // namely D415/D435 and SR300. The implementation WILL NOT work properly for different setups
    // Heuristic occlusion invalidation algorithm:
    // -  Use the uv texels calculated when projecting depth to color
    // -  Scan each line from left to right and check the the U coordinate in the mapping is raising monotonically.
    // -  The occlusion is designated as U coordinate for a given pixel is less than the U coordinate of the predecessing pixel.
    // -  The UV mapping for the occluded pixel is reset to (0,0). Later on the (0,0) coordinate in the texture map is overwritten
    //    with a invalidation color such as black/magenta according to the purpose (production/debugging)
   void occlusion_filter::monotonic_heuristic_invalidation(float3* points, float2* uv_map, const std::vector<float2>& pix_coord, const rs2::depth_frame& depth) const
   {
       float occZTh = 0.1f; //meters
       int occDilationSz = 1;
       auto points_width = _depth_intrinsics->width;
       auto points_height = _depth_intrinsics->height;
       auto pixels_ptr = pix_coord.data();
       auto points_ptr = points;
       auto uv_map_ptr = uv_map;
       float maxInLine = -1;
       float maxZ = 0;

       if (_occlusion_scanning == horizontal)
       {
           for( size_t y = 0; y < points_height; ++y )
           {
               maxInLine = -1;
               maxZ = 0;
               int occDilationLeft = 0;

               for( size_t x = 0; x < points_width; ++x )
               {
                   if( points_ptr->z )
                   {
                       // Occlusion detection
                       if( pixels_ptr->x < maxInLine
                           || ( pixels_ptr->x == maxInLine && ( points_ptr->z - maxZ ) > occZTh ) )
                       {
                           *points_ptr = { 0, 0, 0 };
                           occDilationLeft = occDilationSz;
                       }
                       else
                       {
                           maxInLine = pixels_ptr->x;
                           maxZ = points_ptr->z;
                           if( occDilationLeft > 0 )
                           {
                               *points_ptr = { 0, 0, 0 };
                               occDilationLeft--;
                           }
                       }
                   }
                   ++points_ptr;
                   ++uv_map_ptr;
                   ++pixels_ptr;
               }
           }
       }
       else if (_occlusion_scanning == vertical)
       {
           auto rotated_depth_width = _depth_intrinsics->height;
           auto rotated_depth_height = _depth_intrinsics->width;
           auto depth_ptr = (byte*)(depth.get_data());
           std::vector< byte > alloc( depth.get_bytes_per_pixel() * points_width * points_height );
           byte* depth_planes[1];
           depth_planes[0] = alloc.data();

           rotate_image_optimized<2>(depth_planes, (const byte*)(depth.get_data()), points_width, points_height);

           // scan depth frame after rotation: check if there is a noticed jump between adjacen pixels in Z-axis (depth), it means there could be occlusion.
           // save suspected points and run occlusion-invalidation vertical scan only on them
           // after rotation : height = points_width , width = points_height
           for (int i = 0; i < rotated_depth_height; i++)
           {
               for (int j = 0; j < rotated_depth_width; j++)
               {
                   // before depth frame rotation: occlusion detected in the positive direction of Y
                   // after rotation : scan from right to left (positive direction of X) to detect occlusion
                   // compare depth each pixel only with the pixel on its right (i,j+1)
                   auto index = (j + (rotated_depth_width * i));
                   auto uv_index = ((rotated_depth_height - i - 1) + (rotated_depth_width - j - 1) * rotated_depth_height);
                   auto index_right = index + 1;
                   uint16_t* diff_depth_ptr = (uint16_t*)depth_planes[0];
                   uint16_t diff_right = abs((uint16_t)(*(diff_depth_ptr + index)) - (uint16_t)(*(diff_depth_ptr + index_right)));
                   float scaled_threshold = DEPTH_OCCLUSION_THRESHOLD / _depth_units;
                   if (diff_right > scaled_threshold)
                   {
                       points_ptr = points + uv_index;
                       uv_map_ptr = uv_map + uv_index;

                       if (j >= VERTICAL_SCAN_WINDOW_SIZE) {
                           maxInLine = (uv_map_ptr - 1 * points_width)->y;
                           for (size_t y = 0; y <= VERTICAL_SCAN_WINDOW_SIZE; ++y)
                           {
                               if (((uv_map_ptr + y * points_width)->y < maxInLine))
                               {
                                   *(points_ptr + y * points_width) = { 0.f, 0.f };
                               }
                               else
                               {
                                   break;
                               }

                           }

                       }
                   }
               }
           }
       }
   }
    // Prepare texture map without occlusion that for every texture coordinate there no more than one depth point that is mapped to it
    // i.e. for every (u,v) map coordinate we select the depth point with minimum Z. all other points that are mapped to this texel will be invalidated
    // Algo input data:
    // Vector of 3D [xyz] coordinates of depth_width*depth_height size
    // Vector of 2D [i,j] coordinates where the val[i,j] stores the texture coordinate (s,t) for the corresponding (i,j) pixel in depth frame
    // Algo intermediate data:
    // Vector of depth values (floats) in size of the mapped texture (different from depth width*height) where
    // each (i,j) cell holds the minimal Z among all the depth pixels that are mapped to the specific texel
    void occlusion_filter::comprehensive_invalidation(float3* points, float2* uv_map, const std::vector<float2> & pix_coord) const
    {
        auto depth_points = points;
        auto mapped_pix = pix_coord.data();
        size_t mapped_tex_width = _texels_intrinsics->width;
        size_t mapped_tex_height = _texels_intrinsics->height;
        size_t points_width = _depth_intrinsics->width;
        size_t points_height = _depth_intrinsics->height;

        static const float z_threshold = 0.05f; // Compensate for temporal noise when comparing Z values

        // Clear previous data
        memset((void*)(_texels_depth.data()), 0, _texels_depth.size() * sizeof(float));

        // Pass1 -generate texels mapping with minimal depth for each texel involved
        for (size_t i = 0; i < points_height; i++)
        {
            for (size_t j = 0; j < points_width; j++)
            {
                if ((depth_points->z > 0.0001f) &&
                    (mapped_pix->x > 0.f) && (mapped_pix->x < mapped_tex_width) &&
                    (mapped_pix->y > 0.f) && (mapped_pix->y < mapped_tex_height))
                {
                    size_t texel_index = (size_t)(mapped_pix->y)*mapped_tex_width + (size_t)(mapped_pix->x);

                    if ((_texels_depth[texel_index] < 0.0001f) || ((_texels_depth[texel_index] + z_threshold) > depth_points->z))
                    {
                        _texels_depth[texel_index] = depth_points->z;
                    }
                }

                ++depth_points;
                ++mapped_pix;
            }
        }

        mapped_pix = pix_coord.data();
        depth_points = points;
        auto uv_ptr = uv_map;

        // Pass2 -invalidate depth texels with occlusion traits
        for (size_t i = 0; i < points_height; i++)
        {
            for (size_t j = 0; j < points_width; j++)
            {
                if ((depth_points->z > 0.0001f) &&
                    (mapped_pix->x > 0.f) && (mapped_pix->x < mapped_tex_width) &&
                    (mapped_pix->y > 0.f) && (mapped_pix->y < mapped_tex_height))
                {
                    size_t texel_index = (size_t)(mapped_pix->y)*mapped_tex_width + (size_t)(mapped_pix->x);

                    if ((_texels_depth[texel_index] > 0.0001f) && ((_texels_depth[texel_index] + z_threshold) < depth_points->z))
                    {
                        *uv_ptr = { 0.f, 0.f };
                    }
                }

                ++depth_points;
                ++mapped_pix;
                ++uv_ptr;
            }
        }
    }
}
<commit_msg>L515 occlusion filter bug fix<commit_after>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2018 Intel Corporation. All Rights Reserved.

#include "../include/librealsense2/rs.hpp"
#include "../include/librealsense2/rsutil.h"
#include "proc/synthetic-stream.h"
#include "proc/occlusion-filter.h"
//#include  "../../common/tiny-profiler.h"
#include <vector>
#include <cmath>

namespace librealsense
{
    occlusion_filter::occlusion_filter() : _occlusion_filter(occlusion_monotonic_scan) , _occlusion_scanning(horizontal)
    {
    }

    void occlusion_filter::set_texel_intrinsics(const rs2_intrinsics& in)
    {
        _texels_intrinsics = in;
        _texels_depth.resize(_texels_intrinsics.value().width*_texels_intrinsics.value().height);
    }

   void occlusion_filter::process(float3* points, float2* uv_map, const std::vector<float2> & pix_coord, const rs2::depth_frame& depth) const
    {
        switch (_occlusion_filter)
        {
        case occlusion_none:
            break;
        case occlusion_monotonic_scan:
            monotonic_heuristic_invalidation(points, uv_map, pix_coord, depth);
            break;
        default:
            throw std::runtime_error(to_string() << "Unsupported occlusion filter type " << _occlusion_filter << " requested");
            break;
        }
    }
   int gcd(int a, int b) {
       if (b == 0)
           return a;
       return gcd(b, a % b);
   }
   // Return the greatest common divisor of a
   // and b which lie in the given range.
   int maxDivisorRange(int a, int b, int lo, int hi)
   {
       if (lo > hi)
       {
           std::swap(hi, lo);
       }
       int g = gcd(a, b);
       int res = g;

       // Loop from 1 to sqrt(GCD(a, b).
       for (int i = lo; i * i <= g && i <= hi; i++)

           if ((g % i == 0) && (g / i) < hi)
           {
               res = g / i;
               break;
           }

       return res;
   }
   template<size_t SIZE>
   void rotate_image_optimized(byte* dest[], const byte* source, int width, int height)
   {

       auto width_out = height;
       auto height_out = width;

       auto out = dest[0];
       auto buffer_size = maxDivisorRange(height, width, 1, ROTATION_BUFFER_SIZE);

       byte** buffer = new byte * [buffer_size];
       for (int i = 0; i < buffer_size; ++i)
           buffer[i] = new byte[buffer_size * SIZE];

       for (int i = 0; i <= height - buffer_size; i = i + buffer_size)
       {
           for (int j = 0; j <= width - buffer_size; j = j + buffer_size)
           {
               for (int ii = 0; ii < buffer_size; ++ii)
               {
                   for (int jj = 0; jj < buffer_size; ++jj)
                   {
                       auto source_index = ((j + jj) + (width * (i + ii))) * SIZE;
                       memcpy((void*)&(buffer[(buffer_size-1 - jj)][(buffer_size-1 - ii) * SIZE]), &source[source_index], SIZE);
                   }
               }

               for (int ii = 0; ii < buffer_size; ++ii)
               {
                   auto out_index = (((height_out - buffer_size - j + 1) * width_out) - i - buffer_size + (ii)*width_out);
                   memcpy(&out[(out_index)*SIZE], (buffer[ii]), buffer_size * SIZE);
               }
           }
       }

       for (int i = 0; i < buffer_size; ++i)
       {
           delete[] buffer[i];
       }
       delete[] buffer;

   }
    // IMPORTANT! This implementation is based on the assumption that the RGB sensor is positioned strictly to the left of the depth sensor.
    // namely D415/D435 and SR300. The implementation WILL NOT work properly for different setups
    // Heuristic occlusion invalidation algorithm:
    // -  Use the uv texels calculated when projecting depth to color
    // -  Scan each line from left to right and check the the U coordinate in the mapping is raising monotonically.
    // -  The occlusion is designated as U coordinate for a given pixel is less than the U coordinate of the predecessing pixel.
    // -  The UV mapping for the occluded pixel is reset to (0,0). Later on the (0,0) coordinate in the texture map is overwritten
    //    with a invalidation color such as black/magenta according to the purpose (production/debugging)
   void occlusion_filter::monotonic_heuristic_invalidation(float3* points, float2* uv_map, const std::vector<float2>& pix_coord, const rs2::depth_frame& depth) const
   {
       float occZTh = 0.1f; //meters
       int occDilationSz = 1;
       auto points_width = _depth_intrinsics->width;
       auto points_height = _depth_intrinsics->height;
       auto pixels_ptr = pix_coord.data();
       auto points_ptr = points;
       auto uv_map_ptr = uv_map;
       float maxInLine = -1;
       float maxZ = 0;

       if (_occlusion_scanning == horizontal)
       {
           for( size_t y = 0; y < points_height; ++y )
           {
               maxInLine = -1;
               maxZ = 0;
               int occDilationLeft = 0;

               for( size_t x = 0; x < points_width; ++x )
               {
                   if( points_ptr->z )
                   {
                       // Occlusion detection
                       if( pixels_ptr->x < maxInLine
                           || ( pixels_ptr->x == maxInLine && ( points_ptr->z - maxZ ) > occZTh ) )
                       {
                           *points_ptr = { 0, 0, 0 };
                           occDilationLeft = occDilationSz;
                       }
                       else
                       {
                           maxInLine = pixels_ptr->x;
                           maxZ = points_ptr->z;
                           if( occDilationLeft > 0 )
                           {
                               *points_ptr = { 0, 0, 0 };
                               occDilationLeft--;
                           }
                       }
                   }
                   ++points_ptr;
                   ++uv_map_ptr;
                   ++pixels_ptr;
               }
           }
       }
       else if (_occlusion_scanning == vertical)
       {
           auto rotated_depth_width = _depth_intrinsics->height;
           auto rotated_depth_height = _depth_intrinsics->width;
           auto depth_ptr = (byte*)(depth.get_data());
           std::vector< byte > alloc( depth.get_bytes_per_pixel() * points_width * points_height );
           byte* depth_planes[1];
           depth_planes[0] = alloc.data();

           rotate_image_optimized<2>(depth_planes, (const byte*)(depth.get_data()), points_width, points_height);

           // scan depth frame after rotation: check if there is a noticed jump between adjacen pixels in Z-axis (depth), it means there could be occlusion.
           // save suspected points and run occlusion-invalidation vertical scan only on them
           // after rotation : height = points_width , width = points_height
           for (int i = 0; i < rotated_depth_height; i++)
           {
               for (int j = 0; j < rotated_depth_width; j++)
               {
                   // before depth frame rotation: occlusion detected in the positive direction of Y
                   // after rotation : scan from right to left (positive direction of X) to detect occlusion
                   // compare depth each pixel only with the pixel on its right (i,j+1)
                   auto index = (j + (rotated_depth_width * i));
                   auto uv_index = ((rotated_depth_height - i - 1) + (rotated_depth_width - j - 1) * rotated_depth_height);
                   auto index_right = index + 1;
                   uint16_t* diff_depth_ptr = (uint16_t*)depth_planes[0];
                   uint16_t diff_right = abs((uint16_t)(*(diff_depth_ptr + index)) - (uint16_t)(*(diff_depth_ptr + index_right)));
                   float scaled_threshold = DEPTH_OCCLUSION_THRESHOLD / _depth_units;
                   if (diff_right > scaled_threshold)
                   {
                       points_ptr = points + uv_index;
                       uv_map_ptr = uv_map + uv_index;

                       if (j >= VERTICAL_SCAN_WINDOW_SIZE) {
                           maxInLine = (uv_map_ptr - 1 * points_width)->y;
                           for (size_t y = 0; y <= VERTICAL_SCAN_WINDOW_SIZE; ++y)
                           {
                               if (((uv_map_ptr + y * points_width)->y < maxInLine))
                               {
                                   *(points_ptr + y * points_width) = { 0.f, 0.f };
                               }
                               else
                               {
                                   break;
                               }

                           }

                       }
                   }
               }
           }
       }
   }
    // Prepare texture map without occlusion that for every texture coordinate there no more than one depth point that is mapped to it
    // i.e. for every (u,v) map coordinate we select the depth point with minimum Z. all other points that are mapped to this texel will be invalidated
    // Algo input data:
    // Vector of 3D [xyz] coordinates of depth_width*depth_height size
    // Vector of 2D [i,j] coordinates where the val[i,j] stores the texture coordinate (s,t) for the corresponding (i,j) pixel in depth frame
    // Algo intermediate data:
    // Vector of depth values (floats) in size of the mapped texture (different from depth width*height) where
    // each (i,j) cell holds the minimal Z among all the depth pixels that are mapped to the specific texel
    void occlusion_filter::comprehensive_invalidation(float3* points, float2* uv_map, const std::vector<float2> & pix_coord) const
    {
        auto depth_points = points;
        auto mapped_pix = pix_coord.data();
        size_t mapped_tex_width = _texels_intrinsics->width;
        size_t mapped_tex_height = _texels_intrinsics->height;
        size_t points_width = _depth_intrinsics->width;
        size_t points_height = _depth_intrinsics->height;

        static const float z_threshold = 0.05f; // Compensate for temporal noise when comparing Z values

        // Clear previous data
        memset((void*)(_texels_depth.data()), 0, _texels_depth.size() * sizeof(float));

        // Pass1 -generate texels mapping with minimal depth for each texel involved
        for (size_t i = 0; i < points_height; i++)
        {
            for (size_t j = 0; j < points_width; j++)
            {
                if ((depth_points->z > 0.0001f) &&
                    (mapped_pix->x > 0.f) && (mapped_pix->x < mapped_tex_width) &&
                    (mapped_pix->y > 0.f) && (mapped_pix->y < mapped_tex_height))
                {
                    size_t texel_index = (size_t)(mapped_pix->y)*mapped_tex_width + (size_t)(mapped_pix->x);

                    if ((_texels_depth[texel_index] < 0.0001f) || ((_texels_depth[texel_index] + z_threshold) > depth_points->z))
                    {
                        _texels_depth[texel_index] = depth_points->z;
                    }
                }

                ++depth_points;
                ++mapped_pix;
            }
        }

        mapped_pix = pix_coord.data();
        depth_points = points;
        auto uv_ptr = uv_map;

        // Pass2 -invalidate depth texels with occlusion traits
        for (size_t i = 0; i < points_height; i++)
        {
            for (size_t j = 0; j < points_width; j++)
            {
                if ((depth_points->z > 0.0001f) &&
                    (mapped_pix->x > 0.f) && (mapped_pix->x < mapped_tex_width) &&
                    (mapped_pix->y > 0.f) && (mapped_pix->y < mapped_tex_height))
                {
                    size_t texel_index = (size_t)(mapped_pix->y)*mapped_tex_width + (size_t)(mapped_pix->x);

                    if ((_texels_depth[texel_index] > 0.0001f) && ((_texels_depth[texel_index] + z_threshold) < depth_points->z))
                    {
                        *uv_ptr = { 0.f, 0.f };
                    }
                }

                ++depth_points;
                ++mapped_pix;
                ++uv_ptr;
            }
        }
    }
}
<|endoftext|>


<commit_before>/*
    This file is part of Kontact.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qlabel.h>
#include <qlayout.h>

#include <kdialog.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kparts/part.h>
#include <kstandarddirs.h>
#include <kurllabel.h>
#include <libkcal/event.h>
#include <libkcal/resourcecalendar.h>
#include <libkcal/resourcelocal.h>
#include <libkcal/todo.h>

#include "core.h"
#include "plugin.h"

#include "summarywidget.h"

SummaryWidget::SummaryWidget( Kontact::Plugin*, QWidget *parent,
                              const char *name )
  : Kontact::Summary( parent, name )
{
  QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 );

  QPixmap icon = KGlobal::iconLoader()->loadIcon( "korganizer",
                   KIcon::Desktop, KIcon::SizeMedium );
  QWidget *header = createHeader( this, icon, i18n( "Appointments" ) );
  mainLayout->addWidget(header);

  mLayout = new QGridLayout( mainLayout, 7, 5, 3 );
  mLayout->setRowStretch( 6, 1 );

  KConfig config( "korganizerrc" );
  mCalendar = new KCal::CalendarResources( config.readEntry( "TimeZoneId" ) );
  KCal::CalendarResourceManager *manager = mCalendar->resourceManager();
  if ( manager->isEmpty() ) {
    config.setGroup("General");
    QString fileName = config.readPathEntry( "Active Calendar" );

    QString resourceName;
    if ( fileName.isEmpty() ) {
      fileName = locateLocal( "appdata", "std.ics" );
      resourceName = i18n("Default KOrganizer resource");
    } else {
      resourceName = i18n("Active Calendar");
    }

    KCal::ResourceCalendar *defaultResource = new KCal::ResourceLocal( fileName );
    defaultResource->setResourceName( resourceName );

    manager->add( defaultResource );
    manager->setStandardResource( defaultResource );
  }

  connect( mCalendar, SIGNAL( calendarChanged() ), SLOT( updateView() ) );

  updateView();
}

void SummaryWidget::updateView()
{
  mLabels.setAutoDelete( true );
  mLabels.clear();
  mLabels.setAutoDelete( false );

  KIconLoader loader( "korganizer" );

  QLabel *label = 0;
  int counter = 0;
  KCal::Event::List events = mCalendar->events( QDate::currentDate(), true );
  if ( events.count() > 0 ) {
    QPixmap pm = loader.loadIcon( "appointment", KIcon::Small );

    KCal::Event::List::ConstIterator it2;
    for( it2 = events.begin(); it2 != events.end() && counter < 5; ++it2 ) {
      KCal::Event *ev = *it2;
      if ( !ev->recurrence()->doesRecur() || ev->recursOn( QDate::currentDate() ) ) {
        if ( !ev->doesFloat() ) {
          label = new QLabel( this );
          label->setPixmap( pm );
          mLayout->addWidget( label, counter, 0 );
          mLabels.append( label );

          QString date = ev->dtStartTimeStr() + " - " + ev->dtEndTimeStr();
          label = new QLabel( date, this );
          mLayout->addWidget( label, counter, 1 );
          mLabels.append( label );

          KURLLabel *urlLabel = new KURLLabel( ev->uid(), ev->summary(), this );
          mLayout->addWidget( urlLabel, counter, 2 );
          mLabels.append( urlLabel );

          connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
                   this, SLOT( selectEvent( const QString& ) ) );

          counter++;
        }
      }
    }
  }
  else {
    QLabel *noEvents = new QLabel( i18n("No appointments pending"), this );
    noEvents->setAlignment( AlignRight );
    mLayout->addWidget( noEvents, 0, 2 );
    mLabels.append(noEvents);
  }

  KCal::Todo::List todos = mCalendar->todos();
  if ( todos.count() > 0 ) {
    QPixmap pm = loader.loadIcon( "todo", KIcon::Small );
    KCal::Todo::List::ConstIterator it;
    for( it = todos.begin(); it != todos.end(); ++it ) {
      KCal::Todo *todo = *it;
      if ( todo->hasDueDate() && todo->dtDue().date() == QDate::currentDate() ) {
        label = new QLabel( this );
        label->setPixmap( pm );
        mLayout->addWidget( label, counter, 0 );
        mLabels.append( label );

        KURLLabel *urlLabel = new KURLLabel( todo->uid(), todo->summary(), this );
        mLayout->addWidget( urlLabel, counter, 2 );
        mLabels.append( urlLabel );

        connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
                 this, SLOT( selectEvent( const QString& ) ) );

        counter++;
      }
    }
  }

  show();
}

void SummaryWidget::selectEvent( const QString & )
{
/*
  DCOPRef dcopCall( mDCOPApp.latin1(), "KOrganizerIface" );
  dcopCall.send( "showEventEditor(QString)", uid );
*/
}

#include "summarywidget.moc"
<commit_msg>if you copy code, make sure you adjust it properly ;)<commit_after>/*
    This file is part of Kontact.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qlabel.h>
#include <qlayout.h>

#include <kdialog.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kparts/part.h>
#include <kstandarddirs.h>
#include <kurllabel.h>
#include <libkcal/event.h>
#include <libkcal/resourcecalendar.h>
#include <libkcal/resourcelocal.h>
#include <libkcal/todo.h>

#include "core.h"
#include "plugin.h"

#include "summarywidget.h"

SummaryWidget::SummaryWidget( Kontact::Plugin*, QWidget *parent,
                              const char *name )
  : Kontact::Summary( parent, name )
{
  QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 );

  QPixmap icon = KGlobal::iconLoader()->loadIcon( "korganizer",
                   KIcon::Desktop, KIcon::SizeMedium );
  QWidget *header = createHeader( this, icon, i18n( "Appointments" ) );
  mainLayout->addWidget(header);

  mLayout = new QGridLayout( mainLayout, 7, 5, 3 );
  mLayout->setRowStretch( 6, 1 );

  KConfig config( "korganizerrc" );
  mCalendar = new KCal::CalendarResources( config.readEntry( "TimeZoneId" ) );
  KCal::CalendarResourceManager *manager = mCalendar->resourceManager();
  if ( manager->isEmpty() ) {
    config.setGroup("General");
    QString fileName = config.readPathEntry( "Active Calendar" );

    QString resourceName;
    if ( fileName.isEmpty() ) {
      fileName = locateLocal( "data", "korganizer/std.ics" );
      resourceName = i18n("Default KOrganizer resource");
    } else {
      resourceName = i18n("Active Calendar");
    }

    KCal::ResourceCalendar *defaultResource =
                             new KCal::ResourceLocal( fileName );

    defaultResource->setResourceName( resourceName );

    manager->add( defaultResource );
    manager->setStandardResource( defaultResource );
  }

  connect( mCalendar, SIGNAL( calendarChanged() ), SLOT( updateView() ) );

  updateView();
}

void SummaryWidget::updateView()
{
  mLabels.setAutoDelete( true );
  mLabels.clear();
  mLabels.setAutoDelete( false );

  KIconLoader loader( "korganizer" );

  QLabel *label = 0;
  int counter = 0;
  KCal::Event::List events = mCalendar->events( QDate::currentDate(), true );
  if ( events.count() > 0 ) {
    QPixmap pm = loader.loadIcon( "appointment", KIcon::Small );

    KCal::Event::List::ConstIterator it2;
    for( it2 = events.begin(); it2 != events.end() && counter < 5; ++it2 ) {
      KCal::Event *ev = *it2;
      if ( !ev->recurrence()->doesRecur() || ev->recursOn( QDate::currentDate() ) ) {
        if ( !ev->doesFloat() ) {
          label = new QLabel( this );
          label->setPixmap( pm );
          mLayout->addWidget( label, counter, 0 );
          mLabels.append( label );

          QString date = ev->dtStartTimeStr() + " - " + ev->dtEndTimeStr();
          label = new QLabel( date, this );
          mLayout->addWidget( label, counter, 1 );
          mLabels.append( label );

          KURLLabel *urlLabel = new KURLLabel( ev->uid(), ev->summary(), this );
          mLayout->addWidget( urlLabel, counter, 2 );
          mLabels.append( urlLabel );

          connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
                   this, SLOT( selectEvent( const QString& ) ) );

          counter++;
        }
      }
    }
  }
  else {
    QLabel *noEvents = new QLabel( i18n("No appointments pending"), this );
    noEvents->setAlignment( AlignRight );
    mLayout->addWidget( noEvents, 0, 2 );
    mLabels.append(noEvents);
  }

  KCal::Todo::List todos = mCalendar->todos();
  if ( todos.count() > 0 ) {
    QPixmap pm = loader.loadIcon( "todo", KIcon::Small );
    KCal::Todo::List::ConstIterator it;
    for( it = todos.begin(); it != todos.end(); ++it ) {
      KCal::Todo *todo = *it;
      if ( todo->hasDueDate() && todo->dtDue().date() == QDate::currentDate() ) {
        label = new QLabel( this );
        label->setPixmap( pm );
        mLayout->addWidget( label, counter, 0 );
        mLabels.append( label );

        KURLLabel *urlLabel = new KURLLabel( todo->uid(), todo->summary(), this );
        mLayout->addWidget( urlLabel, counter, 2 );
        mLabels.append( urlLabel );

        connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
                 this, SLOT( selectEvent( const QString& ) ) );

        counter++;
      }
    }
  }

  show();
}

void SummaryWidget::selectEvent( const QString & )
{
/*
  DCOPRef dcopCall( mDCOPApp.latin1(), "KOrganizerIface" );
  dcopCall.send( "showEventEditor(QString)", uid );
*/
}

#include "summarywidget.moc"
<|endoftext|>


<commit_before>#include "GameObject.h"
#include "Application.h"
#include "ModuleRenderer3D.h"
#include "cTransform.h"

#include "glew/include/glew.h"
#include "SDL/include/SDL_opengl.h"
#include <gl/GL.h>
#include <gl/GLU.h>

class cTransform;
GameObject::GameObject(std::string _name, bool _active, GameObject * _parent) : name(_name) , active(_active) , parent(_parent)
{

}

void GameObject::Update()
{
	if (active)
	{
		for (auto comp : components)
		{
			comp.second->Update();
		}

		GLfloat matrix[16];
		glPushMatrix();
		glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
		float4x4 tmp = ((cTransform*)FindComponent(TRANSFORM))->GetMatrixTransf();
		float4x4 tmp1 = ((cTransform*)FindComponent(TRANSFORM))->GetMatrixTransf().Transposed();
		float4x4 tmp2 = float4x4::identity;
		glMultMatrixf(((cTransform*)FindComponent(TRANSFORM))->GetMatrixTransf().ptr());
		//glMultMatrixf(tmp2.ptr());
		glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
	//	GLfloat matrix[16];
	//	glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
	//	matrix;
		if (!sons.empty())
		{
			for (auto itSons : sons)
			{
				itSons->Update();
			}
		}

		App->renderer3D->DrawGameObject(this);

		glPopMatrix();
	}

}

Component * GameObject::FindComponent(componentType type)
{
	Component * ret = nullptr;

	std::map<componentType, Component*>::iterator it = components.find(type);
	if (it != components.end())
	{
		return it->second;
	}
	return nullptr;
}

void GameObject::DrawHeriarchy(GameObject* son)
{
	if (ImGui::TreeNodeEx(name.data(), ImGuiTreeNodeFlags_NoAutoOpenOnLog))
	{
		for (auto sonsSons : son->sons)
		{
			sonsSons->DrawHeriarchy(sonsSons);
		}
		ImGui::TreePop();
	}
}

void GameObject::DrawProperties()
{
	//ImGui::Text("This is GameObject Properties");
	for (auto itComponents : components)
	{
		itComponents.second->DrawUI();
	}
}

void GameObject::AddComponent(Component* addComponent)
{
	components.insert(std::pair<componentType, Component*>(addComponent->type, addComponent));
}
<commit_msg>Component Transform working perfectly perfect :+1:<commit_after>#include "GameObject.h"
#include "Application.h"
#include "ModuleRenderer3D.h"
#include "cTransform.h"

#include "glew/include/glew.h"
#include "SDL/include/SDL_opengl.h"
#include <gl/GL.h>
#include <gl/GLU.h>

class cTransform;
GameObject::GameObject(std::string _name, bool _active, GameObject * _parent) : name(_name) , active(_active) , parent(_parent)
{

}

void GameObject::Update()
{
	if (active)
	{
		for (auto comp : components)
		{
			comp.second->Update();
		}

		//Multiply all the matrixTransform with their sons
		glPushMatrix();
		glMultMatrixf(((cTransform*)FindComponent(TRANSFORM))->GetMatrixTransf().Transposed().ptr());
		if (!sons.empty())

		{
			for (auto itSons : sons)
			{
				itSons->Update();
			}
		}

		App->renderer3D->DrawGameObject(this);

		glPopMatrix();
	}

}

Component * GameObject::FindComponent(componentType type)
{
	Component * ret = nullptr;

	std::map<componentType, Component*>::iterator it = components.find(type);
	if (it != components.end())
	{
		return it->second;
	}
	return nullptr;
}

void GameObject::DrawHeriarchy(GameObject* son)
{
	if (ImGui::TreeNodeEx(name.data(), ImGuiTreeNodeFlags_NoAutoOpenOnLog))
	{
		for (auto sonsSons : son->sons)
		{
			sonsSons->DrawHeriarchy(sonsSons);
		}
		ImGui::TreePop();
	}
}

void GameObject::DrawProperties()
{
	//ImGui::Text("This is GameObject Properties");
	for (auto itComponents : components)
	{
		itComponents.second->DrawUI();
	}
}

void GameObject::AddComponent(Component* addComponent)
{
	components.insert(std::pair<componentType, Component*>(addComponent->type, addComponent));
}
<|endoftext|>


<commit_before>/*
 * internal_rayshooter_nfw.c
 *
 *  Created on: Dec 8, 2009
 *      Author: R.B. Metcalf
 */

#include <slsimlib.h>

/** \ingroup DeflectionL2
 *
 * \brief Routine for calculating the deflection and other lensing quantities for
 * a analytic one plane lens (AnaLens).
 *
 * Can be switched with rayshooterNB() to change
 * to particle lens model.  This transition needs to be made more automatic and
 * fail safe.
 */
void AnaLens::rayshooterInternal(unsigned long Npoints, Point *i_points, bool kappa_off){
	/* i_points need to be already linked to s_points */

    if(this == NULL || !set){
    	ERROR_MESSAGE();
    	std::printf("ERROR: rayshooterInternal  lens not set!\n");
    	exit(0);
    }

	double convert_factor = star_massscale / Sigma_crit;
	long i;

	double x_rescale[2];
    long j;
    float dt,kappa;
	double alpha[2];
	float gamma[3];

#ifdef _OPENMP
#pragma parallel omp for default(shared) private(i,j,x_rescale,dt,kappa,alpha,gamma)
#endif
    for(i = 0; i < Npoints; i++){
    	alpha[0]=alpha[1]=0.0;
    	gamma[0]=gamma[1]=gamma[2]=0.0;
    	dt = kappa = 0.0;

    	i_points[i].dt = 0.0;
    	i_points[i].gamma[2] = 0.0;

    	// host lens
    	if(host_ro > 0){
    		x_rescale[0] = i_points[i].x[0] / host_ro;
    		x_rescale[1] = i_points[i].x[1] / host_ro;

    		alphaNSIE(i_points[i].image->x, x_rescale, host_axis_ratio,
    				host_core / host_ro, host_pos_angle);

    		if(!kappa_off){
    			gammaNSIE(i_points[i].gamma,x_rescale,host_axis_ratio
    					,host_core/host_ro,host_pos_angle);
    			i_points[i].kappa=kappaNSIE(x_rescale,host_axis_ratio
    					,host_core/host_ro,host_pos_angle);
    			i_points[i].dt = phiNSIE(x_rescale,host_axis_ratio
    					,host_core/host_ro,host_pos_angle);
    		}
    		else{
    			i_points[i].kappa=0;
    			i_points[i].gamma[0]=i_points[i].gamma[1]=0.0;
    			i_points[i].dt = 0.0;
    		}

    		i_points[i].image->x[0] *= host_ro;
    		i_points[i].image->x[1] *= host_ro;

    	}
    	else{
    		i_points[i].image->x[0] = 0.0;
    		i_points[i].image->x[1] = 0.0;
    		i_points[i].kappa=0;
    		i_points[i].gamma[0]=i_points[i].gamma[1]=0;
    		i_points[i].dt = 0.0;
    	}

    	// perturbations of host lens
    	if(perturb_Nmodes > 0){
    		i_points[i].kappa += lens_expand(perturb_beta,perturb_modes
    				,perturb_Nmodes,i_points[i].x,alpha,gamma,&dt);

    		i_points[i].image->x[0] += alpha[0];
    		i_points[i].image->x[1] += alpha[1];

    		if(!kappa_off){
    			i_points[i].gamma[0] += gamma[0];
    			i_points[i].gamma[1] += gamma[1];
    			i_points[i].dt += dt;
    		}
    		else
    			i_points[i].kappa = 0;
    	} // end of perturb modes

    	alpha[0]=alpha[1]=0.0;
    	gamma[0]=gamma[1]=gamma[2]=0.0;

    	// add substructure
    	if(substruct_implanted){
    		for(j=0;j<sub_N;++j){
    			sub_alpha_func(alpha,i_points[i].x,sub_Rcut[j],sub_mass[j],sub_beta,sub_x[j],Sigma_crit);

    			i_points[i].image->x[0] += alpha[0];
    			i_points[i].image->x[1] += alpha[1];

    			if(!kappa_off){
    				i_points[i].kappa += sub_kappa_func(i_points[i].x,sub_Rcut[j],sub_mass[j],sub_beta,sub_x[j],Sigma_crit);
    				sub_gamma_func(gamma,i_points[i].x,sub_Rcut[j],sub_mass[j],sub_beta,sub_x[j],Sigma_crit);
    				i_points[i].gamma[0] += gamma[0];
    				i_points[i].gamma[1] += gamma[1];
    				i_points[i].dt += sub_phi_func(i_points[i].x,sub_Rcut[j],sub_mass[j],sub_beta,sub_x[j],Sigma_crit);

    			}
    		}
    	} // end of substructure

    	if(!kappa_off){
    		i_points[i].dt = 0.5*(i_points[i].image->x[0]*i_points[i].image->x[0]
    		                     + i_points[i].image->x[1]*i_points[i].image->x[1])
      		                     - i_points[i].dt;
    		i_points[i].dt *= to;
    	}

    	i_points[i].image->x[0] = i_points[i].x[0] - i_points[i].image->x[0];
    	i_points[i].image->x[1] = i_points[i].x[1] - i_points[i].image->x[1];

    	alpha[0]=alpha[1]=0.0;
    	gamma[0]=gamma[1]=gamma[2]=0.0;

    	if(stars_N > 0 && stars_implanted){
    		// add stars for microlensing
    		substract_stars_disks(i_points[i].x,i_points[i].image->x,
    				&(i_points[i].kappa),i_points[i].gamma);

    		// do stars with tree code
    		//star_tree->force2D(i_points[i].x,alpha,&kappa,gamma,true);
    		star_tree->force2D_recur(i_points[i].x,alpha,&kappa,gamma,true);

    		i_points[i].image->x[0] += convert_factor*alpha[0];
    		i_points[i].image->x[1] += convert_factor*alpha[1];

    		if(!kappa_off){
    			i_points[i].kappa += convert_factor*kappa;
    			i_points[i].gamma[0] += convert_factor*gamma[0];
    			i_points[i].gamma[1] += convert_factor*gamma[1];
    		}

    	} // end of stars

		// final operations to get the inverse magnification
		i_points[i].invmag = (1-i_points[i].kappa)*(1-i_points[i].kappa)
				- i_points[i].gamma[0]*i_points[i].gamma[0] - i_points[i].gamma[1]*i_points[i].gamma[1];

    	i_points[i].image->invmag=i_points[i].invmag;
    	i_points[i].image->kappa=i_points[i].kappa;
    	i_points[i].image->gamma[0]=i_points[i].gamma[0];
    	i_points[i].image->gamma[1]=i_points[i].gamma[1];
    	i_points[i].image->dt = i_points[i].dt;

    }

    return ;
}

/** \ingroup DeflectionL2
   *
   * \brief Routine for calculating the deflection and other lensing quantities for
   * a analytic one plane lens (AnaLens), for just one ray!!
   *
*/
void AnaLens::rayshooterInternal(double *ray, double *alpha, float *gamma, float *kappa, bool kappa_off){
     double x_rescale[2];
     long j;
     double alpha_tmp[2];
     float gamma_tmp[3], dt = 0,tmp = 0;

     gamma_tmp[0] = gamma_tmp[1] = gamma_tmp[2] = 0.0;
     alpha_tmp[0] = alpha_tmp[1] = 0.0;

     alpha[0] = alpha[1] = 0.0;
     gamma[0] = gamma[1] = gamma[2] = 0.0;
     *kappa = 0.0;

     double convert_factor = star_massscale/Sigma_crit;

     if(host_ro > 0){
    	 x_rescale[0] = ray[0]/host_ro;
    	 x_rescale[1] = ray[1]/host_ro;

    	 alphaNSIE(alpha,x_rescale,host_axis_ratio,host_core/host_ro,host_pos_angle);

    	 if(!kappa_off){
    		 gammaNSIE(gamma,x_rescale,host_axis_ratio,host_core/host_ro,host_pos_angle);
    		 *kappa=kappaNSIE(x_rescale,host_axis_ratio,host_core/host_ro,host_pos_angle);
    	 }

    	 alpha[0] *= host_ro;
    	 alpha[1] *= host_ro;
     }

  // perturbations of host lens
     if(perturb_Nmodes > 0){
    	 *kappa += lens_expand(perturb_beta,perturb_modes
    			 ,perturb_Nmodes,ray,alpha_tmp,gamma_tmp,&dt);

    	 alpha[0] += alpha_tmp[0];
    	 alpha[1] += alpha_tmp[1];

   	      if(!kappa_off){
   	    	  gamma[0] += gamma_tmp[0];
   	    	  gamma[1] += gamma_tmp[1];
   	      }

   	     gamma_tmp[0] = gamma_tmp[1] = gamma_tmp[2] = 0.0;
   	     alpha_tmp[0] = alpha_tmp[1] = 0.0;
     }

     // add substructure
     if(substruct_implanted){
    	 for(j=0;j<sub_N;++j){
    		 sub_alpha_func(alpha_tmp,ray,sub_Rcut[j],sub_mass[j],sub_beta,sub_x[j],Sigma_crit);

    		 alpha[0] += alpha_tmp[0];
    		 alpha[1] += alpha_tmp[1];

    		 if(!kappa_off){
    			 *kappa += sub_kappa_func(ray,sub_Rcut[j],sub_mass[j],sub_beta,sub_x[j],Sigma_crit);
    			 sub_gamma_func(gamma_tmp,ray,sub_Rcut[j],sub_mass[j],sub_beta,sub_x[j],Sigma_crit);

    			 gamma[0] += gamma_tmp[0];
    			 gamma[1] += gamma_tmp[1];
    		 }
    	 }

         gamma_tmp[0] = gamma_tmp[1] = gamma_tmp[2] = 0.0;
         alpha_tmp[0] = alpha_tmp[1] = 0.0;
     }

     /// TODO: MARGARITA/BEN make sure units here are OK!!!
     // add stars for microlensing
     if(stars_N > 0 && stars_implanted){

    	 std::cout << "MAke sure the units here are OK (the substract disk) , then delete this line" << std::endl;
    	 exit(1);

    	 substract_stars_disks(ray,alpha,kappa,gamma);

    	 // do stars with tree code
    	 star_tree->force2D(ray,alpha_tmp,&tmp,gamma_tmp,true);
    	 //star_tree->force2D_recur(ray,alpha_tmp,&tmp,gamma_tmp,true);

    	 alpha[0] += convert_factor*alpha_tmp[0];
    	 alpha[1] += convert_factor*alpha_tmp[1];

    	 if(!kappa_off){
    		 *kappa += convert_factor*tmp;
    		 gamma[0] += convert_factor*gamma_tmp[0];
    		 gamma[1] += convert_factor*gamma_tmp[1];
    	 }
     }

     // final operations on results
     convert_factor = 4*pi*Grav*Sigma_crit;

     // convert from physical distance on the lens plane to an angle
	 alpha[0] *= convert_factor;
	 alpha[1] *= convert_factor;

	 // in the multi-plane formalism G^i=partial deflection_angle^i / partial x^i
	 // therefore the quantities need to be in units (1/comoving_distance)
	 // --> convert from unitless quantity to (1/comoving_distance)
	 *kappa *= convert_factor/(1+zlens);
	 gamma[0] *= convert_factor/(1+zlens);
	 gamma[1] *= convert_factor/(1+zlens);
	 gamma[2] *= convert_factor/(1+zlens);

     return ;
}
<commit_msg>inproduced pthreads parallelization of the analens rayshooter<commit_after>/*
 * internal_rayshooter_nfw.c
 *
 *  Created on: Dec 8, 2009
 *      Author: R.B. Metcalf
 */

#include <slsimlib.h>

/** \ingroup DeflectionL2
 *
 * \brief Routine for calculating the deflection and other lensing quantities for
 * a analytic one plane lens (AnaLens).
 *
 * Can be switched with rayshooterNB() to change
 * to particle lens model.  This transition needs to be made more automatic and
 * fail safe.
 */

void *compute_rays_parallel_nfw(void *_p);

struct params{
	Point *i_points;
	bool kappa_off;
	int tid;
	int start;
	int size;
	AnaLens *lens;
};

void AnaLens::rayshooterInternal(unsigned long Npoints, Point *i_points, bool kappa_off){

    if(this == NULL || !set){
    	ERROR_MESSAGE();
    	std::printf("ERROR: rayshooterInternal  lens not set!\n");
    	exit(0);
    }

    int nthreads, rc;

    nthreads = 4;

    int chunk_size;
    do{
      chunk_size = (int)Npoints/nthreads;
      if(chunk_size == 0) nthreads /= 2;
    }while(chunk_size == 0);

    pthread_t threads[nthreads];
    params *thread_params = new params[nthreads];

    for(int i=0; i<nthreads;i++){
      thread_params[i].i_points = i_points;
      thread_params[i].kappa_off = kappa_off;
      thread_params[i].size = chunk_size;
      if(i == nthreads-1)
        thread_params[i].size = (int)Npoints - (nthreads-1)*chunk_size;
      thread_params[i].start = i*chunk_size;
      thread_params[i].tid = i;
      thread_params[i].lens = this;
      rc = pthread_create(&threads[i], NULL, compute_rays_parallel_nfw, (void*) &thread_params[i]);
      assert(rc==0);
    }

    for(int i = 0; i < nthreads; i++){
      rc = pthread_join(threads[i], NULL);
      assert(rc==0);
    }

    delete[] thread_params;
}

void *compute_rays_parallel_nfw(void *_p){
	params *p = (params *) _p;
	bool kappa_off = p->kappa_off;
	AnaLens *lens = p->lens;
	int tid        = p->tid;
	int chunk_size = p->size;
	int start      = p->start;
	int end        = start + chunk_size;

	/* i_points need to be already linked to s_points */

	double convert_factor = lens->star_massscale / lens->Sigma_crit;
	long i;

	double x_rescale[2];
    long j;
    float dt,kappa;
	double alpha[2];
	float gamma[3];

    for(i = start; i < end; i++){
    	alpha[0]=alpha[1]=0.0;
    	gamma[0]=gamma[1]=gamma[2]=0.0;
    	dt = kappa = 0.0;

    	p->i_points[i].dt = 0.0;
    	p->i_points[i].gamma[2] = 0.0;

    	// host lens
    	if(lens->host_ro > 0){
    		x_rescale[0] = p->i_points[i].x[0] / lens->host_ro;
    		x_rescale[1] = p->i_points[i].x[1] / lens->host_ro;

    		alphaNSIE(p->i_points[i].image->x, x_rescale, lens->host_axis_ratio,
    				lens->host_core/ lens->host_ro, lens->host_pos_angle);

    		if(!kappa_off){
    			gammaNSIE(p->i_points[i].gamma,x_rescale,lens->host_axis_ratio
    					,lens->host_core/lens->host_ro,lens->host_pos_angle);
    			p->i_points[i].kappa=kappaNSIE(x_rescale,lens->host_axis_ratio
    					,lens->host_core/lens->host_ro,lens->host_pos_angle);
    			p->i_points[i].dt = phiNSIE(x_rescale,lens->host_axis_ratio
    					,lens->host_core/lens->host_ro,lens->host_pos_angle);
    		}
    		else{
    			p->i_points[i].kappa=0;
    			p->i_points[i].gamma[0]=p->i_points[i].gamma[1]=0.0;
    			p->i_points[i].dt = 0.0;
    		}

    		p->i_points[i].image->x[0] *= lens->host_ro;
    		p->i_points[i].image->x[1] *= lens->host_ro;

    	}
    	else{
    		p->i_points[i].image->x[0] = 0.0;
    		p->i_points[i].image->x[1] = 0.0;
    		p->i_points[i].kappa=0;
    		p->i_points[i].gamma[0]=p->i_points[i].gamma[1]=0;
    		p->i_points[i].dt = 0.0;
    	}

    	// perturbations of host lens
    	if(lens->perturb_Nmodes > 0){
    		p->i_points[i].kappa += lens_expand(lens->perturb_beta,lens->perturb_modes
    				,lens->perturb_Nmodes,p->i_points[i].x,alpha,gamma,&dt);

    		p->i_points[i].image->x[0] += alpha[0];
    		p->i_points[i].image->x[1] += alpha[1];

    		if(!kappa_off){
    			p->i_points[i].gamma[0] += gamma[0];
    			p->i_points[i].gamma[1] += gamma[1];
    			p->i_points[i].dt += dt;
    		}
    		else
    			p->i_points[i].kappa = 0;
    	} // end of perturb modes

    	alpha[0]=alpha[1]=0.0;
    	gamma[0]=gamma[1]=gamma[2]=0.0;

    	// add substructure
    	if(lens->substruct_implanted){
    		for(j=0;j<lens->sub_N;++j){
    			lens->sub_alpha_func(alpha,p->i_points[i].x,lens->sub_Rcut[j],lens->sub_mass[j],lens->sub_beta,lens->sub_x[j],lens->Sigma_crit);

    			p->i_points[i].image->x[0] += alpha[0];
    			p->i_points[i].image->x[1] += alpha[1];

    			if(!kappa_off){
    				p->i_points[i].kappa += lens->sub_kappa_func(p->i_points[i].x,lens->sub_Rcut[j],lens->sub_mass[j],lens->sub_beta,lens->sub_x[j],lens->Sigma_crit);
    				lens->sub_gamma_func(gamma,p->i_points[i].x,lens->sub_Rcut[j],lens->sub_mass[j],lens->sub_beta,lens->sub_x[j],lens->Sigma_crit);
    				p->i_points[i].gamma[0] += gamma[0];
    				p->i_points[i].gamma[1] += gamma[1];
    				p->i_points[i].dt += lens->sub_phi_func(p->i_points[i].x,lens->sub_Rcut[j],lens->sub_mass[j],lens->sub_beta,lens->sub_x[j],lens->Sigma_crit);

    			}
    		}
    	} // end of substructure

    	if(!kappa_off){
    		p->i_points[i].dt = 0.5*(p->i_points[i].image->x[0]*p->i_points[i].image->x[0]
    		                     + p->i_points[i].image->x[1]*p->i_points[i].image->x[1])
      		                     - p->i_points[i].dt;
    		p->i_points[i].dt *= lens->to;
    	}

    	p->i_points[i].image->x[0] = p->i_points[i].x[0] - p->i_points[i].image->x[0];
    	p->i_points[i].image->x[1] = p->i_points[i].x[1] - p->i_points[i].image->x[1];

    	alpha[0]=alpha[1]=0.0;
    	gamma[0]=gamma[1]=gamma[2]=0.0;

    	if(lens->stars_N > 0 && lens->stars_implanted){
    		// add stars for microlensing
    		lens->substract_stars_disks(p->i_points[i].x,p->i_points[i].image->x,
    				&(p->i_points[i].kappa),p->i_points[i].gamma);

    		// do stars with tree code
    		//star_tree->force2D(p->i_points[i].x,alpha,&kappa,gamma,true);
    		lens->star_tree->force2D_recur(p->i_points[i].x,alpha,&kappa,gamma,true);

    		p->i_points[i].image->x[0] += convert_factor*alpha[0];
    		p->i_points[i].image->x[1] += convert_factor*alpha[1];

    		if(!kappa_off){
    			p->i_points[i].kappa += convert_factor*kappa;
    			p->i_points[i].gamma[0] += convert_factor*gamma[0];
    			p->i_points[i].gamma[1] += convert_factor*gamma[1];
    		}

    	} // end of stars

		// final operations to get the inverse magnification
		p->i_points[i].invmag = (1-p->i_points[i].kappa)*(1-p->i_points[i].kappa)
				- p->i_points[i].gamma[0]*p->i_points[i].gamma[0] - p->i_points[i].gamma[1]*p->i_points[i].gamma[1];

    	p->i_points[i].image->invmag=p->i_points[i].invmag;
    	p->i_points[i].image->kappa=p->i_points[i].kappa;
    	p->i_points[i].image->gamma[0]=p->i_points[i].gamma[0];
    	p->i_points[i].image->gamma[1]=p->i_points[i].gamma[1];
    	p->i_points[i].image->dt = p->i_points[i].dt;

    }

    return 0;
}

/** \ingroup DeflectionL2
   *
   * \brief Routine for calculating the deflection and other lensing quantities for
   * a analytic one plane lens (AnaLens), for just one ray!!
   *
*/
void AnaLens::rayshooterInternal(double *ray, double *alpha, float *gamma, float *kappa, bool kappa_off){
     double x_rescale[2];
     long j;
     double alpha_tmp[2];
     float gamma_tmp[3], dt = 0,tmp = 0;

     gamma_tmp[0] = gamma_tmp[1] = gamma_tmp[2] = 0.0;
     alpha_tmp[0] = alpha_tmp[1] = 0.0;

     alpha[0] = alpha[1] = 0.0;
     gamma[0] = gamma[1] = gamma[2] = 0.0;
     *kappa = 0.0;

     double convert_factor = star_massscale/Sigma_crit;

     if(host_ro > 0){
    	 x_rescale[0] = ray[0]/host_ro;
    	 x_rescale[1] = ray[1]/host_ro;

    	 alphaNSIE(alpha,x_rescale,host_axis_ratio,host_core/host_ro,host_pos_angle);

    	 if(!kappa_off){
    		 gammaNSIE(gamma,x_rescale,host_axis_ratio,host_core/host_ro,host_pos_angle);
    		 *kappa=kappaNSIE(x_rescale,host_axis_ratio,host_core/host_ro,host_pos_angle);
    	 }

    	 alpha[0] *= host_ro;
    	 alpha[1] *= host_ro;
     }

  // perturbations of host lens
     if(perturb_Nmodes > 0){
    	 *kappa += lens_expand(perturb_beta,perturb_modes
    			 ,perturb_Nmodes,ray,alpha_tmp,gamma_tmp,&dt);

    	 alpha[0] += alpha_tmp[0];
    	 alpha[1] += alpha_tmp[1];

   	      if(!kappa_off){
   	    	  gamma[0] += gamma_tmp[0];
   	    	  gamma[1] += gamma_tmp[1];
   	      }

   	     gamma_tmp[0] = gamma_tmp[1] = gamma_tmp[2] = 0.0;
   	     alpha_tmp[0] = alpha_tmp[1] = 0.0;
     }

     // add substructure
     if(substruct_implanted){
    	 for(j=0;j<sub_N;++j){
    		 sub_alpha_func(alpha_tmp,ray,sub_Rcut[j],sub_mass[j],sub_beta,sub_x[j],Sigma_crit);

    		 alpha[0] += alpha_tmp[0];
    		 alpha[1] += alpha_tmp[1];

    		 if(!kappa_off){
    			 *kappa += sub_kappa_func(ray,sub_Rcut[j],sub_mass[j],sub_beta,sub_x[j],Sigma_crit);
    			 sub_gamma_func(gamma_tmp,ray,sub_Rcut[j],sub_mass[j],sub_beta,sub_x[j],Sigma_crit);

    			 gamma[0] += gamma_tmp[0];
    			 gamma[1] += gamma_tmp[1];
    		 }
    	 }

         gamma_tmp[0] = gamma_tmp[1] = gamma_tmp[2] = 0.0;
         alpha_tmp[0] = alpha_tmp[1] = 0.0;
     }

     /// TODO: MARGARITA/BEN make sure units here are OK!!!
     // add stars for microlensing
     if(stars_N > 0 && stars_implanted){

    	 std::cout << "MAke sure the units here are OK (the substract disk) , then delete this line" << std::endl;
    	 exit(1);

    	 substract_stars_disks(ray,alpha,kappa,gamma);

    	 // do stars with tree code
    	 //star_tree->force2D(ray,alpha_tmp,&tmp,gamma_tmp,true);
    	 star_tree->force2D_recur(ray,alpha_tmp,&tmp,gamma_tmp,true);

    	 alpha[0] += convert_factor*alpha_tmp[0];
    	 alpha[1] += convert_factor*alpha_tmp[1];

    	 if(!kappa_off){
    		 *kappa += convert_factor*tmp;
    		 gamma[0] += convert_factor*gamma_tmp[0];
    		 gamma[1] += convert_factor*gamma_tmp[1];
    	 }
     }

     // final operations on results
     convert_factor = 4*pi*Grav*Sigma_crit;

     // convert from physical distance on the lens plane to an angle
	 alpha[0] *= convert_factor;
	 alpha[1] *= convert_factor;

	 // in the multi-plane formalism G^i=partial deflection_angle^i / partial x^i
	 // therefore the quantities need to be in units (1/comoving_distance)
	 // --> convert from unitless quantity to (1/comoving_distance)
	 *kappa *= convert_factor/(1+zlens);
	 gamma[0] *= convert_factor/(1+zlens);
	 gamma[1] *= convert_factor/(1+zlens);
	 gamma[2] *= convert_factor/(1+zlens);

     return ;
}
<|endoftext|>


<commit_before>	/* Summary: Algorithm to do fast hashing of a pointer
	 * The result of the hash function is a number in the range
	 * [0..(number_of_slots-1)].
	 */
	HashIndex Hashing::hashPointer(void *const void_ptr)
	{
		double d = ((double)((unsigned long)void_ptr)) * 0.6180339887;
		Index index = (Index)(5832641097.37287 * (d - (double)((unsigned long)d)));

		return ((index < 0) ? -index : index);
	}

	/* Summary: Algorithm to do fast hashing of variable length text
	 * strings. The result of the hash function is a number in the range
	 * [0..255]. This algorithm was published in CACM, 6/90.
	 */
	HashIndex Hashing::hashString(register const char *s)
	{
		static const unsigned char pseudo_random_permuted_key[256] =
		{
			1  ,87 ,49 ,12 ,176,178,102,166,121,193,6  ,84 ,249,230,44 ,163,
			14 ,197,213,181,161,85 ,218,80 ,64 ,239,24 ,226,236,142,38 ,200,
			110,177,104,103,141,253,255,50 ,77 ,101,81 ,18 ,45 ,96 ,31 ,222,
			25 ,107,190,70 ,86 ,237,240,34 ,72 ,242,20 ,214,244,227,149,235,
			97 ,234,57 ,22 ,60 ,250,82 ,175,208,5  ,127,199,111,62 ,135,248,
			174,169,211,58 ,66 ,154,106,195,245,171,17 ,187,182,179,0  ,243,
			132,56 ,148,75 ,128,133,158,100,130,126,91 ,13 ,153,246,216,219,
			119,68 ,223,78 ,83 ,88 ,201,99 ,122,11 ,92 ,32 ,136,114,52 ,10 ,
			138,30 ,48 ,183,156,35 ,61 ,26 ,143,74 ,251,94 ,129,162,63 ,152,
			170,7  ,115,167,241,206,3  ,150,55 ,59 ,151,220,90 ,53 ,23 ,131,
			125,173,15 ,238,79 ,95 ,89 ,16 ,105,137,225,224,217,160,37 ,123,
			118,73 ,2  ,157,46 ,116,9  ,145,134,228,207,212,202,215,69 ,229,
			27 ,188,67 ,124,168,252,42 ,4  ,29 ,108,21 ,247,19 ,205,39 ,203,
			233,40 ,186,147,198,192,155,33 ,164,191,98 ,204,165,180,117,76 ,
			140,36 ,210,172,41 ,54 ,159,8  ,185,232,113,196,231,47 ,146,120,
			51 ,65 ,28 ,144,254,221,93 ,189,194,139,112,43 ,71 ,109,184,209
		};

		register Index index = 0;

		for(;	*s != '\0'; )
			index = pseudo_random_permuted_key[index ^ (*s++)];

		return index;
	}

	/* Summary: A portable one word summary of a string.
	 * Taken from: Tcl, DOC++ (McHashTable.cpp)
	 */
	HashIndex Hashing::hashString2(register const char *s)
	{
		register Index index = 0;

		for (register char c = *s++; c != '\0'; index += (index << 3) + c);

		return index;
	}

	/* Summary: A portable one word summary of a string.
	 * Taken from: DOC++ (nametable.cpp)
	 */
	HashIndex Hashing::hashString3(register const char *s)
	{
		register Index index = 0;

		while (*s != '\0')
		{
			index *= 'A';
			index += (*s++ - '0');
		}

		return index;
	}

	/* Summary: A portable adaptation of Peter Weinberger's (PJW) (AT&T Bell Labs)
	 * generic hashing algorithm based on Allen Holub's version. Accepts a pointer
	 * to a string to be hashed.
	 * Taken from: Dr. Dobb's Journal, April 1996, p.26
	 */
	HashIndex Hashing::hashPJWString(register const char *s)
	{
		register Index index = 0;
		register Index temp_index;

#		define BALL_BITS_IN_HASHVALUE_   (sizeof(Index) * CHAR_BIT)
#		define BALL_THREE_QUARTERS_      ((Index)((BALL_BITS_IN_HASHVALUE_ * 3) / 4))
#		define BALL_ONE_EIGHTH_          ((Index)(BALL_BITS_IN_HASHVALUE_ / 8))
#		define BALL_HIGH_BITS_           (~((Index)(~0) >> BALL_ONE_EIGHTH_))

		for (; *s; s++)
		{
			index = (index << BALL_ONE_EIGHTH_) + *s;
			if ((temp_index = index & BALL_HIGH_BITS_) != 0)
			{
				index = (index ^ (temp_index >> BALL_THREE_QUARTERS_)) & ~BALL_HIGH_BITS_;
			}
		}

#		undef BALL_BITS_IN_HASHVALUE_
#		undef BALL_THREE_QUARTERS_
#		undef BALL_ONE_EIGHTH_
#		undef BALL_HIGH_BITS_

		return index;
	}

	/* Summary: The published hash algorithm used in the UNIX ELF format for
	 * object files. Accepts a pointer to a string to be hashed.
	 * Assumes a long pointer to have 4 bytes of 8 bits.
	 * Taken from: Dr. Dobb's Journal, April 1996, p.26
	 */
	HashIndex Hashing::hashElfString(register const char *s)
	{
		register unsigned long l = 0;
		register unsigned long temp;

		while(*s)
		{
			l = (l << 4) + *s++;
			if ((temp = l & 0xF0000000L))
			{
				l ^= temp >> 24;
			}
			l &= ~temp;
		}

		return (Index)l;
	}
<commit_msg>this file was never needed - contained just some trash<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2011 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    This program 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 General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

# include  "entity.h"
# include  "architec.h"
# include  <iostream>
# include  <fstream>
# include  <iomanip>
# include  <ivl_assert.h>

int emit_entities(void)
{
      int errors = 0;

      for (map<perm_string,Entity*>::iterator cur = design_entities.begin()
		 ; cur != design_entities.end() ; ++cur) {
	    errors += cur->second->emit(cout);
      }

      return errors;
}

int Entity::emit(ostream&out)
{
      int errors = 0;

      out << "module \\" << get_name() << " ";

	// If there are generics, emit them
      if (parms_.size() > 0) {
	    out << "#(";
	    for (vector<InterfacePort*>::const_iterator cur = parms_.begin()
		       ; cur != parms_.end() ; ++cur) {
		  const InterfacePort*curp = *cur;
		  if (cur != parms_.begin())
			out << ", ";
		  out << "parameter \\" << curp->name << " ";
		  if(curp->expr) {
			out << "= ";
			errors += curp->expr->emit(out, this, 0);
                  }
	    }
	    out << ") ";
      }

	// If there are ports, emit them.
      if (ports_.size() > 0) {
	    out << "(";
	    const char*sep = 0;
	    for (vector<InterfacePort*>::const_iterator cur = ports_.begin()
		       ; cur != ports_.end() ; ++cur) {
		  InterfacePort*port = *cur;

		  VType::decl_t&decl = declarations_[port->name];

		  if (sep) out << sep << endl;
		  else sep = ", ";

		  switch (port->mode) {
		      case PORT_NONE: // Should not happen
			cerr << get_fileline() << ": error: Undefined port direction." << endl;
			out << "NO_PORT " << port->name;
			break;
		      case PORT_IN:
			out << "input ";
			break;
		      case PORT_OUT:
			out << "output ";
			break;
		      case PORT_INOUT:
			out << "inout ";
			break;
		  }

		  errors += decl.emit(out, port->name);
	    }
	    cout << ")";
      }

      out << ";" << endl;

      errors += bind_arch_->emit(out, this);

      out << "endmodule" << endl;

      return errors;
}
<commit_msg>vhdlpp: generics without a default value are set to 1'bx.<commit_after>/*
 * Copyright (c) 2011 Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form under the terms of the GNU
 *    General Public License as published by the Free Software
 *    Foundation; either version 2 of the License, or (at your option)
 *    any later version.
 *
 *    This program 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 General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

# include  "entity.h"
# include  "architec.h"
# include  <iostream>
# include  <fstream>
# include  <iomanip>
# include  <ivl_assert.h>

int emit_entities(void)
{
      int errors = 0;

      for (map<perm_string,Entity*>::iterator cur = design_entities.begin()
		 ; cur != design_entities.end() ; ++cur) {
	    errors += cur->second->emit(cout);
      }

      return errors;
}

int Entity::emit(ostream&out)
{
      int errors = 0;

      out << "module \\" << get_name() << " ";

	// If there are generics, emit them
      if (parms_.size() > 0) {
	    out << "#(";
	    for (vector<InterfacePort*>::const_iterator cur = parms_.begin()
		       ; cur != parms_.end() ; ++cur) {
		  const InterfacePort*curp = *cur;
		  if (cur != parms_.begin())
			out << ", ";
		  out << "parameter \\" << curp->name << " = ";
		  if(curp->expr) {
			errors += curp->expr->emit(out, this, 0);
                  } else {
			// Unlike VHDL, Verilog module parameter port list
			// elements are always assignments.  Fill in the blank.
			out << "1'bx";
		  }
	    }
	    out << ") ";
      }

	// If there are ports, emit them.
      if (ports_.size() > 0) {
	    out << "(";
	    const char*sep = 0;
	    for (vector<InterfacePort*>::const_iterator cur = ports_.begin()
		       ; cur != ports_.end() ; ++cur) {
		  InterfacePort*port = *cur;

		  VType::decl_t&decl = declarations_[port->name];

		  if (sep) out << sep << endl;
		  else sep = ", ";

		  switch (port->mode) {
		      case PORT_NONE: // Should not happen
			cerr << get_fileline() << ": error: Undefined port direction." << endl;
			out << "NO_PORT " << port->name;
			break;
		      case PORT_IN:
			out << "input ";
			break;
		      case PORT_OUT:
			out << "output ";
			break;
		      case PORT_INOUT:
			out << "inout ";
			break;
		  }

		  errors += decl.emit(out, port->name);
	    }
	    cout << ")";
      }

      out << ";" << endl;

      errors += bind_arch_->emit(out, this);

      out << "endmodule" << endl;

      return errors;
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 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/website_settings/permission_selector.h"

#include <gtk/gtk.h>

#include "base/compiler_specific.h"
#include "chrome/browser/ui/gtk/gtk_theme_service.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "chrome/browser/ui/website_settings/website_settings_ui.h"
#include "grit/generated_resources.h"
#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/image/image.h"

namespace {

GtkWidget* CreateTextLabel(const std::string& text,
                           GtkThemeService* theme_service) {
  GtkWidget* label = theme_service->BuildLabel(text, ui::kGdkBlack);
  gtk_label_set_selectable(GTK_LABEL(label), TRUE);
  gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD_CHAR);
  return label;
}

}  // namespace

PermissionSelector::PermissionSelector(GtkThemeService* theme_service,
                                       ContentSettingsType type,
                                       ContentSetting setting,
                                       ContentSetting default_setting)
    : theme_service_(theme_service),
      type_(type),
      setting_(setting),
      default_setting_(default_setting),
      icon_(NULL) {
  DCHECK_NE(default_setting, CONTENT_SETTING_DEFAULT);
}

PermissionSelector::~PermissionSelector() {
}

GtkWidget* PermissionSelector::CreateUI() {
  // Create permission info box.
  const int kChildSpacing = 4;
  GtkWidget* hbox = gtk_hbox_new(FALSE, kChildSpacing);

  // Add permission type icon.
  GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon(
      type_, setting_).ToGdkPixbuf();
  icon_ = gtk_image_new_from_pixbuf(pixbuf);
  gtk_box_pack_start(GTK_BOX(hbox), icon_, FALSE, FALSE, 0);

  // Add a label for the permission type.
  GtkWidget* label = CreateTextLabel(
      l10n_util::GetStringFUTF8(
          IDS_WEBSITE_SETTINGS_PERMISSION_TYPE,
          WebsiteSettingsUI::PermissionTypeToUIString(type_)),
      theme_service_);
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

  GtkListStore* store =
      gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
  GtkTreeIter iter;
  // Add option for permission "Global Default" to the combobox model.
  std::string setting_str = l10n_util::GetStringFUTF8(
      IDS_WEBSITE_SETTINGS_DEFAULT_PERMISSION_LABEL,
      WebsiteSettingsUI::PermissionValueToUIString(default_setting_));
  gtk_list_store_append(store, &iter);
  gtk_list_store_set(store, &iter, 0, setting_str.c_str(), 1,
                     CONTENT_SETTING_DEFAULT, -1);
  GtkWidget* combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
  // Add option for permission "Allow" to the combobox model.
  setting_str = l10n_util::GetStringFUTF8(
      IDS_WEBSITE_SETTINGS_PERMISSION_LABEL,
      WebsiteSettingsUI::PermissionValueToUIString(CONTENT_SETTING_ALLOW));
  gtk_list_store_append(store, &iter);
  gtk_list_store_set(store, &iter, 0, setting_str.c_str(), 1,
                     CONTENT_SETTING_ALLOW, -1);
  // The content settings type fullscreen does not support the concept of
  // blocking.
  if (type_ != CONTENT_SETTINGS_TYPE_FULLSCREEN) {
    // Add option for permission "BLOCK" to the combobox model.
    setting_str = l10n_util::GetStringFUTF8(
        IDS_WEBSITE_SETTINGS_PERMISSION_LABEL,
        WebsiteSettingsUI::PermissionValueToUIString(CONTENT_SETTING_BLOCK));
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, 0, setting_str.c_str(), 1,
                       CONTENT_SETTING_BLOCK, -1);
  }
  // Remove reference to the store to prevent leaking.
  g_object_unref(G_OBJECT(store));

  GtkCellRenderer* cell = gtk_cell_renderer_text_new();
  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), cell, TRUE );
  gtk_cell_layout_set_attributes(
      GTK_CELL_LAYOUT(combo_box), cell, "text", 0, NULL);

  // Select the combobox entry for the currently configured permission value.
  int active = -1;
  switch (setting_) {
    case CONTENT_SETTING_DEFAULT: active = 0;
      break;
    case CONTENT_SETTING_ALLOW: active = 1;
      break;
    case CONTENT_SETTING_BLOCK: active = 2;
      break;
    default:
      NOTREACHED() << "Bad content setting:" << setting_;
      break;
  }
  gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), active);

  // Add change listener to the combobox.
  g_signal_connect(combo_box, "changed",
                   G_CALLBACK(OnPermissionChangedThunk), this);
  // Once the popup (window) for a combobox is shown, the bubble container
  // (window) loses it's focus. Therefore it necessary to reset the focus to
  // the bubble container after the combobox popup is closed.
  g_signal_connect(combo_box, "notify::popup-shown",
                   G_CALLBACK(OnComboBoxShownThunk), this);
  gtk_box_pack_start(GTK_BOX(hbox), combo_box, FALSE, FALSE, 0);

  return hbox;
}

void PermissionSelector::AddObserver(PermissionSelectorObserver* observer) {
  observer_list_.AddObserver(observer);
}

void PermissionSelector::OnPermissionChanged(GtkWidget* widget) {
  // Get the selected setting.
  GtkTreeIter it;
  bool has_active = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &it);
  DCHECK(has_active);
  GtkTreeModel* store =
      GTK_TREE_MODEL(gtk_combo_box_get_model(GTK_COMBO_BOX(widget)));
  int value = -1;
  gtk_tree_model_get(store, &it, 1, &value, -1);
  setting_ = ContentSetting(value);

  // Change the permission icon according the the selected setting.
  GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon(
      type_, setting_).ToGdkPixbuf();
  gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), pixbuf);

  FOR_EACH_OBSERVER(PermissionSelectorObserver,
                    observer_list_,
                    OnPermissionChanged(this));
}

void PermissionSelector::OnComboBoxShown(GtkWidget* widget,
                                         GParamSpec* property) {
  // GtkComboBox grabs the keyboard and pointer when it displays its popup,
  // which steals the grabs that BubbleGtk had installed. When the popup is
  // hidden, we notify BubbleGtk so it can try to reacquire the grabs
  // (otherwise, GTK won't activate our widgets when the user clicks in them).
  // When then combobox popup is closed we notify the
  // |PermissionSelectorObserver|s so that BubbleGtk can grab the keyboard and
  // pointer.
  gboolean popup_shown = FALSE;
  g_object_get(G_OBJECT(GTK_COMBO_BOX(widget)), "popup-shown", &popup_shown,
               NULL);
  if (!popup_shown) {
    FOR_EACH_OBSERVER(PermissionSelectorObserver,
                      observer_list_,
                      OnComboboxShown());
  }
}
<commit_msg>(GTK only) Display the correct permission icon for default settings on the Website Settings UI.<commit_after>// Copyright (c) 2012 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/website_settings/permission_selector.h"

#include <gtk/gtk.h>

#include "base/compiler_specific.h"
#include "chrome/browser/ui/gtk/gtk_theme_service.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "chrome/browser/ui/website_settings/website_settings_ui.h"
#include "grit/generated_resources.h"
#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/image/image.h"

namespace {

GtkWidget* CreateTextLabel(const std::string& text,
                           GtkThemeService* theme_service) {
  GtkWidget* label = theme_service->BuildLabel(text, ui::kGdkBlack);
  gtk_label_set_selectable(GTK_LABEL(label), TRUE);
  gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD_CHAR);
  return label;
}

}  // namespace

PermissionSelector::PermissionSelector(GtkThemeService* theme_service,
                                       ContentSettingsType type,
                                       ContentSetting setting,
                                       ContentSetting default_setting)
    : theme_service_(theme_service),
      type_(type),
      setting_(setting),
      default_setting_(default_setting),
      icon_(NULL) {
  DCHECK_NE(default_setting, CONTENT_SETTING_DEFAULT);
}

PermissionSelector::~PermissionSelector() {
}

GtkWidget* PermissionSelector::CreateUI() {
  // Create permission info box.
  const int kChildSpacing = 4;
  GtkWidget* hbox = gtk_hbox_new(FALSE, kChildSpacing);

  // Add permission type icon.
  ContentSetting effective_setting = setting_;
  if (effective_setting == CONTENT_SETTING_DEFAULT)
    effective_setting = default_setting_;
  GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon(
      type_, effective_setting).ToGdkPixbuf();
  icon_ = gtk_image_new_from_pixbuf(pixbuf);
  gtk_box_pack_start(GTK_BOX(hbox), icon_, FALSE, FALSE, 0);

  // Add a label for the permission type.
  GtkWidget* label = CreateTextLabel(
      l10n_util::GetStringFUTF8(
          IDS_WEBSITE_SETTINGS_PERMISSION_TYPE,
          WebsiteSettingsUI::PermissionTypeToUIString(type_)),
      theme_service_);
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

  GtkListStore* store =
      gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
  GtkTreeIter iter;
  // Add option for permission "Global Default" to the combobox model.
  std::string setting_str = l10n_util::GetStringFUTF8(
      IDS_WEBSITE_SETTINGS_DEFAULT_PERMISSION_LABEL,
      WebsiteSettingsUI::PermissionValueToUIString(default_setting_));
  gtk_list_store_append(store, &iter);
  gtk_list_store_set(store, &iter, 0, setting_str.c_str(), 1,
                     CONTENT_SETTING_DEFAULT, -1);
  GtkWidget* combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
  // Add option for permission "Allow" to the combobox model.
  setting_str = l10n_util::GetStringFUTF8(
      IDS_WEBSITE_SETTINGS_PERMISSION_LABEL,
      WebsiteSettingsUI::PermissionValueToUIString(CONTENT_SETTING_ALLOW));
  gtk_list_store_append(store, &iter);
  gtk_list_store_set(store, &iter, 0, setting_str.c_str(), 1,
                     CONTENT_SETTING_ALLOW, -1);
  // The content settings type fullscreen does not support the concept of
  // blocking.
  if (type_ != CONTENT_SETTINGS_TYPE_FULLSCREEN) {
    // Add option for permission "BLOCK" to the combobox model.
    setting_str = l10n_util::GetStringFUTF8(
        IDS_WEBSITE_SETTINGS_PERMISSION_LABEL,
        WebsiteSettingsUI::PermissionValueToUIString(CONTENT_SETTING_BLOCK));
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, 0, setting_str.c_str(), 1,
                       CONTENT_SETTING_BLOCK, -1);
  }
  // Remove reference to the store to prevent leaking.
  g_object_unref(G_OBJECT(store));

  GtkCellRenderer* cell = gtk_cell_renderer_text_new();
  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), cell, TRUE );
  gtk_cell_layout_set_attributes(
      GTK_CELL_LAYOUT(combo_box), cell, "text", 0, NULL);

  // Select the combobox entry for the currently configured permission value.
  int active = -1;
  switch (setting_) {
    case CONTENT_SETTING_DEFAULT: active = 0;
      break;
    case CONTENT_SETTING_ALLOW: active = 1;
      break;
    case CONTENT_SETTING_BLOCK: active = 2;
      break;
    default:
      NOTREACHED() << "Bad content setting:" << setting_;
      break;
  }
  gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), active);

  // Add change listener to the combobox.
  g_signal_connect(combo_box, "changed",
                   G_CALLBACK(OnPermissionChangedThunk), this);
  // Once the popup (window) for a combobox is shown, the bubble container
  // (window) loses it's focus. Therefore it necessary to reset the focus to
  // the bubble container after the combobox popup is closed.
  g_signal_connect(combo_box, "notify::popup-shown",
                   G_CALLBACK(OnComboBoxShownThunk), this);
  gtk_box_pack_start(GTK_BOX(hbox), combo_box, FALSE, FALSE, 0);

  return hbox;
}

void PermissionSelector::AddObserver(PermissionSelectorObserver* observer) {
  observer_list_.AddObserver(observer);
}

void PermissionSelector::OnPermissionChanged(GtkWidget* widget) {
  // Get the selected setting.
  GtkTreeIter it;
  bool has_active = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &it);
  DCHECK(has_active);
  GtkTreeModel* store =
      GTK_TREE_MODEL(gtk_combo_box_get_model(GTK_COMBO_BOX(widget)));
  int value = -1;
  gtk_tree_model_get(store, &it, 1, &value, -1);
  setting_ = ContentSetting(value);

  // Change the permission icon according the the selected setting.
  ContentSetting effective_setting = setting_;
  if (effective_setting == CONTENT_SETTING_DEFAULT)
    effective_setting = default_setting_;
  GdkPixbuf* pixbuf = WebsiteSettingsUI::GetPermissionIcon(
      type_, effective_setting).ToGdkPixbuf();
  gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), pixbuf);

  FOR_EACH_OBSERVER(PermissionSelectorObserver,
                    observer_list_,
                    OnPermissionChanged(this));
}

void PermissionSelector::OnComboBoxShown(GtkWidget* widget,
                                         GParamSpec* property) {
  // GtkComboBox grabs the keyboard and pointer when it displays its popup,
  // which steals the grabs that BubbleGtk had installed. When the popup is
  // hidden, we notify BubbleGtk so it can try to reacquire the grabs
  // (otherwise, GTK won't activate our widgets when the user clicks in them).
  // When then combobox popup is closed we notify the
  // |PermissionSelectorObserver|s so that BubbleGtk can grab the keyboard and
  // pointer.
  gboolean popup_shown = FALSE;
  g_object_get(G_OBJECT(GTK_COMBO_BOX(widget)), "popup-shown", &popup_shown,
               NULL);
  if (!popup_shown) {
    FOR_EACH_OBSERVER(PermissionSelectorObserver,
                      observer_list_,
                      OnComboboxShown());
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 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/browser_action_test_util.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/views/browser_actions_container.h"
#include "chrome/common/chrome_switches.h"

class BrowserActionsContainerTest : public ExtensionBrowserTest {
 public:
  BrowserActionsContainerTest() {
  }
  virtual ~BrowserActionsContainerTest() {}

  virtual Browser* CreateBrowser(Profile* profile) {
    Browser* b = InProcessBrowserTest::CreateBrowser(profile);
    browser_actions_bar_.reset(new BrowserActionTestUtil(b));
    return b;
  }

  BrowserActionTestUtil* browser_actions_bar() {
    return browser_actions_bar_.get();
  }

  // Make sure extension with index |extension_index| has an icon.
  void EnsureExtensionHasIcon(int extension_index) {
    if (!browser_actions_bar_->HasIcon(extension_index)) {
      // The icon is loaded asynchronously and a notification is then sent to
      // observers. So we wait on it.
      browser_actions_bar_->WaitForBrowserActionUpdated(extension_index);
    }
    EXPECT_TRUE(browser_actions_bar()->HasIcon(extension_index));
  }

 private:
  scoped_ptr<BrowserActionTestUtil> browser_actions_bar_;
};

// Test the basic functionality.
IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest, Basic) {
  BrowserActionsContainer::disable_animations_during_testing_ = true;

  // Load an extension with no browser action.
  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
                                          .AppendASCII("browser_action")
                                          .AppendASCII("none")));
  // This extension should not be in the model (has no browser action).
  EXPECT_EQ(0, browser_actions_bar()->NumberOfBrowserActions());

  // Load an extension with a browser action.
  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
                                          .AppendASCII("browser_action")
                                          .AppendASCII("basics")));
  EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions());
  EnsureExtensionHasIcon(0);

  // Unload the extension.
  std::string id = browser_actions_bar()->GetExtensionId(0);
  UnloadExtension(id);
  EXPECT_EQ(0, browser_actions_bar()->NumberOfBrowserActions());
}

// TODO(mpcomplete): http://code.google.com/p/chromium/issues/detail?id=38992
IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest, Visibility) {
  BrowserActionsContainer::disable_animations_during_testing_ = true;

  // Load extension A (contains browser action).
  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
                                          .AppendASCII("browser_action")
                                          .AppendASCII("basics")));
  EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions());
  EnsureExtensionHasIcon(0);
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
  std::string idA = browser_actions_bar()->GetExtensionId(0);

  // Load extension B (contains browser action).
  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
                                          .AppendASCII("browser_action")
                                          .AppendASCII("add_popup")));
  EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
  EnsureExtensionHasIcon(0);
  EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions());
  std::string idB = browser_actions_bar()->GetExtensionId(1);

  EXPECT_NE(idA, idB);

  // Load extension C (contains browser action).
  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
                                          .AppendASCII("browser_action")
                                          .AppendASCII("remove_popup")));
  EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
  EnsureExtensionHasIcon(2);
  EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
  std::string idC = browser_actions_bar()->GetExtensionId(2);

  // Change container to show only one action, rest in overflow: A, [B, C].
  browser_actions_bar()->SetIconVisibilityCount(1);
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());

  // Disable extension A (should disappear). State becomes: B [C].
  DisableExtension(idA);
  EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idB, browser_actions_bar()->GetExtensionId(0));

  // Enable A again. A should get its spot in the same location and the bar
  // should not grow (chevron is showing). For details: http://crbug.com/35349.
  // State becomes: A, [B, C].
  EnableExtension(idA);
  EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0));

  // Disable C (in overflow). State becomes: A, [B].
  DisableExtension(idC);
  EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0));

  // Enable C again. State becomes: A, [B, C].
  EnableExtension(idC);
  EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0));

  // Now we have 3 extensions. Make sure they are all visible. State: A, B, C.
  browser_actions_bar()->SetIconVisibilityCount(3);
  EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());

  // Disable extension A (should disappear). State becomes: B, C.
  DisableExtension(idA);
  EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idB, browser_actions_bar()->GetExtensionId(0));

  // Disable extension B (should disappear). State becomes: C.
  DisableExtension(idB);
  EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idC, browser_actions_bar()->GetExtensionId(0));

  // Enable B (makes B and C showing now). State becomes: B, C.
  EnableExtension(idB);
  EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idB, browser_actions_bar()->GetExtensionId(0));

  // Enable A (makes A, B and C showing now). State becomes: B, C, A.
  EnableExtension(idA);
  EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(2));
}
<commit_msg>Disable BrowserActionsContainerTest.Visibility, it still times out.<commit_after>// Copyright (c) 2010 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/browser_action_test_util.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/views/browser_actions_container.h"
#include "chrome/common/chrome_switches.h"

class BrowserActionsContainerTest : public ExtensionBrowserTest {
 public:
  BrowserActionsContainerTest() {
  }
  virtual ~BrowserActionsContainerTest() {}

  virtual Browser* CreateBrowser(Profile* profile) {
    Browser* b = InProcessBrowserTest::CreateBrowser(profile);
    browser_actions_bar_.reset(new BrowserActionTestUtil(b));
    return b;
  }

  BrowserActionTestUtil* browser_actions_bar() {
    return browser_actions_bar_.get();
  }

  // Make sure extension with index |extension_index| has an icon.
  void EnsureExtensionHasIcon(int extension_index) {
    if (!browser_actions_bar_->HasIcon(extension_index)) {
      // The icon is loaded asynchronously and a notification is then sent to
      // observers. So we wait on it.
      browser_actions_bar_->WaitForBrowserActionUpdated(extension_index);
    }
    EXPECT_TRUE(browser_actions_bar()->HasIcon(extension_index));
  }

 private:
  scoped_ptr<BrowserActionTestUtil> browser_actions_bar_;
};

// Test the basic functionality.
IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest, Basic) {
  BrowserActionsContainer::disable_animations_during_testing_ = true;

  // Load an extension with no browser action.
  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
                                          .AppendASCII("browser_action")
                                          .AppendASCII("none")));
  // This extension should not be in the model (has no browser action).
  EXPECT_EQ(0, browser_actions_bar()->NumberOfBrowserActions());

  // Load an extension with a browser action.
  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
                                          .AppendASCII("browser_action")
                                          .AppendASCII("basics")));
  EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions());
  EnsureExtensionHasIcon(0);

  // Unload the extension.
  std::string id = browser_actions_bar()->GetExtensionId(0);
  UnloadExtension(id);
  EXPECT_EQ(0, browser_actions_bar()->NumberOfBrowserActions());
}

// TODO(mpcomplete): http://code.google.com/p/chromium/issues/detail?id=38992
// Disabled, http://crbug.com/38992.
IN_PROC_BROWSER_TEST_F(BrowserActionsContainerTest, DISABLED_Visibility) {
  BrowserActionsContainer::disable_animations_during_testing_ = true;

  // Load extension A (contains browser action).
  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
                                          .AppendASCII("browser_action")
                                          .AppendASCII("basics")));
  EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions());
  EnsureExtensionHasIcon(0);
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
  std::string idA = browser_actions_bar()->GetExtensionId(0);

  // Load extension B (contains browser action).
  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
                                          .AppendASCII("browser_action")
                                          .AppendASCII("add_popup")));
  EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
  EnsureExtensionHasIcon(0);
  EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions());
  std::string idB = browser_actions_bar()->GetExtensionId(1);

  EXPECT_NE(idA, idB);

  // Load extension C (contains browser action).
  ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
                                          .AppendASCII("browser_action")
                                          .AppendASCII("remove_popup")));
  EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
  EnsureExtensionHasIcon(2);
  EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
  std::string idC = browser_actions_bar()->GetExtensionId(2);

  // Change container to show only one action, rest in overflow: A, [B, C].
  browser_actions_bar()->SetIconVisibilityCount(1);
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());

  // Disable extension A (should disappear). State becomes: B [C].
  DisableExtension(idA);
  EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idB, browser_actions_bar()->GetExtensionId(0));

  // Enable A again. A should get its spot in the same location and the bar
  // should not grow (chevron is showing). For details: http://crbug.com/35349.
  // State becomes: A, [B, C].
  EnableExtension(idA);
  EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0));

  // Disable C (in overflow). State becomes: A, [B].
  DisableExtension(idC);
  EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0));

  // Enable C again. State becomes: A, [B, C].
  EnableExtension(idC);
  EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(0));

  // Now we have 3 extensions. Make sure they are all visible. State: A, B, C.
  browser_actions_bar()->SetIconVisibilityCount(3);
  EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());

  // Disable extension A (should disappear). State becomes: B, C.
  DisableExtension(idA);
  EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idB, browser_actions_bar()->GetExtensionId(0));

  // Disable extension B (should disappear). State becomes: C.
  DisableExtension(idB);
  EXPECT_EQ(1, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(1, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idC, browser_actions_bar()->GetExtensionId(0));

  // Enable B (makes B and C showing now). State becomes: B, C.
  EnableExtension(idB);
  EXPECT_EQ(2, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(2, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idB, browser_actions_bar()->GetExtensionId(0));

  // Enable A (makes A, B and C showing now). State becomes: B, C, A.
  EnableExtension(idA);
  EXPECT_EQ(3, browser_actions_bar()->NumberOfBrowserActions());
  EXPECT_EQ(3, browser_actions_bar()->VisibleBrowserActions());
  EXPECT_EQ(idA, browser_actions_bar()->GetExtensionId(2));
}
<|endoftext|>