<commit_before>// @(#)root/eve7:$Id$
// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/*************************************************************************
 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include <ROOT/REveStraightLineSet.hxx>
#include <ROOT/REveRenderData.hxx>
#include <ROOT/REveProjectionManager.hxx>

#include "TRandom.h"
#include "TClass.h"
#include "json.hpp"

using namespace ROOT::Experimental;

////////////////////////////////////////////////////////////////////////////////
/// Constructor.

REveStraightLineSet::REveStraightLineSet(const std::string& n, const std::string& t):
   REveElement (n, t),

   fLinePlex      (sizeof(Line_t), 4),
   fMarkerPlex    (sizeof(Marker_t), 8),
   fOwnLinesIds   (kFALSE),
   fOwnMarkersIds (kFALSE),
   fRnrMarkers    (kTRUE),
   fRnrLines      (kTRUE),
   fDepthTest     (kTRUE),
   fLastLine      (0)
{
   InitMainTrans();
   fPickable = kTRUE;

   fMainColorPtr = &fLineColor;
   fLineColor    = 4;
   fMarkerColor  = 2;
   fMarkerStyle  = 20;
}

////////////////////////////////////////////////////////////////////////////////
/// Add a line.

REveStraightLineSet::Line_t*
REveStraightLineSet::AddLine(Float_t x1, Float_t y1, Float_t z1,
                             Float_t x2, Float_t y2, Float_t z2)
{
   fLastLine = new (fLinePlex.NewAtom()) Line_t(x1, y1, z1, x2, y2, z2);
   fLastLine->fId = fLinePlex.Size() - 1;
   return fLastLine;
}

////////////////////////////////////////////////////////////////////////////////
/// Add a line.

REveStraightLineSet::Line_t*
REveStraightLineSet::AddLine(const REveVector& p1, const REveVector& p2)
{
   return AddLine(p1.fX, p1.fY, p1.fZ, p2.fX, p2.fY, p2.fZ);
}

////////////////////////////////////////////////////////////////////////////////
/// Set line vertices with given index.

void
REveStraightLineSet::SetLine(int idx,
                             Float_t x1, Float_t y1, Float_t z1,
                             Float_t x2, Float_t y2, Float_t z2)
{
   Line_t* l = (Line_t*) fLinePlex.Atom(idx);

   l->fV1[0] = x1; l->fV1[1] = y1; l->fV1[2] = z1;
   l->fV2[0] = x2; l->fV2[1] = y2; l->fV2[2] = z2;
}

////////////////////////////////////////////////////////////////////////////////
/// Set line vertices with given index.

void
REveStraightLineSet::SetLine(int idx, const REveVector& p1, const REveVector& p2)
{
   SetLine(idx, p1.fX, p1.fY, p1.fZ, p2.fX, p2.fY, p2.fZ);
}

////////////////////////////////////////////////////////////////////////////////
/// Add a marker with given position.

REveStraightLineSet::Marker_t*
REveStraightLineSet::AddMarker(Float_t x, Float_t y, Float_t z, Int_t line_id)
{
   Marker_t* marker = new (fMarkerPlex.NewAtom()) Marker_t(x, y, z, line_id);
   return marker;
}

////////////////////////////////////////////////////////////////////////////////
/// Add a marker with given position.

REveStraightLineSet::Marker_t*
REveStraightLineSet::AddMarker(const REveVector& p, Int_t line_id)
{
   return AddMarker(p.fX, p.fY, p.fZ, line_id);
}

////////////////////////////////////////////////////////////////////////////////
/// Add a marker for line with given index on relative position pos.

REveStraightLineSet::Marker_t*
REveStraightLineSet::AddMarker(Int_t line_id, Float_t pos)
{
   Line_t& l = * (Line_t*) fLinePlex.Atom(line_id);
   return AddMarker(l.fV1[0] + (l.fV2[0] - l.fV1[0])*pos,
                    l.fV1[1] + (l.fV2[1] - l.fV1[1])*pos,
                    l.fV1[2] + (l.fV2[2] - l.fV1[2])*pos,
                    line_id);
}

////////////////////////////////////////////////////////////////////////////////
/// Copy visualization parameters from element el.

void REveStraightLineSet::CopyVizParams(const REveElement* el)
{
   const REveStraightLineSet* m = dynamic_cast<const REveStraightLineSet*>(el);
   if (m)
   {
      TAttLine::operator=(*m);
      TAttMarker::operator=(*m);
      fRnrMarkers = m->fRnrMarkers;
      fRnrLines   = m->fRnrLines;
      fDepthTest  = m->fDepthTest;
   }

   REveElement::CopyVizParams(el);
}

////////////////////////////////////////////////////////////////////////////////
/// Write visualization parameters.

void REveStraightLineSet::WriteVizParams(std::ostream& out, const TString& var)
{
   REveElement::WriteVizParams(out, var);

   TString t = "   " + var + "->";
   TAttMarker::SaveMarkerAttributes(out, var);
   TAttLine  ::SaveLineAttributes  (out, var);
   out << t << "SetRnrMarkers(" << ToString(fRnrMarkers) << ");\n";
   out << t << "SetRnrLines("   << ToString(fRnrLines)   << ");\n";
   out << t << "SetDepthTest("  << ToString(fDepthTest)  << ");\n";
}

////////////////////////////////////////////////////////////////////////////////
/// Fill core part of JSON representation.

Int_t REveStraightLineSet::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
{
   Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);

   j["fLinePlexSize"] = fLinePlex.Size();
   j["fMarkerPlexSize"] = fMarkerPlex.Size();
   j["fLineWidth"] = fLineWidth;
   j["fLineStyle"] = fLineStyle;
   j["fMarkerSize"] = fMarkerSize;
   j["fMarkerStyle"] = fMarkerStyle;
   printf("REveStraightLineSet::WriteCoreJson %d \n", ret);
   return ret;
}

////////////////////////////////////////////////////////////////////////////////
/// Crates 3D point array for rendering.

void REveStraightLineSet::BuildRenderData()
{
   int nVertices =  fLinePlex.Size() * 2 + fMarkerPlex.Size();
   fRenderData = std::make_unique<REveRenderData>("makeStraightLineSet", 3 * nVertices, 0, nVertices);

   printf("REveStraightLineSet::BuildRenderData id = %d \n", GetElementId());
   REveChunkManager::iterator li(fLinePlex);
   while (li.next()) {
      Line_t* l = (Line_t*)li();

      fRenderData->PushV(l->fV1[0], l->fV1[1],l->fV1[2]);
      fRenderData->PushV(l->fV2[0], l->fV2[1],l->fV2[2]);
      fRenderData->PushI(l->fId);
   }

   REveChunkManager::iterator mi(fMarkerPlex);
   while (mi.next()) {
      Marker_t* m = (Marker_t*)mi();
      fRenderData->PushV(m->fV[0], m->fV[1], m->fV[2]);
      fRenderData->PushI(m->fLineId);
   }

   REveElement::BuildRenderData();

   printf("REveStraightLineSet::BuildRenderData size= %d\n", fRenderData->GetBinarySize());
}

////////////////////////////////////////////////////////////////////////////////
/// Return class of projected object.
/// Virtual from REveProjectable.

TClass* REveStraightLineSet::ProjectedClass(const REveProjection*) const
{
   return TClass::GetClass<REveStraightLineSetProjected>();
}

////////////////////////////////////////////////////////////////////////////////
/// Compute bounding-box.
/// Virtual from TAttBBox.

void REveStraightLineSet::ComputeBBox()
{
   if (fLinePlex.Size() == 0 && fMarkerPlex.Size() == 0) {
      BBoxZero();
      return;
   }

   BBoxInit();

   REveChunkManager::iterator li(fLinePlex);
   while (li.next()) {
      BBoxCheckPoint(((Line_t*)li())->fV1);
      BBoxCheckPoint(((Line_t*)li())->fV2);
   }

   REveChunkManager::iterator mi(fMarkerPlex);
   while (mi.next())
   {
      BBoxCheckPoint(((Marker_t*)mi())->fV);
   }
}

/** \class REveStraightLineSetProjected
\ingroup REve
Projected replica of a REveStraightLineSet.
*/

ClassImp(REveStraightLineSetProjected);

////////////////////////////////////////////////////////////////////////////////
/// Constructor.

REveStraightLineSetProjected::REveStraightLineSetProjected() :
   REveStraightLineSet(), REveProjected ()
{
}

////////////////////////////////////////////////////////////////////////////////
/// Set projection manager and model object.

void REveStraightLineSetProjected::SetProjection(REveProjectionManager* mng,
                                                 REveProjectable* model)
{
   REveProjected::SetProjection(mng, model);

   CopyVizParams(dynamic_cast<REveElement*>(model));
}

////////////////////////////////////////////////////////////////////////////////
/// Set depth (z-coordinate) of the projected points.

