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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    ConfidenceConnected.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

// Software Guide : BeginLatex
//
// The following example illustrates the use of the
// \code{itk::ConfidenceConnectedImageFilter}. This filter is based on the use
// of the flood fill iterator. Most of the algorithmic complexity of a region
// growing method comes from the strategy used for visiting the neighbor
// pixels. The flood fill iterator assumes this responsibility and greatly
// simplifies the implementation of a region growing approach. The work left to
// the algorithm is to establish a criterion for deciding whether a particular
// pixel should be included in the current region or not.
//
// \index{itk::FloodFillIterator!In Region Growing}
// \index{itk::ConfidenceConnectedImageFilter|textbf}
// \index{itk::ConfidenceConnectedImageFilter!header}
//
// The criterion used by the \code{ConfidenceConnectedImageFilter} is based on
// simple statistics of the current region. First, the algorithm computes the
// mean and standard deviation of intensity values for all the pixels currently
// included in the region. A user-provided factor is used to multiply the
// standard deviation and define a range aroun the mean. Neighbor pixels whose
// intensity values fall inside the range are accepted to be included in the
// region. When no more neighbor pixes are found that can satisfy the
// criterion, the algorithm considered to have finished its first iteration. At
// that point, the mean and standard deviation of intensity levels are
// recomputed using all the pixels currently included in the region. These mean
// and standard deviation define a new intensity range that is used for
// visiting the current neighbors in search of pixels whose intensity falls
// inside the range.  This iterative process is repated a number of times as
// defined by the user. The following equation illustrates the inclusion
// criterion used by this filter.
//
// \begin{equation}
// I(\mathbf{X}) \in [ m - f \sigma , m + f \sigma ]
// \end{equation}
//
// where $m$ and $\sigma$ are the mean and standard deviation of the  region
// intensities, $f$ is a factor defined by the user. $I()$ is the image and
// $\mathbf{X}$ is the position of the particular neighbor pixel being
// considered for inclusion in the region.
//
// Let's look at the minimal code required to use this algorithm. First, the
// following header defining the \code{ConfidenceConnectedImageFilter} class
// must be included.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkConfidenceConnectedImageFilter.h"
// Software Guide : EndCodeSnippet

#include "itkImage.h"
#include "itkCastImageFilter.h"

//  Software Guide : BeginLatex
//
//  Noise present in the image can reduce the capacity of this filter to grow
//  large regions. When faced with noisy images, it is usually convenient to
//  pre-process the image by using an edge-preserving smoothing filter. Any of
//  the filters discussed in section \ref{sec:EdgePreservingSmoothingFilers}
//  could be used to this end. In this particular example we use the
//  \code{CurvatureFlowImageFilter}, henceforth we need to include its header
//  file.
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkCurvatureFlowImageFilter.h"
// Software Guide : EndCodeSnippet

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

