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

#include "ash/system/power/tray_power.h"

#include "ash/shell.h"
#include "ash/system/date/date_view.h"
#include "ash/system/power/power_supply_status.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/tray_constants.h"
#include "base/string_number_conversions.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "grit/ash_strings.h"
#include "grit/ui_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkRect.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/size.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/text_button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "unicode/fieldpos.h"
#include "unicode/fmtable.h"

namespace ash {
namespace internal {

namespace {
// Width and height of battery images.
const int kBatteryImageHeight = 25;
const int kBatteryImageWidth = 25;
// Number of different power states.
const int kNumPowerImages = 15;
}

namespace tray {

// This view is used only for the tray.
class PowerTrayView : public views::ImageView {
 public:
  PowerTrayView() {
    UpdateImage();
  }

  virtual ~PowerTrayView() {
  }

  void UpdatePowerStatus(const PowerSupplyStatus& status) {
    supply_status_ = status;
    // Sanitize.
    if (supply_status_.battery_is_full)
      supply_status_.battery_percentage = 100.0;

    UpdateImage();
    SetVisible(status.battery_is_present);
  }

 private:
  void UpdateImage() {
    SkBitmap image;
    gfx::Image all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
        IDR_AURA_UBER_TRAY_POWER_SMALL);

    int image_index = 0;
    if (supply_status_.battery_percentage >= 100) {
      image_index = kNumPowerImages - 1;
    } else if (!supply_status_.battery_is_present) {
      image_index = kNumPowerImages;
    } else {
      image_index = static_cast<int> (
          supply_status_.battery_percentage / 100.0 *
          (kNumPowerImages - 1));
      image_index =
        std::max(std::min(image_index, kNumPowerImages - 2), 0);
    }

    // TODO(mbolohan): Remove the 2px offset when the assets are centered. See
    // crbug.com/119832.
    SkIRect region = SkIRect::MakeXYWH(
        (supply_status_.line_power_on ? kBatteryImageWidth : 0) + 2,
        image_index * kBatteryImageHeight,
        kBatteryImageWidth - 2, kBatteryImageHeight);
    all.ToSkBitmap()->extractSubset(&image, region);

    SetImage(image);
  }

  PowerSupplyStatus supply_status_;

  DISALLOW_COPY_AND_ASSIGN(PowerTrayView);
};

// This view is used only for the popup.
class PowerPopupView : public views::Label {
 public:
  PowerPopupView() {
    SetHorizontalAlignment(ALIGN_RIGHT);
    UpdateText();
  }

  virtual ~PowerPopupView() {
  }

  void UpdatePowerStatus(const PowerSupplyStatus& status) {
    supply_status_ = status;
    // Sanitize.
    if (supply_status_.battery_is_full)
      supply_status_.battery_percentage = 100.0;

    UpdateText();
  }

 private:
  void UpdateText() {
    base::TimeDelta time = base::TimeDelta::FromSeconds(
        supply_status_.line_power_on ?
        supply_status_.battery_seconds_to_full :
        supply_status_.battery_seconds_to_empty);
    int hour = time.InHours();
    int min = (time - base::TimeDelta::FromHours(hour)).InMinutes();
    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
    if (hour && min) {
      SetText(l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_BATTERY_STATUS,
          base::IntToString16(
              static_cast<int>(supply_status_.battery_percentage)),
          base::IntToString16(hour),
          base::IntToString16(min)));
    } else {
      if (supply_status_.line_power_on) {
        SetText(bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_BATTERY_FULL));
      } else {
        // Completely discharged? ... ha?
        SetText(string16());
      }
    }
  }

  PowerSupplyStatus supply_status_;

  DISALLOW_COPY_AND_ASSIGN(PowerPopupView);
};

}  // namespace tray

TrayPower::TrayPower()
    : power_(NULL),
      power_tray_(NULL) {
}

TrayPower::~TrayPower() {
}

views::View* TrayPower::CreateTrayView(user::LoginStatus status) {
  // There may not be enough information when this is created about whether
  // there is a battery or not. So always create this, and adjust visibility as
  // necessary.
  PowerSupplyStatus power_status =
      ash::Shell::GetInstance()->tray_delegate()->GetPowerSupplyStatus();
  power_tray_.reset(new tray::PowerTrayView());
  power_tray_->UpdatePowerStatus(power_status);
  return power_tray_.get();
}

views::View* TrayPower::CreateDefaultView(user::LoginStatus status) {
  date_.reset(new tray::DateView(tray::DateView::DATE));
  if (status != user::LOGGED_IN_NONE && status != user::LOGGED_IN_LOCKED)
    date_->set_actionable(true);

  views::View* container = new views::View;
  views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kHorizontal,
      kTrayPopupPaddingHorizontal, 10, 0);
  layout->set_spread_blank_space(true);
  container->SetLayoutManager(layout);
  container->set_background(views::Background::CreateSolidBackground(
      SkColorSetRGB(245, 245, 245)));
  container->AddChildView(date_.get());

  PowerSupplyStatus power_status =
      ash::Shell::GetInstance()->tray_delegate()->GetPowerSupplyStatus();
  if (power_status.battery_is_present) {
    power_.reset(new tray::PowerPopupView());
    power_->UpdatePowerStatus(power_status);
    container->AddChildView(power_.get());
  }
  return container;
}

views::View* TrayPower::CreateDetailedView(user::LoginStatus status) {
  return NULL;
}

void TrayPower::DestroyTrayView() {
  power_tray_.reset();
}

void TrayPower::DestroyDefaultView() {
  date_.reset();
  power_.reset();
}

void TrayPower::DestroyDetailedView() {
}

void TrayPower::OnPowerStatusChanged(const PowerSupplyStatus& status) {
  if (power_tray_.get())
    power_tray_->UpdatePowerStatus(status);
  if (power_.get())
    power_->UpdatePowerStatus(status);
}

}  // namespace internal
}  // namespace ash
<commit_msg>ash: Fix the awesome logic for showing battery status.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/power/tray_power.h"

#include "ash/shell.h"
#include "ash/system/date/date_view.h"
#include "ash/system/power/power_supply_status.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/tray_constants.h"
#include "base/string_number_conversions.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "grit/ash_strings.h"
#include "grit/ui_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkRect.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/size.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/text_button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "unicode/fieldpos.h"
#include "unicode/fmtable.h"

namespace ash {
namespace internal {

namespace {
// Width and height of battery images.
const int kBatteryImageHeight = 25;
const int kBatteryImageWidth = 25;
// Number of different power states.
const int kNumPowerImages = 15;
}

namespace tray {

// This view is used only for the tray.
class PowerTrayView : public views::ImageView {
 public:
  PowerTrayView() {
    UpdateImage();
  }

  virtual ~PowerTrayView() {
  }

  void UpdatePowerStatus(const PowerSupplyStatus& status) {
    supply_status_ = status;
    // Sanitize.
    if (supply_status_.battery_is_full)
      supply_status_.battery_percentage = 100.0;

    UpdateImage();
    SetVisible(status.battery_is_present);
  }

 private:
  void UpdateImage() {
    SkBitmap image;
    gfx::Image all = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
        IDR_AURA_UBER_TRAY_POWER_SMALL);

    int image_index = 0;
    if (supply_status_.battery_percentage >= 100) {
      image_index = kNumPowerImages - 1;
    } else if (!supply_status_.battery_is_present) {
      image_index = kNumPowerImages;
    } else {
      image_index = static_cast<int> (
          supply_status_.battery_percentage / 100.0 *
          (kNumPowerImages - 1));
      image_index =
        std::max(std::min(image_index, kNumPowerImages - 2), 0);
    }

    // TODO(mbolohan): Remove the 2px offset when the assets are centered. See
    // crbug.com/119832.
    SkIRect region = SkIRect::MakeXYWH(
        (supply_status_.line_power_on ? kBatteryImageWidth : 0) + 2,
        image_index * kBatteryImageHeight,
        kBatteryImageWidth - 2, kBatteryImageHeight);
    all.ToSkBitmap()->extractSubset(&image, region);

    SetImage(image);
  }

  PowerSupplyStatus supply_status_;

  DISALLOW_COPY_AND_ASSIGN(PowerTrayView);
};

// This view is used only for the popup.
class PowerPopupView : public views::Label {
 public:
  PowerPopupView() {
    SetHorizontalAlignment(ALIGN_RIGHT);
    UpdateText();
  }

  virtual ~PowerPopupView() {
  }

  void UpdatePowerStatus(const PowerSupplyStatus& status) {
    supply_status_ = status;
    // Sanitize.
    if (supply_status_.battery_is_full)
      supply_status_.battery_percentage = 100.0;

    UpdateText();
  }

 private:
  void UpdateText() {
    base::TimeDelta time = base::TimeDelta::FromSeconds(
        supply_status_.line_power_on ?
        supply_status_.battery_seconds_to_full :
        supply_status_.battery_seconds_to_empty);
    int hour = time.InHours();
    int min = (time - base::TimeDelta::FromHours(hour)).InMinutes();
    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
    if (hour || min) {
      SetText(l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_BATTERY_STATUS,
          base::IntToString16(
              static_cast<int>(supply_status_.battery_percentage)),
          base::IntToString16(hour),
          base::IntToString16(min)));
    } else {
      if (supply_status_.line_power_on) {
        SetText(bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_BATTERY_FULL));
      } else {
        // Completely discharged? ... ha?
        SetText(string16());
      }
    }
  }

  PowerSupplyStatus supply_status_;

  DISALLOW_COPY_AND_ASSIGN(PowerPopupView);
};

}  // namespace tray

TrayPower::TrayPower()
    : power_(NULL),
      power_tray_(NULL) {
}

TrayPower::~TrayPower() {
}

views::View* TrayPower::CreateTrayView(user::LoginStatus status) {
  // There may not be enough information when this is created about whether
  // there is a battery or not. So always create this, and adjust visibility as
  // necessary.
  PowerSupplyStatus power_status =
      ash::Shell::GetInstance()->tray_delegate()->GetPowerSupplyStatus();
  power_tray_.reset(new tray::PowerTrayView());
  power_tray_->UpdatePowerStatus(power_status);
  return power_tray_.get();
}

views::View* TrayPower::CreateDefaultView(user::LoginStatus status) {
  date_.reset(new tray::DateView(tray::DateView::DATE));
  if (status != user::LOGGED_IN_NONE && status != user::LOGGED_IN_LOCKED)
    date_->set_actionable(true);

  views::View* container = new views::View;
  views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kHorizontal,
      kTrayPopupPaddingHorizontal, 10, 0);
  layout->set_spread_blank_space(true);
  container->SetLayoutManager(layout);
  container->set_background(views::Background::CreateSolidBackground(
      SkColorSetRGB(245, 245, 245)));
  container->AddChildView(date_.get());

  PowerSupplyStatus power_status =
      ash::Shell::GetInstance()->tray_delegate()->GetPowerSupplyStatus();
  if (power_status.battery_is_present) {
    power_.reset(new tray::PowerPopupView());
    power_->UpdatePowerStatus(power_status);
    container->AddChildView(power_.get());
  }
  return container;
}