void REveStraightLineSetProjected::SetDepthLocal(Float_t d)
{
   SetDepthCommon(d, this, fBBox);

   REveChunkManager::iterator li(fLinePlex);
   while (li.next())
   {
      REveStraightLineSet::Line_t& l = * (REveStraightLineSet::Line_t*) li();
      l.fV1[2] = fDepth;
      l.fV2[2] = fDepth;
   }

   REveChunkManager::iterator mi(fMarkerPlex);
   while (mi.next())
   {
      Marker_t& m = * (Marker_t*) mi();
      m.fV[2] = fDepth;
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Callback that actually performs the projection.
/// Called when projection parameters have been updated.

void REveStraightLineSetProjected::UpdateProjection()
{
   REveProjection&      proj = * fManager->GetProjection();
   REveStraightLineSet& orig = * dynamic_cast<REveStraightLineSet*>(fProjectable);

   REveTrans *trans = orig.PtrMainTrans(kFALSE);

   BBoxClear();

   // Lines
   Int_t num_lines = orig.GetLinePlex().Size();
   if (proj.HasSeveralSubSpaces())
      num_lines += TMath::Max(1, num_lines/10);
   fLinePlex.Reset(sizeof(Line_t), num_lines);
   REveVector p1, p2;
   REveChunkManager::iterator li(orig.GetLinePlex());
   while (li.next())
   {
      Line_t *l = (Line_t*) li();

      proj.ProjectPointfv(trans, l->fV1, p1, fDepth);
      proj.ProjectPointfv(trans, l->fV2, p2, fDepth);

      if (proj.AcceptSegment(p1, p2, 0.1f))
      {
         AddLine(p1, p2)->fId = l->fId;
      }
      else
      {
         REveVector bp1(l->fV1), bp2(l->fV2);
         if (trans) {
            trans->MultiplyIP(bp1);
            trans->MultiplyIP(bp2);
         }
         proj.BisectBreakPoint(bp1, bp2, kTRUE, fDepth);

         AddLine(p1, bp1)->fId = l->fId;
         AddLine(bp2, p2)->fId = l->fId;
      }
   }
   if (proj.HasSeveralSubSpaces())
      fLinePlex.Refit();

   // Markers
   fMarkerPlex.Reset(sizeof(Marker_t), orig.GetMarkerPlex().Size());
   REveChunkManager::iterator mi(orig.GetMarkerPlex());
   REveVector pp;
   while (mi.next())
   {
      Marker_t &m = * (Marker_t*) mi();

      proj.ProjectPointfv(trans, m.fV, pp, fDepth);
      AddMarker(pp, m.fLineId);
   }
}
<commit_msg>Comment out debug prints<commit_after>// @(#)root/eve7:$Id$
// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/*************************************************************************
 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include <ROOT/REveStraightLineSet.hxx>
#include <ROOT/REveRenderData.hxx>
#include <ROOT/REveProjectionManager.hxx>

#include "TRandom.h"
#include "TClass.h"
#include "json.hpp"

using namespace ROOT::Experimental;

////////////////////////////////////////////////////////////////////////////////
/// Constructor.

REveStraightLineSet::REveStraightLineSet(const std::string& n, const std::string& t):
   REveElement (n, t),

   fLinePlex      (sizeof(Line_t), 4),
   fMarkerPlex    (sizeof(Marker_t), 8),
   fOwnLinesIds   (kFALSE),
   fOwnMarkersIds (kFALSE),
   fRnrMarkers    (kTRUE),
   fRnrLines      (kTRUE),
   fDepthTest     (kTRUE),
   fLastLine      (0)
{
   InitMainTrans();
   fPickable = kTRUE;

   fMainColorPtr = &fLineColor;
   fLineColor    = 4;
   fMarkerColor  = 2;
   fMarkerStyle  = 20;
}

////////////////////////////////////////////////////////////////////////////////
/// Add a line.

REveStraightLineSet::Line_t*
REveStraightLineSet::AddLine(Float_t x1, Float_t y1, Float_t z1,
                             Float_t x2, Float_t y2, Float_t z2)
{
   fLastLine = new (fLinePlex.NewAtom()) Line_t(x1, y1, z1, x2, y2, z2);
   fLastLine->fId = fLinePlex.Size() - 1;
   return fLastLine;
}

////////////////////////////////////////////////////////////////////////////////
/// Add a line.

REveStraightLineSet::Line_t*
REveStraightLineSet::AddLine(const REveVector& p1, const REveVector& p2)
{
   return AddLine(p1.fX, p1.fY, p1.fZ, p2.fX, p2.fY, p2.fZ);
}

////////////////////////////////////////////////////////////////////////////////
/// Set line vertices with given index.

void
REveStraightLineSet::SetLine(int idx,
                             Float_t x1, Float_t y1, Float_t z1,
                             Float_t x2, Float_t y2, Float_t z2)
{
   Line_t* l = (Line_t*) fLinePlex.Atom(idx);

   l->fV1[0] = x1; l->fV1[1] = y1; l->fV1[2] = z1;
   l->fV2[0] = x2; l->fV2[1] = y2; l->fV2[2] = z2;
}

////////////////////////////////////////////////////////////////////////////////
/// Set line vertices with given index.

void
REveStraightLineSet::SetLine(int idx, const REveVector& p1, const REveVector& p2)
{
   SetLine(idx, p1.fX, p1.fY, p1.fZ, p2.fX, p2.fY, p2.fZ);
}

////////////////////////////////////////////////////////////////////////////////
/// Add a marker with given position.

REveStraightLineSet::Marker_t*
REveStraightLineSet::AddMarker(Float_t x, Float_t y, Float_t z, Int_t line_id)
{
   Marker_t* marker = new (fMarkerPlex.NewAtom()) Marker_t(x, y, z, line_id);
   return marker;
}

////////////////////////////////////////////////////////////////////////////////
/// Add a marker with given position.

REveStraightLineSet::Marker_t*
REveStraightLineSet::AddMarker(const REveVector& p, Int_t line_id)
{
   return AddMarker(p.fX, p.fY, p.fZ, line_id);
}

////////////////////////////////////////////////////////////////////////////////
/// Add a marker for line with given index on relative position pos.

REveStraightLineSet::Marker_t*
REveStraightLineSet::AddMarker(Int_t line_id, Float_t pos)
{
   Line_t& l = * (Line_t*) fLinePlex.Atom(line_id);
   return AddMarker(l.fV1[0] + (l.fV2[0] - l.fV1[0])*pos,
                    l.fV1[1] + (l.fV2[1] - l.fV1[1])*pos,
                    l.fV1[2] + (l.fV2[2] - l.fV1[2])*pos,
                    line_id);
}

////////////////////////////////////////////////////////////////////////////////
/// Copy visualization parameters from element el.

void REveStraightLineSet::CopyVizParams(const REveElement* el)
{
   const REveStraightLineSet* m = dynamic_cast<const REveStraightLineSet*>(el);
   if (m)
   {
      TAttLine::operator=(*m);
      TAttMarker::operator=(*m);
      fRnrMarkers = m->fRnrMarkers;
      fRnrLines   = m->fRnrLines;
      fDepthTest  = m->fDepthTest;
   }

   REveElement::CopyVizParams(el);
}

////////////////////////////////////////////////////////////////////////////////
/// Write visualization parameters.

void REveStraightLineSet::WriteVizParams(std::ostream& out, const TString& var)
{
   REveElement::WriteVizParams(out, var);

   TString t = "   " + var + "->";
   TAttMarker::SaveMarkerAttributes(out, var);
   TAttLine  ::SaveLineAttributes  (out, var);
   out << t << "SetRnrMarkers(" << ToString(fRnrMarkers) << ");\n";
   out << t << "SetRnrLines("   << ToString(fRnrLines)   << ");\n";
   out << t << "SetDepthTest("  << ToString(fDepthTest)  << ");\n";
}

////////////////////////////////////////////////////////////////////////////////
/// Fill core part of JSON representation.

Int_t REveStraightLineSet::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
{
   Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);

   j["fLinePlexSize"] = fLinePlex.Size();
   j["fMarkerPlexSize"] = fMarkerPlex.Size();
   j["fLineWidth"] = fLineWidth;
   j["fLineStyle"] = fLineStyle;
   j["fMarkerSize"] = fMarkerSize;
   j["fMarkerStyle"] = fMarkerStyle;
   // printf("REveStraightLineSet::WriteCoreJson %d \n", ret);
   return ret;
}

////////////////////////////////////////////////////////////////////////////////
/// Crates 3D point array for rendering.

void REveStraightLineSet::BuildRenderData()
{
   int nVertices =  fLinePlex.Size() * 2 + fMarkerPlex.Size();
   fRenderData = std::make_unique<REveRenderData>("makeStraightLineSet", 3 * nVertices, 0, nVertices);

   // printf("REveStraightLineSet::BuildRenderData id = %d \n", GetElementId());
   REveChunkManager::iterator li(fLinePlex);
   while (li.next()) {
      Line_t* l = (Line_t*)li();

      fRenderData->PushV(l->fV1[0], l->fV1[1],l->fV1[2]);
      fRenderData->PushV(l->fV2[0], l->fV2[1],l->fV2[2]);
      fRenderData->PushI(l->fId);
   }

   REveChunkManager::iterator mi(fMarkerPlex);
   while (mi.next()) {
      Marker_t* m = (Marker_t*)mi();
      fRenderData->PushV(m->fV[0], m->fV[1], m->fV[2]);
      fRenderData->PushI(m->fLineId);
   }

   REveElement::BuildRenderData();

   // printf("REveStraightLineSet::BuildRenderData size= %d\n", fRenderData->GetBinarySize());
}

////////////////////////////////////////////////////////////////////////////////
/// Return class of projected object.
/// Virtual from REveProjectable.

TClass* REveStraightLineSet::ProjectedClass(const REveProjection*) const
{
   return TClass::GetClass<REveStraightLineSetProjected>();
}

////////////////////////////////////////////////////////////////////////////////
/// Compute bounding-box.
/// Virtual from TAttBBox.

void REveStraightLineSet::ComputeBBox()
{
   if (fLinePlex.Size() == 0 && fMarkerPlex.Size() == 0) {
      BBoxZero();
      return;
   }

   BBoxInit();

   REveChunkManager::iterator li(fLinePlex);
   while (li.next()) {
      BBoxCheckPoint(((Line_t*)li())->fV1);
      BBoxCheckPoint(((Line_t*)li())->fV2);
   }

   REveChunkManager::iterator mi(fMarkerPlex);
   while (mi.next())
   {
      BBoxCheckPoint(((Marker_t*)mi())->fV);
   }
}

/** \class REveStraightLineSetProjected
\ingroup REve
Projected replica of a REveStraightLineSet.
*/

ClassImp(REveStraightLineSetProjected);

////////////////////////////////////////////////////////////////////////////////
/// Constructor.

REveStraightLineSetProjected::REveStraightLineSetProjected() :
   REveStraightLineSet(), REveProjected ()
{
}

////////////////////////////////////////////////////////////////////////////////
/// Set projection manager and model object.

void REveStraightLineSetProjected::SetProjection(REveProjectionManager* mng,
                                                 REveProjectable* model)
{
   REveProjected::SetProjection(mng, model);

   CopyVizParams(dynamic_cast<REveElement*>(model));
}

////////////////////////////////////////////////////////////////////////////////
/// Set depth (z-coordinate) of the projected points.

void REveStraightLineSetProjected::SetDepthLocal(Float_t d)
{
   SetDepthCommon(d, this, fBBox);

   REveChunkManager::iterator li(fLinePlex);
   while (li.next())
   {
      REveStraightLineSet::Line_t& l = * (REveStraightLineSet::Line_t*) li();
      l.fV1[2] = fDepth;
      l.fV2[2] = fDepth;
   }

   REveChunkManager::iterator mi(fMarkerPlex);
   while (mi.next())
   {
      Marker_t& m = * (Marker_t*) mi();
      m.fV[2] = fDepth;
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Callback that actually performs the projection.
/// Called when projection parameters have been updated.

void REveStraightLineSetProjected::UpdateProjection()
{
   REveProjection&      proj = * fManager->GetProjection();
   REveStraightLineSet& orig = * dynamic_cast<REveStraightLineSet*>(fProjectable);

   REveTrans *trans = orig.PtrMainTrans(kFALSE);

   BBoxClear();

   // Lines
   Int_t num_lines = orig.GetLinePlex().Size();
   if (proj.HasSeveralSubSpaces())
      num_lines += TMath::Max(1, num_lines/10);
   fLinePlex.Reset(sizeof(Line_t), num_lines);
   REveVector p1, p2;
   REveChunkManager::iterator li(orig.GetLinePlex());
   while (li.next())
   {
      Line_t *l = (Line_t*) li();

      proj.ProjectPointfv(trans, l->fV1, p1, fDepth);
      proj.ProjectPointfv(trans, l->fV2, p2, fDepth);

      if (proj.AcceptSegment(p1, p2, 0.1f))
      {
         AddLine(p1, p2)->fId = l->fId;
      }
      else
      {
         REveVector bp1(l->fV1), bp2(l->fV2);
         if (trans) {
            trans->MultiplyIP(bp1);
            trans->MultiplyIP(bp2);
         }
         proj.BisectBreakPoint(bp1, bp2, kTRUE, fDepth);

         AddLine(p1, bp1)->fId = l->fId;
         AddLine(bp2, p2)->fId = l->fId;
      }
   }
   if (proj.HasSeveralSubSpaces())
      fLinePlex.Refit();

   // Markers
   fMarkerPlex.Reset(sizeof(Marker_t), orig.GetMarkerPlex().Size());
   REveChunkManager::iterator mi(orig.GetMarkerPlex());
   REveVector pp;
   while (mi.next())
   {
      Marker_t &m = * (Marker_t*) mi();

      proj.ProjectPointfv(trans, m.fV, pp, fDepth);
      AddMarker(pp, m.fLineId);
   }
}
<|endoftext|>


<commit_before>#include "cinder/Cinder.h"
// select an appropriate base class for our App based on whether we're on iOS or not
#if defined( CINDER_COCOA_TOUCH )
	#include "cinder/app/AppCocoaTouch.h"
	typedef ci::app::AppCocoaTouch AppBase;
#else
	#include "cinder/app/AppBasic.h"
	typedef ci::app::AppBasic AppBase;
#endif

#include "cinder/Camera.h"
#include "cinder/gl/Fbo.h"

using namespace ci;
using namespace ci::app;
using namespace std;

// This sample shows a very basic use case for FBOs - it renders a spinning torus
// into an FBO, and uses that as a Texture onto the sides of a cube.
class FBOBasicApp : public AppBase {
  public:
	virtual void	setup();
	virtual void	update();
	virtual void	draw();
	virtual void	mouseDown( MouseEvent event );

	void			renderSceneToFbo();

	gl::Fbo				mFbo;
	Matrix44f			mTorusRotation;
	static const int	FBO_WIDTH = 256, FBO_HEIGHT = 256;
};

void FBOBasicApp::setup()
{
	gl::Fbo::Format format;
//	format.setSamples( 4 ); // uncomment this to enable 4x antialiasing
	mFbo = gl::Fbo( FBO_WIDTH, FBO_HEIGHT, format );

	gl::enableDepthRead();
	gl::enableDepthWrite();

	mTorusRotation.setToIdentity();
}

// Render the torus into the FBO
void FBOBasicApp::renderSceneToFbo()
{
	// this will restore the old framebuffer binding when we leave this function
	// on non-OpenGL ES platforms, you can just call mFbo.unbindFramebuffer() at the end of the function
	// but this will restore the "screen" FBO on OpenGL ES, and does the right thing on both platforms
	gl::SaveFramebufferBinding bindingSaver;

	// bind the framebuffer - now everything we draw will go there
	mFbo.bindFramebuffer();

	// setup the viewport to match the dimensions of the FBO
	gl::setViewport( mFbo.getBounds() );

	// setup our camera to render the torus scene
	CameraPersp cam( mFbo.getWidth(), mFbo.getHeight(), 60.0f );
	cam.setPerspective( 60, mFbo.getAspectRatio(), 1, 1000 );
	cam.lookAt( Vec3f( 2.8f, 1.8f, -2.8f ), Vec3f::zero() );
	gl::setMatrices( cam );

	// set the modelview matrix to reflect our current rotation
	gl::multModelView( mTorusRotation );

	// clear out the FBO with blue
	gl::clear( Color( 0.25, 0.5f, 1.0f ) );

	// render an orange torus, with no textures
	glDisable( GL_TEXTURE_2D );
	gl::color( Color( 1.0f, 0.5f, 0.25f ) );
	gl::drawTorus( 1.4f, 0.3f, 32, 64 );
//	gl::drawColorCube( Vec3f::zero(), Vec3f( 2.2f, 2.2f, 2.2f ) );
}

void FBOBasicApp::update()
{
	// Rotate the torus by .06 radians around an arbitrary axis
	mTorusRotation.rotate( Vec3f( 0.16666f, 0.333333f, 0.666666f ).normalized(), 0.06f );

	// render into our FBO
	renderSceneToFbo();
}

void FBOBasicApp::draw()
{
	// clear the window to gray
	gl::clear( Color( 0.35f, 0.35f, 0.35f ) );

	// setup our camera to render the cube
	CameraPersp cam( getWindowWidth(), getWindowHeight(), 60.0f );
	cam.setPerspective( 60, getWindowAspectRatio(), 1, 1000 );
	cam.lookAt( Vec3f( 2.6f, 1.6f, -2.6f ), Vec3f::zero() );
	gl::setMatrices( cam );

	// set the viewport to match our window
	gl::setViewport( getWindowBounds() );

	// use the scene we rendered into the FBO as a texture
	glEnable( GL_TEXTURE_2D );
	mFbo.bindTexture();

	// draw a cube textured with the FBO
	gl::color( Color::white() );
	gl::drawCube( Vec3f::zero(), Vec3f( 2.2f, 2.2f, 2.2f ) );

	// show the FBO texture in the upper left corner
	gl::setMatricesWindow( getWindowSize() );
	gl::draw( mFbo.getTexture(0), Rectf( 0, 0, 96, 96 ) );

#if ! defined( CINDER_GLES ) // OpenGL ES can't do depth textures, otherwise draw the FBO's
	gl::draw( mFbo.getDepthTexture(), Rectf( 96, 0, 96 + 96, 96 ) );
#endif
	Surface whatever( 640, 460, false );
	cocoa::writeToSavedPhotosAlbum( whatever );

}

void FBOBasicApp::mouseDown( MouseEvent event )
{
}

#if defined( CINDER_COCOA_TOUCH )
CINDER_APP_COCOA_TOUCH( FBOBasicApp, RendererGl )
#else
CINDER_APP_BASIC( FBOBasicApp, RendererGl )
#endif<commit_msg>Fixing stray code added to FBOBasic sample<commit_after>#include "cinder/Cinder.h"
// select an appropriate base class for our App based on whether we're on iOS or not
#if defined( CINDER_COCOA_TOUCH )
	#include "cinder/app/AppCocoaTouch.h"
	typedef ci::app::AppCocoaTouch AppBase;
#else
	#include "cinder/app/AppBasic.h"
	typedef ci::app::AppBasic AppBase;
#endif

#include "cinder/Camera.h"
#include "cinder/gl/Fbo.h"

using namespace ci;
using namespace ci::app;
using namespace std;

// This sample shows a very basic use case for FBOs - it renders a spinning torus
// into an FBO, and uses that as a Texture onto the sides of a cube.
class FBOBasicApp : public AppBase {
  public:
	virtual void	setup();
	virtual void	update();
	virtual void	draw();

	void			renderSceneToFbo();

	gl::Fbo				mFbo;
	Matrix44f			mTorusRotation;
	static const int	FBO_WIDTH = 256, FBO_HEIGHT = 256;
};

void FBOBasicApp::setup()
{
	gl::Fbo::Format format;
//	format.setSamples( 4 ); // uncomment this to enable 4x antialiasing
	mFbo = gl::Fbo( FBO_WIDTH, FBO_HEIGHT, format );

	gl::enableDepthRead();
	gl::enableDepthWrite();

	mTorusRotation.setToIdentity();
}

// Render the torus into the FBO
void FBOBasicApp::renderSceneToFbo()
{
	// this will restore the old framebuffer binding when we leave this function
	// on non-OpenGL ES platforms, you can just call mFbo.unbindFramebuffer() at the end of the function
	// but this will restore the "screen" FBO on OpenGL ES, and does the right thing on both platforms
	gl::SaveFramebufferBinding bindingSaver;

	// bind the framebuffer - now everything we draw will go there
	mFbo.bindFramebuffer();

	// setup the viewport to match the dimensions of the FBO
	gl::setViewport( mFbo.getBounds() );

	// setup our camera to render the torus scene
	CameraPersp cam( mFbo.getWidth(), mFbo.getHeight(), 60.0f );
	cam.setPerspective( 60, mFbo.getAspectRatio(), 1, 1000 );
	cam.lookAt( Vec3f( 2.8f, 1.8f, -2.8f ), Vec3f::zero() );
	gl::setMatrices( cam );

	// set the modelview matrix to reflect our current rotation
	gl::multModelView( mTorusRotation );

	// clear out the FBO with blue
	gl::clear( Color( 0.25, 0.5f, 1.0f ) );

	// render an orange torus, with no textures
	glDisable( GL_TEXTURE_2D );
	gl::color( Color( 1.0f, 0.5f, 0.25f ) );
	gl::drawTorus( 1.4f, 0.3f, 32, 64 );
//	gl::drawColorCube( Vec3f::zero(), Vec3f( 2.2f, 2.2f, 2.2f ) );
}

void FBOBasicApp::update()
{
	// Rotate the torus by .06 radians around an arbitrary axis
	mTorusRotation.rotate( Vec3f( 0.16666f, 0.333333f, 0.666666f ).normalized(), 0.06f );

	// render into our FBO
	renderSceneToFbo();
}

void FBOBasicApp::draw()
{
	// clear the window to gray
	gl::clear( Color( 0.35f, 0.35f, 0.35f ) );

	// setup our camera to render the cube
	CameraPersp cam( getWindowWidth(), getWindowHeight(), 60.0f );
	cam.setPerspective( 60, getWindowAspectRatio(), 1, 1000 );
	cam.lookAt( Vec3f( 2.6f, 1.6f, -2.6f ), Vec3f::zero() );
	gl::setMatrices( cam );

	// set the viewport to match our window
	gl::setViewport( getWindowBounds() );

	// use the scene we rendered into the FBO as a texture
	glEnable( GL_TEXTURE_2D );
	mFbo.bindTexture();

	// draw a cube textured with the FBO
	gl::color( Color::white() );
	gl::drawCube( Vec3f::zero(), Vec3f( 2.2f, 2.2f, 2.2f ) );

	// show the FBO texture in the upper left corner
	gl::setMatricesWindow( getWindowSize() );
	gl::draw( mFbo.getTexture(0), Rectf( 0, 0, 96, 96 ) );

#if ! defined( CINDER_GLES ) // OpenGL ES can't do depth textures, otherwise draw the FBO's
	gl::draw( mFbo.getDepthTexture(), Rectf( 96, 0, 96 + 96, 96 ) );
#endif
}

#if defined( CINDER_COCOA_TOUCH )
CINDER_APP_COCOA_TOUCH( FBOBasicApp, RendererGl )
#else
CINDER_APP_BASIC( FBOBasicApp, RendererGl )
#endif<|endoftext|>


<commit_before>/**
 * This file is part of the "FnordMetric" project
 *   Copyright (c) 2014 Paul Asmuth, Google Inc.
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include "fnord-base/exception.h"
#include "fnord-base/inspect.h"
#include "fnord-base/logging.h"
#include "fnord-http/httpserverconnection.h"
#include "fnord-http/httpgenerator.h"

namespace fnord {

template <>
std::string inspect(const http::HTTPServerConnection& conn) {
  return StringUtil::format("<HTTPServerConnection $0>", inspect(&conn));
}

namespace http {

void HTTPServerConnection::start(
    HTTPHandlerFactory* handler_factory,
    ScopedPtr<net::TCPConnection> conn,
    TaskScheduler* scheduler,
    HTTPServerStats* stats) {
  auto http_conn = new HTTPServerConnection(
      handler_factory,
      std::move(conn),
      scheduler,
      stats);

  // N.B. we don't leak the connection here. it is ref counted and will
  // free itself
  http_conn->incRef();
  http_conn->nextRequest();
}

HTTPServerConnection::HTTPServerConnection(
    HTTPHandlerFactory* handler_factory,
    ScopedPtr<net::TCPConnection> conn,
    TaskScheduler* scheduler,
    HTTPServerStats* stats) :
    handler_factory_(handler_factory),
    conn_(std::move(conn)),
    scheduler_(scheduler),
    on_write_completed_cb_(nullptr),
    stats_(stats),
    parser_(HTTPParser::PARSE_HTTP_REQUEST),
    closed_(false) {
  logTrace("fnord.http.server", "New HTTP connection: $0", inspect(*this));
  stats_->total_connections.incr(1);
  stats_->current_connections.incr(1);

  conn_->setNonblocking(true);
  read_buf_.reserve(kMinBufferSize);

  parser_.onMethod([this] (HTTPMessage::kHTTPMethod method) {
    cur_request_->setMethod(method);
  });

  parser_.onURI([this] (const char* data, size_t size) {
    cur_request_->setURI(std::string(data, size));
  });

  parser_.onVersion([this] (const char* data, size_t size) {
    cur_request_->setVersion(std::string(data, size));
  });

  parser_.onHeader([this] (
      const char* key,
      size_t key_size,
      const char* val,
      size_t val_size) {
    cur_request_->addHeader(
        std::string(key, key_size),
        std::string(val, val_size));
  });

  parser_.onHeadersComplete(
      std::bind(&HTTPServerConnection::dispatchRequest, this));
}

HTTPServerConnection::~HTTPServerConnection() {
  stats_->current_connections.decr(1);
}

void HTTPServerConnection::read() {
  std::unique_lock<std::mutex> lk(mutex_);

  size_t len;
  try {
    len = conn_->read(read_buf_.data(), read_buf_.allocSize());
    stats_->received_bytes.incr(len);
  } catch (Exception& e) {
    if (e.ofType(kWouldBlockError)) {
      return awaitRead();
    }

    lk.unlock();
    logDebug("fnord.http.server", e, "read() failed, closing...");

    close();
    return;
  }

  lk.unlock();

  try {
    if (len == 0) {
      parser_.eof();
      close();
      return;
    } else {
      parser_.parse((char *) read_buf_.data(), len);
    }
  } catch (Exception& e) {
    logDebug("fnord.http.server", e, "HTTP parse error, closing...");
    close();
    return;
  }

  if (parser_.state() != HTTPParser::S_DONE) {
    lk.lock();
    awaitRead();
    lk.unlock();
  }
}

void HTTPServerConnection::write() {
  std::unique_lock<std::mutex> lk(mutex_);

  auto data = ((char *) write_buf_.data()) + write_buf_.mark();
  auto size = write_buf_.size() - write_buf_.mark();

  size_t len;
  try {
    len = conn_->write(data, size);
    write_buf_.setMark(write_buf_.mark() + len);
    stats_->sent_bytes.incr(len);
  } catch (Exception& e) {
    if (e.ofType(kWouldBlockError)) {
      return awaitWrite();
    }

    lk.unlock();
    logDebug("fnord.http.server", e, "write() failed, closing...");
    close();
    return;
  }

  if (write_buf_.mark() < write_buf_.size()) {
    awaitWrite();
  } else {
    write_buf_.clear();
    lk.unlock();
    if (on_write_completed_cb_) {
      on_write_completed_cb_();
    }
  }
}

// precondition: must hold mutex
void HTTPServerConnection::awaitRead() {
  if (closed_) {
    RAISE(kIllegalStateError, "read() on closed HTTP connection");
  }

  scheduler_->runOnReadable(
      std::bind(&HTTPServerConnection::read, this),
      *conn_);
}

// precondition: must hold mutex
void HTTPServerConnection::awaitWrite() {
  if (closed_) {
    RAISE(kIllegalStateError, "write() on closed HTTP connection");
  }

  scheduler_->runOnWritable(
      std::bind(&HTTPServerConnection::write, this),
      *conn_);
}

void HTTPServerConnection::nextRequest() {
  parser_.reset();
  cur_request_.reset(new HTTPRequest());
  cur_handler_.reset(nullptr);
  on_write_completed_cb_ = nullptr;
  body_buf_.clear();

  parser_.onBodyChunk([this] (const char* data, size_t size) {
    std::unique_lock<std::mutex> lk(mutex_);
    body_buf_.append(data, size);
  });

  awaitRead();
}

void HTTPServerConnection::dispatchRequest() {
  stats_->total_requests.incr(1);
  stats_->current_requests.incr(1);

  incRef();
  cur_handler_= handler_factory_->getHandler(this, cur_request_.get());
  cur_handler_->handleHTTPRequest();
}

void HTTPServerConnection::readRequestBody(
    Function<void (const void*, size_t, bool)> callback) {
  std::unique_lock<std::mutex> lk(mutex_);

  switch (parser_.state()) {
    case HTTPParser::S_REQ_METHOD:
    case HTTPParser::S_REQ_URI:
    case HTTPParser::S_REQ_VERSION:
    case HTTPParser::S_RES_VERSION:
    case HTTPParser::S_RES_STATUS_CODE:
    case HTTPParser::S_RES_STATUS_NAME:
    case HTTPParser::S_HEADER:
      RAISE(kIllegalStateError, "can't read body before headers are parsed");
    case HTTPParser::S_BODY:
    case HTTPParser::S_DONE:
      break;
  }

  auto read_body_chunk_fn = [this, callback] (const char* data, size_t size) {
    std::unique_lock<std::mutex> lk(mutex_);
    body_buf_.append(data, size);
    auto last_chunk = parser_.state() == HTTPParser::S_DONE;

    if (last_chunk || body_buf_.size() > 0) {
      callback(
          (const char*) body_buf_.data(),
          body_buf_.size(),
          last_chunk);

      body_buf_.clear();
    }
  };

  parser_.onBodyChunk(read_body_chunk_fn);
  lk.unlock();
  read_body_chunk_fn(nullptr, 0);
}

void HTTPServerConnection::discardRequestBody(Function<void ()> callback) {
  readRequestBody([callback] (const void* data, size_t size, bool last) {
    if (last) {
      callback();
    }
  });
}

void HTTPServerConnection::writeResponse(
    const HTTPResponse& resp,
    Function<void()> ready_callback) {
  std::lock_guard<std::mutex> lk(mutex_);

  if (parser_.state() != HTTPParser::S_DONE) {
    RAISE(kIllegalStateError, "can't write response before request is read");
  }

  BufferOutputStream os(&write_buf_);
  HTTPGenerator::generate(resp, &os);
  on_write_completed_cb_ = ready_callback;
  awaitWrite();
}

void HTTPServerConnection::writeResponseBody(
    const void* data,
    size_t size,
    Function<void()> ready_callback) {
  std::lock_guard<std::mutex> lk(mutex_);

  if (parser_.state() != HTTPParser::S_DONE) {
    RAISE(kIllegalStateError, "can't write response before request is read");
  }

  write_buf_.append(data, size);
  on_write_completed_cb_ = ready_callback;
  awaitWrite();
}

void HTTPServerConnection::finishResponse() {
  stats_->current_requests.decr(1);

  if (decRef()) {
    return;
  }

  if (false && cur_request_->keepalive()) {
    std::lock_guard<std::mutex> lk(mutex_);
    nextRequest();
  } else {
    close();
  }
}

// precondition: must not hold mutex
void HTTPServerConnection::close() {
  std::unique_lock<std::mutex> lk(mutex_);

  logTrace("fnord.http.server", "HTTP connection close: $0", inspect(*this));

  if (closed_) {
    RAISE(kIllegalStateError, "HTTP connection is already closed");
  }

  closed_ = true;
  scheduler_->cancelFD(conn_->fd());
  conn_->close();
  lk.unlock();

  decRef();
}

} // namespace http
} // namespace fnord

<commit_msg>no deadlock<commit_after>/**
 * This file is part of the "FnordMetric" project
 *   Copyright (c) 2014 Paul Asmuth, Google Inc.
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include "fnord-base/exception.h"
#include "fnord-base/inspect.h"
#include "fnord-base/logging.h"
#include "fnord-http/httpserverconnection.h"
#include "fnord-http/httpgenerator.h"

namespace fnord {

template <>
std::string inspect(const http::HTTPServerConnection& conn) {
  return StringUtil::format("<HTTPServerConnection $0>", inspect(&conn));
}

namespace http {

void HTTPServerConnection::start(
    HTTPHandlerFactory* handler_factory,
    ScopedPtr<net::TCPConnection> conn,
    TaskScheduler* scheduler,
    HTTPServerStats* stats) {
  auto http_conn = new HTTPServerConnection(
      handler_factory,
      std::move(conn),
      scheduler,
      stats);

  // N.B. we don't leak the connection here. it is ref counted and will
  // free itself
  http_conn->incRef();
  http_conn->nextRequest();
}

HTTPServerConnection::HTTPServerConnection(
    HTTPHandlerFactory* handler_factory,
    ScopedPtr<net::TCPConnection> conn,
    TaskScheduler* scheduler,
    HTTPServerStats* stats) :
    handler_factory_(handler_factory),
    conn_(std::move(conn)),
    scheduler_(scheduler),
    on_write_completed_cb_(nullptr),
    stats_(stats),
    parser_(HTTPParser::PARSE_HTTP_REQUEST),
    closed_(false) {
  logTrace("fnord.http.server", "New HTTP connection: $0", inspect(*this));
  stats_->total_connections.incr(1);
  stats_->current_connections.incr(1);

  conn_->setNonblocking(true);
  read_buf_.reserve(kMinBufferSize);

  parser_.onMethod([this] (HTTPMessage::kHTTPMethod method) {
    cur_request_->setMethod(method);
  });

  parser_.onURI([this] (const char* data, size_t size) {
    cur_request_->setURI(std::string(data, size));
  });

  parser_.onVersion([this] (const char* data, size_t size) {
    cur_request_->setVersion(std::string(data, size));
  });

  parser_.onHeader([this] (
      const char* key,
      size_t key_size,
      const char* val,
      size_t val_size) {
    cur_request_->addHeader(
        std::string(key, key_size),
        std::string(val, val_size));
  });

  parser_.onHeadersComplete(
      std::bind(&HTTPServerConnection::dispatchRequest, this));
}

HTTPServerConnection::~HTTPServerConnection() {
  stats_->current_connections.decr(1);
}

void HTTPServerConnection::read() {
  std::unique_lock<std::mutex> lk(mutex_);

  size_t len;
  try {
    len = conn_->read(read_buf_.data(), read_buf_.allocSize());
    stats_->received_bytes.incr(len);
  } catch (Exception& e) {
    if (e.ofType(kWouldBlockError)) {
      return awaitRead();
    }

    lk.unlock();
    logDebug("fnord.http.server", e, "read() failed, closing...");

    close();
    return;
  }

  lk.unlock();

  try {
    if (len == 0) {
      parser_.eof();
      close();
      return;
    } else {
      parser_.parse((char *) read_buf_.data(), len);
    }
  } catch (Exception& e) {
    logDebug("fnord.http.server", e, "HTTP parse error, closing...");
    close();
    return;
  }

  if (parser_.state() != HTTPParser::S_DONE) {
    lk.lock();
    awaitRead();
    lk.unlock();
  }
}

void HTTPServerConnection::write() {
  std::unique_lock<std::mutex> lk(mutex_);

  auto data = ((char *) write_buf_.data()) + write_buf_.mark();
  auto size = write_buf_.size() - write_buf_.mark();

  size_t len;
  try {
    len = conn_->write(data, size);
    write_buf_.setMark(write_buf_.mark() + len);
    stats_->sent_bytes.incr(len);
  } catch (Exception& e) {
    if (e.ofType(kWouldBlockError)) {
      return awaitWrite();
    }

    lk.unlock();
    logDebug("fnord.http.server", e, "write() failed, closing...");
    close();
    return;
  }

  if (write_buf_.mark() < write_buf_.size()) {
    awaitWrite();
  } else {
    write_buf_.clear();
    lk.unlock();
    if (on_write_completed_cb_) {
      on_write_completed_cb_();
    }
  }
}

// precondition: must hold mutex
void HTTPServerConnection::awaitRead() {
  if (closed_) {
    RAISE(kIllegalStateError, "read() on closed HTTP connection");
  }

  scheduler_->runOnReadable(
      std::bind(&HTTPServerConnection::read, this),
      *conn_);
}

// precondition: must hold mutex
void HTTPServerConnection::awaitWrite() {
  if (closed_) {
    RAISE(kIllegalStateError, "write() on closed HTTP connection");
  }

  scheduler_->runOnWritable(
      std::bind(&HTTPServerConnection::write, this),
      *conn_);
}

void HTTPServerConnection::nextRequest() {
  parser_.reset();
  cur_request_.reset(new HTTPRequest());
  cur_handler_.reset(nullptr);
  on_write_completed_cb_ = nullptr;
  body_buf_.clear();

  parser_.onBodyChunk([this] (const char* data, size_t size) {
    std::unique_lock<std::mutex> lk(mutex_);
    body_buf_.append(data, size);
  });

  awaitRead();
}

void HTTPServerConnection::dispatchRequest() {
  stats_->total_requests.incr(1);
  stats_->current_requests.incr(1);

  incRef();
  cur_handler_= handler_factory_->getHandler(this, cur_request_.get());
  cur_handler_->handleHTTPRequest();
}

void HTTPServerConnection::readRequestBody(
    Function<void (const void*, size_t, bool)> callback) {
  std::unique_lock<std::mutex> lk(mutex_);

  switch (parser_.state()) {
    case HTTPParser::S_REQ_METHOD:
    case HTTPParser::S_REQ_URI:
    case HTTPParser::S_REQ_VERSION:
    case HTTPParser::S_RES_VERSION:
    case HTTPParser::S_RES_STATUS_CODE:
    case HTTPParser::S_RES_STATUS_NAME:
    case HTTPParser::S_HEADER:
      RAISE(kIllegalStateError, "can't read body before headers are parsed");
    case HTTPParser::S_BODY:
    case HTTPParser::S_DONE:
      break;
  }

  auto read_body_chunk_fn = [this, callback] (const char* data, size_t size) {
    std::unique_lock<std::mutex> lk(mutex_);
    auto chunk = body_buf_;
    chunk.append(data, size);
    auto last_chunk = parser_.state() == HTTPParser::S_DONE;
    body_buf_.clear();
    lk.unlock();

    if (last_chunk || body_buf_.size() > 0) {
      callback(
          (const char*) chunk.data(),
          chunk.size(),
          last_chunk);

    }
  };

  parser_.onBodyChunk(read_body_chunk_fn);
  lk.unlock();
  read_body_chunk_fn(nullptr, 0);
}

void HTTPServerConnection::discardRequestBody(Function<void ()> callback) {
  readRequestBody([callback] (const void* data, size_t size, bool last) {
    if (last) {
      callback();
    }
  });
}

void HTTPServerConnection::writeResponse(
    const HTTPResponse& resp,
    Function<void()> ready_callback) {
  std::lock_guard<std::mutex> lk(mutex_);

  if (parser_.state() != HTTPParser::S_DONE) {
    RAISE(kIllegalStateError, "can't write response before request is read");
  }

  BufferOutputStream os(&write_buf_);
  HTTPGenerator::generate(resp, &os);
  on_write_completed_cb_ = ready_callback;
  awaitWrite();
}

void HTTPServerConnection::writeResponseBody(
    const void* data,
    size_t size,
    Function<void()> ready_callback) {
  std::lock_guard<std::mutex> lk(mutex_);

  if (parser_.state() != HTTPParser::S_DONE) {
    RAISE(kIllegalStateError, "can't write response before request is read");
  }

  write_buf_.append(data, size);
  on_write_completed_cb_ = ready_callback;
  awaitWrite();
}

void HTTPServerConnection::finishResponse() {
  stats_->current_requests.decr(1);

  if (decRef()) {
    return;
  }

  if (false && cur_request_->keepalive()) {
    std::lock_guard<std::mutex> lk(mutex_);
    nextRequest();
  } else {
    close();
  }
}

// precondition: must not hold mutex
void HTTPServerConnection::close() {
  std::unique_lock<std::mutex> lk(mutex_);

  logTrace("fnord.http.server", "HTTP connection close: $0", inspect(*this));

  if (closed_) {
    RAISE(kIllegalStateError, "HTTP connection is already closed");
  }

  closed_ = true;
  scheduler_->cancelFD(conn_->fd());
  conn_->close();
  lk.unlock();

  decRef();
}

} // namespace http
} // namespace fnord

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ListBox.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: fs $ $Date: 2002-12-02 09:56:34 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _FORMS_LISTBOX_HXX_
#define _FORMS_LISTBOX_HXX_

#ifndef _FORMS_FORMCOMPONENT_HXX_
#include "FormComponent.hxx"
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
#include <cppuhelper/interfacecontainer.hxx>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
#include <cppuhelper/interfacecontainer.hxx>
#endif
#ifndef _SV_TIMER_HXX
#include <vcl/timer.hxx>
#endif

#ifndef _COM_SUN_STAR_UTIL_XREFRESHABLE_HPP_
#include <com/sun/star/util/XRefreshable.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_
#include <com/sun/star/util/XNumberFormatter.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XSQLERRORBROADCASTER_HPP_
#include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_LISTSOURCETYPE_HPP_
#include <com/sun/star/form/ListSourceType.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XITEMLISTENER_HPP_
#include <com/sun/star/awt/XItemListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XFOCUSLISTENER_HPP_
#include <com/sun/star/awt/XFocusListener.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XCHANGEBROADCASTER_HPP_
#include <com/sun/star/form/XChangeBroadcaster.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif
#ifndef FORMS_ERRORBROADCASTER_HXX
#include "errorbroadcaster.hxx"
#endif

//.........................................................................
namespace frm
{

const ::rtl::OUString LISTBOX_EMPTY_VALUE = ::rtl::OUString::createFromAscii("$$$empty$$$");

//==================================================================
//= OListBoxModel
//==================================================================
typedef ::cppu::ImplHelper1 <   ::com::sun::star::util::XRefreshable
                            >   OListBoxModel_BASE;

class OListBoxModel :public OBoundControlModel
                    ,public OListBoxModel_BASE
                    ,public OErrorBroadcaster
                    ,public ::comphelper::OAggregationArrayUsageHelper< OListBoxModel >
{
    ::com::sun::star::uno::Any                  m_aSaveValue;

    // <properties>
    ::com::sun::star::form::ListSourceType      m_eListSourceType;      // type der list source
    ::com::sun::star::uno::Any                  m_aBoundColumn;
    StringSequence                              m_aListSourceSeq;       //
    StringSequence                              m_aValueSeq;            // alle Werte, readonly
    ::com::sun::star::uno::Sequence<sal_Int16>  m_aDefaultSelectSeq;    // DefaultSelected
    // </properties>

    ::cppu::OInterfaceContainerHelper   m_aRefreshListeners;

    static sal_Int32        nSelectHandle;
    // [properties]

    sal_Int16               m_nNULLPos; // Position an der der NULLwert abgelegt wird
    sal_Bool                m_bBoundComponent : 1;

    // Helper functions
    StringSequence GetCurValueSeq() const;

    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>   _getTypes();

protected:
    // UNO Anbindung
    virtual void _onValueChanged();

public:
    DECLARE_DEFAULT_LEAF_XTOR( OListBoxModel );

// XServiceInfo
    IMPLEMENTATION_NAME(OListBoxModel);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

// UNO Anbindung
    DECLARE_UNO3_AGG_DEFAULTS(OListBoxModel, OBoundControlModel);
    virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);

// OComponentHelper
    virtual void SAL_CALL disposing();

// OPropertySetHelper
    virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
                throw (::com::sun::star::uno::Exception);
    virtual sal_Bool SAL_CALL convertFastPropertyValue(
                ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
                throw (::com::sun::star::lang::IllegalArgumentException);

// XLoadListener
    virtual void         _loaded(const ::com::sun::star::lang::EventObject& rEvent);
    virtual void         _unloaded();

// XBoundComponent
    virtual sal_Bool _commit();

// XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
    virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

// XPersistObject
    virtual ::rtl::OUString SAL_CALL    getServiceName() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

// XReset
    virtual void _reset();

// XRefreshable
    virtual void SAL_CALL refresh() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addRefreshListener(const ::com::sun::star::uno::Reference< ::com::sun::star::util::XRefreshListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeRefreshListener(const ::com::sun::star::uno::Reference< ::com::sun::star::util::XRefreshListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);

    // OAggregationArrayUsageHelper
    virtual void fillProperties(
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps,
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
        ) const;
    IMPLEMENT_INFO_SERVICE()

protected:
    void loadData();

    DECLARE_XCLONEABLE();
};

//==================================================================
//= OListBoxControl
//==================================================================
typedef ::cppu::ImplHelper3<    ::com::sun::star::awt::XFocusListener,
                                ::com::sun::star::awt::XItemListener,
                                ::com::sun::star::form::XChangeBroadcaster > OListBoxControl_BASE;

class OListBoxControl   :public OBoundControl
                        ,public OListBoxControl_BASE
{
    ::cppu::OInterfaceContainerHelper       m_aChangeListeners;

    ::com::sun::star::uno::Any              m_aCurrentSelection;
    Timer                                   m_aChangeTimer;

protected:
    // UNO Anbindung
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>   _getTypes();

public:
    OListBoxControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
    virtual ~OListBoxControl();

    // UNO Anbindung
    DECLARE_UNO3_AGG_DEFAULTS(OListBoxControl, OBoundControl);
    virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);

// XServiceInfo
    IMPLEMENTATION_NAME(OListBoxControl);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

// XChangeBroadcaster
    virtual void SAL_CALL addChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XChangeListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XChangeListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);

// XFocusListener
    virtual void SAL_CALL focusGained(const ::com::sun::star::awt::FocusEvent& _rEvent) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL focusLost(const ::com::sun::star::awt::FocusEvent& _rEvent) throw(::com::sun::star::uno::RuntimeException);

// XItemListener
    virtual void SAL_CALL itemStateChanged(const ::com::sun::star::awt::ItemEvent& _rEvent) throw(::com::sun::star::uno::RuntimeException);

// XEventListener
    virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);

// OComponentHelper
    virtual void SAL_CALL disposing();

private:
    DECL_LINK( OnTimeout, void* );
};

//.........................................................................
}
//.........................................................................

#endif // _FORMS_LISTBOX_HXX_

<commit_msg>INTEGRATION: CWS formcelllinkage (1.6.92); FILE MERGED 2003/10/01 09:18:29 fs 1.6.92.1: #i18994# merging the changes from the CWS fs002<commit_after>/*************************************************************************
 *
 *  $RCSfile: ListBox.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2003-10-21 08:59:16 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _FORMS_LISTBOX_HXX_
#define _FORMS_LISTBOX_HXX_

#ifndef _FORMS_FORMCOMPONENT_HXX_
#include "FormComponent.hxx"
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
#include <cppuhelper/interfacecontainer.hxx>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
#include <cppuhelper/interfacecontainer.hxx>
#endif
#ifndef _SV_TIMER_HXX
#include <vcl/timer.hxx>
#endif

#ifndef _COM_SUN_STAR_UTIL_XREFRESHABLE_HPP_
#include <com/sun/star/util/XRefreshable.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_
#include <com/sun/star/util/XNumberFormatter.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XSQLERRORBROADCASTER_HPP_
#include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_LISTSOURCETYPE_HPP_
#include <com/sun/star/form/ListSourceType.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XITEMLISTENER_HPP_
#include <com/sun/star/awt/XItemListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XFOCUSLISTENER_HPP_
#include <com/sun/star/awt/XFocusListener.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XCHANGEBROADCASTER_HPP_
#include <com/sun/star/form/XChangeBroadcaster.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_FORM_XLISTENTRYSINK_HDL_
#include <drafts/com/sun/star/form/XListEntrySink.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_FORM_XLISTENTRYLISTENER_HDL_
#include <drafts/com/sun/star/form/XListEntryListener.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif
#ifndef FORMS_ERRORBROADCASTER_HXX
#include "errorbroadcaster.hxx"
#endif
#ifndef FORMS_ENTRYLISTHELPER_HXX
#include "entrylisthelper.hxx"
#endif

//.........................................................................
namespace frm
{

//==================================================================
//= OListBoxModel
//==================================================================
typedef ::cppu::ImplHelper1 <   ::com::sun::star::util::XRefreshable
                            >   OListBoxModel_BASE;

class OListBoxModel :public OBoundControlModel
                    ,public OListBoxModel_BASE
                    ,public OEntryListHelper
                    ,public OErrorBroadcaster
                    ,public ::comphelper::OAggregationArrayUsageHelper< OListBoxModel >
{
    ::com::sun::star::uno::Any                  m_aSaveValue;

    // <properties>
    ::com::sun::star::form::ListSourceType      m_eListSourceType;      // type der list source
    ::com::sun::star::uno::Any                  m_aBoundColumn;
    StringSequence                              m_aListSourceSeq;       //
    StringSequence                              m_aValueSeq;            // alle Werte, readonly
    ::com::sun::star::uno::Sequence<sal_Int16>  m_aDefaultSelectSeq;    // DefaultSelected
    // </properties>

    ::cppu::OInterfaceContainerHelper           m_aRefreshListeners;

    sal_Int16                                   m_nNULLPos;             // position of the NULL value in our list
    sal_Bool                                    m_bBoundComponent : 1;

    /** type how we should transfer our selection to external value bindings
    */
    enum TransferSelection
    {
        tsIndexList,        /// as list of indexes of selected entries
        tsIndex,            /// as index of the selected entry
        tsEntryList,        /// as list of string representations of selected entries
        tsEntry             /// as string representation of the selected entry
    };
    TransferSelection                           m_eTransferSelectionAs;

private:
    // Helper functions
    StringSequence GetCurValueSeq() const;

    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>   _getTypes();

public:
    DECLARE_DEFAULT_LEAF_XTOR( OListBoxModel );

// XServiceInfo
    IMPLEMENTATION_NAME(OListBoxModel);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

// UNO Anbindung
    DECLARE_UNO3_AGG_DEFAULTS(OListBoxModel, OBoundControlModel);
    virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);

// OComponentHelper
    virtual void SAL_CALL disposing();

// OPropertySetHelper
    virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
                throw (::com::sun::star::uno::Exception);
    virtual sal_Bool SAL_CALL convertFastPropertyValue(
                ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
                throw (::com::sun::star::lang::IllegalArgumentException);

protected:
    // XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
    virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

    // XPersistObject
    virtual ::rtl::OUString SAL_CALL    getServiceName() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    // XRefreshable
    virtual void SAL_CALL refresh() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addRefreshListener(const ::com::sun::star::uno::Reference< ::com::sun::star::util::XRefreshListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeRefreshListener(const ::com::sun::star::uno::Reference< ::com::sun::star::util::XRefreshListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);

    // OAggregationArrayUsageHelper
    virtual void fillProperties(
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps,
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
        ) const;
    IMPLEMENT_INFO_SERVICE()

    // XEventListener
    virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);

protected:
    // OBoundControlModel overridables
    virtual ::com::sun::star::uno::Any
                            translateDbColumnToControlValue( );
    virtual ::com::sun::star::uno::Any
                            translateExternalValueToControlValue( );
    virtual ::com::sun::star::uno::Any
                            translateControlValueToExternalValue( );
    virtual sal_Bool        commitControlValueToDbColumn( bool _bPostReset );

    virtual void            onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
    virtual void            onDisconnectedDbColumn();
    virtual void            onConnectedExternalValue( );

    virtual ::com::sun::star::uno::Any
                            getDefaultForReset() const;

    virtual sal_Bool        approveValueBinding( const ::com::sun::star::uno::Reference< ::drafts::com::sun::star::form::XValueBinding >& _rxBinding );

    // OEntryListHelper overriables
    virtual void    stringItemListChanged( );
    virtual void    connectedExternalListSource( );
    virtual void    disconnectedExternalListSource( );

protected:
    DECLARE_XCLONEABLE();

private:
    void        loadData();

    /**
    @precond we don't actually have an external list source
    */
    void        implRefreshListFromDbBinding( );
};

//==================================================================
//= OListBoxControl
//==================================================================
typedef ::cppu::ImplHelper3<    ::com::sun::star::awt::XFocusListener,
                                ::com::sun::star::awt::XItemListener,
                                ::com::sun::star::form::XChangeBroadcaster > OListBoxControl_BASE;

class OListBoxControl   :public OBoundControl
                        ,public OListBoxControl_BASE
{
    ::cppu::OInterfaceContainerHelper       m_aChangeListeners;

    ::com::sun::star::uno::Any              m_aCurrentSelection;
    Timer                                   m_aChangeTimer;

protected:
    // UNO Anbindung
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>   _getTypes();

public:
    OListBoxControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
    virtual ~OListBoxControl();

    // UNO Anbindung
    DECLARE_UNO3_AGG_DEFAULTS(OListBoxControl, OBoundControl);
    virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);

// XServiceInfo
    IMPLEMENTATION_NAME(OListBoxControl);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

// XChangeBroadcaster
    virtual void SAL_CALL addChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XChangeListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XChangeListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException);

// XFocusListener
    virtual void SAL_CALL focusGained(const ::com::sun::star::awt::FocusEvent& _rEvent) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL focusLost(const ::com::sun::star::awt::FocusEvent& _rEvent) throw(::com::sun::star::uno::RuntimeException);

// XItemListener
    virtual void SAL_CALL itemStateChanged(const ::com::sun::star::awt::ItemEvent& _rEvent) throw(::com::sun::star::uno::RuntimeException);

// XEventListener
    virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException);