int main( int argc, char **argv )
{

  if( argc < 5 )
    {
    std::cerr << "Missing Parameters " << std::endl;
    std::cerr << "Usage: " << argv[0];
    std::cerr << " inputImage  outputImage seedX seedY " << std::endl;
    return 1;
    }

  //  Software Guide : BeginLatex
  //
  //  We declare now the image type using a pixel type and a particular
  //  dimension. In this case the \code{float} type is used for the pixels due
  //  to the requirements of the smoothing filter.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef   float           InternalPixelType;
  const     unsigned int    Dimension = 2;

  typedef itk::Image< InternalPixelType, Dimension >  InternalImageType;
  // Software Guide : EndCodeSnippet

  typedef unsigned char OutputPixelType;
  typedef itk::Image< OutputPixelType, Dimension > OutputImageType;

  typedef itk::CastImageFilter<
                        InternalImageType,
                        OutputImageType    >    CastingFilterType;

  CastingFilterType::Pointer caster = CastingFilterType::New();

  //
  // We instantiate reader and writer types
  //
  typedef  itk::ImageFileReader< InternalImageType > ReaderType;
  typedef  itk::ImageFileWriter<  OutputImageType  > WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName( argv[1] );
  writer->SetFileName( argv[2] );

  //  Software Guide : BeginLatex
  //
  //
  //  The smoothing filter type is instantiated using the image type as
  //  template parameter.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef   itk::CurvatureFlowImageFilter<
                               InternalImageType,
                               InternalImageType >  CurvatureFlowImageFilterType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Then, the filter is created by invoking the \code{New()} method and
  //  assigning the result to a \code{SmartPointer}.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  CurvatureFlowImageFilterType::Pointer smoothing =
                         CurvatureFlowImageFilterType::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We declare now the type of the region growing filter. In this case it is
  //  the \code{itk::ConfidenceConectedImageFilter}.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef  itk::ConfidenceConnectedImageFilter<
                                    InternalImageType,
                                    InternalImageType > ConnectedFilterType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  then, we  construct one filter of this class using the \code{New()} method.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ConnectedFilterType::Pointer confidenceConnected = ConnectedFilterType::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Now is time for connecting the pipeline. This is pretty linear in our
  //  example. A file reader is added at the beginning of the pipeline and a
  //  caster filter and writer are added at the end. The caster filter is
  //  required here to convert \code{float} pixel types to the integers types
  //  since only a few image file formats support \code{float} types.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  smoothing->SetInput( reader->GetOutput() );

  confidenceConnected->SetInput( smoothing->GetOutput() );

  caster->SetInput( confidenceConnected->GetOutput() );

  writer->SetInput( caster->GetOutput() );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The \code{CurvatureFlowImageFilter} requires a couple of parameter to be
  //  defined. The following are typical values for $2D$ images. However they
  //  may have to be adjusted depending on the amount of noise present in the
  //  input image.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  smoothing->SetNumberOfIterations( 5 );

  smoothing->SetTimeStep( 0.25 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The \code{ConfidenceConnectedImageFilter} has two parameters to be
  //  defined. First, the factor $f$ that the defines how large the range of
  //  intensities will be. Small values of the multiplier will restrict the
  //  inclusion of pixels to those having very similar intensities to those in
  //  the current region. Larger values of the multiplier will relax the
  //  accepting condition and will result in more generous growth of the
  //  region. Too large values will make the region ingest neighbor regions in
  //  the image that may actually belong to separate anatomical structures.
  //
  //  \index{itk::ConfidenceConnectedImageFilter!SetMultiplier()}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetMultiplier( 2.5 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The number of iteration may be decided based on how homogeneous are the
  //  intensities on the anatomical structure to be segmented. Very homogeneous
  //  regions may require only a couple of iterations. Regions with ramp
  //  effects, like for example MRI images with inhomogenous fields may require
  //  more iterations. In practice, it seems to be more relevant to carefully
  //  select the multiplier factor rather than the number of iterations.
  //  However keep in mind that there is no reason to assumet that this
  //  algorithm should converge to a stable region. It is possible that by
  //  letting the algorithm run for more iterations the region will end up
  //  engulfing the entire image.
  //
  //  \index{itk::ConfidenceConnectedImageFilter!SetNumberOfIterations()}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetNumberOfIterations( 5 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The output of this filter is a binary image with zero-value pixels every
  //  where except on the extracted region. The intensity value to be put
  //  inside the region is selected with the method \code{SetReplaceValue()}
  //
  //  \index{itk::ConfidenceConnectedImageFilter!SetReplaceValue()}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetReplaceValue( 255 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The initialization of the algorithm requires the user to provide a seed
  //  point. It is convenient to select this point to be placed in a
  //  \emph{typical} region of the anatomical structure to be segmented. A
  //  small neighborhood around the seed point will be used to compute the
  //  initial mean and standard deviation for the inclusion criterion. The seed
  //  is passed in the form of a \code{Index} to the \code{SetSeed()} method.
  //
  //  \index{itk::ConfidenceConnectedImageFilter!SetSeed()}
  //  \index{itk::ConfidenceConnectedImageFilter!SetInitialNeighborhoodRadius()}
  //
  //  Software Guide : EndLatex

  InternalImageType::IndexType  index;

  index[0] = atoi( argv[3] );
  index[1] = atoi( argv[4] );

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetSeed( index );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //
  //  The size of the initial neighborhood around the seed is defined with the
  //  method \code{SetInitialNeighborhoodRadius()}. The neighborhood will be
  //  defined as an $N$-Dimensional rectangular region with $2r+1$ pixels on
  //  the side, where $r$ is the value passed as initial neighborhood radius.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetInitialNeighborhoodRadius( 2 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The invokation of the \code{Update()} method on the writer triggers the
  //  execution of the pipeline.  It is usually wise to put update calls in
  //  \code{try/catch} block in case error ocurr and exceptions are thrown.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & excep )
    {
    std::cerr << "Exception caught !" << std::endl;
    std::cerr << excep << std::endl;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Let's now run this example using as input the image
  //  \code{BrainProtonDensitySlice.png} provided in the directory
  //  \code{Insight/Examples/Data}. We can easily segment the major anatomical
  //  structures by providing seeds in the appropriate locations. For example
  //
  //  \begin{center}
  //  \begin{tabular}{|l|c|c|}
  //  \hline
  //  Structure & Seed Index & Output Image \\
  //  \hline
  //  White matter & $(60,116)$ & Second from left in Figure \ref{fig:ConfidenceConnectedOutput} \\
  //  Ventricle    & $(81,112)$ & Third  from left in Figure \ref{fig:ConfidenceConnectedOutput} \\
  //  Gray matter  & $(107,69)$ & Fouth  from left in Figure \ref{fig:ConfidenceConnectedOutput} \\
  //  \hline
  //  \end{tabular}
  //  \end{center}
  //
  // \begin{figure} \center
  // \includegraphics[width=4cm]{BrainProtonDensitySlice.eps}
  // \includegraphics[width=4cm]{ConfidenceConnectedOutput1.eps}
  // \includegraphics[width=4cm]{ConfidenceConnectedOutput2.eps}
  // \includegraphics[width=4cm]{ConfidenceConnectedOutput3.eps}
  // \caption{Segmentation results of the ConfidenceConnected filter for various seed points.}
  // \label{fig:ConfidenceConnectedOutput}
  // \end{figure}
  //
  //  As it is always the case with medical images, the results of
  //  segmentations should not be blindly accepted. Neigbbor anatomical
  //  structures may have similar characteristics when viewed in the current
  //  image modality and may have been absorbed by the current region. However
  //  this kind of segmentation results are a good start for a more refined
  //  post-processing stage in which anatomical knowledge may be included.
  //
  //  Software Guide : EndLatex

  return 0;

}

<commit_msg>DOC: Minor fixes, mainly typos.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    ConfidenceConnected.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

// Software Guide : BeginLatex
//
// The following example illustrates the use of the
// \code{itk::ConfidenceConnectedImageFilter}. This filter is based on the use
// of the flood fill iterator. Most of the algorithmic complexity of a region
// growing method comes from the strategy used for visiting the neighbor
// pixels. The flood fill iterator assumes this responsibility and greatly
// simplifies the implementation of a region growing approach. The work left to
// the algorithm is to establish a criterion for deciding whether a particular
// pixel should be included in the current region or not.
//
// \index{itk::FloodFillIterator!In Region Growing}
// \index{itk::ConfidenceConnectedImageFilter|textbf}
// \index{itk::ConfidenceConnectedImageFilter!header}
//
// The criterion used by the \code{ConfidenceConnectedImageFilter} is based on
// simple statistics of the current region. First, the algorithm computes the
// mean and standard deviation of intensity values for all the pixels currently
// included in the region. A user-provided factor is used to multiply the
// standard deviation and define a range aroun the mean. Neighbor pixels whose
// intensity values fall inside the range are accepted to be included in the
// region. When no more neighbor pixes are found that can satisfy the
// criterion, the algorithm considered to have finished its first iteration. At
// that point, the mean and standard deviation of intensity levels are
// recomputed using all the pixels currently included in the region. These mean
// and standard deviation define a new intensity range that is used for
// visiting the current neighbors in search of pixels whose intensity falls
// inside the range.  This iterative process is repated a number of times as
// defined by the user. The following equation illustrates the inclusion
// criterion used by this filter.
//
// \begin{equation}
// I(\mathbf{X}) \in [ m - f \sigma , m + f \sigma ]
// \end{equation}
//
// where $m$ and $\sigma$ are the mean and standard deviation of the  region
// intensities, $f$ is a factor defined by the user. $I()$ is the image and
// $\mathbf{X}$ is the position of the particular neighbor pixel being
// considered for inclusion in the region.
//
// Let's look at the minimal code required to use this algorithm. First, the
// following header defining the \code{ConfidenceConnectedImageFilter} class
// must be included.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkConfidenceConnectedImageFilter.h"
// Software Guide : EndCodeSnippet

#include "itkImage.h"
#include "itkCastImageFilter.h"

//  Software Guide : BeginLatex
//
//  Noise present in the image can reduce the capacity of this filter to grow
//  large regions. When faced with noisy images, it is usually convenient to
//  pre-process the image by using an edge-preserving smoothing filter. Any of
//  the filters discussed in section \ref{sec:EdgePreservingSmoothingFilers}
//  could be used to this end. In this particular example we use the
//  \code{CurvatureFlowImageFilter}, henceforth we need to include its header
//  file.
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkCurvatureFlowImageFilter.h"
// Software Guide : EndCodeSnippet

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

int main( int argc, char **argv )
{

  if( argc < 5 )
    {
    std::cerr << "Missing Parameters " << std::endl;
    std::cerr << "Usage: " << argv[0];
    std::cerr << " inputImage  outputImage seedX seedY " << std::endl;
    return 1;
    }

  //  Software Guide : BeginLatex
  //
  //  We declare now the image type using a pixel type and a particular
  //  dimension. In this case the \code{float} type is used for the pixels due
  //  to the requirements of the smoothing filter.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef   float           InternalPixelType;
  const     unsigned int    Dimension = 2;

  typedef itk::Image< InternalPixelType, Dimension >  InternalImageType;
  // Software Guide : EndCodeSnippet

  typedef unsigned char OutputPixelType;
  typedef itk::Image< OutputPixelType, Dimension > OutputImageType;

  typedef itk::CastImageFilter<
                        InternalImageType,
                        OutputImageType    >    CastingFilterType;

  CastingFilterType::Pointer caster = CastingFilterType::New();

  //
  // We instantiate reader and writer types
  //
  typedef  itk::ImageFileReader< InternalImageType > ReaderType;
  typedef  itk::ImageFileWriter<  OutputImageType  > WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName( argv[1] );
  writer->SetFileName( argv[2] );

  //  Software Guide : BeginLatex
  //
  //
  //  The smoothing filter type is instantiated using the image type as
  //  template parameter.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef   itk::CurvatureFlowImageFilter<
                               InternalImageType,
                               InternalImageType >  CurvatureFlowImageFilterType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Then, the filter is created by invoking the \code{New()} method and
  //  assigning the result to a \code{SmartPointer}.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  CurvatureFlowImageFilterType::Pointer smoothing =
                         CurvatureFlowImageFilterType::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We declare now the type of the region growing filter. In this case it is
  //  the \code{itk::ConfidenceConectedImageFilter}.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef  itk::ConfidenceConnectedImageFilter<
                                    InternalImageType,
                                    InternalImageType > ConnectedFilterType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  then, we  construct one filter of this class using the \code{New()} method.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ConnectedFilterType::Pointer confidenceConnected = ConnectedFilterType::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Now is time for connecting the pipeline. This is pretty linear in our
  //  example. A file reader is added at the beginning of the pipeline and a
  //  caster filter and writer are added at the end. The caster filter is
  //  required here to convert \code{float} pixel types to the integers types
  //  since only a few image file formats support \code{float} types.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  smoothing->SetInput( reader->GetOutput() );

  confidenceConnected->SetInput( smoothing->GetOutput() );

  caster->SetInput( confidenceConnected->GetOutput() );

  writer->SetInput( caster->GetOutput() );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The \code{CurvatureFlowImageFilter} requires a couple of parameter to be
  //  defined. The following are typical values for $2D$ images. However they
  //  may have to be adjusted depending on the amount of noise present in the
  //  input image.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  smoothing->SetNumberOfIterations( 5 );

  smoothing->SetTimeStep( 0.25 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The \code{ConfidenceConnectedImageFilter} has two parameters to be
  //  defined. First, the factor $f$ that the defines how large the range of
  //  intensities will be. Small values of the multiplier will restrict the
  //  inclusion of pixels to those having very similar intensities to those in
  //  the current region. Larger values of the multiplier will relax the
  //  accepting condition and will result in more generous growth of the
  //  region. Too large values will make the region ingest neighbor regions in
  //  the image that may actually belong to separate anatomical structures.
  //
  //  \index{itk::ConfidenceConnectedImageFilter!SetMultiplier()}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetMultiplier( 2.5 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The number of iteration may be decided based on how homogeneous are the
  //  intensities on the anatomical structure to be segmented. Very homogeneous
  //  regions may require only a couple of iterations. Regions with ramp
  //  effects, like for example MRI images with inhomogenous fields may require
  //  more iterations. In practice, it seems to be more relevant to carefully
  //  select the multiplier factor rather than the number of iterations.
  //  However keep in mind that there is no reason to assume that this
  //  algorithm should converge to a stable region. It is possible that by
  //  letting the algorithm run for more iterations the region will end up
  //  engulfing the entire image.
  //
  //  \index{itk::ConfidenceConnectedImageFilter!SetNumberOfIterations()}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetNumberOfIterations( 5 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The output of this filter is a binary image with zero-value pixels
  //  everywhere except on the extracted region. The intensity value to be put
  //  inside the region is selected with the method \code{SetReplaceValue()}
  //
  //  \index{itk::ConfidenceConnectedImageFilter!SetReplaceValue()}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetReplaceValue( 255 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The initialization of the algorithm requires the user to provide a seed
  //  point. It is convenient to select this point to be placed in a
  //  \emph{typical} region of the anatomical structure to be segmented. A
  //  small neighborhood around the seed point will be used to compute the
  //  initial mean and standard deviation for the inclusion criterion. The seed
  //  is passed in the form of a \code{Index} to the \code{SetSeed()} method.
  //
  //  \index{itk::ConfidenceConnectedImageFilter!SetSeed()}
  //  \index{itk::ConfidenceConnectedImageFilter!SetInitialNeighborhoodRadius()}
  //
  //  Software Guide : EndLatex

  InternalImageType::IndexType  index;

  index[0] = atoi( argv[3] );
  index[1] = atoi( argv[4] );

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetSeed( index );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //
  //  The size of the initial neighborhood around the seed is defined with the
  //  method \code{SetInitialNeighborhoodRadius()}. The neighborhood will be
  //  defined as an $N$-Dimensional rectangular region with $2r+1$ pixels on
  //  the side, where $r$ is the value passed as initial neighborhood radius.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  confidenceConnected->SetInitialNeighborhoodRadius( 2 );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The invokation of the \code{Update()} method on the writer triggers the
  //  execution of the pipeline.  It is usually wise to put update calls in
  //  \code{try/catch} block in case errors ocurr and exceptions are thrown.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & excep )
    {
    std::cerr << "Exception caught !" << std::endl;
    std::cerr << excep << std::endl;
    }
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Let's now run this example using as input the image
  //  \code{BrainProtonDensitySlice.png} provided in the directory
  //  \code{Insight/Examples/Data}. We can easily segment the major anatomical
  //  structures by providing seeds in the appropriate locations. For example
  //
  //  \begin{center}
  //  \begin{tabular}{|l|c|c|}
  //  \hline
  //  Structure & Seed Index & Output Image \\
  //  \hline
  //  White matter & $(60,116)$ & Second from left in Figure \ref{fig:ConfidenceConnectedOutput} \\
  //  Ventricle    & $(81,112)$ & Third  from left in Figure \ref{fig:ConfidenceConnectedOutput} \\
  //  Gray matter  & $(107,69)$ & Fourth from left in Figure \ref{fig:ConfidenceConnectedOutput} \\
  //  \hline
  //  \end{tabular}
  //  \end{center}
  //
  // \begin{figure} \center
  // \includegraphics[width=4cm]{BrainProtonDensitySlice.eps}
  // \includegraphics[width=4cm]{ConfidenceConnectedOutput1.eps}
  // \includegraphics[width=4cm]{ConfidenceConnectedOutput2.eps}
  // \includegraphics[width=4cm]{ConfidenceConnectedOutput3.eps}
  // \caption{Segmentation results of the ConfidenceConnected filter for various seed points.}
  // \label{fig:ConfidenceConnectedOutput}
  // \end{figure}
  //
  //  It can be noticed that the gray matter is not being completly segmented.
  //  This illustrates the vulnerability of the region growing methods when the
  //  anatomical structures to be segmented do not have a homogeneous
  //  statistical distribution over the image space. You may want to experiment
  //  with differnt numbers of iterations to verify how the accepted region
  //  will extend.
  //
  //  Software Guide : EndLatex

  return 0;

}

<|endoftext|>


<commit_before><commit_msg>- Removed uneeded code from Compiler::varDeclaration()<commit_after><|endoftext|>


<commit_before>/*
 * This istream filter removes HTTP chunking.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "istream_dechunk.hxx"
#include "http/ChunkParser.hxx"
#include "FacadeIstream.hxx"
#include "pool.hxx"
#include "event/DeferEvent.hxx"
#include "event/Callback.hxx"

#include <algorithm>

#include <glib.h>

#include <assert.h>
#include <string.h>

class DechunkIstream final : public FacadeIstream {
    HttpChunkParser parser;

    bool eof = false, closed = false;

    bool had_input, had_output;

    /**
     * Copy chunked data verbatim to handler?
     *
     * @see istream_dechunk_check_verbatim()
     */
    bool verbatim = false;

    /**
     * Was the end-of-file chunk seen at the end of #pending_verbatim?
     */
    bool eof_verbatim;

    bool seen_eof = false;

    /**
     * Number of data chunk bytes already seen, but not yet consumed
     * by our #IstreamHandler.  In verbatim mode, this attribute is
     * unused.
     */
    size_t seen_data = 0;

    /**
     * Number of bytes to be passed to handler verbatim, which have
     * already been parsed but have not yet been consumed by the
     * handler.
     */
    size_t pending_verbatim;

    /**
     * This event is used to defer an DechunkHandler::OnDechunkEnd()
     * call.
     */
    DeferEvent defer_eof_event;

    DechunkHandler &dechunk_handler;

public:
    DechunkIstream(struct pool &p, Istream &_input,
                   DechunkHandler &_dechunk_handler)
        :FacadeIstream(p, _input),
         defer_eof_event(MakeSimpleEventCallback(DechunkIstream, DeferredEof),
                         this),
         dechunk_handler(_dechunk_handler)
    {
    }

    static DechunkIstream *CheckCast(Istream &i) {
        return dynamic_cast<DechunkIstream *>(&i);
    }

    void SetVerbatim() {
        verbatim = true;
        eof_verbatim = false;
        pending_verbatim = 0;
    }

private:
    void Abort(GError *error);

    gcc_pure
    bool IsEofPending() const {
        return defer_eof_event.IsPending();
    }

    void DeferredEof();

    void EofDetected();

    bool CalculateRemainingDataSize(const char *src, const char *src_end);

    size_t Feed(const void *data, size_t length);

public:
    /* virtual methods from class Istream */

    off_t _GetAvailable(bool partial) override;
    void _Read() override;
    void _Close() override;

protected:
    /* virtual methods from class IstreamHandler */
    size_t OnData(const void *data, size_t length) override;
    void OnEof() override;
    void OnError(GError *error) override;
};

void
DechunkIstream::Abort(GError *error)
{
    assert(!closed);
    assert(!parser.HasEnded());
    assert(input.IsDefined());
    assert(!IsEofPending());

    closed = true;

    input.ClearAndClose();
    DestroyError(error);
}

void
DechunkIstream::DeferredEof()
{
    assert(parser.HasEnded());
    assert(!eof);

    eof = true;

    dechunk_handler.OnDechunkEnd(input.Steal());

    assert(!input.IsDefined());
    assert(parser.HasEnded());

    const ScopePoolRef ref(GetPool() TRACE_ARGS);

    if (!closed) {
        closed = true;
        DestroyEof();
    }
}

void
DechunkIstream::EofDetected()
{
    assert(input.IsDefined());
    assert(parser.HasEnded());

    defer_eof_event.Add();
}

inline bool
DechunkIstream::CalculateRemainingDataSize(const char *src,
                                           const char *const src_end)
{
    assert(!IsEofPending());
    assert(!eof);

    seen_data = 0;

    if (parser.HasEnded()) {
        if (!seen_eof) {
            seen_eof = true;
            dechunk_handler.OnDechunkEndSeen();
        }

        return true;
    }

    /* work with a copy of our HttpChunkParser */
    HttpChunkParser p(parser);

    while (src != src_end) {
        GError *error = nullptr;
        const ConstBuffer<char> src_remaining(src, src_end - src);
        auto data = ConstBuffer<char>::FromVoid(p.Parse(src_remaining.ToVoid(),
                                                        &error));
        if (data.IsNull()) {
            Abort(error);
            return false;
        }

        if (data.IsEmpty()) {
            if (p.HasEnded() && !seen_eof) {
                seen_eof = true;
                dechunk_handler.OnDechunkEndSeen();
            }

            break;
        }

        seen_data += data.size;
        p.Consume(data.size);
        src = data.end();
    }

    return true;
}

size_t
DechunkIstream::Feed(const void *data0, size_t length)
{
    assert(!closed);
    assert(input.IsDefined());
    assert(!IsEofPending());
    assert(!verbatim || !eof_verbatim);

    had_input = true;

    const auto src_begin = (const char *)data0;
    const auto src_end = src_begin + length;

    auto src = src_begin;
    if (verbatim)
        /* skip the part that has already been parsed in the last
           invocation, but could not be consumed by the handler */
        src += pending_verbatim;

    while (src != src_end) {
        GError *error = nullptr;
        const ConstBuffer<char> src_remaining(src, src_end - src);
        auto data = ConstBuffer<char>::FromVoid(parser.Parse(src_remaining.ToVoid(),
                                                             &error));
        if (data.IsNull()) {
            Abort(error);
            return 0;
        }

        assert(data.data >= src);
        assert(data.data <= src_end);
        assert(data.end() <= src_end);

        src = data.data;

        if (!data.IsEmpty()) {
            assert(!parser.HasEnded());

            size_t nbytes;

            if (verbatim) {
                /* postpone this data chunk; try to send it all later in
                   one big block */
                nbytes = data.size;
            } else {
                had_output = true;
                seen_data += data.size;
                nbytes = InvokeData(src, data.size);
                assert(nbytes <= data.size);

                if (nbytes == 0) {
                    if (closed)
                        return 0;
                    else
                        break;
                }
            }

            src += nbytes;

            bool finished = parser.Consume(nbytes);
            if (!finished && !verbatim)
                break;
        } else if (parser.HasEnded()) {
            break;
        } else {
            assert(src == src_end);
        }
    }

    const size_t position = src - src_begin;
    if (verbatim && position > 0) {
        /* send all chunks in one big block */
        had_output = true;
        size_t nbytes = InvokeData(src_begin, position);
        if (closed)
            return 0;

        /* postpone the rest that was not handled; it will not be
           parsed again */
        pending_verbatim = position - nbytes;
        if (parser.HasEnded()) {
            if (pending_verbatim > 0)
                /* not everything could be sent; postpone to
                   next call */
                eof_verbatim = true;
            else
                EofDetected();
        }

        return nbytes;
    } else if (parser.HasEnded())
        EofDetected();

    if (!verbatim && !CalculateRemainingDataSize(src, src_end))
        return 0;

    return position;
}

/*
 * istream handler
 *
 */

size_t
DechunkIstream::OnData(const void *data, size_t length)
{
    assert(!verbatim || length >= pending_verbatim);

    if (IsEofPending())
        /* don't accept any more data after the EOF chunk */
        return 0;

    if (verbatim && eof_verbatim) {
        /* during the last call, the EOF chunk was parsed, but we
           could not handle it yet, because the handler did not
           consume all data yet; try to send the remaining pre-EOF
           data again and then handle the EOF chunk */

        assert(pending_verbatim > 0);

        assert(length >= pending_verbatim);

        had_output = true;
        size_t nbytes = InvokeData(data, pending_verbatim);
        if (nbytes == 0)
            return 0;

        pending_verbatim -= nbytes;
        if (pending_verbatim == 0)
            EofDetected();

        return nbytes;
    }

    const ScopePoolRef ref(GetPool() TRACE_ARGS);
    return Feed(data, length);
}

void
DechunkIstream::OnEof()
{
    assert(!closed);

    input.Clear();

    if (IsEofPending())
        /* let defer_eof_event handle this */
        return;

    closed = true;

    if (eof)
        return;

    GError *error =
        g_error_new_literal(dechunk_quark(), 0,
                            "premature EOF in dechunker");
    DestroyError(error);
}

void
DechunkIstream::OnError(GError *error)
{
    input.Clear();

    if (IsEofPending()) {
        /* let defer_eof_event handle this */
        g_error_free(error);
        return;
    }

    assert(!closed);
    closed = true;
    DestroyError(error);
}

/*
 * istream implementation
 *
 */

off_t
DechunkIstream::_GetAvailable(bool partial)
{
    if (IsEofPending())
        return 0;

    if (verbatim) {
        if (!partial && !eof_verbatim)
            return -1;

        return pending_verbatim;
    } else {
        if (!partial && !seen_eof)
            return -1;

        return seen_data;
    }
}

void
DechunkIstream::_Read()
{
    if (IsEofPending())
        return;

    const ScopePoolRef ref(GetPool() TRACE_ARGS);

    had_output = false;

    do {
        had_input = false;
        input.Read();
    } while (input.IsDefined() && had_input && !had_output &&
             !IsEofPending());
}

void
DechunkIstream::_Close()
{
    assert(!eof);
    assert(!closed);

    closed = true;
    defer_eof_event.Cancel();

    if (input.IsDefined())
        input.ClearAndClose();
    Destroy();
}

/*
 * constructor
 *
 */

Istream *
istream_dechunk_new(struct pool *pool, Istream &input,
                    DechunkHandler &dechunk_handler)
{
    return NewIstream<DechunkIstream>(*pool, input, dechunk_handler);
}

bool
istream_dechunk_check_verbatim(Istream &i)
{
    auto *dechunk = DechunkIstream::CheckCast(i);
    if (dechunk == nullptr)
        /* not a DechunkIstream instance */
        return false;

    dechunk->SetVerbatim();
    return true;
}
<commit_msg>istream/dechunk: skip CalculateRemainingDataSize() call after EofDetected()<commit_after>/*
 * This istream filter removes HTTP chunking.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "istream_dechunk.hxx"
#include "http/ChunkParser.hxx"
#include "FacadeIstream.hxx"
#include "pool.hxx"
#include "event/DeferEvent.hxx"
#include "event/Callback.hxx"

#include <algorithm>

#include <glib.h>

#include <assert.h>
#include <string.h>

class DechunkIstream final : public FacadeIstream {
    HttpChunkParser parser;

    bool eof = false, closed = false;

    bool had_input, had_output;

    /**
     * Copy chunked data verbatim to handler?
     *
     * @see istream_dechunk_check_verbatim()
     */
    bool verbatim = false;

    /**
     * Was the end-of-file chunk seen at the end of #pending_verbatim?
     */
    bool eof_verbatim;

    bool seen_eof = false;

    /**
     * Number of data chunk bytes already seen, but not yet consumed
     * by our #IstreamHandler.  In verbatim mode, this attribute is
     * unused.
     */
    size_t seen_data = 0;

    /**
     * Number of bytes to be passed to handler verbatim, which have
     * already been parsed but have not yet been consumed by the
     * handler.
     */
    size_t pending_verbatim;

    /**
     * This event is used to defer an DechunkHandler::OnDechunkEnd()
     * call.
     */
    DeferEvent defer_eof_event;

    DechunkHandler &dechunk_handler;

public:
    DechunkIstream(struct pool &p, Istream &_input,
                   DechunkHandler &_dechunk_handler)
        :FacadeIstream(p, _input),
         defer_eof_event(MakeSimpleEventCallback(DechunkIstream, DeferredEof),
                         this),
         dechunk_handler(_dechunk_handler)
    {
    }

    static DechunkIstream *CheckCast(Istream &i) {
        return dynamic_cast<DechunkIstream *>(&i);
    }

    void SetVerbatim() {
        verbatim = true;
        eof_verbatim = false;
        pending_verbatim = 0;
    }

private:
    void Abort(GError *error);

    gcc_pure
    bool IsEofPending() const {
        return defer_eof_event.IsPending();
    }

    void DeferredEof();

    void EofDetected();

    bool CalculateRemainingDataSize(const char *src, const char *src_end);

    size_t Feed(const void *data, size_t length);

public:
    /* virtual methods from class Istream */

    off_t _GetAvailable(bool partial) override;
    void _Read() override;
    void _Close() override;

protected:
    /* virtual methods from class IstreamHandler */
    size_t OnData(const void *data, size_t length) override;
    void OnEof() override;
    void OnError(GError *error) override;
};

void
DechunkIstream::Abort(GError *error)
{
    assert(!closed);
    assert(!parser.HasEnded());
    assert(input.IsDefined());
    assert(!IsEofPending());

    closed = true;

    input.ClearAndClose();
    DestroyError(error);
}

void
DechunkIstream::DeferredEof()
{
    assert(parser.HasEnded());
    assert(!eof);

    eof = true;

    dechunk_handler.OnDechunkEnd(input.Steal());

    assert(!input.IsDefined());
    assert(parser.HasEnded());

    const ScopePoolRef ref(GetPool() TRACE_ARGS);

    if (!closed) {
        closed = true;
        DestroyEof();
    }
}

void
DechunkIstream::EofDetected()
{
    assert(input.IsDefined());
    assert(parser.HasEnded());

    defer_eof_event.Add();
}

inline bool
DechunkIstream::CalculateRemainingDataSize(const char *src,
                                           const char *const src_end)
{
    assert(!IsEofPending());
    assert(!eof);

    seen_data = 0;

    if (parser.HasEnded()) {
        if (!seen_eof) {
            seen_eof = true;
            dechunk_handler.OnDechunkEndSeen();
        }

        return true;
    }

    /* work with a copy of our HttpChunkParser */
    HttpChunkParser p(parser);

    while (src != src_end) {
        GError *error = nullptr;
        const ConstBuffer<char> src_remaining(src, src_end - src);
        auto data = ConstBuffer<char>::FromVoid(p.Parse(src_remaining.ToVoid(),
                                                        &error));
        if (data.IsNull()) {
            Abort(error);
            return false;
        }

        if (data.IsEmpty()) {
            if (p.HasEnded() && !seen_eof) {
                seen_eof = true;
                dechunk_handler.OnDechunkEndSeen();
            }

            break;
        }

        seen_data += data.size;
        p.Consume(data.size);
        src = data.end();
    }

    return true;
}

size_t
DechunkIstream::Feed(const void *data0, size_t length)
{
    assert(!closed);
    assert(input.IsDefined());
    assert(!IsEofPending());
    assert(!verbatim || !eof_verbatim);

    had_input = true;

    const auto src_begin = (const char *)data0;
    const auto src_end = src_begin + length;

    auto src = src_begin;
    if (verbatim)
        /* skip the part that has already been parsed in the last
           invocation, but could not be consumed by the handler */
        src += pending_verbatim;

    while (src != src_end) {
        GError *error = nullptr;
        const ConstBuffer<char> src_remaining(src, src_end - src);
        auto data = ConstBuffer<char>::FromVoid(parser.Parse(src_remaining.ToVoid(),
                                                             &error));
        if (data.IsNull()) {
            Abort(error);
            return 0;
        }

        assert(data.data >= src);
        assert(data.data <= src_end);
        assert(data.end() <= src_end);

        src = data.data;

        if (!data.IsEmpty()) {
            assert(!parser.HasEnded());

            size_t nbytes;

            if (verbatim) {
                /* postpone this data chunk; try to send it all later in
                   one big block */
                nbytes = data.size;
            } else {
                had_output = true;
                seen_data += data.size;
                nbytes = InvokeData(src, data.size);
                assert(nbytes <= data.size);

                if (nbytes == 0) {
                    if (closed)
                        return 0;
                    else
                        break;
                }
            }

            src += nbytes;

            bool finished = parser.Consume(nbytes);
            if (!finished && !verbatim)
                break;
        } else if (parser.HasEnded()) {
            break;
        } else {
            assert(src == src_end);
        }
    }

    const size_t position = src - src_begin;
    if (verbatim && position > 0) {
        /* send all chunks in one big block */
        had_output = true;
        size_t nbytes = InvokeData(src_begin, position);
        if (closed)
            return 0;

        /* postpone the rest that was not handled; it will not be
           parsed again */
        pending_verbatim = position - nbytes;
        if (parser.HasEnded()) {
            if (pending_verbatim > 0)
                /* not everything could be sent; postpone to
                   next call */
                eof_verbatim = true;
            else
                EofDetected();
        }

        return nbytes;
    } else if (parser.HasEnded()) {
        EofDetected();
        return position;
    }

    if (!verbatim && !CalculateRemainingDataSize(src, src_end))
        return 0;

    return position;
}

/*
 * istream handler
 *
 */

size_t
DechunkIstream::OnData(const void *data, size_t length)
{
    assert(!verbatim || length >= pending_verbatim);

    if (IsEofPending())
        /* don't accept any more data after the EOF chunk */
        return 0;

    if (verbatim && eof_verbatim) {
        /* during the last call, the EOF chunk was parsed, but we
           could not handle it yet, because the handler did not
           consume all data yet; try to send the remaining pre-EOF
           data again and then handle the EOF chunk */

        assert(pending_verbatim > 0);

        assert(length >= pending_verbatim);

        had_output = true;
        size_t nbytes = InvokeData(data, pending_verbatim);
        if (nbytes == 0)
            return 0;

        pending_verbatim -= nbytes;
        if (pending_verbatim == 0)
            EofDetected();

        return nbytes;
    }

    const ScopePoolRef ref(GetPool() TRACE_ARGS);
    return Feed(data, length);
}

void
DechunkIstream::OnEof()
{
    assert(!closed);

    input.Clear();

    if (IsEofPending())
        /* let defer_eof_event handle this */
        return;

    closed = true;

    if (eof)
        return;

    GError *error =
        g_error_new_literal(dechunk_quark(), 0,
                            "premature EOF in dechunker");
    DestroyError(error);
}

void
DechunkIstream::OnError(GError *error)
{
    input.Clear();

    if (IsEofPending()) {
        /* let defer_eof_event handle this */
        g_error_free(error);
        return;
    }

    assert(!closed);
    closed = true;
    DestroyError(error);
}

/*
 * istream implementation
 *
 */

off_t
DechunkIstream::_GetAvailable(bool partial)
{
    if (IsEofPending())
        return 0;

    if (verbatim) {
        if (!partial && !eof_verbatim)
            return -1;

        return pending_verbatim;
    } else {
        if (!partial && !seen_eof)
            return -1;

        return seen_data;
    }
}

void
DechunkIstream::_Read()
{
    if (IsEofPending())
        return;

    const ScopePoolRef ref(GetPool() TRACE_ARGS);

    had_output = false;

    do {
        had_input = false;
        input.Read();
    } while (input.IsDefined() && had_input && !had_output &&
             !IsEofPending());
}

void
DechunkIstream::_Close()
{
    assert(!eof);
    assert(!closed);

    closed = true;
    defer_eof_event.Cancel();

    if (input.IsDefined())
        input.ClearAndClose();
    Destroy();
}

/*
 * constructor
 *
 */

Istream *
istream_dechunk_new(struct pool *pool, Istream &input,
                    DechunkHandler &dechunk_handler)
{
    return NewIstream<DechunkIstream>(*pool, input, dechunk_handler);
}

bool
istream_dechunk_check_verbatim(Istream &i)
{
    auto *dechunk = DechunkIstream::CheckCast(i);
    if (dechunk == nullptr)
        /* not a DechunkIstream instance */
        return false;

    dechunk->SetVerbatim();
    return true;
}
<|endoftext|>


<commit_before>#ifndef DROPWHILE__H__
#define DROPWHILE__H__

namespace iter {

    //Forward declarations of DropWhile and dropwhile
    template <typename FilterFunc, typename Container>
    class DropWhile;

    template <typename FilterFunc, typename Container>
    DropWhile<FilterFunc, Container> dropwhile(FilterFunc, Container &);

    template <typename FilterFunc, typename Container>
    class DropWhile {
        friend DropWhile dropwhile<FilterFunc, Container>(
                FilterFunc, Container &);

        // Type of the Container::Iterator, but since the name of that
        // iterator can be anything, we have to grab it with this
        using contained_iter_type =
            decltype(((Container *)nullptr)->begin());

        // The type returned when dereferencing the Container::Iterator
        using contained_iter_ret =
            decltype(((contained_iter_type *)nullptr)->operator*());

        private:
            Container & container;
            FilterFunc filter_func;

            // Value constructor for use only in the dropwhile function
            DropWhile(FilterFunc filter_func, Container & container) :
                container(container),
                filter_func(filter_func)
            { }
            DropWhile () = delete;
            DropWhile & operator=(const DropWhile &) = delete;
            // Default copy constructor used

        public:
            class Iterator {
                private:
                    contained_iter_type sub_iter;
                    const contained_iter_type sub_end;
                    FilterFunc filter_func;

                    // skip all values for which the predicate is true
                    void skip_passes() {
                        while (this->sub_iter != this->sub_end
                                && this->filter_func(*this->sub_iter)) {
                            ++this->sub_iter;
                        }
                    }

                public:
                    Iterator (contained_iter_type iter,
                            contained_iter_type end,
                            FilterFunc filter_func) :
                        sub_iter(iter),
                        sub_end(end),
                        filter_func(filter_func)
                    {
                        this->skip_passes();
                    }

                    contained_iter_ret operator*() const {
                        return *this->sub_iter;
                    }

                    Iterator & operator++() {
                        ++this->sub_iter;
                        return *this;
                    }

                    bool operator!=(const Iterator & other) const {
                        return this->sub_iter != other.sub_iter;
                    }
            };

            Iterator begin() const {
                return Iterator(
                        this->container.begin(),
                        this->container.end(),
                        this->filter_func);
            }

            Iterator end() const {
                return Iterator(
                        this->container.end(),
                        this->container.end(),
                        this->filter_func);
            }

    };

    // Helper function to instantiate a DropWhile
    template <typename FilterFunc, typename Container>
    DropWhile<FilterFunc, Container> dropwhile(
            FilterFunc filter_func, Container & container) {
        return DropWhile<FilterFunc, Container>(filter_func, container);
    }

}

#endif //ifndef DROPWHILE__H__
<commit_msg>Replaces ugly decltype with std::declval in dropwhile<commit_after>#ifndef DROPWHILE__H__
#define DROPWHILE__H__

#include <utility>

namespace iter {

    //Forward declarations of DropWhile and dropwhile
    template <typename FilterFunc, typename Container>
    class DropWhile;

    template <typename FilterFunc, typename Container>
    DropWhile<FilterFunc, Container> dropwhile(FilterFunc, Container &);

    template <typename FilterFunc, typename Container>
    class DropWhile {
        friend DropWhile dropwhile<FilterFunc, Container>(
                FilterFunc, Container &);

        // Type of the Container::Iterator, but since the name of that
        // iterator can be anything, we have to grab it with this
        using contained_iter_type =
            decltype(std::declval<Container>().begin());

        // The type returned when dereferencing the Container::Iterator
        using contained_iter_ret =
            decltype(std::declval<contained_iter_type>().operator*());

        private:
            Container & container;
            FilterFunc filter_func;

            // Value constructor for use only in the dropwhile function
            DropWhile(FilterFunc filter_func, Container & container) :
                container(container),
                filter_func(filter_func)
            { }
            DropWhile () = delete;
            DropWhile & operator=(const DropWhile &) = delete;
            // Default copy constructor used

        public:
            class Iterator {
                private:
                    contained_iter_type sub_iter;
                    const contained_iter_type sub_end;
                    FilterFunc filter_func;

                    // skip all values for which the predicate is true
                    void skip_passes() {
                        while (this->sub_iter != this->sub_end
                                && this->filter_func(*this->sub_iter)) {
                            ++this->sub_iter;
                        }
                    }

                public:
                    Iterator (contained_iter_type iter,
                            contained_iter_type end,
                            FilterFunc filter_func) :
                        sub_iter(iter),
                        sub_end(end),
                        filter_func(filter_func)
                    {
                        this->skip_passes();
                    }

                    contained_iter_ret operator*() const {
                        return *this->sub_iter;
                    }

                    Iterator & operator++() {
                        ++this->sub_iter;
                        return *this;
                    }

                    bool operator!=(const Iterator & other) const {
                        return this->sub_iter != other.sub_iter;
                    }
            };

            Iterator begin() const {
                return Iterator(
                        this->container.begin(),
                        this->container.end(),
                        this->filter_func);
            }

            Iterator end() const {
                return Iterator(
                        this->container.end(),
                        this->container.end(),
                        this->filter_func);
            }

    };

    // Helper function to instantiate a DropWhile
    template <typename FilterFunc, typename Container>
    DropWhile<FilterFunc, Container> dropwhile(
            FilterFunc filter_func, Container & container) {
        return DropWhile<FilterFunc, Container>(filter_func, container);
    }

}

#endif //ifndef DROPWHILE__H__
<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"

#ifndef _COM_SUN_STAR_XML_XPATH_XXPATHAPI_HPP_
#include <com/sun/star/xml/xpath/XXPathAPI.hpp>
#endif

#include "updateprotocol.hxx"

#ifndef _COM_SUN_STAR_DEPLOYMENT_UPDATEINFORMATINENTRY_HPP_
#include <com/sun/star/deployment/UpdateInformationEntry.hpp>
#endif

#include <rtl/ref.hxx>
#include <rtl/uri.hxx>
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/bootstrap.hxx>
#include <osl/process.h>

#include <cppuhelper/implbase1.hxx>

namespace css = com::sun::star ;
namespace container = css::container ;
namespace deployment = css::deployment ;
namespace lang = css::lang ;
namespace uno = css::uno ;
namespace task = css::task ;
namespace xml = css::xml ;

#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))

//------------------------------------------------------------------------------

static bool
getBootstrapData(
    uno::Sequence< ::rtl::OUString > & rRepositoryList,
    ::rtl::OUString & rBuildID,
    ::rtl::OUString & rInstallSetID)
{
    rtl::OUString aPath, aPath2;
    if( osl_getExecutableFile(&aPath.pData) != osl_Process_E_None )
        return false;

    sal_uInt32 lastIndex = aPath.lastIndexOf('/');
    if ( lastIndex > 0 )
    {
        aPath = aPath.copy( 0, lastIndex+1 );
        aPath += UNISTRING( SAL_CONFIGFILE( "version" ) );
    }

    rtl::Bootstrap aVersionFile(aPath);
    aVersionFile.getFrom(UNISTRING("ProductBuildid"), rBuildID, rtl::OUString());
    aVersionFile.getFrom(UNISTRING("UpdateID"), rInstallSetID, rtl::OUString());

    rtl::OUString aValue;
    aVersionFile.getFrom(UNISTRING("UpdateURL"), aValue, rtl::OUString());
    if( aValue.getLength() > 0 )
    {
        rRepositoryList.realloc(1);
        rRepositoryList[0] = aValue;
    }

    return true;
}

//------------------------------------------------------------------------------

// Returns 'true' if successfully connected to the update server
bool
checkForUpdates(
    UpdateInfo& o_rUpdateInfo,
    uno::Reference< uno::XComponentContext > const & rxContext,
    uno::Reference< task::XInteractionHandler > const & rxInteractionHandler,
    const uno::Reference< deployment::XUpdateInformationProvider >& rUpdateInfoProvider)
{
    OSL_TRACE("checking for updates ..\n");

    ::rtl::OUString myArch;
    ::rtl::OUString myOS;

    rtl::Bootstrap::get(UNISTRING("_OS"), myOS);
    rtl::Bootstrap::get(UNISTRING("_ARCH"), myArch);

    uno::Sequence< ::rtl::OUString > aRepositoryList;
    ::rtl::OUString aBuildID;
    ::rtl::OUString aInstallSetID;

    if( ! ( getBootstrapData(aRepositoryList, aBuildID, aInstallSetID) && (aRepositoryList.getLength() > 0) ) )
        return false;

    if( !rxContext.is() )
        throw uno::RuntimeException(
            UNISTRING( "checkForUpdates: empty component context" ), uno::Reference< uno::XInterface >() );

    OSL_ASSERT( rxContext->getServiceManager().is() );

    // XPath implementation
    uno::Reference< xml::xpath::XXPathAPI > xXPath(
        rxContext->getServiceManager()->createInstanceWithContext( UNISTRING( "com.sun.star.xml.xpath.XPathAPI" ), rxContext ),
        uno::UNO_QUERY_THROW);

    xXPath->registerNS( UNISTRING("inst"), UNISTRING("http://installation.openoffice.org/description") );

    if( rxInteractionHandler.is() )
        rUpdateInfoProvider->setInteractionHandler(rxInteractionHandler);

    try
    {
        uno::Reference< container::XEnumeration > aUpdateInfoEnumeration =
            rUpdateInfoProvider->getUpdateInformationEnumeration( aRepositoryList, aInstallSetID );

        rtl::OUStringBuffer aBuffer;
        aBuffer.appendAscii("/child::inst:description[inst:os=\'");
        aBuffer.append( myOS );
        aBuffer.appendAscii("\' and inst:arch=\'");
        aBuffer.append( myArch );
        aBuffer.appendAscii("\' and inst:buildid>");
        aBuffer.append( aBuildID );
        aBuffer.appendAscii("]");

        rtl::OUString aXPathExpression = aBuffer.makeStringAndClear();

        while( aUpdateInfoEnumeration->hasMoreElements() )
        {
            deployment::UpdateInformationEntry aEntry;

            if( aUpdateInfoEnumeration->nextElement() >>= aEntry )
            {
                uno::Reference< xml::dom::XNode > xNode( aEntry.UpdateDocument.get() );
                uno::Reference< xml::dom::XNodeList > xNodeList =
                    xXPath->selectNodeList(xNode, aXPathExpression + UNISTRING("/inst:update/attribute::src"));

/*
                o_rUpdateInfo.Sources.push_back( DownloadSource(true,
                    UNISTRING("http://openoffice.bouncer.osuosl.org/?product=OpenOffice.org&os=solarissparcwjre&lang=en-US&version=2.2.1") ) );
*/

                sal_Int32 i, imax = xNodeList->getLength();
                for( i = 0; i < imax; ++i )
                {
                    uno::Reference< xml::dom::XNode > xNode2( xNodeList->item(i) );

                    if( xNode2.is() )
                    {
                        uno::Reference< xml::dom::XElement > xParent(xNode2->getParentNode(), uno::UNO_QUERY_THROW);
                        rtl::OUString aType = xParent->getAttribute(UNISTRING("type"));
                        bool bIsDirect = ( sal_False == aType.equalsIgnoreAsciiCaseAscii("text/html") );

                        o_rUpdateInfo.Sources.push_back( DownloadSource(bIsDirect, xNode2->getNodeValue()) );
                    }
                }

                uno::Reference< xml::dom::XNode > xNode2 =
                    xXPath->selectSingleNode(xNode, aXPathExpression + UNISTRING("/inst:version/text()"));

                if( xNode2.is() )
                    o_rUpdateInfo.Version = xNode2->getNodeValue();

                xNode2 = xXPath->selectSingleNode(xNode, aXPathExpression + UNISTRING("/inst:buildid/text()"));

                if( xNode2.is() )
                    o_rUpdateInfo.BuildId = xNode2->getNodeValue();

                o_rUpdateInfo.Description = aEntry.Description;

                // Release Notes
                xNodeList = xXPath->selectNodeList(xNode, aXPathExpression + UNISTRING("/inst:relnote"));
                imax = xNodeList->getLength();
                for( i = 0; i < imax; ++i )
                {
                    uno::Reference< xml::dom::XElement > xRelNote(xNodeList->item(i), uno::UNO_QUERY);
                    if( xRelNote.is() )
                    {
                        sal_Int32 pos = xRelNote->getAttribute(UNISTRING("pos")).toInt32();

                        ReleaseNote aRelNote((sal_uInt8) pos, xRelNote->getAttribute(UNISTRING("src")));

                        if( xRelNote->hasAttribute(UNISTRING("src2")) )
                        {
                            pos = xRelNote->getAttribute(UNISTRING("pos2")).toInt32();
                            aRelNote.Pos2 = (sal_Int8) pos;
                            aRelNote.URL2 = xRelNote->getAttribute(UNISTRING("src2"));
                        }

                        o_rUpdateInfo.ReleaseNotes.push_back(aRelNote);
                    }
                }
/*
                o_rUpdateInfo.ReleaseNotes.push_back(
                    ReleaseNote(1, UNISTRING("http://qa.openoffice.org/tests/online_update_test.html"))
                );
*/

                if( o_rUpdateInfo.Sources.size() > 0 )
                    return true;
            }
        }
    }
    catch( ... )
    {
        return false;
    }

    return true;
}
<commit_msg>INTEGRATION: CWS updchk07 (1.6.2); FILE MERGED 2007/07/09 11:10:02 obr 1.6.2.1: #i79223# check enumeration reference<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: updateprotocol.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2007-07-31 15:58:00 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"

#ifndef _COM_SUN_STAR_XML_XPATH_XXPATHAPI_HPP_
#include <com/sun/star/xml/xpath/XXPathAPI.hpp>
#endif

#include "updateprotocol.hxx"

#ifndef _COM_SUN_STAR_DEPLOYMENT_UPDATEINFORMATINENTRY_HPP_
#include <com/sun/star/deployment/UpdateInformationEntry.hpp>
#endif

#include <rtl/ref.hxx>
#include <rtl/uri.hxx>
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/bootstrap.hxx>
#include <osl/process.h>

#include <cppuhelper/implbase1.hxx>

namespace css = com::sun::star ;
namespace container = css::container ;
namespace deployment = css::deployment ;
namespace lang = css::lang ;
namespace uno = css::uno ;
namespace task = css::task ;
namespace xml = css::xml ;

#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))

//------------------------------------------------------------------------------

static bool
getBootstrapData(
    uno::Sequence< ::rtl::OUString > & rRepositoryList,
    ::rtl::OUString & rBuildID,
    ::rtl::OUString & rInstallSetID)
{
    rtl::OUString aPath, aPath2;
    if( osl_getExecutableFile(&aPath.pData) != osl_Process_E_None )
        return false;

    sal_uInt32 lastIndex = aPath.lastIndexOf('/');
    if ( lastIndex > 0 )
    {
        aPath = aPath.copy( 0, lastIndex+1 );
        aPath += UNISTRING( SAL_CONFIGFILE( "version" ) );
    }

    rtl::Bootstrap aVersionFile(aPath);
    aVersionFile.getFrom(UNISTRING("ProductBuildid"), rBuildID, rtl::OUString());
    aVersionFile.getFrom(UNISTRING("UpdateID"), rInstallSetID, rtl::OUString());

    rtl::OUString aValue;
    aVersionFile.getFrom(UNISTRING("UpdateURL"), aValue, rtl::OUString());
    if( aValue.getLength() > 0 )
    {
        rRepositoryList.realloc(1);
        rRepositoryList[0] = aValue;
    }

    return true;
}

//------------------------------------------------------------------------------

// Returns 'true' if successfully connected to the update server
bool
checkForUpdates(
    UpdateInfo& o_rUpdateInfo,
    uno::Reference< uno::XComponentContext > const & rxContext,
    uno::Reference< task::XInteractionHandler > const & rxInteractionHandler,
    const uno::Reference< deployment::XUpdateInformationProvider >& rUpdateInfoProvider)
{
    OSL_TRACE("checking for updates ..\n");

    ::rtl::OUString myArch;
    ::rtl::OUString myOS;

    rtl::Bootstrap::get(UNISTRING("_OS"), myOS);
    rtl::Bootstrap::get(UNISTRING("_ARCH"), myArch);

    uno::Sequence< ::rtl::OUString > aRepositoryList;
    ::rtl::OUString aBuildID;
    ::rtl::OUString aInstallSetID;

    if( ! ( getBootstrapData(aRepositoryList, aBuildID, aInstallSetID) && (aRepositoryList.getLength() > 0) ) )
        return false;

    if( !rxContext.is() )
        throw uno::RuntimeException(
            UNISTRING( "checkForUpdates: empty component context" ), uno::Reference< uno::XInterface >() );

    OSL_ASSERT( rxContext->getServiceManager().is() );

    // XPath implementation
    uno::Reference< xml::xpath::XXPathAPI > xXPath(
        rxContext->getServiceManager()->createInstanceWithContext( UNISTRING( "com.sun.star.xml.xpath.XPathAPI" ), rxContext ),
        uno::UNO_QUERY_THROW);

    xXPath->registerNS( UNISTRING("inst"), UNISTRING("http://installation.openoffice.org/description") );

    if( rxInteractionHandler.is() )
        rUpdateInfoProvider->setInteractionHandler(rxInteractionHandler);

    try
    {
        uno::Reference< container::XEnumeration > aUpdateInfoEnumeration =
            rUpdateInfoProvider->getUpdateInformationEnumeration( aRepositoryList, aInstallSetID );

        if ( !aUpdateInfoEnumeration.is() )
            return false; // something went wrong ..

        rtl::OUStringBuffer aBuffer;
        aBuffer.appendAscii("/child::inst:description[inst:os=\'");
        aBuffer.append( myOS );
        aBuffer.appendAscii("\' and inst:arch=\'");
        aBuffer.append( myArch );
        aBuffer.appendAscii("\' and inst:buildid>");
        aBuffer.append( aBuildID );
        aBuffer.appendAscii("]");

        rtl::OUString aXPathExpression = aBuffer.makeStringAndClear();

        while( aUpdateInfoEnumeration->hasMoreElements() )
        {
            deployment::UpdateInformationEntry aEntry;

            if( aUpdateInfoEnumeration->nextElement() >>= aEntry )
            {
                uno::Reference< xml::dom::XNode > xNode( aEntry.UpdateDocument.get() );
                uno::Reference< xml::dom::XNodeList > xNodeList =
                    xXPath->selectNodeList(xNode, aXPathExpression + UNISTRING("/inst:update/attribute::src"));

/*
                o_rUpdateInfo.Sources.push_back( DownloadSource(true,
                    UNISTRING("http://openoffice.bouncer.osuosl.org/?product=OpenOffice.org&os=solarissparcwjre&lang=en-US&version=2.2.1") ) );
*/

                sal_Int32 i, imax = xNodeList->getLength();
                for( i = 0; i < imax; ++i )
                {
                    uno::Reference< xml::dom::XNode > xNode2( xNodeList->item(i) );

                    if( xNode2.is() )
                    {
                        uno::Reference< xml::dom::XElement > xParent(xNode2->getParentNode(), uno::UNO_QUERY_THROW);
                        rtl::OUString aType = xParent->getAttribute(UNISTRING("type"));
                        bool bIsDirect = ( sal_False == aType.equalsIgnoreAsciiCaseAscii("text/html") );

                        o_rUpdateInfo.Sources.push_back( DownloadSource(bIsDirect, xNode2->getNodeValue()) );
                    }
                }

                uno::Reference< xml::dom::XNode > xNode2 =
                    xXPath->selectSingleNode(xNode, aXPathExpression + UNISTRING("/inst:version/text()"));

                if( xNode2.is() )
                    o_rUpdateInfo.Version = xNode2->getNodeValue();

                xNode2 = xXPath->selectSingleNode(xNode, aXPathExpression + UNISTRING("/inst:buildid/text()"));

                if( xNode2.is() )
                    o_rUpdateInfo.BuildId = xNode2->getNodeValue();

                o_rUpdateInfo.Description = aEntry.Description;

                // Release Notes
                xNodeList = xXPath->selectNodeList(xNode, aXPathExpression + UNISTRING("/inst:relnote"));
                imax = xNodeList->getLength();
                for( i = 0; i < imax; ++i )
                {
                    uno::Reference< xml::dom::XElement > xRelNote(xNodeList->item(i), uno::UNO_QUERY);
                    if( xRelNote.is() )
                    {
                        sal_Int32 pos = xRelNote->getAttribute(UNISTRING("pos")).toInt32();

                        ReleaseNote aRelNote((sal_uInt8) pos, xRelNote->getAttribute(UNISTRING("src")));

                        if( xRelNote->hasAttribute(UNISTRING("src2")) )
                        {
                            pos = xRelNote->getAttribute(UNISTRING("pos2")).toInt32();
                            aRelNote.Pos2 = (sal_Int8) pos;
                            aRelNote.URL2 = xRelNote->getAttribute(UNISTRING("src2"));
                        }

                        o_rUpdateInfo.ReleaseNotes.push_back(aRelNote);
                    }
                }
/*
                o_rUpdateInfo.ReleaseNotes.push_back(
                    ReleaseNote(1, UNISTRING("http://qa.openoffice.org/tests/online_update_test.html"))
                );
*/

                if( o_rUpdateInfo.Sources.size() > 0 )
                    return true;
            }
        }
    }
    catch( ... )
    {
        return false;
    }

    return true;
}
<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basctl.hxx"

#include <ide_pch.hxx>

#include <basidesh.hrc>
#include <basidesh.hxx>
#include <basobj.hxx>

#include <basicbox.hxx>
#include <iderid.hxx>
#include <iderdll.hxx>
#include <bastypes.hxx>

#ifndef _BASTYPE2_HXX
#include "bastype2.hxx"
#endif
#ifndef _BASDOC_HXX
#include "basdoc.hxx"
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

SFX_IMPL_TOOLBOX_CONTROL( LibBoxControl, SfxStringItem );

LibBoxControl::LibBoxControl( USHORT nSlotId, USHORT nId, ToolBox& rTbx )
    : SfxToolBoxControl( nSlotId, nId, rTbx )
{
}

LibBoxControl::~LibBoxControl()
{
}

void LibBoxControl::StateChanged( USHORT nSID, SfxItemState eState, const SfxPoolItem* pState )
{
    BasicLibBox* pBox = (BasicLibBox*) GetToolBox().GetItemWindow( GetId() );

    DBG_ASSERT( pBox, "Box not found" );
    if ( !pBox )
        return;

    if ( eState != SFX_ITEM_AVAILABLE )
        pBox->Disable();
    else
    {
        pBox->Enable();

        if ( pState->ISA(SfxStringItem) )
            pBox->Update( (const SfxStringItem*)pState );
        else
            pBox->Update( NULL );
    }
}

Window* LibBoxControl::CreateItemWindow( Window *pParent )
{
    return new BasicLibBox( pParent, m_xFrame );
}

BasicLibBox::BasicLibBox( Window* pParent, const uno::Reference< frame::XFrame >& rFrame ) :
    ListBox( pParent, WinBits( WB_BORDER | WB_DROPDOWN ) ),
    m_xFrame( rFrame )
{
    FillBox();
    bIgnoreSelect = TRUE;   // Select von 0 noch nicht weiterleiten
    bFillBox = TRUE;
    SelectEntryPos( 0 );
    aCurText = GetEntry( 0 );
    SetSizePixel( Size( 250, 200 ) );
    bIgnoreSelect = FALSE;
    StartListening( *SFX_APP(), TRUE /* Nur einmal anmelden */ );
}

__EXPORT BasicLibBox::~BasicLibBox()
{
    DeleteEntryData();
}

void __EXPORT BasicLibBox::Update( const SfxStringItem* pItem )
{
    // Immer auf dem laufenden sein...
//  if ( !pItem  || !pItem->GetValue().Len() )
        FillBox();

    if ( pItem )
    {
        aCurText = pItem->GetValue();
        if ( aCurText.Len() == 0 )
            aCurText = String( IDEResId( RID_STR_ALL ) );
    }

    if ( GetSelectEntry() != aCurText )
        SelectEntry( aCurText );
}

void __EXPORT BasicLibBox::ReleaseFocus()
{
    SfxViewShell* pCurSh = SfxViewShell::Current();
    DBG_ASSERT( pCurSh, "Current ViewShell not found!" );

    if ( pCurSh )
    {
        Window* pShellWin = pCurSh->GetWindow();
        if ( !pShellWin )       // sonst werde ich ihn nicht los
            pShellWin = Application::GetDefDialogParent();

        pShellWin->GrabFocus();
    }
}

void __EXPORT BasicLibBox::SFX_NOTIFY(  SfxBroadcaster& rBC, const TypeId&,
                                        const SfxHint& rHint, const TypeId& )
{
    if ( rHint.IsA( TYPE( SfxEventHint ) ) )
    {
        switch ( ((SfxEventHint&)rHint).GetEventId() )
        {
            case SFX_EVENT_CREATEDOC:
            case SFX_EVENT_OPENDOC:
            {
                FillBox();  // IDE reagiert selbst, wenn == aktuelle Lib
            }
            break;
            case SFX_EVENT_SAVEASDOC:
            {
                FillBox( TRUE );
            }
            break;
            case SFX_EVENT_CLOSEDOC:
            {
                if ( SFX_APP()->IsInBasicCall() )   // Nicht wenn Office beendet
                    FillBox();
            }
            break;
        }
    }
}

void BasicLibBox::FillBox( BOOL bSelect )
{
    SetUpdateMode( FALSE );
    bIgnoreSelect = TRUE;

    aCurText = GetSelectEntry();

    SelectEntryPos( 0 );
    Clear();

    // create list box entries
    USHORT nPos = InsertEntry( String( IDEResId( RID_STR_ALL ) ), LISTBOX_APPEND );
    SetEntryData( nPos, new BasicLibEntry( 0, LIBRARY_LOCATION_UNKNOWN, String() ) );
    InsertEntries( 0, LIBRARY_LOCATION_USER );
    InsertEntries( 0, LIBRARY_LOCATION_SHARE );
    SfxObjectShell* pShell = SfxObjectShell::GetFirst();
    while ( pShell )
    {
        // only if there's a corresponding window (not for remote documents)
        if ( SfxViewFrame::GetFirst( pShell ) && !pShell->ISA( BasicDocShell ) )
            InsertEntries( pShell, LIBRARY_LOCATION_DOCUMENT );

        pShell = SfxObjectShell::GetNext( *pShell );
    }

    SetUpdateMode( TRUE );

    if ( bSelect )
    {
        SelectEntry( aCurText );
        if ( !GetSelectEntryCount() )
        {
            SelectEntryPos( GetEntryCount() );  // gibst es nicht => leer?
            aCurText = GetSelectEntry();
        }
    }
    bIgnoreSelect = FALSE;
}

void BasicLibBox::InsertEntries( SfxObjectShell* pShell, LibraryLocation eLocation )
{
    // get a sorted list of library names
    Sequence< ::rtl::OUString > aLibNames = BasicIDE::GetLibraryNames( pShell );
    sal_Int32 nLibCount = aLibNames.getLength();
    const ::rtl::OUString* pLibNames = aLibNames.getConstArray();

    for ( sal_Int32 i = 0 ; i < nLibCount ; ++i )
    {
        String aLibName = pLibNames[ i ];
        if ( eLocation == BasicIDE::GetLibraryLocation( pShell, aLibName ) )
        {
            String aName( BasicIDE::GetTitle( pShell, eLocation, SFX_TITLE_CAPTION ) );
            String aEntryText( CreateMgrAndLibStr( aName, aLibName ) );
            USHORT nPos = InsertEntry( aEntryText, LISTBOX_APPEND );
            SetEntryData( nPos, new BasicLibEntry( pShell, eLocation, aLibName ) );
        }
    }
}

void BasicLibBox::DeleteEntryData()
{
    USHORT nCount = GetEntryCount();
    for ( USHORT i = 0; i < nCount; ++i )
    {
        BasicLibEntry* pEntry = (BasicLibEntry*)GetEntryData( i );
        delete pEntry;
    }
}

long BasicLibBox::PreNotify( NotifyEvent& rNEvt )
{
    long nDone = 0;
    if( rNEvt.GetType() == EVENT_KEYINPUT )
    {
        KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
        USHORT nKeyCode = aKeyEvt.GetKeyCode().GetCode();
        switch( nKeyCode )
        {
            case KEY_RETURN:
            {
                NotifyIDE();
                nDone = 1;
            }
            break;

            case KEY_ESCAPE:
            {
                SelectEntry( aCurText );
                ReleaseFocus();
                nDone = 1;
            }
            break;
        }
    }
    else if( rNEvt.GetType() == EVENT_GETFOCUS )
    {
        if ( bFillBox )
        {
            FillBox();
            bFillBox = FALSE;
        }
    }
    else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
    {
        if ( !HasChildPathFocus( TRUE ) )
        {
            bIgnoreSelect = TRUE;
            bFillBox = TRUE;
        }
    }

    return nDone ? nDone : ListBox::PreNotify( rNEvt );
}

void __EXPORT BasicLibBox::Select()
{
    if ( !IsTravelSelect() )
    {
        if ( !bIgnoreSelect )
            NotifyIDE();
        else
            SelectEntry( aCurText );    // Seit 306... (Select nach Escape)
    }
}

void BasicLibBox::NotifyIDE()
{
    USHORT nSelPos = GetSelectEntryPos();
    BasicLibEntry* pEntry = (BasicLibEntry*)GetEntryData( nSelPos );
    if ( pEntry )
    {
        SfxObjectShell* pShell = pEntry->GetShell();
        SfxObjectShellItem aShellItem( SID_BASICIDE_ARG_SHELL, pShell );
        String aLibName = pEntry->GetLibName();
        SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
        BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
        SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
        SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
        if ( pDispatcher )
        {
            pDispatcher->Execute( SID_BASICIDE_LIBSELECTED,
                                  SFX_CALLMODE_SYNCHRON, &aShellItem, &aLibNameItem, 0L );
        }
    }
    ReleaseFocus();
}

void BasicLibBox::Clear()
{
    DeleteEntryData();
    ListBox::Clear();
}
<commit_msg>INTEGRATION: CWS ab31 (1.10.32); FILE MERGED 2006/12/15 09:50:50 ab 1.10.32.6: #i72282# BasicLanguageBox sets current, not default language 2006/12/15 08:00:15 pb 1.10.32.5: fix: #i72282# disable LanguageBox is necessary 2006/12/14 17:48:43 pb 1.10.32.4: fix: #i72282# LanguageBox more wider 2006/12/14 12:48:51 pb 1.10.32.3: fix: #i72282# more implemented 2006/12/13 16:58:10 pb 1.10.32.2: fix: #i72282# class BasicLanguageBox added 2006/12/07 08:23:38 pb 1.10.32.1: fix: #i72282# new class LangBoxControl<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: basicbox.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: hr $ $Date: 2007-01-02 15:48:49 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basctl.hxx"

#include <ide_pch.hxx>

#include <basidesh.hrc>
#include <basidesh.hxx>
#include <basobj.hxx>

#include <basicbox.hxx>
#include <iderid.hxx>
#include <iderdll.hxx>
#include <bastypes.hxx>

#ifndef _BASTYPE2_HXX
#include "bastype2.hxx"
#endif
#ifndef _BASDOC_HXX
#include "basdoc.hxx"
#endif

#include "localizationmgr.hxx"
#include "managelang.hxx"
#include "dlgresid.hrc"

#ifndef _UNO_LINGU_HXX
#include <svx/unolingu.hxx>
#endif
#ifndef _SVX_LANGTAB_HXX
#include <svx/langtab.hxx>
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;

SFX_IMPL_TOOLBOX_CONTROL( LibBoxControl, SfxStringItem );

LibBoxControl::LibBoxControl( USHORT nSlotId, USHORT nId, ToolBox& rTbx )
    : SfxToolBoxControl( nSlotId, nId, rTbx )
{
}

LibBoxControl::~LibBoxControl()
{
}

void LibBoxControl::StateChanged( USHORT, SfxItemState eState, const SfxPoolItem* pState )
{
    BasicLibBox* pBox = (BasicLibBox*) GetToolBox().GetItemWindow( GetId() );

    DBG_ASSERT( pBox, "Box not found" );
    if ( !pBox )
        return;

    if ( eState != SFX_ITEM_AVAILABLE )
        pBox->Disable();
    else
    {
        pBox->Enable();

        if ( pState->ISA(SfxStringItem) )
            pBox->Update( (const SfxStringItem*)pState );
        else
            pBox->Update( NULL );
    }
}

Window* LibBoxControl::CreateItemWindow( Window *pParent )
{
    return new BasicLibBox( pParent, m_xFrame );
}

BasicLibBox::BasicLibBox( Window* pParent, const uno::Reference< frame::XFrame >& rFrame ) :
    ListBox( pParent, WinBits( WB_BORDER | WB_DROPDOWN ) ),
    m_xFrame( rFrame )
{
    FillBox();
    bIgnoreSelect = TRUE;   // Select von 0 noch nicht weiterleiten
    bFillBox = TRUE;
    SelectEntryPos( 0 );
    aCurText = GetEntry( 0 );
    SetSizePixel( Size( 250, 200 ) );
    bIgnoreSelect = FALSE;
    StartListening( *SFX_APP(), TRUE /* Nur einmal anmelden */ );
}

__EXPORT BasicLibBox::~BasicLibBox()
{
    ClearBox();
}

void __EXPORT BasicLibBox::Update( const SfxStringItem* pItem )
{
    // Immer auf dem laufenden sein...
//  if ( !pItem  || !pItem->GetValue().Len() )
        FillBox();

    if ( pItem )
    {
        aCurText = pItem->GetValue();
        if ( aCurText.Len() == 0 )
            aCurText = String( IDEResId( RID_STR_ALL ) );
    }

    if ( GetSelectEntry() != aCurText )
        SelectEntry( aCurText );
}

void __EXPORT BasicLibBox::ReleaseFocus()
{
    SfxViewShell* pCurSh = SfxViewShell::Current();
    DBG_ASSERT( pCurSh, "Current ViewShell not found!" );

    if ( pCurSh )
    {
        Window* pShellWin = pCurSh->GetWindow();
        if ( !pShellWin )       // sonst werde ich ihn nicht los
            pShellWin = Application::GetDefDialogParent();

        pShellWin->GrabFocus();
    }
}

void __EXPORT BasicLibBox::SFX_NOTIFY(  SfxBroadcaster&, const TypeId&,
                                        const SfxHint& rHint, const TypeId& )
{
    if ( rHint.IsA( TYPE( SfxEventHint ) ) )
    {
        switch ( ((SfxEventHint&)rHint).GetEventId() )
        {
            case SFX_EVENT_CREATEDOC:
            case SFX_EVENT_OPENDOC:
            {
                FillBox();  // IDE reagiert selbst, wenn == aktuelle Lib
            }
            break;
            case SFX_EVENT_SAVEASDOC:
            {
                FillBox( TRUE );
            }
            break;
            case SFX_EVENT_CLOSEDOC:
            {
                if ( SFX_APP()->IsInBasicCall() )   // Nicht wenn Office beendet
                    FillBox();
            }
            break;
        }
    }
}

void BasicLibBox::FillBox( BOOL bSelect )
{
    SetUpdateMode( FALSE );
    bIgnoreSelect = TRUE;

    aCurText = GetSelectEntry();

    SelectEntryPos( 0 );
    ClearBox();

    // create list box entries
    USHORT nPos = InsertEntry( String( IDEResId( RID_STR_ALL ) ), LISTBOX_APPEND );
    SetEntryData( nPos, new BasicLibEntry( 0, LIBRARY_LOCATION_UNKNOWN, String() ) );
    InsertEntries( 0, LIBRARY_LOCATION_USER );
    InsertEntries( 0, LIBRARY_LOCATION_SHARE );
    SfxObjectShell* pShell = SfxObjectShell::GetFirst();
    while ( pShell )
    {
        // only if there's a corresponding window (not for remote documents)
        if ( SfxViewFrame::GetFirst( pShell ) && !pShell->ISA( BasicDocShell ) )
            InsertEntries( pShell, LIBRARY_LOCATION_DOCUMENT );

        pShell = SfxObjectShell::GetNext( *pShell );
    }

    SetUpdateMode( TRUE );

    if ( bSelect )
    {
        SelectEntry( aCurText );
        if ( !GetSelectEntryCount() )
        {
            SelectEntryPos( GetEntryCount() );  // gibst es nicht => leer?
            aCurText = GetSelectEntry();
        }
    }
    bIgnoreSelect = FALSE;
}

void BasicLibBox::InsertEntries( SfxObjectShell* pShell, LibraryLocation eLocation )
{
    // get a sorted list of library names
    Sequence< ::rtl::OUString > aLibNames = BasicIDE::GetLibraryNames( pShell );
    sal_Int32 nLibCount = aLibNames.getLength();
    const ::rtl::OUString* pLibNames = aLibNames.getConstArray();

    for ( sal_Int32 i = 0 ; i < nLibCount ; ++i )
    {
        String aLibName = pLibNames[ i ];
        if ( eLocation == BasicIDE::GetLibraryLocation( pShell, aLibName ) )
        {
            String aName( BasicIDE::GetTitle( pShell, eLocation, SFX_TITLE_CAPTION ) );
            String aEntryText( CreateMgrAndLibStr( aName, aLibName ) );
            USHORT nPos = InsertEntry( aEntryText, LISTBOX_APPEND );
            SetEntryData( nPos, new BasicLibEntry( pShell, eLocation, aLibName ) );
        }
    }
}

long BasicLibBox::PreNotify( NotifyEvent& rNEvt )
{
    long nDone = 0;
    if( rNEvt.GetType() == EVENT_KEYINPUT )
    {
        KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
        USHORT nKeyCode = aKeyEvt.GetKeyCode().GetCode();
        switch( nKeyCode )
        {
            case KEY_RETURN:
            {
                NotifyIDE();
                nDone = 1;
            }
            break;

            case KEY_ESCAPE:
            {
                SelectEntry( aCurText );
                ReleaseFocus();
                nDone = 1;
            }
            break;
        }
    }
    else if( rNEvt.GetType() == EVENT_GETFOCUS )
    {
        if ( bFillBox )
        {
            FillBox();
            bFillBox = FALSE;
        }
    }
    else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
    {
        if ( !HasChildPathFocus( TRUE ) )
        {
            bIgnoreSelect = TRUE;
            bFillBox = TRUE;
        }
    }

    return nDone ? nDone : ListBox::PreNotify( rNEvt );
}

void __EXPORT BasicLibBox::Select()
{
    if ( !IsTravelSelect() )
    {
        if ( !bIgnoreSelect )
            NotifyIDE();
        else
            SelectEntry( aCurText );    // Seit 306... (Select nach Escape)
    }
}

void BasicLibBox::NotifyIDE()
{
    USHORT nSelPos = GetSelectEntryPos();
    BasicLibEntry* pEntry = (BasicLibEntry*)GetEntryData( nSelPos );
    if ( pEntry )
    {
        SfxObjectShell* pShell = pEntry->GetShell();
        SfxObjectShellItem aShellItem( SID_BASICIDE_ARG_SHELL, pShell );
        String aLibName = pEntry->GetLibName();
        SfxStringItem aLibNameItem( SID_BASICIDE_ARG_LIBNAME, aLibName );
        BasicIDEShell* pIDEShell = IDE_DLL()->GetShell();
        SfxViewFrame* pViewFrame = pIDEShell ? pIDEShell->GetViewFrame() : NULL;
        SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : NULL;
        if ( pDispatcher )
        {
            pDispatcher->Execute( SID_BASICIDE_LIBSELECTED,
                                  SFX_CALLMODE_SYNCHRON, &aShellItem, &aLibNameItem, 0L );
        }
    }
    ReleaseFocus();
}

void BasicLibBox::ClearBox()
{
    USHORT nCount = GetEntryCount();
    for ( USHORT i = 0; i < nCount; ++i )
    {
        BasicLibEntry* pEntry = (BasicLibEntry*)GetEntryData( i );
        delete pEntry;
    }
    ListBox::Clear();
}

// class LanguageBoxControl ----------------------------------------------

SFX_IMPL_TOOLBOX_CONTROL( LanguageBoxControl, SfxStringItem );

LanguageBoxControl::LanguageBoxControl( USHORT nSlotId, USHORT nId, ToolBox& rTbx )
    : SfxToolBoxControl( nSlotId, nId, rTbx )
{
}

LanguageBoxControl::~LanguageBoxControl()
{
}

void LanguageBoxControl::StateChanged( USHORT _nID, SfxItemState _eState, const SfxPoolItem* _pItem )
{
    BasicLanguageBox* pBox = (BasicLanguageBox*)( GetToolBox().GetItemWindow( GetId() ) );

    if ( pBox )
    {
        if ( _eState != SFX_ITEM_AVAILABLE )
            pBox->Disable();
        else
        {
            pBox->Enable();
            if ( _pItem->ISA(SfxStringItem) )
                pBox->Update( (const SfxStringItem*)_pItem );
            else
                pBox->Update( NULL );
        }
    }
}

Window* LanguageBoxControl::CreateItemWindow( Window *pParent )
{
    return new BasicLanguageBox( pParent );
}

// class BasicLanguageBox ------------------------------------------------

BasicLanguageBox::BasicLanguageBox( Window* pParent ) :

    ListBox( pParent, WinBits( WB_BORDER | WB_DROPDOWN ) ),

    m_sNotLocalizedStr( IDEResId( RID_STR_TRANSLATION_NOTLOCALIZED ) ),
    m_sDefaultLanguageStr( IDEResId( RID_STR_TRANSLATION_DEFAULT ) ),

    m_bIgnoreSelect( false )

{
    SetSizePixel( Size( 210, 200 ) );

    FillBox();
    StartListening( *SFX_APP(), TRUE /* Nur einmal anmelden */ );
}

BasicLanguageBox::~BasicLanguageBox()
{
    ClearBox();
}

void BasicLanguageBox::FillBox()
{
    SetUpdateMode( FALSE );
    m_bIgnoreSelect = true;
    m_sCurrentText = GetSelectEntry();
    ClearBox();

    LocalizationMgr* pCurMgr = IDE_DLL()->GetShell()->GetCurLocalizationMgr();
    if ( pCurMgr->isLibraryLocalized() )
    {
        Enable();
        SvxLanguageTable aLangTable;
        Locale aDefaultLocale = pCurMgr->getStringResourceManager()->getDefaultLocale();
        Locale aCurrentLocale = pCurMgr->getStringResourceManager()->getCurrentLocale();
        Sequence< Locale > aLocaleSeq = pCurMgr->getStringResourceManager()->getLocales();
        const Locale* pLocale = aLocaleSeq.getConstArray();
        INT32 i, nCount = aLocaleSeq.getLength();
        USHORT nSelPos = LISTBOX_ENTRY_NOTFOUND;
        for ( i = 0;  i < nCount;  ++i )
        {
            bool bIsDefault = localesAreEqual( aDefaultLocale, pLocale[i] );
            bool bIsCurrent = localesAreEqual( aCurrentLocale, pLocale[i] );
            LanguageType eLangType = SvxLocaleToLanguage( pLocale[i] );
            String sLanguage = aLangTable.GetString( eLangType );
            if ( bIsDefault )
            {
                sLanguage += ' ';
                sLanguage += m_sDefaultLanguageStr;
            }
            USHORT nPos = InsertEntry( sLanguage );
            SetEntryData( nPos, new LanguageEntry( sLanguage, pLocale[i], bIsDefault ) );

            if ( bIsCurrent )
                nSelPos = nPos;
        }

        if ( nSelPos != LISTBOX_ENTRY_NOTFOUND )
        {
            SelectEntryPos( nSelPos );
            m_sCurrentText = GetSelectEntry();
        }
    }
    else
    {
        InsertEntry( m_sNotLocalizedStr );
        SelectEntryPos(0);
        Disable();
    }

    SetUpdateMode( TRUE );
    m_bIgnoreSelect = false;
}

void BasicLanguageBox::ClearBox()
{
    USHORT nCount = GetEntryCount();
    for ( USHORT i = 0; i < nCount; ++i )
    {
        LanguageEntry* pEntry = (LanguageEntry*)GetEntryData(i);
        delete pEntry;
    }
    ListBox::Clear();
}

void BasicLanguageBox::SetLanguage()
{
    LanguageEntry* pEntry = (LanguageEntry*)GetEntryData( GetSelectEntryPos() );
    if ( pEntry )
        IDE_DLL()->GetShell()->GetCurLocalizationMgr()->handleSetCurrentLocale( pEntry->m_aLocale );
}

void BasicLanguageBox::Select()
{
    if ( !m_bIgnoreSelect )
        SetLanguage();
    else
        SelectEntry( m_sCurrentText );  // Select after Escape
}

long BasicLanguageBox::PreNotify( NotifyEvent& rNEvt )
{
    long nDone = 0;
    if( rNEvt.GetType() == EVENT_KEYINPUT )
    {
        USHORT nKeyCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
        switch( nKeyCode )
        {
            case KEY_RETURN:
            {
                SetLanguage();
                nDone = 1;
            }
            break;

            case KEY_ESCAPE:
            {
                SelectEntry( m_sCurrentText );
                nDone = 1;
            }
            break;
        }
    }
    else if( rNEvt.GetType() == EVENT_GETFOCUS )
    {
    }
    else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
    {
    }

    return nDone ? nDone : ListBox::PreNotify( rNEvt );
}

void BasicLanguageBox::SFX_NOTIFY( SfxBroadcaster&, const TypeId&, const SfxHint& rHint, const TypeId& )
{
    if ( rHint.IsA( TYPE( SfxEventHint ) ) )
    {
        USHORT nEventId = ( (SfxEventHint&)rHint ).GetEventId();
        switch ( nEventId )
        {
            case SFX_EVENT_CREATEDOC:
            case SFX_EVENT_OPENDOC:
            case SFX_EVENT_SAVEASDOC:
            case SFX_EVENT_CLOSEDOC:
            {
                if ( nEventId != SFX_EVENT_CLOSEDOC || SFX_APP()->IsInBasicCall() )
                    FillBox();
            }
            break;
        }
    }
}

void BasicLanguageBox::Update( const SfxStringItem* pItem )
{
    FillBox();

    if ( pItem && pItem->GetValue().Len() > 0 )
    {
        m_sCurrentText = pItem->GetValue();
        if ( GetSelectEntry() != m_sCurrentText )
            SelectEntry( m_sCurrentText );
    }
}

<|endoftext|>