views::View* TrayPower::CreateDetailedView(user::LoginStatus status) {
  return NULL;
}

void TrayPower::DestroyTrayView() {
  power_tray_.reset();
}

void TrayPower::DestroyDefaultView() {
  date_.reset();
  power_.reset();
}

void TrayPower::DestroyDetailedView() {
}

void TrayPower::OnPowerStatusChanged(const PowerSupplyStatus& status) {
  if (power_tray_.get())
    power_tray_->UpdatePowerStatus(status);
  if (power_.get())
    power_->UpdatePowerStatus(status);
}

}  // namespace internal
}  // namespace ash
<|endoftext|>


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

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

#include <tools/list.hxx>
#include <tools/table.hxx>

#ifndef _HTMLTOKN_H
#include <svtools/htmltokn.h>
#endif
#ifndef   SVTOOLS_ASYNCLINK_HXX
#include <svtools/asynclink.hxx>
#endif

#ifndef GCC
#endif

#include "docinf.hxx"

#define _SVSTDARR_USHORTS
#define _SVSTDARR_ULONGS
#include <svtools/svstdarr.hxx>

#include "sfx.hrc"

#include "frmhtml.hxx"
#include "docfile.hxx"
#include "viewfrm.hxx"
#include "evntconf.hxx"
#include "request.hxx"
#include "fcontnr.hxx"
#include "sfxtypes.hxx"

#define SFX_HTMLFRMSIZE_REL 0x0001
#define SFX_HTMLFRMSIZE_PERCENT 0x0002

static sal_Char __READONLY_DATA sHTML_SC_yes[] =    "YES";
static sal_Char __READONLY_DATA sHTML_SC_no[] =     "NO";
static sal_Char __READONLY_DATA sHTML_SC_auto[] =   "AUTO";

#define HTML_O_READONLY "READONLY"
#define HTML_O_EDIT     "EDIT"

static HTMLOptionEnum __READONLY_DATA aScollingTable[] =
{
    { sHTML_SC_yes,     ScrollingYes    },
    { sHTML_SC_no,      ScrollingNo     },
    { sHTML_SC_auto,    ScrollingAuto   },
    { 0,                0               }
};

void SfxFrameHTMLParser::ParseFrameOptions( SfxFrameDescriptor *pFrame, const HTMLOptions *pOptions, const String& rBaseURL )
{
    // die Optionen holen und setzen
    Size aMargin( pFrame->GetMargin() );

    // MIB 15.7.97: Netscape scheint marginwidth auf 0 zu setzen, sobald
    // marginheight gesetzt wird und umgekehrt. Machen wir jetzt wegen
    // bug #41665# auch so.
    // Netscape l"a\st aber ein direktes Setzen auf 0 nicht zu, IE4.0 schon.
    // Den Bug machen wir nicht mit!
    BOOL bMarginWidth = FALSE, bMarginHeight = FALSE;

    USHORT nArrLen = pOptions->Count();
    for ( USHORT i=0; i<nArrLen; i++ )
    {
        const HTMLOption *pOption = (*pOptions)[i];
        switch( pOption->GetToken() )
        {
        case HTML_O_BORDERCOLOR:
            {
                Color aColor;
                pOption->GetColor( aColor );
                pFrame->SetWallpaper( Wallpaper( aColor ) );
                break;
            }
        case HTML_O_SRC:
            pFrame->SetURL(
                String(
                    INetURLObject::GetAbsURL(
                        rBaseURL, pOption->GetString())) );
            break;
        case HTML_O_NAME:
            pFrame->SetName( pOption->GetString() );
            break;
        case HTML_O_MARGINWIDTH:
            aMargin.Width() = pOption->GetNumber();

//          if( aMargin.Width() < 1 )
//              aMargin.Width() = 1;
            if( !bMarginHeight )
                aMargin.Height() = 0;
            bMarginWidth = TRUE;
            break;
        case HTML_O_MARGINHEIGHT:
            aMargin.Height() = pOption->GetNumber();

//          if( aMargin.Height() < 1 )
//              aMargin.Height() = 1;
            if( !bMarginWidth )
                aMargin.Width() = 0;
            bMarginHeight = TRUE;
            break;
        case HTML_O_SCROLLING:
            pFrame->SetScrollingMode(
                (ScrollingMode)pOption->GetEnum( aScollingTable,
                                                 ScrollingAuto ) );
            break;
        case HTML_O_FRAMEBORDER:
        {
            String aStr = pOption->GetString();
            BOOL bBorder = TRUE;
            if ( aStr.EqualsIgnoreCaseAscii("NO") ||
                 aStr.EqualsIgnoreCaseAscii("0") )
                bBorder = FALSE;
            pFrame->SetFrameBorder( bBorder );
            break;
        }
        case HTML_O_NORESIZE:
            pFrame->SetResizable( FALSE );
            break;
        default:
            if ( pOption->GetTokenString().EqualsIgnoreCaseAscii(
                                                        HTML_O_READONLY ) )
            {
                String aStr = pOption->GetString();
                BOOL bReadonly = TRUE;
                if ( aStr.EqualsIgnoreCaseAscii("FALSE") )
                    bReadonly = FALSE;
                pFrame->SetReadOnly( bReadonly );
            }
            else if ( pOption->GetTokenString().EqualsIgnoreCaseAscii(
                                                        HTML_O_EDIT ) )
            {
                String aStr = pOption->GetString();
                BOOL bEdit = TRUE;
                if ( aStr.EqualsIgnoreCaseAscii("FALSE") )
                    bEdit = FALSE;
                pFrame->SetEditable( bEdit );
            }

            break;
        }
    }

    pFrame->SetMargin( aMargin );
}
<commit_msg>INTEGRATION: CWS vgbugs07 (1.11.218); FILE MERGED 2007/06/04 13:34:43 vg 1.11.218.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: frmhtml.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 23:03:11 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include <tools/list.hxx>
#include <tools/table.hxx>

#ifndef _HTMLTOKN_H
#include <svtools/htmltokn.h>
#endif
#ifndef   SVTOOLS_ASYNCLINK_HXX
#include <svtools/asynclink.hxx>
#endif

#ifndef GCC
#endif

#include <sfx2/docinf.hxx>

#define _SVSTDARR_USHORTS
#define _SVSTDARR_ULONGS
#include <svtools/svstdarr.hxx>

#include <sfx2/sfx.hrc>

#include <sfx2/frmhtml.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/evntconf.hxx>
#include <sfx2/request.hxx>
#include <sfx2/fcontnr.hxx>
#include "sfxtypes.hxx"

#define SFX_HTMLFRMSIZE_REL 0x0001
#define SFX_HTMLFRMSIZE_PERCENT 0x0002

static sal_Char __READONLY_DATA sHTML_SC_yes[] =    "YES";
static sal_Char __READONLY_DATA sHTML_SC_no[] =     "NO";
static sal_Char __READONLY_DATA sHTML_SC_auto[] =   "AUTO";

#define HTML_O_READONLY "READONLY"
#define HTML_O_EDIT     "EDIT"

static HTMLOptionEnum __READONLY_DATA aScollingTable[] =
{
    { sHTML_SC_yes,     ScrollingYes    },
    { sHTML_SC_no,      ScrollingNo     },
    { sHTML_SC_auto,    ScrollingAuto   },
    { 0,                0               }
};