// OComponentHelper
    virtual void SAL_CALL disposing();

private:
    DECL_LINK( OnTimeout, void* );
};

//.........................................................................
}
//.........................................................................

#endif // _FORMS_LISTBOX_HXX_

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: langselect.cxx,v $
 *
 *  $Revision: 1.10 $
 *  last change: $Author: rt $ $Date: 2004-08-20 13:00:26 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "app.hxx"
#include "langselect.hxx"
#include "langselect.hrc"
#include <stdio.h>

#ifndef _RTL_STRING_HXX
#include <rtl/string.hxx>
#endif
#ifndef _SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef _TOOLS_RESID_HXX
#include <tools/resid.hxx>
#endif
#ifndef _TOOLS_ISOLANG_HXX
#include <tools/isolang.hxx>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/lang/XLocalizable.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <rtl/locale.hxx>
#ifndef INCLUDED_RTL_INSTANCE_HXX
#include <rtl/instance.hxx>
#endif
#include <osl/process.h>

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace com::sun::star::beans;

namespace desktop {

LanguageSelectionDialog::LanguageSelectionDialog(ResMgr *pResMgr) :
    ModalDialog(NULL,ResId(DLG_LANGSELECT, pResMgr)),
    m_aText(this, ResId(TXT_DLG_LANGSELECT, pResMgr)),
    m_aListBox(this, ResId(LST_DLG_LANGSELECT, pResMgr)),
    m_aButton(this, ResId(BTN_DLG_LANGSELECT_OK, pResMgr))
{
    FreeResource();
}

namespace { struct lLanguages : public rtl::Static<IsoList, lLanguages> {}; }

// execute the language selection
// display a dialog if more than one language is installed
// XXX this is a temporary solution
static sal_Bool bFoundLanguage = sal_False;
//static LanguageType aFoundLanguageType = LANGUAGE_DONTKNOW;
static OUString aFoundLanguage;

Locale LanguageSelection::IsoStringToLocale(const OUString& str)
{
    Locale l;
    sal_Int32 index=0;
    l.Language = str.getToken(0, '-', index);
    if (index >= 0) l.Country = str.getToken(0, '-', index);
    if (index >= 0) l.Variant = str.getToken(0, '-', index);
    return l;
}

void LanguageSelection::prepareLanguage()
{
    // XXX make everything works without assertions in first run
    // in multi-language installations, some things might fail in first run
    if (getUserLanguage().getLength() > 0) return;
    IsoList l = getInstalledIsoLanguages();
    if (l.size() >= 1)
    {
        // throw any away existing default config
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XLocalizable > theConfigProvider(
            theMSF->createInstance( sConfigSrvc ),UNO_QUERY );
        OSL_ENSURE(theConfigProvider.is(), "cannot localize config manager.");
        if (theConfigProvider.is())
        {
            OUString aLocaleString = *l.begin();
            Locale loc = LanguageSelection::IsoStringToLocale(aLocaleString);
            theConfigProvider->setLocale(loc);
        }
    }
}

OUString LanguageSelection::getLanguageString()
{

    if (bFoundLanguage)
        return aFoundLanguage;

    // check whether there was aleady a language selected by the user
    OUString aUserLanguage = getUserLanguage();
    if (aUserLanguage.getLength() > 0 )
    {
        bFoundLanguage = sal_True;
        aFoundLanguage = aUserLanguage;
        // return aFoundLanguageType;
        // we can not return yet, we need to check whether this instance supports
        // the language that was previously chosen by the user...
    }

    // fill list
    IsoList &rLanguages = lLanguages::get();
    if (rLanguages.size() < 1)
        rLanguages = getInstalledIsoLanguages();
    // check whether found language is available
    if (bFoundLanguage)
    {
        IsoList::const_iterator iLang = rLanguages.begin();
        while (iLang != rLanguages.end())
        {
            if (iLang->equals(aFoundLanguage))
                return aFoundLanguage;
            else
                iLang++;
        }
    }
    if (rLanguages.size() > 1) {
        // are there multiple languages installed?
        // get resource
        rtl::OString aMgrName = OString("langselect") + OString::valueOf((sal_Int32)SUPD, 10);
        ::com::sun::star::lang::Locale aLocale;
        ResMgr* pResMgr = ResMgr::SearchCreateResMgr( aMgrName, aLocale );
        LanguageSelectionDialog lsd(pResMgr);
        StrList languages(getLanguageStrings(rLanguages));
        for (StrList::iterator str_iter = languages.begin(); str_iter != languages.end(); str_iter++)
        {
            lsd.m_aListBox.InsertEntry(*str_iter);
        }

        lsd.Execute();
        short nSelected = lsd.m_aListBox.GetSelectEntryPos();
        IsoList::const_iterator i = rLanguages.begin();
        for (sal_Int32 n=0; n<nSelected; n++) i++;
        bFoundLanguage = sal_True;
        aFoundLanguage = *i;
        return aFoundLanguage;
    } else {
        // if there is only one language, use it
        if (rLanguages.size() == 1) {
            bFoundLanguage = sal_True;
            aFoundLanguage = *(rLanguages.begin());
            return aFoundLanguage;
        } else {
            // last resort
            // don't save
            return ConvertLanguageToIsoString((LanguageType) SvtPathOptions().SubstituteVariable(
                String::CreateFromAscii("$(langid)")).ToInt32()) ;
            /*
            ::com::sun::star::lang::Locale aLocale;
            OUString aLocString( aLocale.Language );
            if ( aLocale.Country.getLength() != 0 )
            {
                aLocString += OUString::createFromAscii("-")
                                + aLocale.Country;
                if ( aLocale.Variant.getLength() != 0 )
                {
                    aLocString += OUString::createFromAscii("-")
                                    + aLocale.Variant;
                }
            }
            return aLocString;
            */
        }
    }
}

// Get the localized selection strings for the list of languages
StrList LanguageSelection::getLanguageStrings(const IsoList& langLst)
{
    StrList aList;
    rtl::OString aMgrName = OString("langselect") + OString::valueOf((sal_Int32)SUPD, 10);
    for (IsoList::const_iterator lang_iter = langLst.begin(); lang_iter != langLst.end(); lang_iter++)
    {
        rtl::OUString lang = static_cast<OUString>(*lang_iter);
        ::com::sun::star::lang::Locale aLocale = LanguageSelection::IsoStringToLocale(lang);
        ResMgr* pResMgr = ResMgr::SearchCreateResMgr( aMgrName, aLocale );
        if (pResMgr != NULL) {
            String aString(ResId(STR_LANGSELECT, pResMgr));
            aList.push_back(aString);
            delete pResMgr;
        }
    }
    return aList;
}

// get a language choosen by the user
OUString LanguageSelection::getUserLanguage()
{
    OUString aLanguage;
    try{

        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
        OUString sConfigURL = OUString::createFromAscii("org.openoffice.Setup/L10N/");
        OUString sLocales = OUString::createFromAscii("ooLocale");

        // get configuration provider
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY );
        // check provider
        if (!theConfigProvider.is()) return aLanguage;

        // access the provider
        Sequence< Any > theArgs(1);
        theArgs[ 0 ] <<= sConfigURL;
        Reference< XNameAccess > theNameAccess = Reference< XNameAccess > (
                theConfigProvider->createInstanceWithArguments(
                sAccessSrvc, theArgs ), UNO_QUERY );
        // check access
        if (!theNameAccess.is()) return aLanguage;
        // run query
        Any aResult = theNameAccess->getByName( sLocales );
        OUString aLangString;
        if (aResult >>= aLangString)
        {
            aLanguage = aLangString;
        }
    } catch (com::sun::star::uno::Exception)
    {
        // didn't work - return dontknow
        return aLanguage;
    }
    return aLanguage;
}