void SfxFrameHTMLParser::ParseFrameOptions( SfxFrameDescriptor *pFrame, const HTMLOptions *pOptions, const String& rBaseURL )
{
    // die Optionen holen und setzen
    Size aMargin( pFrame->GetMargin() );

    // MIB 15.7.97: Netscape scheint marginwidth auf 0 zu setzen, sobald
    // marginheight gesetzt wird und umgekehrt. Machen wir jetzt wegen
    // bug #41665# auch so.
    // Netscape l"a\st aber ein direktes Setzen auf 0 nicht zu, IE4.0 schon.
    // Den Bug machen wir nicht mit!
    BOOL bMarginWidth = FALSE, bMarginHeight = FALSE;

    USHORT nArrLen = pOptions->Count();
    for ( USHORT i=0; i<nArrLen; i++ )
    {
        const HTMLOption *pOption = (*pOptions)[i];
        switch( pOption->GetToken() )
        {
        case HTML_O_BORDERCOLOR:
            {
                Color aColor;
                pOption->GetColor( aColor );
                pFrame->SetWallpaper( Wallpaper( aColor ) );
                break;
            }
        case HTML_O_SRC:
            pFrame->SetURL(
                String(
                    INetURLObject::GetAbsURL(
                        rBaseURL, pOption->GetString())) );
            break;
        case HTML_O_NAME:
            pFrame->SetName( pOption->GetString() );
            break;
        case HTML_O_MARGINWIDTH:
            aMargin.Width() = pOption->GetNumber();

//          if( aMargin.Width() < 1 )
//              aMargin.Width() = 1;
            if( !bMarginHeight )
                aMargin.Height() = 0;
            bMarginWidth = TRUE;
            break;
        case HTML_O_MARGINHEIGHT:
            aMargin.Height() = pOption->GetNumber();

//          if( aMargin.Height() < 1 )
//              aMargin.Height() = 1;
            if( !bMarginWidth )
                aMargin.Width() = 0;
            bMarginHeight = TRUE;
            break;
        case HTML_O_SCROLLING:
            pFrame->SetScrollingMode(
                (ScrollingMode)pOption->GetEnum( aScollingTable,
                                                 ScrollingAuto ) );
            break;
        case HTML_O_FRAMEBORDER:
        {
            String aStr = pOption->GetString();
            BOOL bBorder = TRUE;
            if ( aStr.EqualsIgnoreCaseAscii("NO") ||
                 aStr.EqualsIgnoreCaseAscii("0") )
                bBorder = FALSE;
            pFrame->SetFrameBorder( bBorder );
            break;
        }
        case HTML_O_NORESIZE:
            pFrame->SetResizable( FALSE );
            break;
        default:
            if ( pOption->GetTokenString().EqualsIgnoreCaseAscii(
                                                        HTML_O_READONLY ) )
            {
                String aStr = pOption->GetString();
                BOOL bReadonly = TRUE;
                if ( aStr.EqualsIgnoreCaseAscii("FALSE") )
                    bReadonly = FALSE;
                pFrame->SetReadOnly( bReadonly );
            }
            else if ( pOption->GetTokenString().EqualsIgnoreCaseAscii(
                                                        HTML_O_EDIT ) )
            {
                String aStr = pOption->GetString();
                BOOL bEdit = TRUE;
                if ( aStr.EqualsIgnoreCaseAscii("FALSE") )
                    bEdit = FALSE;
                pFrame->SetEditable( bEdit );
            }

            break;
        }
    }

    pFrame->SetMargin( aMargin );
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2010 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
// $Id$

#include "sqlite_datasource.hpp"
#include "sqlite_featureset.hpp"

// mapnik
#include <mapnik/ptree_helpers.hpp>
#include <mapnik/sql_utils.hpp>

// boost
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <boost/filesystem/operations.hpp>

using boost::lexical_cast;
using boost::bad_lexical_cast;

using mapnik::datasource;
using mapnik::parameters;

DATASOURCE_PLUGIN(sqlite_datasource)

using mapnik::box2d;
using mapnik::coord2d;
using mapnik::query;
using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::attribute_descriptor;
using mapnik::datasource_exception;

sqlite_datasource::sqlite_datasource(parameters const& params, bool bind)
   : datasource(params),
     extent_(),
     extent_initialized_(false),
     type_(datasource::Vector),
     table_(*params_.get<std::string>("table","")),
     fields_(*params_.get<std::string>("fields","*")),
     metadata_(*params_.get<std::string>("metadata","")),
     geometry_table_(*params_.get<std::string>("geometry_table","")),
     geometry_field_(*params_.get<std::string>("geometry_field","the_geom")),
     // http://www.sqlite.org/lang_createtable.html#rowid
     key_field_(*params_.get<std::string>("key_field","rowid")),
     row_offset_(*params_.get<int>("row_offset",0)),
     row_limit_(*params_.get<int>("row_limit",0)),
     desc_(*params_.get<std::string>("type"), *params_.get<std::string>("encoding","utf-8")),
     format_(mapnik::wkbGeneric)
{
    boost::optional<std::string> file = params_.get<std::string>("file");
    if (!file) throw datasource_exception("Sqlite Plugin: missing <file> parameter");

    if (table_.empty()) throw mapnik::datasource_exception("Sqlite Plugin: missing <table> parameter");

    boost::optional<std::string> wkb = params_.get<std::string>("wkb_format");
    if (wkb)
    {
        if (*wkb == "spatialite")
            format_ = mapnik::wkbSpatiaLite;
    }

    multiple_geometries_ = *params_.get<mapnik::boolean>("multiple_geometries",false);
    use_spatial_index_ = *params_.get<mapnik::boolean>("use_spatial_index",true);

    boost::optional<std::string> ext  = params_.get<std::string>("extent");
    if (ext) extent_initialized_ = extent_.from_string(*ext);

    boost::optional<std::string> base = params_.get<std::string>("base");
    if (base)
        dataset_name_ = *base + "/" + *file;
    else
        dataset_name_ = *file;

    if (bind)
    {
        this->bind();
    }
}

void sqlite_datasource::bind() const
{
    if (is_bound_) return;

    if (!boost::filesystem::exists(dataset_name_))
        throw datasource_exception("Sqlite Plugin: " + dataset_name_ + " does not exist");

    dataset_ = new sqlite_connection (dataset_name_);

    if(geometry_table_.empty())
    {
        geometry_table_ = mapnik::table_from_sql(table_);
    }

    if (use_spatial_index_)
    {
        std::ostringstream s;
        s << "SELECT COUNT (*) FROM sqlite_master";
        s << " WHERE LOWER(name) = LOWER('idx_" << geometry_table_ << "_" << geometry_field_ << "')";
        boost::scoped_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));
        if (rs->is_valid () && rs->step_next())
        {
            use_spatial_index_ = rs->column_integer (0) == 1;
        }

        if (!use_spatial_index_)
           std::clog << "Sqlite Plugin: spatial index not found for table '"
             << geometry_table_ << "'" << std::endl;
    }

    if (metadata_ != "" && !extent_initialized_)
    {
        std::ostringstream s;
        s << "SELECT xmin, ymin, xmax, ymax FROM " << metadata_;
        s << " WHERE LOWER(f_table_name) = LOWER('" << geometry_table_ << "')";
        boost::scoped_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));
        if (rs->is_valid () && rs->step_next())
        {
            double xmin = rs->column_double (0);
            double ymin = rs->column_double (1);
            double xmax = rs->column_double (2);
            double ymax = rs->column_double (3);

            extent_.init (xmin,ymin,xmax,ymax);
            extent_initialized_ = true;
        }
    }

    if (!extent_initialized_ && use_spatial_index_)
    {
        std::ostringstream s;
        s << "SELECT MIN(xmin), MIN(ymin), MAX(xmax), MAX(ymax) FROM "
        << "idx_" << geometry_table_ << "_" << geometry_field_;
        boost::scoped_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));
        if (rs->is_valid () && rs->step_next())
        {
            double xmin = rs->column_double (0);
            double ymin = rs->column_double (1);
            double xmax = rs->column_double (2);
            double ymax = rs->column_double (3);

            extent_.init (xmin,ymin,xmax,ymax);
            extent_initialized_ = true;
        }
    }

    {

        // should we deduce column names and types using PRAGMA?
        bool use_pragma_table_info = true;

        if (table_ != geometry_table_)
        {
            // if 'table_' is a subquery then we try to deduce names
            // and types from the first row returned from that query
            use_pragma_table_info = false;
        }

        if (!use_pragma_table_info)
        {
            std::ostringstream s;
            s << "SELECT " << fields_ << " FROM (" << table_ << ") LIMIT 1";

            boost::scoped_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));
            if (rs->is_valid () && rs->step_next())
            {
                for (int i = 0; i < rs->column_count (); ++i)
                {
                   const int type_oid = rs->column_type (i);
                   const char* fld_name = rs->column_name (i);
                   switch (type_oid)
                   {
                      case SQLITE_INTEGER:
                         desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
                         break;

                      case SQLITE_FLOAT:
                         desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
                         break;

                      case SQLITE_TEXT:
                         desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
                         break;

                      case SQLITE_NULL:
                         // sqlite reports based on value, not actual column type unless
                         // PRAGMA table_info is used so here we assume the column is a string
                         // which is a lesser evil than altogether dropping the column
                         desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));

                      case SQLITE_BLOB:
                         break;

                      default:
    #ifdef MAPNIK_DEBUG
                         std::clog << "Sqlite Plugin: unknown type_oid=" << type_oid << std::endl;
    #endif
                         break;
                    }
                }
            }
            else
            {
                // if we do not have at least a row and
                // we cannot determine the right columns types and names
                // as all column_type are SQLITE_NULL
                // so we fallback to using PRAGMA table_info
                use_pragma_table_info = true;
            }
        }

        // TODO - ensure that the supplied key_field is a valid "integer primary key"
        desc_.add_descriptor(attribute_descriptor("rowid",mapnik::Integer));

        if (use_pragma_table_info)
        {
            std::ostringstream s;
            s << "PRAGMA table_info(" << geometry_table_ << ")";
            boost::scoped_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));
            while (rs->is_valid () && rs->step_next())
            {
                const char* fld_name = rs->column_text(1);
                std::string fld_type(rs->column_text(2));
                boost::algorithm::to_lower(fld_type);

                // see 2.1 "Column Affinity" at http://www.sqlite.org/datatype3.html

                if (boost::algorithm::contains(fld_type,"int"))
                {
                    desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
                }
                else if (boost::algorithm::contains(fld_type,"text") ||
                         boost::algorithm::contains(fld_type,"char") ||
                         boost::algorithm::contains(fld_type,"clob"))
                {
                    desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
                }
                else if (boost::algorithm::contains(fld_type,"real") ||
                         boost::algorithm::contains(fld_type,"float") ||
                         boost::algorithm::contains(fld_type,"double"))
                {
                    desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
                }
                //else if (boost::algorithm::contains(fld_type,"blob")
                //     desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
#ifdef MAPNIK_DEBUG
                else
                {
                    // "Column Affinity" says default to "Numeric" but for now we pass..
                    //desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
                    std::clog << "Sqlite Plugin: unknown type_oid=" << fld_type << std::endl;
                }
#endif
            }
        }
    }

    is_bound_ = true;
}

sqlite_datasource::~sqlite_datasource()
{
    if (is_bound_)
    {
        delete dataset_;
    }
}

std::string sqlite_datasource::name()
{
   return "sqlite";
}

int sqlite_datasource::type() const
{
   return type_;
}

box2d<double> sqlite_datasource::envelope() const
{
   if (!is_bound_) bind();
   return extent_;
}

layer_descriptor sqlite_datasource::get_descriptor() const
{
   if (!is_bound_) bind();
   return desc_;
}

featureset_ptr sqlite_datasource::features(query const& q) const
{
   if (!is_bound_) bind();
   if (dataset_)
   {
        mapnik::box2d<double> const& e = q.get_bbox();

        std::ostringstream s;

        s << "SELECT " << geometry_field_ << "," << key_field_;
        std::set<std::string> const& props = q.property_names();
        std::set<std::string>::const_iterator pos = props.begin();
        std::set<std::string>::const_iterator end = props.end();
        while (pos != end)
        {
            s << ",\"" << *pos << "\"";
            ++pos;
        }

        s << " FROM ";

        std::string query (table_);

        if (use_spatial_index_)
        {
           std::ostringstream spatial_sql;
           spatial_sql << std::setprecision(16);
           spatial_sql << " WHERE " << key_field_ << " IN (SELECT pkid FROM idx_" << geometry_table_ << "_" << geometry_field_;
           spatial_sql << " WHERE xmax>=" << e.minx() << " AND xmin<=" << e.maxx() ;
           spatial_sql << " AND ymax>=" << e.miny() << " AND ymin<=" << e.maxy() << ")";
           if (boost::algorithm::ifind_first(query, "WHERE"))
           {
              boost::algorithm::ireplace_first(query, "WHERE", spatial_sql.str() + " AND ");
           }
           else if (boost::algorithm::ifind_first(query, geometry_table_))
           {
              boost::algorithm::ireplace_first(query, table_, table_ + " " + spatial_sql.str());
           }
        }

        s << query ;

        if (row_limit_ > 0) {
            s << " LIMIT " << row_limit_;
        }

        if (row_offset_ > 0) {
            s << " OFFSET " << row_offset_;
        }

#ifdef MAPNIK_DEBUG
        std::clog << "Sqlite Plugin: " << s.str() << std::endl;
#endif

        boost::shared_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));

        return featureset_ptr (new sqlite_featureset(rs, desc_.get_encoding(), format_, multiple_geometries_));
   }

   return featureset_ptr();
}

featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt) const
{
   if (!is_bound_) bind();

   return featureset_ptr();
}

<commit_msg>sqlite plugin: add features_at_point() impl<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2010 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
// $Id$

#include "sqlite_datasource.hpp"
#include "sqlite_featureset.hpp"

// mapnik
#include <mapnik/ptree_helpers.hpp>
#include <mapnik/sql_utils.hpp>

// boost
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <boost/filesystem/operations.hpp>

using boost::lexical_cast;
using boost::bad_lexical_cast;

using mapnik::datasource;
using mapnik::parameters;

DATASOURCE_PLUGIN(sqlite_datasource)

using mapnik::box2d;
using mapnik::coord2d;
using mapnik::query;
using mapnik::featureset_ptr;
using mapnik::layer_descriptor;
using mapnik::attribute_descriptor;
using mapnik::datasource_exception;

sqlite_datasource::sqlite_datasource(parameters const& params, bool bind)
   : datasource(params),
     extent_(),
     extent_initialized_(false),
     type_(datasource::Vector),
     table_(*params_.get<std::string>("table","")),
     fields_(*params_.get<std::string>("fields","*")),
     metadata_(*params_.get<std::string>("metadata","")),
     geometry_table_(*params_.get<std::string>("geometry_table","")),
     geometry_field_(*params_.get<std::string>("geometry_field","the_geom")),
     // http://www.sqlite.org/lang_createtable.html#rowid
     key_field_(*params_.get<std::string>("key_field","rowid")),
     row_offset_(*params_.get<int>("row_offset",0)),
     row_limit_(*params_.get<int>("row_limit",0)),
     desc_(*params_.get<std::string>("type"), *params_.get<std::string>("encoding","utf-8")),
     format_(mapnik::wkbGeneric)
{
    boost::optional<std::string> file = params_.get<std::string>("file");
    if (!file) throw datasource_exception("Sqlite Plugin: missing <file> parameter");

    if (table_.empty()) throw mapnik::datasource_exception("Sqlite Plugin: missing <table> parameter");

    boost::optional<std::string> wkb = params_.get<std::string>("wkb_format");
    if (wkb)
    {
        if (*wkb == "spatialite")
            format_ = mapnik::wkbSpatiaLite;
    }

    multiple_geometries_ = *params_.get<mapnik::boolean>("multiple_geometries",false);
    use_spatial_index_ = *params_.get<mapnik::boolean>("use_spatial_index",true);

    boost::optional<std::string> ext  = params_.get<std::string>("extent");
    if (ext) extent_initialized_ = extent_.from_string(*ext);

    boost::optional<std::string> base = params_.get<std::string>("base");
    if (base)
        dataset_name_ = *base + "/" + *file;
    else
        dataset_name_ = *file;

    if (bind)
    {
        this->bind();
    }
}

void sqlite_datasource::bind() const
{
    if (is_bound_) return;

    if (!boost::filesystem::exists(dataset_name_))
        throw datasource_exception("Sqlite Plugin: " + dataset_name_ + " does not exist");

    dataset_ = new sqlite_connection (dataset_name_);

    if(geometry_table_.empty())
    {
        geometry_table_ = mapnik::table_from_sql(table_);
    }

    if (use_spatial_index_)
    {
        std::ostringstream s;
        s << "SELECT COUNT (*) FROM sqlite_master";
        s << " WHERE LOWER(name) = LOWER('idx_" << geometry_table_ << "_" << geometry_field_ << "')";
        boost::scoped_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));
        if (rs->is_valid () && rs->step_next())
        {
            use_spatial_index_ = rs->column_integer (0) == 1;
        }

        if (!use_spatial_index_)
           std::clog << "Sqlite Plugin: spatial index not found for table '"
             << geometry_table_ << "'" << std::endl;
    }

    if (metadata_ != "" && !extent_initialized_)
    {
        std::ostringstream s;
        s << "SELECT xmin, ymin, xmax, ymax FROM " << metadata_;
        s << " WHERE LOWER(f_table_name) = LOWER('" << geometry_table_ << "')";
        boost::scoped_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));
        if (rs->is_valid () && rs->step_next())
        {
            double xmin = rs->column_double (0);
            double ymin = rs->column_double (1);
            double xmax = rs->column_double (2);
            double ymax = rs->column_double (3);

            extent_.init (xmin,ymin,xmax,ymax);
            extent_initialized_ = true;
        }
    }

    if (!extent_initialized_ && use_spatial_index_)
    {
        std::ostringstream s;
        s << "SELECT MIN(xmin), MIN(ymin), MAX(xmax), MAX(ymax) FROM "
        << "idx_" << geometry_table_ << "_" << geometry_field_;
        boost::scoped_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));
        if (rs->is_valid () && rs->step_next())
        {
            double xmin = rs->column_double (0);
            double ymin = rs->column_double (1);
            double xmax = rs->column_double (2);
            double ymax = rs->column_double (3);

            extent_.init (xmin,ymin,xmax,ymax);
            extent_initialized_ = true;
        }
    }

    {

        // should we deduce column names and types using PRAGMA?
        bool use_pragma_table_info = true;

        if (table_ != geometry_table_)
        {
            // if 'table_' is a subquery then we try to deduce names
            // and types from the first row returned from that query
            use_pragma_table_info = false;
        }

        if (!use_pragma_table_info)
        {
            std::ostringstream s;
            s << "SELECT " << fields_ << " FROM (" << table_ << ") LIMIT 1";

            boost::scoped_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));
            if (rs->is_valid () && rs->step_next())
            {
                for (int i = 0; i < rs->column_count (); ++i)
                {
                   const int type_oid = rs->column_type (i);
                   const char* fld_name = rs->column_name (i);
                   switch (type_oid)
                   {
                      case SQLITE_INTEGER:
                         desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
                         break;

                      case SQLITE_FLOAT:
                         desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
                         break;

                      case SQLITE_TEXT:
                         desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
                         break;

                      case SQLITE_NULL:
                         // sqlite reports based on value, not actual column type unless
                         // PRAGMA table_info is used so here we assume the column is a string
                         // which is a lesser evil than altogether dropping the column
                         desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));

                      case SQLITE_BLOB:
                         break;

                      default:
    #ifdef MAPNIK_DEBUG
                         std::clog << "Sqlite Plugin: unknown type_oid=" << type_oid << std::endl;
    #endif
                         break;
                    }
                }
            }
            else
            {
                // if we do not have at least a row and
                // we cannot determine the right columns types and names
                // as all column_type are SQLITE_NULL
                // so we fallback to using PRAGMA table_info
                use_pragma_table_info = true;
            }
        }

        // TODO - ensure that the supplied key_field is a valid "integer primary key"
        desc_.add_descriptor(attribute_descriptor("rowid",mapnik::Integer));

        if (use_pragma_table_info)
        {
            std::ostringstream s;
            s << "PRAGMA table_info(" << geometry_table_ << ")";
            boost::scoped_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));
            while (rs->is_valid () && rs->step_next())
            {
                const char* fld_name = rs->column_text(1);
                std::string fld_type(rs->column_text(2));
                boost::algorithm::to_lower(fld_type);

                // see 2.1 "Column Affinity" at http://www.sqlite.org/datatype3.html

                if (boost::algorithm::contains(fld_type,"int"))
                {
                    desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
                }
                else if (boost::algorithm::contains(fld_type,"text") ||
                         boost::algorithm::contains(fld_type,"char") ||
                         boost::algorithm::contains(fld_type,"clob"))
                {
                    desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
                }
                else if (boost::algorithm::contains(fld_type,"real") ||
                         boost::algorithm::contains(fld_type,"float") ||
                         boost::algorithm::contains(fld_type,"double"))
                {
                    desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
                }
                //else if (boost::algorithm::contains(fld_type,"blob")
                //     desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
#ifdef MAPNIK_DEBUG
                else
                {
                    // "Column Affinity" says default to "Numeric" but for now we pass..
                    //desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
                    std::clog << "Sqlite Plugin: unknown type_oid=" << fld_type << std::endl;
                }
#endif
            }
        }
    }

    is_bound_ = true;
}

sqlite_datasource::~sqlite_datasource()
{
    if (is_bound_)
    {
        delete dataset_;
    }
}

std::string sqlite_datasource::name()
{
   return "sqlite";
}

int sqlite_datasource::type() const
{
   return type_;
}

box2d<double> sqlite_datasource::envelope() const
{
   if (!is_bound_) bind();
   return extent_;
}

layer_descriptor sqlite_datasource::get_descriptor() const
{
   if (!is_bound_) bind();
   return desc_;
}

featureset_ptr sqlite_datasource::features(query const& q) const
{
   if (!is_bound_) bind();
   if (dataset_)
   {
        mapnik::box2d<double> const& e = q.get_bbox();

        std::ostringstream s;

        s << "SELECT " << geometry_field_ << "," << key_field_;
        std::set<std::string> const& props = q.property_names();
        std::set<std::string>::const_iterator pos = props.begin();
        std::set<std::string>::const_iterator end = props.end();
        while (pos != end)
        {
            s << ",\"" << *pos << "\"";
            ++pos;
        }

        s << " FROM ";

        std::string query (table_);

        if (use_spatial_index_)
        {
           std::ostringstream spatial_sql;
           spatial_sql << std::setprecision(16);
           spatial_sql << " WHERE " << key_field_ << " IN (SELECT pkid FROM idx_" << geometry_table_ << "_" << geometry_field_;
           spatial_sql << " WHERE xmax>=" << e.minx() << " AND xmin<=" << e.maxx() ;
           spatial_sql << " AND ymax>=" << e.miny() << " AND ymin<=" << e.maxy() << ")";
           if (boost::algorithm::ifind_first(query, "WHERE"))
           {
              boost::algorithm::ireplace_first(query, "WHERE", spatial_sql.str() + " AND ");
           }
           else if (boost::algorithm::ifind_first(query, geometry_table_))
           {
              boost::algorithm::ireplace_first(query, table_, table_ + " " + spatial_sql.str());
           }
        }

        s << query ;

        if (row_limit_ > 0) {
            s << " LIMIT " << row_limit_;
        }

        if (row_offset_ > 0) {
            s << " OFFSET " << row_offset_;
        }

#ifdef MAPNIK_DEBUG
        std::clog << "Sqlite Plugin: " << s.str() << std::endl;
#endif

        boost::shared_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));

        return featureset_ptr (new sqlite_featureset(rs, desc_.get_encoding(), format_, multiple_geometries_));
   }

   return featureset_ptr();
}

featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt) const
{
   if (!is_bound_) bind();

   if (dataset_)
   {
        // TODO - need tolerance
        mapnik::box2d<double> const e(pt.x,pt.y,pt.x,pt.y);

        std::ostringstream s;

        s << "SELECT " << geometry_field_ << "," << key_field_;
        std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
        std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
        while (itr != end)
        {
            std::string fld_name = itr->get_name();
            if (fld_name != key_field_)
                s << ",\"" << itr->get_name() << "\"";
            ++itr;
        }

        s << " FROM ";

        std::string query (table_);

        if (use_spatial_index_)
        {
           std::ostringstream spatial_sql;
           spatial_sql << std::setprecision(16);
           spatial_sql << " WHERE " << key_field_ << " IN (SELECT pkid FROM idx_" << geometry_table_ << "_" << geometry_field_;
           spatial_sql << " WHERE xmax>=" << e.minx() << " AND xmin<=" << e.maxx() ;
           spatial_sql << " AND ymax>=" << e.miny() << " AND ymin<=" << e.maxy() << ")";
           if (boost::algorithm::ifind_first(query, "WHERE"))
           {
              boost::algorithm::ireplace_first(query, "WHERE", spatial_sql.str() + " AND ");
           }
           else if (boost::algorithm::ifind_first(query, geometry_table_))
           {
              boost::algorithm::ireplace_first(query, table_, table_ + " " + spatial_sql.str());
           }
        }

        s << query ;

        if (row_limit_ > 0) {
            s << " LIMIT " << row_limit_;
        }

        if (row_offset_ > 0) {
            s << " OFFSET " << row_offset_;
        }

#ifdef MAPNIK_DEBUG
        std::clog << "Sqlite Plugin: " << s.str() << std::endl;
#endif

        boost::shared_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str()));

        return featureset_ptr (new sqlite_featureset(rs, desc_.get_encoding(), format_, multiple_geometries_));
   }

   return featureset_ptr();
}