// get a list with the languages that are installed
IsoList LanguageSelection::getInstalledIsoLanguages()
{
    IsoList aList;
    // read language list from org.openoffice.Setup/Office/ooSetupLocales
    try{
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
        OUString sConfigURL = OUString::createFromAscii("org.openoffice.Setup/Office/InstalledLocales");

        // get configuration provider
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY );
        // check provider
        if (!theConfigProvider.is()) return aList;

        // access the provider
        Sequence< Any > theArgs(1);
        theArgs[ 0 ] <<= sConfigURL;
        Reference< XNameAccess > theNameAccess = Reference< XNameAccess > (
                theConfigProvider->createInstanceWithArguments(
                sAccessSrvc, theArgs ), UNO_QUERY );
        //check access
        if (!theNameAccess.is()) return aList;

        Sequence< OUString > aLangSeq = theNameAccess->getElementNames();

        for (int i=0; i<aLangSeq.getLength(); i++)
               aList.push_back(aLangSeq[i]);
    } catch (com::sun::star::uno::Exception)
    {
        // didn't work - return empty list
    }
    return aList;
}

/*
// get a list with the languages that are installed
LangList LanguageSelection::getInstalledLanguages()
{
    LangList aList;
    // read language list from org.openoffice.Setup/Office/ooSetupLocales
    try{
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
        OUString sConfigURL = OUString::createFromAscii("org.openoffice.Setup/Office/InstalledLocales");

        // get configuration provider
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY );
        // check provider
        if (!theConfigProvider.is()) return aList;

        // access the provider
        Sequence< Any > theArgs(1);
        theArgs[ 0 ] <<= sConfigURL;
        Reference< XNameAccess > theNameAccess = Reference< XNameAccess > (
                theConfigProvider->createInstanceWithArguments(
                sAccessSrvc, theArgs ), UNO_QUERY );
        //check access
        if (!theNameAccess.is()) return aList;

        Sequence< OUString > aLangSeq = theNameAccess->getElementNames();

        for (int i=0; i<aLangSeq.getLength(); i++)
            aList.push_back(ConvertIsoStringToLanguage(aLangSeq[i]));

    } catch (com::sun::star::uno::Exception&)
    {
        // didn't work - return empty list
    }
    return aList;
}
*/
} // namespace desktop
<commit_msg>INTEGRATION: CWS syssettings01 (1.7.26); FILE MERGED 2004/08/04 11:39:16 lo 1.7.26.5: #i32207# select UI language from Language Options dialog 2004/08/03 15:39:32 lo 1.7.26.4: #i32207# select UI language from Language Options dialog 2004/08/03 08:25:29 lo 1.7.26.3: #i8452# language selections through tools/options 2004/08/02 08:36:04 obr 1.7.26.2: RESYNC: (1.7-1.9); FILE MERGED 2004/07/30 16:31:39 lo 1.7.26.1: #i32207# select UI language from Language Options dialog<commit_after>/*************************************************************************
 *
 *  $RCSfile: langselect.cxx,v $
 *
 *  $Revision: 1.11 $
 *  last change: $Author: rt $ $Date: 2004-08-20 14:23:23 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "app.hxx"