<|endoftext|>


<commit_before>//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   xs/test/tstXS.cc
 * \author Thomas M. Evans
 * \date   Fri Jan 31 12:54:58 2014
 * \brief  XS container test.
 * \note   Copyright (C) 2014 Oak Ridge National Laboratory, UT-Battelle, LLC.
 */
//---------------------------------------------------------------------------//

#include "gtest/utils_gtest.hh"

#include "../XS.hh"

//---------------------------------------------------------------------------//
// Test fixture
//---------------------------------------------------------------------------//

// NOTE: the test class name must not contain underscores.
class XS_Test : public testing::Test
{
  protected:
    typedef profugus::XS  XS;
    typedef XS::Vector    Vector;
    typedef XS::Matrix    Matrix;
    typedef XS::OneDArray OneDArray;
    typedef XS::TwoDArray TwoDArray;
    typedef XS::Vec_Int   Vec_Int;

  protected:
    // Initialization that are performed for each test
    void SetUp()
    {
        Ng = 4;

        // build data
        m1_sig.resize(Ng);

        m5_sig.resize(Ng);
        sigf.resize(Ng);
        nusigf.resize(Ng);
        chi.resize(Ng);

        m1_sig[0] = 2.0;
        m1_sig[1] = 3.0;
        m1_sig[2] = 4.0;
        m1_sig[3] = 5.0;

        m5_sig[0] = 20.0;
        m5_sig[1] = 30.0;
        m5_sig[2] = 40.0;
        m5_sig[3] = 50.0;

        sigf[0] = 11.0;
        sigf[1] = 12.0;
        sigf[2] = 13.0;
        sigf[3] = 14.0;

        double nu = 2.4;
        for (int n = 0; n < 4; ++n)
        {
            nusigf[n] = sigf[n] * nu;
        }

        chi[0] = 0.6;
        chi[1] = 0.3;
        chi[2] = 0.1;

        xs.set(1, Ng);
    }

  protected:

    int Ng;

    OneDArray m1_sig;
    OneDArray m5_sig, sigf, nusigf, chi;

    XS xs;

};

//---------------------------------------------------------------------------//
// TESTS
//---------------------------------------------------------------------------//

TEST_F(XS_Test, totals_assignment)
{
    EXPECT_EQ(1, xs.pn_order());
    EXPECT_EQ(4, xs.num_groups());
    EXPECT_EQ(0, xs.num_mat());

    xs.add(1, XS::TOTAL, m1_sig);

    xs.add(5, XS::TOTAL, m5_sig);
    xs.add(5, XS::SIG_F, sigf);
    xs.add(5, XS::NU_SIG_F, nusigf);
    xs.add(5, XS::CHI, chi);

    EXPECT_EQ(0, xs.num_mat());

    xs.complete();

    EXPECT_EQ(2, xs.num_mat());
    EXPECT_EQ(1, xs.pn_order());
    EXPECT_EQ(4, xs.num_groups());

    EXPECT_TRUE(xs.has(1));
    EXPECT_TRUE(xs.has(5));

    Vec_Int mids;
    xs.get_matids(mids);
    EXPECT_EQ(2, mids.size());
    EXPECT_EQ(1, mids[0]);
    EXPECT_EQ(5, mids[1]);

    // material 1
    {
        const Vector &sigt = xs.vector(1, XS::TOTAL);
        EXPECT_EQ(4, sigt.length());

        EXPECT_EQ(2.0, sigt(0));
        EXPECT_EQ(3.0, sigt(1));
        EXPECT_EQ(4.0, sigt(2));
        EXPECT_EQ(5.0, sigt(3));

        for (int t = 1; t < XS::END_XS_TYPES; ++t)
        {
            const Vector &sig = xs.vector(1, t);
            EXPECT_EQ(4, sig.length());
            for (int g = 0; g < 4; ++g)
            {
                EXPECT_EQ(0.0, sig(g));
            }
        }
    }

    // material 5
    {
        const Vector &sigt = xs.vector(5, XS::TOTAL);
        EXPECT_EQ(4, sigt.length());

        EXPECT_EQ(20.0, sigt(0));
        EXPECT_EQ(30.0, sigt(1));
        EXPECT_EQ(40.0, sigt(2));
        EXPECT_EQ(50.0, sigt(3));

        const Vector &sigf = xs.vector(5, XS::SIG_F);
        EXPECT_EQ(4, sigf.length());

        EXPECT_EQ(11.0, sigf(0));
        EXPECT_EQ(12.0, sigf(1));
        EXPECT_EQ(13.0, sigf(2));
        EXPECT_EQ(14.0, sigf(3));

        const Vector &nusigf = xs.vector(5, XS::NU_SIG_F);
        EXPECT_EQ(4, nusigf.length());

        EXPECT_EQ(2.4*11.0, nusigf(0));
        EXPECT_EQ(2.4*12.0, nusigf(1));
        EXPECT_EQ(2.4*13.0, nusigf(2));
        EXPECT_EQ(2.4*14.0, nusigf(3));

        const Vector &chi = xs.vector(5, XS::CHI);
        EXPECT_EQ(4, chi.length());

        EXPECT_EQ(0.6, chi(0));
        EXPECT_EQ(0.3, chi(1));
        EXPECT_EQ(0.1, chi(2));
        EXPECT_EQ(0.0, chi(3));
    }

    for (int m = 0; m < 2; ++m)
    {
        int matid = mids[m];
        for (int n = 0; n < 1; ++n)
        {
            const Matrix &sigs = xs.matrix(matid, n);
            EXPECT_EQ(4, sigs.numRows());
            EXPECT_EQ(4, sigs.numCols());
            for (int g = 0; g < 4; ++g)
            {
                for (int gp = 0; gp < 4; ++gp)
                {
                    EXPECT_EQ(0.0, sigs(g, gp));
                }
            }
        }
    }
}

//---------------------------------------------------------------------------//
//                 end of tstXS.cc
//---------------------------------------------------------------------------//
<commit_msg>Finished XS assignment.<commit_after>//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   xs/test/tstXS.cc
 * \author Thomas M. Evans
 * \date   Fri Jan 31 12:54:58 2014
 * \brief  XS container test.
 * \note   Copyright (C) 2014 Oak Ridge National Laboratory, UT-Battelle, LLC.
 */
//---------------------------------------------------------------------------//

#include "gtest/utils_gtest.hh"

#include "../XS.hh"

//---------------------------------------------------------------------------//
// Test fixture
//---------------------------------------------------------------------------//

// NOTE: the test class name must not contain underscores.
class XS_Test : public testing::Test
{
  protected:
    typedef profugus::XS  XS;
    typedef XS::Vector    Vector;
    typedef XS::Matrix    Matrix;
    typedef XS::OneDArray OneDArray;
    typedef XS::TwoDArray TwoDArray;
    typedef XS::Vec_Int   Vec_Int;

  protected:
    // Initialization that are performed for each test
    void SetUp()
    {
        Ng = 4;

        // build data
        m1_sig.resize(Ng);

        m5_sig.resize(Ng);
        sigf.resize(Ng);
        nusigf.resize(Ng);
        chi.resize(Ng);

        m1_sigs0.resizeRows(Ng);
        m1_sigs0.resizeCols(Ng);

        m1_sigs1.resizeRows(Ng);
        m1_sigs1.resizeCols(Ng);

        m5_sigs0.resizeRows(Ng);
        m5_sigs0.resizeCols(Ng);

        m5_sigs1.resizeRows(Ng);
        m5_sigs1.resizeCols(Ng);

        m1_sig[0] = 2.0;
        m1_sig[1] = 3.0;
        m1_sig[2] = 4.0;
        m1_sig[3] = 5.0;

        m5_sig[0] = 20.0;
        m5_sig[1] = 30.0;
        m5_sig[2] = 40.0;
        m5_sig[3] = 50.0;

        sigf[0] = 11.0;
        sigf[1] = 12.0;
        sigf[2] = 13.0;
        sigf[3] = 14.0;

        double nu = 2.4;
        for (int n = 0; n < 4; ++n)
        {
            nusigf[n] = sigf[n] * nu;
        }

        chi[0] = 0.6;
        chi[1] = 0.3;
        chi[2] = 0.1;

        // scattering m1
        double m1s0[][4] = {{1.1, 0.0, 0.0, 0.0},
                            {0.4, 1.4, 0.0, 0.0},
                            {0.2, 0.9, 3.2, 0.2},
                            {0.1, 0.2, 0.4, 4.8}};
        double m1s1[][4] = {{0.11, 0.00, 0.00, 0.00},
                            {0.04, 0.14, 0.00, 0.00},
                            {0.02, 0.09, 0.32, 0.02},
                            {0.01, 0.02, 0.04, 0.48}};

        // scattering m5
        double m5s0[][4] = {{2.1, 0.0, 0.0, 0.0},
                            {1.4, 2.4, 0.0, 0.0},
                            {1.2, 1.9, 5.2, 1.2},
                            {1.1, 1.2, 2.4, 9.8}};
        double m5s1[][4] = {{0.21, 0.00, 0.00, 0.00},
                            {0.14, 0.24, 0.00, 0.00},
                            {0.12, 0.19, 0.52, 0.12},
                            {0.11, 0.12, 0.24, 0.98}};

        for (int g = 0; g < 4; ++g)
        {
            for (int gp = 0; gp < 4; ++gp)
            {
                m1_sigs0(g, gp) = m1s0[g][gp];
                m1_sigs1(g, gp) = m1s1[g][gp];
                m5_sigs0(g, gp) = m5s0[g][gp];
                m5_sigs1(g, gp) = m5s1[g][gp];
            }
        }

        xs.set(1, Ng);
    }

  protected:

    int Ng;

    OneDArray m1_sig;
    OneDArray m5_sig, sigf, nusigf, chi;

    TwoDArray m1_sigs0, m1_sigs1, m5_sigs0, m5_sigs1;

    XS xs;

};

//---------------------------------------------------------------------------//
// TESTS
//---------------------------------------------------------------------------//

TEST_F(XS_Test, totals_assignment)
{
    EXPECT_EQ(1, xs.pn_order());
    EXPECT_EQ(4, xs.num_groups());
    EXPECT_EQ(0, xs.num_mat());

    xs.add(1, XS::TOTAL, m1_sig);

    xs.add(5, XS::TOTAL, m5_sig);
    xs.add(5, XS::SIG_F, sigf);
    xs.add(5, XS::NU_SIG_F, nusigf);
    xs.add(5, XS::CHI, chi);

    EXPECT_EQ(0, xs.num_mat());

    xs.complete();

    EXPECT_EQ(2, xs.num_mat());
    EXPECT_EQ(1, xs.pn_order());
    EXPECT_EQ(4, xs.num_groups());

    EXPECT_TRUE(xs.has(1));
    EXPECT_TRUE(xs.has(5));

    Vec_Int mids;
    xs.get_matids(mids);
    EXPECT_EQ(2, mids.size());
    EXPECT_EQ(1, mids[0]);
    EXPECT_EQ(5, mids[1]);

    // material 1
    {
        const Vector &sigt = xs.vector(1, XS::TOTAL);
        EXPECT_EQ(4, sigt.length());

        EXPECT_EQ(2.0, sigt(0));
        EXPECT_EQ(3.0, sigt(1));
        EXPECT_EQ(4.0, sigt(2));
        EXPECT_EQ(5.0, sigt(3));

        for (int t = 1; t < XS::END_XS_TYPES; ++t)
        {
            const Vector &sig = xs.vector(1, t);
            EXPECT_EQ(4, sig.length());
            for (int g = 0; g < 4; ++g)
            {
                EXPECT_EQ(0.0, sig(g));
            }
        }
    }

    // material 5
    {
        const Vector &sigt = xs.vector(5, XS::TOTAL);
        EXPECT_EQ(4, sigt.length());

        EXPECT_EQ(20.0, sigt(0));
        EXPECT_EQ(30.0, sigt(1));
        EXPECT_EQ(40.0, sigt(2));
        EXPECT_EQ(50.0, sigt(3));

        const Vector &sigf = xs.vector(5, XS::SIG_F);
        EXPECT_EQ(4, sigf.length());

        EXPECT_EQ(11.0, sigf(0));
        EXPECT_EQ(12.0, sigf(1));
        EXPECT_EQ(13.0, sigf(2));
        EXPECT_EQ(14.0, sigf(3));

        const Vector &nusigf = xs.vector(5, XS::NU_SIG_F);
        EXPECT_EQ(4, nusigf.length());

        EXPECT_EQ(2.4*11.0, nusigf(0));
        EXPECT_EQ(2.4*12.0, nusigf(1));
        EXPECT_EQ(2.4*13.0, nusigf(2));
        EXPECT_EQ(2.4*14.0, nusigf(3));

        const Vector &chi = xs.vector(5, XS::CHI);
        EXPECT_EQ(4, chi.length());

        EXPECT_EQ(0.6, chi(0));
        EXPECT_EQ(0.3, chi(1));
        EXPECT_EQ(0.1, chi(2));
        EXPECT_EQ(0.0, chi(3));
    }

    for (int m = 0; m < 2; ++m)
    {
        int matid = mids[m];
        for (int n = 0; n < 1; ++n)
        {
            const Matrix &sigs = xs.matrix(matid, n);
            EXPECT_EQ(4, sigs.numRows());
            EXPECT_EQ(4, sigs.numCols());
            for (int g = 0; g < 4; ++g)
            {
                for (int gp = 0; gp < 4; ++gp)
                {
                    EXPECT_EQ(0.0, sigs(g, gp));
                }
            }
        }
    }
}

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

TEST_F(XS_Test, scat_assignment)
{
    xs.add(1, XS::TOTAL, m1_sig);
    xs.add(1, 0, m1_sigs0);
    xs.add(1, 1, m1_sigs1);
    xs.add(5, XS::TOTAL, m5_sig);
    xs.add(5, 0, m5_sigs0);
    xs.add(5, 1, m5_sigs1);

    xs.complete();

    EXPECT_EQ(2, xs.num_mat());
    EXPECT_EQ(1, xs.pn_order());
    EXPECT_EQ(4, xs.num_groups());

    // material 1
    {
        const Vector &sigt = xs.vector(1, XS::TOTAL);
        EXPECT_EQ(4, sigt.length());

        EXPECT_EQ(2.0, sigt(0));
        EXPECT_EQ(3.0, sigt(1));
        EXPECT_EQ(4.0, sigt(2));
        EXPECT_EQ(5.0, sigt(3));

        const Matrix &p0 = xs.matrix(1, 0);
        const Matrix &p1 = xs.matrix(1, 1);
        EXPECT_EQ(4, p0.numRows());
        EXPECT_EQ(4, p0.numCols());
        EXPECT_EQ(4, p1.numRows());
        EXPECT_EQ(4, p1.numCols());

        EXPECT_EQ(1.1, p0(0, 0));
        EXPECT_EQ(0.0, p0(0, 1));
        EXPECT_EQ(0.0, p0(0, 2));
        EXPECT_EQ(0.0, p0(0, 3));

        EXPECT_EQ(0.4, p0(1, 0));
        EXPECT_EQ(1.4, p0(1, 1));
        EXPECT_EQ(0.0, p0(1, 2));
        EXPECT_EQ(0.0, p0(1, 3));

        EXPECT_EQ(0.2, p0(2, 0));
        EXPECT_EQ(0.9, p0(2, 1));
        EXPECT_EQ(3.2, p0(2, 2));
        EXPECT_EQ(0.2, p0(2, 3));

        EXPECT_EQ(0.1, p0(3, 0));
        EXPECT_EQ(0.2, p0(3, 1));
        EXPECT_EQ(0.4, p0(3, 2));
        EXPECT_EQ(4.8, p0(3, 3));

        for (int g = 0; g < 4; ++g)
        {
            for (int gp = 0; gp < 4; ++gp)
            {
                EXPECT_SOFTEQ(p0(g,gp)*0.1, p1(g,gp), 1.0e-12);
            }
        }
    }

    // material 5
    {
        const Vector &sigt = xs.vector(5, XS::TOTAL);
        EXPECT_EQ(4, sigt.length());

        EXPECT_EQ(20.0, sigt(0));
        EXPECT_EQ(30.0, sigt(1));
        EXPECT_EQ(40.0, sigt(2));
        EXPECT_EQ(50.0, sigt(3));

        const Matrix &p0 = xs.matrix(5, 0);
        const Matrix &p1 = xs.matrix(5, 1);
        EXPECT_EQ(4, p0.numRows());
        EXPECT_EQ(4, p0.numCols());
        EXPECT_EQ(4, p1.numRows());
        EXPECT_EQ(4, p1.numCols());

        EXPECT_EQ(2.1, p0(0, 0));
        EXPECT_EQ(0.0, p0(0, 1));
        EXPECT_EQ(0.0, p0(0, 2));
        EXPECT_EQ(0.0, p0(0, 3));

        EXPECT_EQ(1.4, p0(1, 0));
        EXPECT_EQ(2.4, p0(1, 1));
        EXPECT_EQ(0.0, p0(1, 2));
        EXPECT_EQ(0.0, p0(1, 3));

        EXPECT_EQ(1.2, p0(2, 0));
        EXPECT_EQ(1.9, p0(2, 1));
        EXPECT_EQ(5.2, p0(2, 2));
        EXPECT_EQ(1.2, p0(2, 3));

        EXPECT_EQ(1.1, p0(3, 0));
        EXPECT_EQ(1.2, p0(3, 1));
        EXPECT_EQ(2.4, p0(3, 2));
        EXPECT_EQ(9.8, p0(3, 3));

        for (int g = 0; g < 4; ++g)
        {
            for (int gp = 0; gp < 4; ++gp)
            {
                EXPECT_SOFTEQ(p0(g,gp)*0.1, p1(g,gp), 1.0e-12);
            }
        }
    }

    Vec_Int mids;
    xs.get_matids(mids);

    for (int m = 0; m < 2; ++m)
    {
        for (int t = 1; t < XS::END_XS_TYPES; ++t)
        {
            const Vector &sig = xs.vector(mids[m], t);
            EXPECT_EQ(4, sig.length());
            for (int g = 0; g < 4; ++g)
            {
                EXPECT_EQ(0.0, sig(g));
            }
        }
    }
}

//---------------------------------------------------------------------------//
//                 end of tstXS.cc
//---------------------------------------------------------------------------//
<|endoftext|>


<commit_before>/***********************************************************************
	created:	22/2/2004
	author:		Paul D Turner

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

// Start of CEGUI namespace section
namespace CEGUI
{
/*************************************************************************
	Static Data Definitions
*************************************************************************/
// singleton instance pointer
template<> WindowFactoryManager* Singleton<WindowFactoryManager>::ms_Singleton	= 0;
// list of owned WindowFactory object pointers
WindowFactoryManager::OwnedWindowFactoryList WindowFactoryManager::d_ownedFactories;

//----------------------------------------------------------------------------//
WindowFactoryManager::WindowFactoryManager(void)
{
    Logger::getSingleton().logEvent(
        "CEGUI::WindowFactoryManager singleton created");

    // complete addition of any pre-added WindowFactory objects
    WindowFactoryManager::OwnedWindowFactoryList::iterator i =
        d_ownedFactories.begin();

    if (d_ownedFactories.end() != i)
    {
        Logger::getSingleton().logEvent(
        "---- Adding pre-registered WindowFactory objects ----");

        for (; d_ownedFactories.end() != i; ++i)
            addFactory(*i);
    }
}

/*************************************************************************
	Adds a WindowFactory object to the registry
*************************************************************************/
void WindowFactoryManager::addFactory(WindowFactory* factory)
{
	// throw exception if passed factory is null.
	if (!factory)
	{
		CEGUI_THROW(NullObjectException(
            "The provided WindowFactory pointer was invalid."));
	}

	// throw exception if type name for factory is already in use
	if (d_factoryRegistry.find(factory->getTypeName()) != d_factoryRegistry.end())
	{
		CEGUI_THROW(AlreadyExistsException(
            "A WindowFactory for type '" + factory->getTypeName() +
            "' is already registered."));
	}

	// add the factory to the registry
	d_factoryRegistry[factory->getTypeName()] = factory;

    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(factory));
	Logger::getSingleton().logEvent("WindowFactory for '" +
       factory->getTypeName() +"' windows added. " + addr_buff);
}

/*************************************************************************
	removes a WindowFactory from the registry (by name)
*************************************************************************/
void WindowFactoryManager::removeFactory(const String& name)
{
    WindowFactoryRegistry::iterator i = d_factoryRegistry.find(name);

    // exit if no factory exists for this type
    if (i == d_factoryRegistry.end())
        return;

    // see if we own this factory
    OwnedWindowFactoryList::iterator j = std::find(d_ownedFactories.begin(),
                                                   d_ownedFactories.end(),
                                                   (*i).second);

    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>((*i).second));

	d_factoryRegistry.erase(name);

    Logger::getSingleton().logEvent("WindowFactory for '" + name +
                                    "' windows removed. " + addr_buff);

    // delete factory object if we created it
    if (j != d_ownedFactories.end())
    {
        Logger::getSingleton().logEvent("Deleted WindowFactory for '" +
                                        (*j)->getTypeName() +
                                        "' windows.");

        CEGUI_DELETE_AO (*j);
        d_ownedFactories.erase(j);
    }
}