#include "langselect.hxx"
#include <stdio.h>

#ifndef _RTL_STRING_HXX
#include <rtl/string.hxx>
#endif
#ifndef _SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef _TOOLS_RESID_HXX
#include <tools/resid.hxx>
#endif
#ifndef _TOOLS_ISOLANG_HXX
#include <tools/isolang.hxx>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/util/XChangesBatch.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/lang/XLocalizable.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <rtl/locale.hxx>
#ifndef INCLUDED_RTL_INSTANCE_HXX
#include <rtl/instance.hxx>
#endif
#include <osl/process.h>

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace com::sun::star::beans;
using namespace com::sun::star::util;

namespace desktop {

sal_Bool LanguageSelection::bFoundLanguage = sal_False;
OUString LanguageSelection::aFoundLanguage;
const OUString LanguageSelection::usFallbackLanguage = OUString::createFromAscii("en-US");

Locale LanguageSelection::IsoStringToLocale(const OUString& str)
{
    Locale l;
    sal_Int32 index=0;
    l.Language = str.getToken(0, '-', index);
    if (index >= 0) l.Country = str.getToken(0, '-', index);
    if (index >= 0) l.Variant = str.getToken(0, '-', index);
    return l;
}

void LanguageSelection::prepareLanguage()
{
    OUString aLocaleString = getLanguageString();
    OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
    Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
    try
    {

        Reference< XLocalizable > theConfigProvider(
            theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );
        Locale loc = LanguageSelection::IsoStringToLocale(aLocaleString);
        theConfigProvider->setLocale(loc);
        Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Setup/L10N/", sal_True), UNO_QUERY_THROW);
        xProp->setPropertyValue(OUString::createFromAscii("ooLocale"), makeAny(aLocaleString));
        Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
    }
    catch (Exception& e)
    {
        OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
        OSL_ENSURE(sal_False, aMsg.getStr());

    }
}

OUString LanguageSelection::getLanguageString()
{
    // did we already find a language?
    if (bFoundLanguage)
        return aFoundLanguage;
    // check whether the user has selected a specific language
    OUString aUserLanguage = getUserLanguage();
    if (aUserLanguage.getLength() > 0 )
    {
        if (isInstalledLanguage(aUserLanguage))
        {
            // all is well
            bFoundLanguage = sal_True;
            aFoundLanguage = aUserLanguage;
            return aFoundLanguage;
        }
        else
        {
            // selected language is not/no longer installed
            resetUserLanguage();
        }
    }
    // try to use system default
    aUserLanguage = getSystemLanguage();
    if (isInstalledLanguage(aUserLanguage, sal_False))
    {
        // great, system default language is available
        bFoundLanguage = sal_True;
        aFoundLanguage = aUserLanguage;
        return aFoundLanguage;
    }
    // fallback 1: en-US
    OUString usFB = usFallbackLanguage;
    if (isInstalledLanguage(usFB))
    {
        bFoundLanguage = sal_True;
        aFoundLanguage = usFallbackLanguage;
        return aFoundLanguage;
    }
    // falback didn't work use first installed language
    aUserLanguage = getFirstInstalledLanguage();
    bFoundLanguage = sal_True;
    aFoundLanguage = aUserLanguage;
    return aFoundLanguage;
}

Reference< XNameAccess > LanguageSelection::getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate)
{
    Reference< XNameAccess > xNameAccess;
    try{
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        OUString sAccessSrvc;
        if (bUpdate)
            sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess");
        else
            sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");

        OUString sConfigURL = OUString::createFromAscii(pPath);

        // get configuration provider
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );

        // access the provider
        Sequence< Any > theArgs(1);
        theArgs[ 0 ] <<= sConfigURL;
        xNameAccess = Reference< XNameAccess > (
                theConfigProvider->createInstanceWithArguments(
                sAccessSrvc, theArgs ), UNO_QUERY_THROW );
    } catch (com::sun::star::uno::Exception& e)
    {
        OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
        OSL_ENSURE(sal_False, aMsg.getStr());
    }
    return xNameAccess;
}