/*************************************************************************
	removes a WindowFactory from the registry (by pointer)
*************************************************************************/
void WindowFactoryManager::removeFactory(WindowFactory* factory)
{
	if (factory)
	{
		removeFactory(factory->getTypeName());
	}

}

//----------------------------------------------------------------------------//
void WindowFactoryManager::removeAllFactories(void)
{
    while (!d_factoryRegistry.empty())
        removeFactory((*d_factoryRegistry.begin()).second);
}

/*************************************************************************
	returns a pointer to the requested WindowFactory object
*************************************************************************/
WindowFactory* WindowFactoryManager::getFactory(const String& type) const
{
    // first, dereference aliased types, as needed.
    String targetType(getDereferencedAliasType(type));

	// try for a 'real' type
	WindowFactoryRegistry::const_iterator pos = d_factoryRegistry.find(targetType);

	// found an actual factory for this type
	if (pos != d_factoryRegistry.end())
	{
		return pos->second;
	}
    // no concrete type, try for a falagard mapped type
    else
    {
        FalagardMapRegistry::const_iterator falagard = d_falagardRegistry.find(targetType);

        // found falagard mapping for this type
        if (falagard != d_falagardRegistry.end())
        {
            // recursively call getFactory on the target base type
            return getFactory(falagard->second.d_baseType);
        }
        // type not found anywhere, give up with an exception.
        else
        {
            CEGUI_THROW(UnknownObjectException(
                "A WindowFactory object, an alias, or mapping for '" + type +
                "' Window objects is not registered with the system."));
        }
    }
}

/*************************************************************************
    Returns true if a WindowFactory, an alias, or a falagard mapping for
    a specified window type is present
*************************************************************************/
bool WindowFactoryManager::isFactoryPresent(const String& name) const
{
    // first, dereference aliased types, as needed.
    String targetType(getDereferencedAliasType(name));

    // now try for a 'real' type
    if (d_factoryRegistry.find(targetType) != d_factoryRegistry.end())
    {
        return true;
    }
    // not a concrete type, so return whether it's a Falagard mapped type.
    else
    {
        return (d_falagardRegistry.find(targetType) != d_falagardRegistry.end());
    }
}

/*************************************************************************
	Return a WindowFactoryManager::WindowFactoryIterator object to
	iterate over the available WindowFactory types.
*************************************************************************/
WindowFactoryManager::WindowFactoryIterator	WindowFactoryManager::getIterator(void) const
{
	return WindowFactoryIterator(d_factoryRegistry.begin(), d_factoryRegistry.end());
}

/*************************************************************************
	Return a WindowFactoryManager::TypeAliasIterator object to iterate
	over the defined aliases for window types.
*************************************************************************/
WindowFactoryManager::TypeAliasIterator WindowFactoryManager::getAliasIterator(void) const
{
	return TypeAliasIterator(d_aliasRegistry.begin(), d_aliasRegistry.end());
}

/*************************************************************************
	Add a window type alias mapping
*************************************************************************/
void WindowFactoryManager::addWindowTypeAlias(const String& aliasName, const String& targetType)
{
	TypeAliasRegistry::iterator pos = d_aliasRegistry.find(aliasName);

	if (pos == d_aliasRegistry.end())
	{
		d_aliasRegistry[aliasName].d_targetStack.push_back(targetType);
	}
	// alias already exists, add our new entry to the list already there
	else
	{
		pos->second.d_targetStack.push_back(targetType);
	}

	Logger::getSingleton().logEvent("Window type alias named '" + aliasName + "' added for window type '" + targetType +"'.");
}

/*************************************************************************
	Remove a window type alias mapping
*************************************************************************/
void WindowFactoryManager::removeWindowTypeAlias(const String& aliasName, const String& targetType)
{
	// find alias name
	TypeAliasRegistry::iterator pos = d_aliasRegistry.find(aliasName);

	// if alias name exists
	if (pos != d_aliasRegistry.end())
	{
		// find the specified target for this alias
		AliasTargetStack::TargetTypeStack::iterator aliasPos = std::find(pos->second.d_targetStack.begin(), pos->second.d_targetStack.end(), targetType);

		// if the target exists for this alias
		if (aliasPos != pos->second.d_targetStack.end())
		{
			// erase the target mapping
			pos->second.d_targetStack.erase(aliasPos);

			Logger::getSingleton().logEvent("Window type alias named '" + aliasName + "' removed for window type '" + targetType +"'.");

			// if the list of targets for this alias is now empty
			if (pos->second.d_targetStack.empty())
			{
				// erase the alias name also
				d_aliasRegistry.erase(aliasName);

				Logger::getSingleton().logEvent("Window type alias named '" + aliasName + "' has no more targets and has been removed.", Informative);
			}

		}

	}

}

void WindowFactoryManager::removeAllWindowTypeAliases()
{
	d_aliasRegistry.clear();
}

void WindowFactoryManager::addFalagardWindowMapping(const String& newType,
                                                    const String& targetType,
                                                    const String& lookName,
                                                    const String& renderer,
                                                    const String& effectName)
{
    WindowFactoryManager::FalagardWindowMapping mapping;
    mapping.d_windowType = newType;
    mapping.d_baseType   = targetType;
    mapping.d_lookName   = lookName;
    mapping.d_rendererType = renderer;
    mapping.d_effectName = effectName;

    // see if the type we're creating already exists
    if (d_falagardRegistry.find(newType) != d_falagardRegistry.end())
    {
        // type already exists, log the fact that it's going to be replaced.
        Logger::getSingleton().logEvent("Falagard mapping for type '" + newType + "' already exists - current mapping will be replaced.");
    }

    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(&mapping));
    Logger::getSingleton().logEvent("Creating falagard mapping for type '" +
        newType + "' using base type '" + targetType + "', window renderer '" +
        renderer + "' Look'N'Feel '" + lookName + "' and RenderEffect '" +
        effectName + "'. " + addr_buff);

    d_falagardRegistry[newType] = mapping;
}

void WindowFactoryManager::removeFalagardWindowMapping(const String& type)
{
    FalagardMapRegistry::iterator iter = d_falagardRegistry.find(type);

    if (iter != d_falagardRegistry.end())
    {
        Logger::getSingleton().logEvent("Removing falagard mapping for type '" + type + "'.");
        d_falagardRegistry.erase(iter);
    }
}

void WindowFactoryManager::removeAllFalagardWindowMappings()
{
	d_falagardRegistry.clear();
}

WindowFactoryManager::FalagardMappingIterator WindowFactoryManager::getFalagardMappingIterator() const
{
    return FalagardMappingIterator(d_falagardRegistry.begin(), d_falagardRegistry.end());
}

bool WindowFactoryManager::isFalagardMappedType(const String& type) const
{
    return d_falagardRegistry.find(getDereferencedAliasType(type)) != d_falagardRegistry.end();
}

const String& WindowFactoryManager::getMappedLookForType(const String& type) const
{
    FalagardMapRegistry::const_iterator iter =
        d_falagardRegistry.find(getDereferencedAliasType(type));

    if (iter != d_falagardRegistry.end())
    {
        return (*iter).second.d_lookName;
    }
    // type does not exist as a mapped type (or an alias for one)
    else
    {
        CEGUI_THROW(InvalidRequestException(
            "Window factory type '" + type +
            "' is not a falagard mapped type (or an alias for one)."));
    }
}

const String& WindowFactoryManager::getMappedRendererForType(const String& type) const
{
    FalagardMapRegistry::const_iterator iter =
        d_falagardRegistry.find(getDereferencedAliasType(type));

    if (iter != d_falagardRegistry.end())
    {
        return (*iter).second.d_rendererType;
    }
    // type does not exist as a mapped type (or an alias for one)
    else
    {
        CEGUI_THROW(InvalidRequestException(
            "Window factory type '" + type +
            "' is not a falagard mapped type (or an alias for one)."));
    }
}

String WindowFactoryManager::getDereferencedAliasType(const String& type) const
{
    TypeAliasRegistry::const_iterator alias = d_aliasRegistry.find(type);

    // if this is an aliased type, ensure to fully dereference by recursively
    // calling ourselves on the active target for the given type.
    if (alias != d_aliasRegistry.end())
        return getDereferencedAliasType(alias->second.getActiveTarget());

    // we're not an alias, so return the input type unchanged
    return type;
}

const WindowFactoryManager::FalagardWindowMapping& WindowFactoryManager::getFalagardMappingForType(const String& type) const
{
    FalagardMapRegistry::const_iterator iter =
        d_falagardRegistry.find(getDereferencedAliasType(type));

    if (iter != d_falagardRegistry.end())
    {
        return (*iter).second;
    }
    // type does not exist as a mapped type (or an alias for one)
    else
    {
        CEGUI_THROW(InvalidRequestException(
            "Window factory type '" + type +
            "' is not a falagard mapped type (or an alias for one)."));
    }
}

//////////////////////////////////////////////////////////////////////////
/*************************************************************************
	Methods for AliasTargetStack class
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
const String& WindowFactoryManager::AliasTargetStack::getActiveTarget(void) const
{
	return d_targetStack.back();
}

uint WindowFactoryManager::AliasTargetStack::getStackedTargetCount(void) const
{
	return (uint)d_targetStack.size();
}

} // End of  CEGUI namespace section
<commit_msg>Hint towards SchemeManager when window factory manager can't find a window factory<commit_after>/***********************************************************************
	created:	22/2/2004
	author:		Paul D Turner

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

// Start of CEGUI namespace section
namespace CEGUI
{
/*************************************************************************
	Static Data Definitions
*************************************************************************/
// singleton instance pointer
template<> WindowFactoryManager* Singleton<WindowFactoryManager>::ms_Singleton	= 0;
// list of owned WindowFactory object pointers
WindowFactoryManager::OwnedWindowFactoryList WindowFactoryManager::d_ownedFactories;

//----------------------------------------------------------------------------//
WindowFactoryManager::WindowFactoryManager(void)
{
    Logger::getSingleton().logEvent(
        "CEGUI::WindowFactoryManager singleton created");

    // complete addition of any pre-added WindowFactory objects
    WindowFactoryManager::OwnedWindowFactoryList::iterator i =
        d_ownedFactories.begin();

    if (d_ownedFactories.end() != i)
    {
        Logger::getSingleton().logEvent(
        "---- Adding pre-registered WindowFactory objects ----");

        for (; d_ownedFactories.end() != i; ++i)
            addFactory(*i);
    }
}

/*************************************************************************
	Adds a WindowFactory object to the registry
*************************************************************************/
void WindowFactoryManager::addFactory(WindowFactory* factory)
{
	// throw exception if passed factory is null.
	if (!factory)
	{
		CEGUI_THROW(NullObjectException(
            "The provided WindowFactory pointer was invalid."));
	}

	// throw exception if type name for factory is already in use
	if (d_factoryRegistry.find(factory->getTypeName()) != d_factoryRegistry.end())
	{
		CEGUI_THROW(AlreadyExistsException(
            "A WindowFactory for type '" + factory->getTypeName() +
            "' is already registered."));
	}

	// add the factory to the registry
	d_factoryRegistry[factory->getTypeName()] = factory;

    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(factory));
	Logger::getSingleton().logEvent("WindowFactory for '" +
       factory->getTypeName() +"' windows added. " + addr_buff);
}

/*************************************************************************
	removes a WindowFactory from the registry (by name)
*************************************************************************/
void WindowFactoryManager::removeFactory(const String& name)
{
    WindowFactoryRegistry::iterator i = d_factoryRegistry.find(name);

    // exit if no factory exists for this type
    if (i == d_factoryRegistry.end())
        return;

    // see if we own this factory
    OwnedWindowFactoryList::iterator j = std::find(d_ownedFactories.begin(),
                                                   d_ownedFactories.end(),
                                                   (*i).second);

    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>((*i).second));

	d_factoryRegistry.erase(name);

    Logger::getSingleton().logEvent("WindowFactory for '" + name +
                                    "' windows removed. " + addr_buff);

    // delete factory object if we created it
    if (j != d_ownedFactories.end())
    {
        Logger::getSingleton().logEvent("Deleted WindowFactory for '" +
                                        (*j)->getTypeName() +
                                        "' windows.");

        CEGUI_DELETE_AO (*j);
        d_ownedFactories.erase(j);
    }
}

/*************************************************************************
	removes a WindowFactory from the registry (by pointer)
*************************************************************************/
void WindowFactoryManager::removeFactory(WindowFactory* factory)
{
	if (factory)
	{
		removeFactory(factory->getTypeName());
	}

}

//----------------------------------------------------------------------------//
void WindowFactoryManager::removeAllFactories(void)
{
    while (!d_factoryRegistry.empty())
        removeFactory((*d_factoryRegistry.begin()).second);
}

/*************************************************************************
	returns a pointer to the requested WindowFactory object
*************************************************************************/
WindowFactory* WindowFactoryManager::getFactory(const String& type) const
{
    // first, dereference aliased types, as needed.
    String targetType(getDereferencedAliasType(type));

	// try for a 'real' type
	WindowFactoryRegistry::const_iterator pos = d_factoryRegistry.find(targetType);

	// found an actual factory for this type
	if (pos != d_factoryRegistry.end())
	{
		return pos->second;
	}
    // no concrete type, try for a falagard mapped type
    else
    {
        FalagardMapRegistry::const_iterator falagard = d_falagardRegistry.find(targetType);

        // found falagard mapping for this type
        if (falagard != d_falagardRegistry.end())
        {
            // recursively call getFactory on the target base type
            return getFactory(falagard->second.d_baseType);
        }
        // type not found anywhere, give up with an exception.
        else
        {
            CEGUI_THROW(UnknownObjectException(
                "A WindowFactory object, an alias, or mapping for '" + type +
                "' Window objects is not registered with the system.\n\n"
                "Have you forgotten to load a scheme using "
                "CEGUI::SchemeManager::createFromFile(..)?"));
        }
    }
}

/*************************************************************************
    Returns true if a WindowFactory, an alias, or a falagard mapping for
    a specified window type is present
*************************************************************************/
bool WindowFactoryManager::isFactoryPresent(const String& name) const
{
    // first, dereference aliased types, as needed.
    String targetType(getDereferencedAliasType(name));

    // now try for a 'real' type
    if (d_factoryRegistry.find(targetType) != d_factoryRegistry.end())
    {
        return true;
    }
    // not a concrete type, so return whether it's a Falagard mapped type.
    else
    {
        return (d_falagardRegistry.find(targetType) != d_falagardRegistry.end());
    }
}

/*************************************************************************
	Return a WindowFactoryManager::WindowFactoryIterator object to
	iterate over the available WindowFactory types.
*************************************************************************/
WindowFactoryManager::WindowFactoryIterator	WindowFactoryManager::getIterator(void) const
{
	return WindowFactoryIterator(d_factoryRegistry.begin(), d_factoryRegistry.end());
}

/*************************************************************************
	Return a WindowFactoryManager::TypeAliasIterator object to iterate
	over the defined aliases for window types.
*************************************************************************/
WindowFactoryManager::TypeAliasIterator WindowFactoryManager::getAliasIterator(void) const
{
	return TypeAliasIterator(d_aliasRegistry.begin(), d_aliasRegistry.end());
}

/*************************************************************************
	Add a window type alias mapping
*************************************************************************/
void WindowFactoryManager::addWindowTypeAlias(const String& aliasName, const String& targetType)
{
	TypeAliasRegistry::iterator pos = d_aliasRegistry.find(aliasName);

	if (pos == d_aliasRegistry.end())
	{
		d_aliasRegistry[aliasName].d_targetStack.push_back(targetType);
	}
	// alias already exists, add our new entry to the list already there
	else
	{
		pos->second.d_targetStack.push_back(targetType);
	}

	Logger::getSingleton().logEvent("Window type alias named '" + aliasName + "' added for window type '" + targetType +"'.");
}

/*************************************************************************
	Remove a window type alias mapping
*************************************************************************/
void WindowFactoryManager::removeWindowTypeAlias(const String& aliasName, const String& targetType)
{
	// find alias name
	TypeAliasRegistry::iterator pos = d_aliasRegistry.find(aliasName);

	// if alias name exists
	if (pos != d_aliasRegistry.end())
	{
		// find the specified target for this alias
		AliasTargetStack::TargetTypeStack::iterator aliasPos = std::find(pos->second.d_targetStack.begin(), pos->second.d_targetStack.end(), targetType);

		// if the target exists for this alias
		if (aliasPos != pos->second.d_targetStack.end())
		{
			// erase the target mapping
			pos->second.d_targetStack.erase(aliasPos);

			Logger::getSingleton().logEvent("Window type alias named '" + aliasName + "' removed for window type '" + targetType +"'.");

			// if the list of targets for this alias is now empty
			if (pos->second.d_targetStack.empty())
			{
				// erase the alias name also
				d_aliasRegistry.erase(aliasName);

				Logger::getSingleton().logEvent("Window type alias named '" + aliasName + "' has no more targets and has been removed.", Informative);
			}

		}

	}

}

void WindowFactoryManager::removeAllWindowTypeAliases()
{
	d_aliasRegistry.clear();
}

void WindowFactoryManager::addFalagardWindowMapping(const String& newType,
                                                    const String& targetType,
                                                    const String& lookName,
                                                    const String& renderer,
                                                    const String& effectName)
{
    WindowFactoryManager::FalagardWindowMapping mapping;
    mapping.d_windowType = newType;
    mapping.d_baseType   = targetType;
    mapping.d_lookName   = lookName;
    mapping.d_rendererType = renderer;
    mapping.d_effectName = effectName;

    // see if the type we're creating already exists
    if (d_falagardRegistry.find(newType) != d_falagardRegistry.end())
    {
        // type already exists, log the fact that it's going to be replaced.
        Logger::getSingleton().logEvent("Falagard mapping for type '" + newType + "' already exists - current mapping will be replaced.");
    }

    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(&mapping));
    Logger::getSingleton().logEvent("Creating falagard mapping for type '" +
        newType + "' using base type '" + targetType + "', window renderer '" +
        renderer + "' Look'N'Feel '" + lookName + "' and RenderEffect '" +
        effectName + "'. " + addr_buff);

    d_falagardRegistry[newType] = mapping;
}

void WindowFactoryManager::removeFalagardWindowMapping(const String& type)
{
    FalagardMapRegistry::iterator iter = d_falagardRegistry.find(type);

    if (iter != d_falagardRegistry.end())
    {
        Logger::getSingleton().logEvent("Removing falagard mapping for type '" + type + "'.");
        d_falagardRegistry.erase(iter);
    }
}

void WindowFactoryManager::removeAllFalagardWindowMappings()
{
	d_falagardRegistry.clear();
}

WindowFactoryManager::FalagardMappingIterator WindowFactoryManager::getFalagardMappingIterator() const
{
    return FalagardMappingIterator(d_falagardRegistry.begin(), d_falagardRegistry.end());
}

bool WindowFactoryManager::isFalagardMappedType(const String& type) const
{
    return d_falagardRegistry.find(getDereferencedAliasType(type)) != d_falagardRegistry.end();
}

const String& WindowFactoryManager::getMappedLookForType(const String& type) const
{
    FalagardMapRegistry::const_iterator iter =
        d_falagardRegistry.find(getDereferencedAliasType(type));

    if (iter != d_falagardRegistry.end())
    {
        return (*iter).second.d_lookName;
    }
    // type does not exist as a mapped type (or an alias for one)
    else
    {
        CEGUI_THROW(InvalidRequestException(
            "Window factory type '" + type +
            "' is not a falagard mapped type (or an alias for one)."));
    }
}

const String& WindowFactoryManager::getMappedRendererForType(const String& type) const
{
    FalagardMapRegistry::const_iterator iter =
        d_falagardRegistry.find(getDereferencedAliasType(type));

    if (iter != d_falagardRegistry.end())
    {
        return (*iter).second.d_rendererType;
    }
    // type does not exist as a mapped type (or an alias for one)
    else
    {
        CEGUI_THROW(InvalidRequestException(
            "Window factory type '" + type +
            "' is not a falagard mapped type (or an alias for one)."));
    }
}

String WindowFactoryManager::getDereferencedAliasType(const String& type) const
{
    TypeAliasRegistry::const_iterator alias = d_aliasRegistry.find(type);

    // if this is an aliased type, ensure to fully dereference by recursively
    // calling ourselves on the active target for the given type.
    if (alias != d_aliasRegistry.end())
        return getDereferencedAliasType(alias->second.getActiveTarget());

    // we're not an alias, so return the input type unchanged
    return type;
}

const WindowFactoryManager::FalagardWindowMapping& WindowFactoryManager::getFalagardMappingForType(const String& type) const
{
    FalagardMapRegistry::const_iterator iter =
        d_falagardRegistry.find(getDereferencedAliasType(type));

    if (iter != d_falagardRegistry.end())
    {
        return (*iter).second;
    }
    // type does not exist as a mapped type (or an alias for one)
    else
    {
        CEGUI_THROW(InvalidRequestException(
            "Window factory type '" + type +
            "' is not a falagard mapped type (or an alias for one)."));
    }
}

//////////////////////////////////////////////////////////////////////////
/*************************************************************************
	Methods for AliasTargetStack class
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
const String& WindowFactoryManager::AliasTargetStack::getActiveTarget(void) const
{
	return d_targetStack.back();
}

uint WindowFactoryManager::AliasTargetStack::getStackedTargetCount(void) const
{
	return (uint)d_targetStack.size();
}

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