Sequence< OUString > LanguageSelection::getInstalledLanguages()
{
    Sequence< OUString > seqLanguages;
    Reference< XNameAccess > xAccess = getConfigAccess("org.openoffice.Setup/Office/InstalledLocales", sal_False);
    if (!xAccess.is()) return seqLanguages;
    seqLanguages = xAccess->getElementNames();
    return seqLanguages;
}

sal_Bool LanguageSelection::isInstalledLanguage(OUString& usLocale, sal_Bool bExact)
{
    sal_Bool bInstalled = sal_False;
    Sequence< OUString > seqLanguages = getInstalledLanguages();
    for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
    {
        if (usLocale.equals(seqLanguages[i]))
        {
            bInstalled = sal_True;
            break;
        }
    }

    if (!bInstalled && !bExact)
    {
        // no exact match was found, well try to find a substitute
        Locale aLocale = IsoStringToLocale(usLocale);
        Locale aInstalledLocale;
        for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
        {
            aInstalledLocale = IsoStringToLocale(seqLanguages[i]);
            if (aLocale.Language.equals(aInstalledLocale.Language))
            {
                bInstalled = sal_True;
                usLocale = seqLanguages[i];
                break;
            }
        }
    }
    return bInstalled;
}

OUString LanguageSelection::getFirstInstalledLanguage()
{
    OUString aLanguage;
    Sequence< OUString > seqLanguages = getInstalledLanguages();
    if (seqLanguages.getLength() > 0)
        aLanguage = seqLanguages[0];
    return aLanguage;
}

OUString LanguageSelection::getUserLanguage()
{
    OUString aUserLanguage;
    Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_False));
    if (xAccess.is())
    {
        xAccess->getByName(OUString::createFromAscii("UILocale")) >>= aUserLanguage;
    }
    return aUserLanguage;
}

OUString LanguageSelection::getSystemLanguage()
{
    OUString aUserLanguage;
    Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.System/L10N", sal_False));
    if (xAccess.is())
    {
        xAccess->getByName(OUString::createFromAscii("UILocale")) >>= aUserLanguage;
    }
    return aUserLanguage;
}

void LanguageSelection::resetUserLanguage()
{
    try{
       Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_True), UNO_QUERY_THROW);
        xProp->setPropertyValue(OUString::createFromAscii("UILocale"), makeAny(OUString::createFromAscii("")));
        Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
    } catch (com::sun::star::uno::RuntimeException& e)
    {
        OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
        OSL_ENSURE(sal_False, aMsg.getStr());
    }

}

} // namespace desktop
<|endoftext|>