<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include <fstream>

#include "paddle/fluid/framework/data_type_transform.h"
#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/platform/device_context.h"
#include "paddle/fluid/platform/profiler.h"

namespace paddle {
namespace operators {

class LoadOp : public framework::OperatorBase {
 public:
  LoadOp(const std::string &type, const framework::VariableNameMap &inputs,
         const framework::VariableNameMap &outputs,
         const framework::AttributeMap &attrs)
      : OperatorBase(type, inputs, outputs, attrs) {}

 private:
  void RunImpl(const framework::Scope &scope,
               const platform::Place &place) const override {
    auto *dev_ctx = platform::DeviceContextPool::Instance().Get(place);
    platform::RecordEvent record_event(Type(), dev_ctx);

    auto filename = Attr<std::string>("file_path");
    std::ifstream fin(filename);
    PADDLE_ENFORCE(static_cast<bool>(fin), "Cannot open file %s for load op",
                   filename);

    auto out_var_name = Output("Out");
    auto *out_var = scope.FindVar(out_var_name);
    PADDLE_ENFORCE(out_var != nullptr, "Output variable %s cannot be found",
                   out_var_name);

    }
  }

  void LoadLodTensor(const std::string &filename, const platform::Place &place,
                     framework::Variable *var) const {
    auto &tensor = var->Get<framework::LoDTensor>();

    // get device context from pool
    platform::DeviceContextPool &pool = platform::DeviceContextPool::Instance();
    auto &dev_ctx = *pool.Get(place);

    // FIXME(yuyang18): We save variable to local file now, but we should change
    // it to save an output stream.
    std::ifstream fin(filename);
    PADDLE_ENFORCE(static_cast<bool>(fout), "Cannot open %s to write",
                   filename);

      auto *tensor = out_var->GetMutable<framework::LoDTensor>();

    DeserializeFromStream(fin, tensor, *dev_ctx);

    auto load_as_fp16 = Attr<bool>("load_as_fp16");
    auto in_dtype = framework::ToDataType(tensor->type());
    auto out_dtype = load_as_fp16 ? framework::proto::VarType::FP16 : in_dtype;

    if (in_dtype != out_dtype) {
      // convert to float16 tensor
      auto in_kernel_type = framework::OpKernelType(in_dtype, place);
      auto out_kernel_type = framework::OpKernelType(out_dtype, place);
      framework::LoDTensor fp16_tensor;
      // copy LoD info to the new tensor
      fp16_tensor.set_lod(tensor->lod());
      framework::TransDataType(in_kernel_type, out_kernel_type, *tensor,
                               &fp16_tensor);

      // reset output tensor
      out_var->Clear();
      tensor = out_var->GetMutable<framework::LoDTensor>();
      tensor->set_lod(fp16_tensor.lod());
      tensor->ShareDataWith(fp16_tensor);
  }

  void LoadSelectedRows(const std::string &filename,
                        const framework::Scope &scope,
                        const platform::Place &place,
                        framework::Variable *var) const {

    auto &selectedRows = var->Get<framework::SelectedRows>();

    // get device context from pool
    platform::DeviceContextPool &pool = platform::DeviceContextPool::Instance();
    auto &dev_ctx = *pool.Get(place);

    // FIXME(yuyang18): We save variable to local file now, but we should change
    // it to save an output stream.
    std::ifstream fin(filename);
    PADDLE_ENFORCE(static_cast<bool>(fin), "Cannot open %s to write",
                   filename);
    framework::DeserializeFromStream(fin, selectedRows, dev_ctx);
  }
};

class LoadOpProtoMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddOutput("Out", "The tensor need to be loaded");
    AddAttr<bool>(
        "load_as_fp16",
        "If true, the tensor will be first loaded and then "
        "converted to float16 data type. Otherwise, the tensor will be "
        "directly loaded without data type conversion. Default is false.")
        .SetDefault(false);
    AddAttr<std::string>("file_path",
                         R"(Variable will be loaded from "file_path")")
        .AddCustomChecker(
            [](const std::string &path) { return !path.empty(); });
    AddComment("Load operator will load a tensor variable from disk file.");
  }
};
}  // namespace operators
}  // namespace paddle
namespace ops = paddle::operators;

REGISTER_OPERATOR(load, ops::LoadOp, ops::LoadOpProtoMaker);
<commit_msg>load op add seletedRows<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include <fstream>

#include "paddle/fluid/framework/data_type_transform.h"
#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/platform/device_context.h"
#include "paddle/fluid/platform/profiler.h"

namespace paddle {
namespace operators {

class LoadOp : public framework::OperatorBase {
 public:
  LoadOp(const std::string &type, const framework::VariableNameMap &inputs,
         const framework::VariableNameMap &outputs,
         const framework::AttributeMap &attrs)
      : OperatorBase(type, inputs, outputs, attrs) {}

 private:
  void RunImpl(const framework::Scope &scope,
               const platform::Place &place) const override {
    auto *dev_ctx = platform::DeviceContextPool::Instance().Get(place);
    platform::RecordEvent record_event(Type(), dev_ctx);

    auto filename = Attr<std::string>("file_path");
    std::ifstream fin(filename);
    PADDLE_ENFORCE(static_cast<bool>(fin), "Cannot open file %s for load op",
                   filename);

    auto out_var_name = Output("Out");
    auto *out_var = scope.FindVar(out_var_name);
    PADDLE_ENFORCE(out_var != nullptr, "Output variable %s cannot be found",
                   out_var_name);

    if (out_var->IsType<framework::LoDTensor>()) {
      SaveLodTensor(filename, place, out_var);
    } else if (out_var->IsType<framework::SelectedRows>()) {
      SaveSelectedRows(filename, scope, place, out_var);
    } else {
      PADDLE_ENFORCE(
          false,
          "Load only support LoDTensor and SelectedRows, %s has wrong type",
          iname);
    }
    }
  }

  void LoadLodTensor(const std::string &filename, const platform::Place &place,
                     framework::Variable *var) const {
    auto &tensor = var->Get<framework::LoDTensor>();

    // get device context from pool
    platform::DeviceContextPool &pool = platform::DeviceContextPool::Instance();
    auto &dev_ctx = *pool.Get(place);

    // FIXME(yuyang18): We save variable to local file now, but we should change
    // it to save an output stream.
    std::ifstream fin(filename);
    PADDLE_ENFORCE(static_cast<bool>(fout), "Cannot open %s to write",
                   filename);

      auto *tensor = out_var->GetMutable<framework::LoDTensor>();

    DeserializeFromStream(fin, tensor, *dev_ctx);

    auto load_as_fp16 = Attr<bool>("load_as_fp16");
    auto in_dtype = framework::ToDataType(tensor->type());
    auto out_dtype = load_as_fp16 ? framework::proto::VarType::FP16 : in_dtype;

    if (in_dtype != out_dtype) {
      // convert to float16 tensor
      auto in_kernel_type = framework::OpKernelType(in_dtype, place);
      auto out_kernel_type = framework::OpKernelType(out_dtype, place);
      framework::LoDTensor fp16_tensor;
      // copy LoD info to the new tensor
      fp16_tensor.set_lod(tensor->lod());
      framework::TransDataType(in_kernel_type, out_kernel_type, *tensor,
                               &fp16_tensor);

      // reset output tensor
      out_var->Clear();
      tensor = out_var->GetMutable<framework::LoDTensor>();
      tensor->set_lod(fp16_tensor.lod());
      tensor->ShareDataWith(fp16_tensor);
  }

  void LoadSelectedRows(const std::string &filename,
                        const framework::Scope &scope,
                        const platform::Place &place,
                        framework::Variable *var) const {

    auto *selectedRows = var->GetMutable<framework::SelectedRows>();

    // get device context from pool
    platform::DeviceContextPool &pool = platform::DeviceContextPool::Instance();
    auto &dev_ctx = *pool.Get(place);

    // FIXME(yuyang18): We save variable to local file now, but we should change
    // it to save an output stream.
    std::ifstream fin(filename);
    PADDLE_ENFORCE(static_cast<bool>(fin), "Cannot open %s to write",
                   filename);
    framework::DeserializeFromStream(fin, selectedRows, dev_ctx);
  }
};

class LoadOpProtoMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddOutput("Out", "The tensor need to be loaded");
    AddAttr<bool>(
        "load_as_fp16",
        "If true, the tensor will be first loaded and then "
        "converted to float16 data type. Otherwise, the tensor will be "
        "directly loaded without data type conversion. Default is false.")
        .SetDefault(false);
    AddAttr<std::string>("file_path",
                         R"(Variable will be loaded from "file_path")")
        .AddCustomChecker(
            [](const std::string &path) { return !path.empty(); });
    AddComment("Load operator will load a tensor variable from disk file.");
  }
};
}  // namespace operators
}  // namespace paddle
namespace ops = paddle::operators;

REGISTER_OPERATOR(load, ops::LoadOp, ops::LoadOpProtoMaker);
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: tbinsert.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2004-07-06 12:53:48 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

// System - Includes -----------------------------------------------------

#include <string> // HACK: prevent conflict between STLPORT and Workshop headers

#ifdef PCH
#include "ui_pch.hxx"
#endif

#pragma hdrstop

// INCLUDE ---------------------------------------------------------------

#include <tools/shl.hxx>
#include <svtools/intitem.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/imagemgr.hxx>

#include "tbinsert.hxx"
#include "tbinsert.hrc"
#include "global.hxx"
#include "scmod.hxx"
#include "scresid.hxx"
#include "sc.hrc"

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

SFX_IMPL_TOOLBOX_CONTROL( ScTbxInsertCtrl, SfxUInt16Item);

//------------------------------------------------------------------
//
//  ToolBox - Controller
//
//------------------------------------------------------------------

ScTbxInsertCtrl::ScTbxInsertCtrl( USHORT nSlotId, USHORT nId, ToolBox& rTbx  ) :
        SfxToolBoxControl( nSlotId, nId, rTbx ),
        nLastSlotId(0)
{
    rTbx.SetItemBits( nId, TIB_DROPDOWN | rTbx.GetItemBits( nId ) );
}

__EXPORT ScTbxInsertCtrl::~ScTbxInsertCtrl()
{
}

void __EXPORT ScTbxInsertCtrl::StateChanged( USHORT nSID, SfxItemState eState,
                                              const SfxPoolItem* pState )
{
    GetToolBox().EnableItem( GetId(), (GetItemState(pState) != SFX_ITEM_DISABLED) );

    if( eState == SFX_ITEM_AVAILABLE )
    {

        const SfxUInt16Item* pItem = PTR_CAST( SfxUInt16Item, pState );
        if(pItem)
        {
            nLastSlotId = pItem->GetValue();
            USHORT nImageId = nLastSlotId ? nLastSlotId : GetSlotId();
            rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
            aSlotURL += rtl::OUString::valueOf( sal_Int32( nImageId ));
            Image aImage = GetImage( m_xFrame,
                                     aSlotURL,
                                     hasBigImages(),
                                     GetToolBox().GetDisplayBackground().GetColor().IsDark() );
/*
            Image aImage = GetBindings().GetImageManager()->GetImage( nImageId,
                           GetToolBox().GetDisplayBackground().GetColor().IsDark(),
                           SC_MOD() );
*/
            GetToolBox().SetItemImage(GetId(), aImage);
        }
    }
}

SfxPopupWindow* __EXPORT ScTbxInsertCtrl::CreatePopupWindow()
{
    USHORT nWinResId, nTbxResId;
    USHORT nSlotId = GetSlotId();
    if (nSlotId == SID_TBXCTL_INSERT)
    {
        rtl::OUString aInsertBarResStr( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/insertbar" ));
        createAndPositionSubToolBar( aInsertBarResStr );
//      nWinResId = RID_TBXCTL_INSERT;
//      nTbxResId = RID_TOOLBOX_INSERT;
    }
    else if (nSlotId == SID_TBXCTL_INSCELLS)
    {
        rtl::OUString aInsertCellsBarResStr( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/insertcellsbar" ));
        createAndPositionSubToolBar( aInsertCellsBarResStr );
//      nWinResId = RID_TBXCTL_INSCELLS;
//      nTbxResId = RID_TOOLBOX_INSCELLS;
    }
    else /* SID_TBXCTL_INSOBJ */
    {
        rtl::OUString aInsertObjectBarResStr( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/insertobjectbar" ));
        createAndPositionSubToolBar( aInsertObjectBarResStr );
//      nWinResId = RID_TBXCTL_INSOBJ;
//      nTbxResId = RID_TOOLBOX_INSOBJ;
    }
/*
    WindowAlign eNewAlign = ( GetToolBox().IsHorizontal() ) ? WINDOWALIGN_LEFT : WINDOWALIGN_TOP;
    ScTbxInsertPopup *pWin = new ScTbxInsertPopup( nSlotId, eNewAlign,
                                    ScResId(nWinResId), ScResId(nTbxResId), GetBindings() );
    pWin->StartPopupMode(&GetToolBox(), TRUE);
    pWin->StartSelection();
    pWin->Show();
    return pWin;
*/
    return NULL;
}

SfxPopupWindowType __EXPORT ScTbxInsertCtrl::GetPopupWindowType() const
{
    return nLastSlotId ? SFX_POPUPWINDOW_ONTIMEOUT : SFX_POPUPWINDOW_ONCLICK;
}

void __EXPORT ScTbxInsertCtrl::Select( BOOL bMod1 )
{
    SfxViewShell*   pCurSh( SfxViewShell::Current() );
    SfxDispatcher*  pDispatch( 0 );

    if ( pCurSh )
    {
        SfxViewFrame*   pViewFrame = pCurSh->GetViewFrame();
        if ( pViewFrame )
            pDispatch = pViewFrame->GetDispatcher();
    }

    if ( pDispatch )
        pDispatch->Execute(nLastSlotId);
}
/*
//------------------------------------------------------------------
//
//  Popup - Window
//
//------------------------------------------------------------------

ScTbxInsertPopup::ScTbxInsertPopup( USHORT nId, WindowAlign eNewAlign,
                        const ResId& rRIdWin, const ResId& rRIdTbx,
                        SfxBindings& rBindings ) :
                SfxPopupWindow  ( nId, rRIdWin, rBindings),
                aTbx            ( this, GetBindings(), rRIdTbx ),
                aRIdWinTemp(rRIdWin),
                aRIdTbxTemp(rRIdTbx)
{
    aTbx.UseDefault();
    FreeResource();

    aTbx.GetToolBox().SetAlign( eNewAlign );
    if (eNewAlign == WINDOWALIGN_LEFT || eNewAlign == WINDOWALIGN_RIGHT)
        SetText( EMPTY_STRING );

    Size aSize = aTbx.CalcWindowSizePixel();
    aTbx.SetPosSizePixel( Point(), aSize );
    SetOutputSizePixel( aSize );
    aTbx.GetToolBox().SetSelectHdl( LINK(this, ScTbxInsertPopup, TbxSelectHdl));
    aTbxClickHdl = aTbx.GetToolBox().GetClickHdl();
    aTbx.GetToolBox().SetClickHdl(  LINK(this, ScTbxInsertPopup, TbxClickHdl));
}

ScTbxInsertPopup::~ScTbxInsertPopup()
{
}

SfxPopupWindow* __EXPORT ScTbxInsertPopup::Clone() const
{
    return new ScTbxInsertPopup( GetId(), aTbx.GetToolBox().GetAlign(),
                                    aRIdWinTemp, aRIdTbxTemp,
                                    (SfxBindings&) GetBindings() );
}

void ScTbxInsertPopup::StartSelection()
{
    aTbx.GetToolBox().StartSelection();
}

IMPL_LINK(ScTbxInsertPopup, TbxSelectHdl, ToolBox*, pBox)
{
    EndPopupMode();

    USHORT nLastSlotId = pBox->GetCurItemId();
    SfxUInt16Item aItem( GetId(), nLastSlotId );
    SfxDispatcher* pDisp = GetBindings().GetDispatcher();
    pDisp->Execute( GetId(), SFX_CALLMODE_SYNCHRON, &aItem, 0L );
    pDisp->Execute( nLastSlotId, SFX_CALLMODE_ASYNCHRON );
    return 0;
}

IMPL_LINK(ScTbxInsertPopup, TbxClickHdl, ToolBox*, pBox)
{
    USHORT nLastSlotId = pBox->GetCurItemId();
    SfxUInt16Item aItem( GetId(), nLastSlotId );
    GetBindings().GetDispatcher()->Execute( GetId(), SFX_CALLMODE_SYNCHRON, &aItem, 0L );
    if(aTbxClickHdl.IsSet())
        aTbxClickHdl.Call(pBox);
    return 0;
}

void __EXPORT ScTbxInsertPopup::PopupModeEnd()
{
    aTbx.GetToolBox().EndSelection();
    SfxPopupWindow::PopupModeEnd();
}
*/

<commit_msg>INTEGRATION: CWS oooicons (1.5.146); FILE MERGED 2004/10/29 15:45:21 cd 1.5.146.1: #i35368# Adapt code to use static sfx imagelist and removed obsolete images<commit_after>/*************************************************************************
 *
 *  $RCSfile: tbinsert.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-19 11:15:30 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

// System - Includes -----------------------------------------------------

#include <string> // HACK: prevent conflict between STLPORT and Workshop headers

#ifdef PCH
#include "ui_pch.hxx"
#endif

#pragma hdrstop

// INCLUDE ---------------------------------------------------------------

#include <tools/shl.hxx>
#include <svtools/intitem.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/imagemgr.hxx>

#include "tbinsert.hxx"
#include "tbinsert.hrc"
#include "global.hxx"
#include "scmod.hxx"
#include "scresid.hxx"
#include "sc.hrc"

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

SFX_IMPL_TOOLBOX_CONTROL( ScTbxInsertCtrl, SfxUInt16Item);

//------------------------------------------------------------------
//
//  ToolBox - Controller
//
//------------------------------------------------------------------

ScTbxInsertCtrl::ScTbxInsertCtrl( USHORT nSlotId, USHORT nId, ToolBox& rTbx  ) :
        SfxToolBoxControl( nSlotId, nId, rTbx ),
        nLastSlotId(0)
{
    rTbx.SetItemBits( nId, TIB_DROPDOWN | rTbx.GetItemBits( nId ) );
}

__EXPORT ScTbxInsertCtrl::~ScTbxInsertCtrl()
{
}

void __EXPORT ScTbxInsertCtrl::StateChanged( USHORT nSID, SfxItemState eState,
                                              const SfxPoolItem* pState )
{
    GetToolBox().EnableItem( GetId(), (GetItemState(pState) != SFX_ITEM_DISABLED) );

    if( eState == SFX_ITEM_AVAILABLE )
    {

        const SfxUInt16Item* pItem = PTR_CAST( SfxUInt16Item, pState );
        if(pItem)
        {
            nLastSlotId = pItem->GetValue();
            USHORT nImageId = nLastSlotId ? nLastSlotId : GetSlotId();
            rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
            aSlotURL += rtl::OUString::valueOf( sal_Int32( nImageId ));
            Image aImage = GetImage( m_xFrame,
                                     aSlotURL,
                                     hasBigImages(),
                                     GetToolBox().GetDisplayBackground().GetColor().IsDark() );
            GetToolBox().SetItemImage(GetId(), aImage);
        }
    }
}

SfxPopupWindow* __EXPORT ScTbxInsertCtrl::CreatePopupWindow()
{
    USHORT nWinResId, nTbxResId;
    USHORT nSlotId = GetSlotId();
    if (nSlotId == SID_TBXCTL_INSERT)
    {
        rtl::OUString aInsertBarResStr( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/insertbar" ));
        createAndPositionSubToolBar( aInsertBarResStr );
//      nWinResId = RID_TBXCTL_INSERT;
//      nTbxResId = RID_TOOLBOX_INSERT;
    }
    else if (nSlotId == SID_TBXCTL_INSCELLS)
    {
        rtl::OUString aInsertCellsBarResStr( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/insertcellsbar" ));
        createAndPositionSubToolBar( aInsertCellsBarResStr );
//      nWinResId = RID_TBXCTL_INSCELLS;
//      nTbxResId = RID_TOOLBOX_INSCELLS;
    }
    else /* SID_TBXCTL_INSOBJ */
    {
        rtl::OUString aInsertObjectBarResStr( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/insertobjectbar" ));
        createAndPositionSubToolBar( aInsertObjectBarResStr );
//      nWinResId = RID_TBXCTL_INSOBJ;
//      nTbxResId = RID_TOOLBOX_INSOBJ;
    }
/*
    WindowAlign eNewAlign = ( GetToolBox().IsHorizontal() ) ? WINDOWALIGN_LEFT : WINDOWALIGN_TOP;
    ScTbxInsertPopup *pWin = new ScTbxInsertPopup( nSlotId, eNewAlign,
                                    ScResId(nWinResId), ScResId(nTbxResId), GetBindings() );
    pWin->StartPopupMode(&GetToolBox(), TRUE);
    pWin->StartSelection();
    pWin->Show();
    return pWin;
*/
    return NULL;
}

SfxPopupWindowType __EXPORT ScTbxInsertCtrl::GetPopupWindowType() const
{
    return nLastSlotId ? SFX_POPUPWINDOW_ONTIMEOUT : SFX_POPUPWINDOW_ONCLICK;
}

void __EXPORT ScTbxInsertCtrl::Select( BOOL bMod1 )
{
    SfxViewShell*   pCurSh( SfxViewShell::Current() );
    SfxDispatcher*  pDispatch( 0 );

    if ( pCurSh )
    {
        SfxViewFrame*   pViewFrame = pCurSh->GetViewFrame();
        if ( pViewFrame )
            pDispatch = pViewFrame->GetDispatcher();
    }

    if ( pDispatch )
        pDispatch->Execute(nLastSlotId);
}
/*
//------------------------------------------------------------------
//
//  Popup - Window
//
//------------------------------------------------------------------

ScTbxInsertPopup::ScTbxInsertPopup( USHORT nId, WindowAlign eNewAlign,
                        const ResId& rRIdWin, const ResId& rRIdTbx,
                        SfxBindings& rBindings ) :
                SfxPopupWindow  ( nId, rRIdWin, rBindings),
                aTbx            ( this, GetBindings(), rRIdTbx ),
                aRIdWinTemp(rRIdWin),
                aRIdTbxTemp(rRIdTbx)
{
    aTbx.UseDefault();
    FreeResource();

    aTbx.GetToolBox().SetAlign( eNewAlign );
    if (eNewAlign == WINDOWALIGN_LEFT || eNewAlign == WINDOWALIGN_RIGHT)
        SetText( EMPTY_STRING );

    Size aSize = aTbx.CalcWindowSizePixel();
    aTbx.SetPosSizePixel( Point(), aSize );
    SetOutputSizePixel( aSize );
    aTbx.GetToolBox().SetSelectHdl( LINK(this, ScTbxInsertPopup, TbxSelectHdl));
    aTbxClickHdl = aTbx.GetToolBox().GetClickHdl();
    aTbx.GetToolBox().SetClickHdl(  LINK(this, ScTbxInsertPopup, TbxClickHdl));
}

ScTbxInsertPopup::~ScTbxInsertPopup()
{
}

SfxPopupWindow* __EXPORT ScTbxInsertPopup::Clone() const
{
    return new ScTbxInsertPopup( GetId(), aTbx.GetToolBox().GetAlign(),
                                    aRIdWinTemp, aRIdTbxTemp,
                                    (SfxBindings&) GetBindings() );
}

void ScTbxInsertPopup::StartSelection()
{
    aTbx.GetToolBox().StartSelection();
}

IMPL_LINK(ScTbxInsertPopup, TbxSelectHdl, ToolBox*, pBox)
{
    EndPopupMode();

    USHORT nLastSlotId = pBox->GetCurItemId();
    SfxUInt16Item aItem( GetId(), nLastSlotId );
    SfxDispatcher* pDisp = GetBindings().GetDispatcher();
    pDisp->Execute( GetId(), SFX_CALLMODE_SYNCHRON, &aItem, 0L );
    pDisp->Execute( nLastSlotId, SFX_CALLMODE_ASYNCHRON );
    return 0;
}

IMPL_LINK(ScTbxInsertPopup, TbxClickHdl, ToolBox*, pBox)
{
    USHORT nLastSlotId = pBox->GetCurItemId();
    SfxUInt16Item aItem( GetId(), nLastSlotId );
    GetBindings().GetDispatcher()->Execute( GetId(), SFX_CALLMODE_SYNCHRON, &aItem, 0L );
    if(aTbxClickHdl.IsSet())
        aTbxClickHdl.Call(pBox);
    return 0;
}

void __EXPORT ScTbxInsertPopup::PopupModeEnd()
{
    aTbx.GetToolBox().EndSelection();
    SfxPopupWindow::PopupModeEnd();
}
*/

<|endoftext|>


<commit_before><commit_msg>Sketcher: clean up general commands tooltips<commit_after><|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2013 Luke Parry <l.parry@warwick.ac.uk>                 *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
#include <QAction>
#include <QApplication>
#include <QContextMenuEvent>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QGraphicsSceneHoverEvent>
#include <QPainterPathStroker>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include <QBitmap>
#include <QFile>
#include <QFileInfo>
#endif

#include <QFile>
#include <QTextStream>
#include <QRectF>
#include <QPointF>

#include <cmath>

#include <App/Application.h>
#include <App/Material.h>
#include <Base/Console.h>
#include <Base/Parameter.h>

#include <Mod/TechDraw/App/DrawUtil.h>

#include "Rez.h"
#include "QGCustomSvg.h"
#include "QGCustomRect.h"
#include "QGIFace.h"

using namespace TechDrawGui;
using namespace TechDraw;

QGIFace::QGIFace(int index) :
    projIndex(index),
    m_colDefFill(Qt::white),          //Qt::transparent?  paper colour?
    m_styleDef(Qt::SolidPattern),
    m_styleSelect(Qt::SolidPattern)
{
    setFillMode(NoFill);
    isHatched(false);
    setFlag(QGraphicsItem::ItemClipsChildrenToShape,true);

    //setStyle(Qt::NoPen);    //don't draw face lines, just fill for debugging
    setStyle(Qt::DashLine);

    m_styleNormal = m_styleDef;
    m_fillStyle = m_styleDef;
    m_colNormalFill = m_colDefFill;
    m_geomColor = QColor(Qt::black);
    setLineWeight(0.5);                   //0 = cosmetic

    setPrettyNormal();
    m_texture = nullptr;                      //empty texture

    m_svg = new QGCustomSvg();

    m_rect = new QGCustomRect();
    m_rect->setParentItem(this);

    m_svgCol = SVGCOLDEFAULT;
    m_fillScale = 1.0;
}

QGIFace::~QGIFace()
{
    //nothing to do. every item is a child of QGIFace & will get removed/deleted when QGIF is deleted
}

void QGIFace::draw()
{
    setPath(m_outline);                         //Face boundary

    if (isHatched()) {
        if (m_mode == GeomHatchFill) {                             //crosshatch
            if (!m_geomHatchPaths.empty()) {                                  //surrogate for LineSets.empty
                m_brush.setTexture(nullptr);
                m_fillStyle = m_styleDef;
                m_styleNormal = m_fillStyle;
                int pathNo = 0;
                for (auto& pp: m_geomHatchPaths) {
                    QGraphicsPathItem* fillItem = m_fillItems.at(pathNo);
                    fillItem->setPath(pp);
                    QPen geomPen = setGeomPen(pathNo);
                    fillItem->setPen(geomPen);
                    pathNo++;
                }
            }
        } else if ((m_mode == FromFile) ||
                   (m_mode == SvgFill)  ||
                   (m_mode == BitmapFill)) {
            QFileInfo hfi(QString::fromUtf8(m_fileSpec.data(),m_fileSpec.size()));
            if (hfi.isReadable()) {
                QString ext = hfi.suffix();
                if (ext.toUpper() == QString::fromUtf8("SVG")) {
                    setFillMode(SvgFill);
                    m_brush.setTexture(nullptr);
                    m_fillStyle = m_styleDef;
                    m_styleNormal = m_fillStyle;
                    loadSvgHatch(m_fileSpec);
                    buildSvgHatch();
                    toggleSvg(true);
                } else if ((ext.toUpper() == QString::fromUtf8("JPG"))   ||
                         (ext.toUpper() == QString::fromUtf8("PNG"))   ||
                         (ext.toUpper() == QString::fromUtf8("JPEG"))  ||
                         (ext.toUpper() == QString::fromUtf8("BMP")) ) {
                    setFillMode(BitmapFill);
                    toggleSvg(false);
                    m_fillStyle   = Qt::TexturePattern;
                    m_texture = textureFromBitmap(m_fileSpec);
                    m_brush.setTexture(m_texture);
                }
            }
        }
    }
    show();
}

void QGIFace::setPrettyNormal() {
    if (isHatched()  &&
        (m_mode == BitmapFill) ) {                               //hatch with bitmap fill
        m_fillStyle = Qt::TexturePattern;
        m_brush.setTexture(m_texture);
    } else {
        m_fillStyle = m_styleNormal;
        m_brush.setTexture(nullptr);
        m_brush.setStyle(m_fillStyle);
        m_fillColor = m_colNormalFill;
    }
    QGIPrimPath::setPrettyNormal();
}

void QGIFace::setPrettyPre() {
    m_brush.setTexture(nullptr);
    m_fillStyle = m_styleSelect;
    m_fillColor = getPreColor();
    QGIPrimPath::setPrettyPre();
}

void QGIFace::setPrettySel() {
    m_brush.setTexture(nullptr);
    m_fillStyle = m_styleSelect;
    m_fillColor = getSelectColor();
    QGIPrimPath::setPrettySel();
}

void QGIFace::setDrawEdges(bool b) {
    if (b) {
        setStyle(Qt::DashLine);
    } else {
        setStyle(Qt::NoPen);    //don't draw face lines, just fill
    }
}

void QGIFace::setHatchFile(std::string fileSpec)
{
    m_fileSpec = fileSpec;
}

void QGIFace::loadSvgHatch(std::string fileSpec)
{
    QString qfs(QString::fromUtf8(fileSpec.data(),fileSpec.size()));
    QFile f(qfs);
    if (!f.open(QFile::ReadOnly | QFile::Text))  {
        Base::Console().Error("QGIFace could not read %s\n",fileSpec.c_str());
        return;
    }
    m_svgXML = f.readAll();
    if (!m_svg->load(&m_svgXML)) {
        Base::Console().Error("Error - Could not load hatch into SVG renderer for %s\n", fileSpec.c_str());
        return;
    }
}

void QGIFace::setFillMode(QGIFace::fillMode m)
{
    m_mode = m;
    if ((m_mode == NoFill) ||
        (m_mode == PlainFill)) {
        isHatched(false);
    } else {
        isHatched(true);
    }
}

void QGIFace::setOutline(const QPainterPath & path)
{
    m_outline = path;
}

void QGIFace::clearLineSets(void)
{
    m_geomHatchPaths.clear();
    m_dashSpecs.clear();
    clearFillItems();
}

//each line set needs a painterpath, a dashspec and a QGPItem to show them
void QGIFace::addLineSet(QPainterPath pp, std::vector<double> dp)
{
    m_geomHatchPaths.push_back(pp);
    m_dashSpecs.push_back(DashSpec(dp));
    addFillItem();
}

QGraphicsPathItem*  QGIFace::addFillItem()
{
    QGraphicsPathItem* fillItem = new QGraphicsPathItem();
    fillItem->setParentItem(this);
    m_fillItems.push_back(fillItem);
    return fillItem;
}

void QGIFace::clearFillItems(void)
{
    for (auto& f: m_fillItems) {
        f->setParentItem(nullptr);
        this->scene()->removeItem(f);
        delete f;
    }
}

//convert from PAT style "-1,0,-1,+1" to Qt style "mark,space,mark,space"
QVector<qreal> QGIFace::decodeDashSpec(DashSpec patDash)
{
    //Rez::guiX(something)?
    double dotLength = 3.0;
    double unitLength = 6.0;
//    double penWidth = m_geomWeight;    //mark, space and dot lengths are to be in terms of penWidth(Qt) or mm(PAT)??
//                                        //if we want it in terms of mm, we need to divide by penWidth?
//    double minPen = 0.01;               //avoid trouble with cosmetic pen (zero width)
    std::vector<double> result;
    std::string prim;
    for (auto& d: patDash.get()) {
        double strokeLength;
        if (DrawUtil::fpCompare(d,0.0)) {                       //pat dot
             strokeLength = dotLength;
        } else if (Rez::guiX(d) < 0) {                          //pat space
             strokeLength = fabs(Rez::guiX(d)) * unitLength;
        } else {                                                //pat dash
             strokeLength = Rez::guiX(d) * unitLength;
        }
        result.push_back(strokeLength);
    }
    return QVector<qreal>::fromStdVector( result );
}

QPen QGIFace::setGeomPen(int i)
{
    //m_dashSpecs[i].dump("spec test");
    DashSpec ourSpec = m_dashSpecs.at(i);
    //ourSpec.dump("our spec");

    QPen result;
    result.setWidthF(Rez::guiX(m_geomWeight));    //Rez::guiX() ?? line weights are in mm?
    result.setColor(m_geomColor);
    if (ourSpec.empty()) {
       result.setStyle(Qt::SolidLine);
    } else {
       result.setStyle(Qt::CustomDashLine);
       result.setDashPattern(decodeDashSpec(ourSpec));
    }
    return result;
}

void QGIFace::buildSvgHatch()
{
    double wTile = SVGSIZEW * m_fillScale;
    double hTile = SVGSIZEH * m_fillScale;
    double w = m_outline.boundingRect().width();
    double h = m_outline.boundingRect().height();
    QRectF r = m_outline.boundingRect();
    QPointF fCenter = r.center();
    double nw = ceil(w / wTile);
    double nh = ceil(h / hTile);
    w = nw * wTile;
    h = nh * hTile;
    m_rect->setRect(0.,0.,w,-h);
    m_rect->centerAt(fCenter);
    r = m_rect->rect();
    QByteArray before,after;
    before.append(QString::fromStdString(SVGCOLPREFIX + SVGCOLDEFAULT));
    after.append(QString::fromStdString(SVGCOLPREFIX + m_svgCol));
    QByteArray colorXML = m_svgXML.replace(before,after);
    for (int iw = 0; iw < int(nw); iw++) {
        for (int ih = 0; ih < int(nh); ih++) {
            QGCustomSvg* tile = new QGCustomSvg();
            tile->setScale(m_fillScale);
            if (tile->load(&colorXML)) {
                tile->setParentItem(m_rect);
                tile->setPos(iw*wTile,-h + ih*hTile);
            }
        }
    }
}

void QGIFace::clearSvg()
{
    toggleSvg(false);
}

//this isn't used currently
QPixmap QGIFace::textureFromSvg(std::string fileSpec)
{
    QPixmap result;
    QString qs(QString::fromStdString(fileSpec));
    QFileInfo ffi(qs);
    if (ffi.isReadable()) {
        QSvgRenderer renderer(qs);
        QPixmap pixMap(renderer.defaultSize());
        pixMap.fill(Qt::white);                                            //try  Qt::transparent?
        QPainter painter(&pixMap);
        renderer.render(&painter);                                         //svg texture -> bitmap
        result = pixMap.scaled(m_fillScale,m_fillScale);
    }  //else return empty pixmap
    return result;
}

void QGIFace::setHatchColor(App::Color c)
{
    m_svgCol = c.asCSSString();
    m_geomColor = c.asValue<QColor>();
}

void QGIFace::setHatchScale(double s)
{
    m_fillScale = s;
}

//QtSvg does not handle clipping, so we must be able to turn the hatching on/off
void QGIFace::toggleSvg(bool b)
{
    if (b) {
        m_rect->show();
    } else {
        m_rect->hide();
    }
    update();
}

QPixmap QGIFace::textureFromBitmap(std::string fileSpec)
{
    QPixmap pix;
    QString qs = QString::fromUtf8(fileSpec.data(),fileSpec.size());
    QFileInfo ffi(qs);
    if (ffi.isReadable()) {
        QImage img = QImage(qs);
        img = img.scaled(Rez::guiX(m_fillScale),Rez::guiX(m_fillScale));
        pix = QPixmap::fromImage(img);
    }
    return pix;
}

void QGIFace::setFill(QColor c, Qt::BrushStyle s) {
    m_colNormalFill = c;
    m_styleNormal = s;
}

void QGIFace::setFill(QBrush b) {
    m_colNormalFill = b.color();
    m_styleNormal = b.style();
}

void QGIFace::resetFill() {
    m_colNormalFill = m_colDefFill;
    m_styleNormal = m_styleDef;
}

void QGIFace::setLineWeight(double w) {
    m_geomWeight = w;
}

QRectF QGIFace::boundingRect() const
{
    return shape().controlPointRect();
}

QPainterPath QGIFace::shape() const
{
    return path();
}

void QGIFace::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) {
    QStyleOptionGraphicsItem myOption(*option);
    myOption.state &= ~QStyle::State_Selected;

    m_brush.setStyle(m_fillStyle);
    m_brush.setColor(m_fillColor);
    setBrush(m_brush);
    QGIPrimPath::paint (painter, &myOption, widget);
}

<commit_msg>can't assign nullptr to a QPixmap<commit_after>/***************************************************************************
 *   Copyright (c) 2013 Luke Parry <l.parry@warwick.ac.uk>                 *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
#include <QAction>
#include <QApplication>
#include <QContextMenuEvent>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QGraphicsSceneHoverEvent>
#include <QPainterPathStroker>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include <QBitmap>
#include <QFile>
#include <QFileInfo>
#endif

#include <QFile>
#include <QTextStream>
#include <QRectF>
#include <QPointF>

#include <cmath>

#include <App/Application.h>
#include <App/Material.h>
#include <Base/Console.h>
#include <Base/Parameter.h>

#include <Mod/TechDraw/App/DrawUtil.h>

#include "Rez.h"
#include "QGCustomSvg.h"
#include "QGCustomRect.h"
#include "QGIFace.h"

using namespace TechDrawGui;
using namespace TechDraw;

QGIFace::QGIFace(int index) :
    projIndex(index),
    m_colDefFill(Qt::white),          //Qt::transparent?  paper colour?
    m_styleDef(Qt::SolidPattern),
    m_styleSelect(Qt::SolidPattern)
{
    setFillMode(NoFill);
    isHatched(false);
    setFlag(QGraphicsItem::ItemClipsChildrenToShape,true);

    //setStyle(Qt::NoPen);    //don't draw face lines, just fill for debugging
    setStyle(Qt::DashLine);

    m_styleNormal = m_styleDef;
    m_fillStyle = m_styleDef;
    m_colNormalFill = m_colDefFill;
    m_geomColor = QColor(Qt::black);
    setLineWeight(0.5);                   //0 = cosmetic

    setPrettyNormal();
    m_texture = QPixmap();                      //empty texture

    m_svg = new QGCustomSvg();

    m_rect = new QGCustomRect();
    m_rect->setParentItem(this);

    m_svgCol = SVGCOLDEFAULT;
    m_fillScale = 1.0;
}

QGIFace::~QGIFace()
{
    //nothing to do. every item is a child of QGIFace & will get removed/deleted when QGIF is deleted
}

void QGIFace::draw()
{
    setPath(m_outline);                         //Face boundary

    if (isHatched()) {
        if (m_mode == GeomHatchFill) {                             //crosshatch
            if (!m_geomHatchPaths.empty()) {                                  //surrogate for LineSets.empty
                m_brush.setTexture(QPixmap());
                m_fillStyle = m_styleDef;
                m_styleNormal = m_fillStyle;
                int pathNo = 0;
                for (auto& pp: m_geomHatchPaths) {
                    QGraphicsPathItem* fillItem = m_fillItems.at(pathNo);
                    fillItem->setPath(pp);
                    QPen geomPen = setGeomPen(pathNo);
                    fillItem->setPen(geomPen);
                    pathNo++;
                }
            }
        } else if ((m_mode == FromFile) ||
                   (m_mode == SvgFill)  ||
                   (m_mode == BitmapFill)) {
            QFileInfo hfi(QString::fromUtf8(m_fileSpec.data(),m_fileSpec.size()));
            if (hfi.isReadable()) {
                QString ext = hfi.suffix();
                if (ext.toUpper() == QString::fromUtf8("SVG")) {
                    setFillMode(SvgFill);
                    m_brush.setTexture(QPixmap());
                    m_fillStyle = m_styleDef;
                    m_styleNormal = m_fillStyle;
                    loadSvgHatch(m_fileSpec);
                    buildSvgHatch();
                    toggleSvg(true);
                } else if ((ext.toUpper() == QString::fromUtf8("JPG"))   ||
                         (ext.toUpper() == QString::fromUtf8("PNG"))   ||
                         (ext.toUpper() == QString::fromUtf8("JPEG"))  ||
                         (ext.toUpper() == QString::fromUtf8("BMP")) ) {
                    setFillMode(BitmapFill);
                    toggleSvg(false);
                    m_fillStyle   = Qt::TexturePattern;
                    m_texture = textureFromBitmap(m_fileSpec);
                    m_brush.setTexture(m_texture);
                }
            }
        }
    }
    show();
}

void QGIFace::setPrettyNormal() {
    if (isHatched()  &&
        (m_mode == BitmapFill) ) {                               //hatch with bitmap fill
        m_fillStyle = Qt::TexturePattern;
        m_brush.setTexture(m_texture);
    } else {
        m_fillStyle = m_styleNormal;
        m_brush.setTexture(QPixmap());
        m_brush.setStyle(m_fillStyle);
        m_fillColor = m_colNormalFill;
    }
    QGIPrimPath::setPrettyNormal();
}

void QGIFace::setPrettyPre() {
    m_brush.setTexture(QPixmap());
    m_fillStyle = m_styleSelect;
    m_fillColor = getPreColor();
    QGIPrimPath::setPrettyPre();
}

void QGIFace::setPrettySel() {
    m_brush.setTexture(QPixmap());
    m_fillStyle = m_styleSelect;
    m_fillColor = getSelectColor();
    QGIPrimPath::setPrettySel();
}

void QGIFace::setDrawEdges(bool b) {
    if (b) {
        setStyle(Qt::DashLine);
    } else {
        setStyle(Qt::NoPen);    //don't draw face lines, just fill
    }
}

void QGIFace::setHatchFile(std::string fileSpec)
{
    m_fileSpec = fileSpec;
}

void QGIFace::loadSvgHatch(std::string fileSpec)
{
    QString qfs(QString::fromUtf8(fileSpec.data(),fileSpec.size()));
    QFile f(qfs);
    if (!f.open(QFile::ReadOnly | QFile::Text))  {
        Base::Console().Error("QGIFace could not read %s\n",fileSpec.c_str());
        return;
    }
    m_svgXML = f.readAll();
    if (!m_svg->load(&m_svgXML)) {
        Base::Console().Error("Error - Could not load hatch into SVG renderer for %s\n", fileSpec.c_str());
        return;
    }
}

void QGIFace::setFillMode(QGIFace::fillMode m)
{
    m_mode = m;
    if ((m_mode == NoFill) ||
        (m_mode == PlainFill)) {
        isHatched(false);
    } else {
        isHatched(true);
    }
}

void QGIFace::setOutline(const QPainterPath & path)
{
    m_outline = path;
}

void QGIFace::clearLineSets(void)
{
    m_geomHatchPaths.clear();
    m_dashSpecs.clear();
    clearFillItems();
}

//each line set needs a painterpath, a dashspec and a QGPItem to show them
void QGIFace::addLineSet(QPainterPath pp, std::vector<double> dp)
{
    m_geomHatchPaths.push_back(pp);
    m_dashSpecs.push_back(DashSpec(dp));
    addFillItem();
}

QGraphicsPathItem*  QGIFace::addFillItem()
{
    QGraphicsPathItem* fillItem = new QGraphicsPathItem();
    fillItem->setParentItem(this);
    m_fillItems.push_back(fillItem);
    return fillItem;
}

void QGIFace::clearFillItems(void)
{
    for (auto& f: m_fillItems) {
        f->setParentItem(nullptr);
        this->scene()->removeItem(f);
        delete f;
    }
}

//convert from PAT style "-1,0,-1,+1" to Qt style "mark,space,mark,space"
QVector<qreal> QGIFace::decodeDashSpec(DashSpec patDash)
{
    //Rez::guiX(something)?
    double dotLength = 3.0;
    double unitLength = 6.0;
//    double penWidth = m_geomWeight;    //mark, space and dot lengths are to be in terms of penWidth(Qt) or mm(PAT)??
//                                        //if we want it in terms of mm, we need to divide by penWidth?
//    double minPen = 0.01;               //avoid trouble with cosmetic pen (zero width)
    std::vector<double> result;
    std::string prim;
    for (auto& d: patDash.get()) {
        double strokeLength;
        if (DrawUtil::fpCompare(d,0.0)) {                       //pat dot
             strokeLength = dotLength;
        } else if (Rez::guiX(d) < 0) {                          //pat space
             strokeLength = fabs(Rez::guiX(d)) * unitLength;
        } else {                                                //pat dash
             strokeLength = Rez::guiX(d) * unitLength;
        }
        result.push_back(strokeLength);
    }
    return QVector<qreal>::fromStdVector( result );
}

QPen QGIFace::setGeomPen(int i)
{
    //m_dashSpecs[i].dump("spec test");
    DashSpec ourSpec = m_dashSpecs.at(i);
    //ourSpec.dump("our spec");

    QPen result;
    result.setWidthF(Rez::guiX(m_geomWeight));    //Rez::guiX() ?? line weights are in mm?
    result.setColor(m_geomColor);
    if (ourSpec.empty()) {
       result.setStyle(Qt::SolidLine);
    } else {
       result.setStyle(Qt::CustomDashLine);
       result.setDashPattern(decodeDashSpec(ourSpec));
    }
    return result;
}

void QGIFace::buildSvgHatch()
{
    double wTile = SVGSIZEW * m_fillScale;
    double hTile = SVGSIZEH * m_fillScale;
    double w = m_outline.boundingRect().width();
    double h = m_outline.boundingRect().height();
    QRectF r = m_outline.boundingRect();
    QPointF fCenter = r.center();
    double nw = ceil(w / wTile);
    double nh = ceil(h / hTile);
    w = nw * wTile;
    h = nh * hTile;
    m_rect->setRect(0.,0.,w,-h);
    m_rect->centerAt(fCenter);
    r = m_rect->rect();
    QByteArray before,after;
    before.append(QString::fromStdString(SVGCOLPREFIX + SVGCOLDEFAULT));
    after.append(QString::fromStdString(SVGCOLPREFIX + m_svgCol));
    QByteArray colorXML = m_svgXML.replace(before,after);
    for (int iw = 0; iw < int(nw); iw++) {
        for (int ih = 0; ih < int(nh); ih++) {
            QGCustomSvg* tile = new QGCustomSvg();
            tile->setScale(m_fillScale);
            if (tile->load(&colorXML)) {
                tile->setParentItem(m_rect);
                tile->setPos(iw*wTile,-h + ih*hTile);
            }
        }
    }
}

void QGIFace::clearSvg()
{
    toggleSvg(false);
}

//this isn't used currently
QPixmap QGIFace::textureFromSvg(std::string fileSpec)
{
    QPixmap result;
    QString qs(QString::fromStdString(fileSpec));
    QFileInfo ffi(qs);
    if (ffi.isReadable()) {
        QSvgRenderer renderer(qs);
        QPixmap pixMap(renderer.defaultSize());
        pixMap.fill(Qt::white);                                            //try  Qt::transparent?
        QPainter painter(&pixMap);
        renderer.render(&painter);                                         //svg texture -> bitmap
        result = pixMap.scaled(m_fillScale,m_fillScale);
    }  //else return empty pixmap
    return result;
}

void QGIFace::setHatchColor(App::Color c)
{
    m_svgCol = c.asCSSString();
    m_geomColor = c.asValue<QColor>();
}

void QGIFace::setHatchScale(double s)
{
    m_fillScale = s;
}

//QtSvg does not handle clipping, so we must be able to turn the hatching on/off
void QGIFace::toggleSvg(bool b)
{
    if (b) {
        m_rect->show();
    } else {
        m_rect->hide();
    }
    update();
}

QPixmap QGIFace::textureFromBitmap(std::string fileSpec)
{
    QPixmap pix;
    QString qs = QString::fromUtf8(fileSpec.data(),fileSpec.size());
    QFileInfo ffi(qs);
    if (ffi.isReadable()) {
        QImage img = QImage(qs);
        img = img.scaled(Rez::guiX(m_fillScale),Rez::guiX(m_fillScale));
        pix = QPixmap::fromImage(img);
    }
    return pix;
}

void QGIFace::setFill(QColor c, Qt::BrushStyle s) {
    m_colNormalFill = c;
    m_styleNormal = s;
}

void QGIFace::setFill(QBrush b) {
    m_colNormalFill = b.color();
    m_styleNormal = b.style();
}

void QGIFace::resetFill() {
    m_colNormalFill = m_colDefFill;
    m_styleNormal = m_styleDef;
}

void QGIFace::setLineWeight(double w) {
    m_geomWeight = w;
}

QRectF QGIFace::boundingRect() const
{
    return shape().controlPointRect();
}

QPainterPath QGIFace::shape() const
{
    return path();
}

void QGIFace::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) {
    QStyleOptionGraphicsItem myOption(*option);
    myOption.state &= ~QStyle::State_Selected;

    m_brush.setStyle(m_fillStyle);
    m_brush.setColor(m_fillColor);
    setBrush(m_brush);
    QGIPrimPath::paint (painter, &myOption, widget);
}

<|endoftext|>


<commit_before>/**
*@file
 */
#pragma once

#include "numbirch/utility.hpp"
#include "numbirch/cuda/cuda.hpp"
#include "numbirch/cuda/curand.hpp"

namespace numbirch {

struct simulate_bernoulli_functor {
  curandState_t* rngs;
  simulate_bernoulli_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE bool operator()(const real rho) {
    #ifndef __CUDA_ARCH__
    return std::bernoulli_distribution(rho)(stl<bool>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return curand_uniform_double(curand_rng(rngs)) <= rho;
    } else {
      return curand_uniform(curand_rng(rngs)) <= rho;
    }
    #endif
  }
};

struct simulate_beta_functor {
  curandState_t* rngs;
  simulate_beta_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real alpha, const real beta) {
    real u, v;
    #ifndef __CUDA_ARCH__
    auto& rng = stl<real>::rng();
    u = std::gamma_distribution<real>(alpha)(rng);
    v = std::gamma_distribution<real>(beta)(rng);
    #else
    if constexpr (std::is_same_v<real,double>) {
      u = curand_gamma_double(curand_rng(rngs), alpha);
      v = curand_gamma_double(curand_rng(rngs), beta);
    } else {
      u = curand_gamma(curand_rng(rngs), alpha);
      v = curand_gamma(curand_rng(rngs), beta);
    }
    #endif
    return u/(u + v);
  }
};

struct simulate_binomial_functor {
  curandState_t* rngs;
  simulate_binomial_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE int operator()(const real n, const real rho) {
    #ifndef __CUDA_ARCH__
    return std::binomial_distribution<int>(n, rho)(stl<int>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return curand_binomial_double(curand_rng(rngs), n, rho);
    } else {
      return curand_binomial(curand_rng(rngs), n, rho);
    }
    #endif
  }
};

struct simulate_chi_squared_functor {
  curandState_t* rngs;
  simulate_chi_squared_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real nu) {
    #ifndef __CUDA_ARCH__
    return std::chi_squared_distribution<real>(nu)(stl<real>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return real(2.0)*curand_gamma_double(curand_rng(rngs), real(0.5)*nu);
    } else {
      return real(2.0)*curand_gamma(curand_rng(rngs), real(0.5)*nu);
    }
    #endif
  }
};

struct simulate_exponential_functor {
  curandState_t* rngs;
  simulate_exponential_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real lambda) {
    #ifndef __CUDA_ARCH__
    return std::exponential_distribution<real>(lambda)(stl<real>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return -std::log(curand_uniform_double(curand_rng(rngs)))/lambda;
    } else {
      return -std::log(curand_uniform(curand_rng(rngs)))/lambda;
    }
    #endif
  }
};

struct simulate_gamma_functor {
  curandState_t* rngs;
  simulate_gamma_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real k, const real theta) {
    #ifndef __CUDA_ARCH__
    return std::gamma_distribution<real>(k, theta)(stl<real>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return curand_gamma(curand_rng(rngs), k)*theta;
    } else {
      return curand_gamma_double(curand_rng(rngs), k)*theta;
    }
    #endif
  }
};

struct simulate_gaussian_functor {
  curandState_t* rngs;
  simulate_gaussian_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real mu, const real sigma2) {
    #ifndef __CUDA_ARCH__
    return std::normal_distribution<real>(mu, std::sqrt(sigma2))(stl<real>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return mu + std::sqrt(sigma2)*curand_normal_double(curand_rng(rngs));
    } else {
      return mu + std::sqrt(sigma2)*curand_normal(curand_rng(rngs));
    }
    #endif
  }
};

struct simulate_negative_binomial_functor {
  curandState_t* rngs;
  simulate_negative_binomial_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real k, const real rho) {
    #ifndef __CUDA_ARCH__
    return std::negative_binomial_distribution<int>(k, rho)(stl<real>::rng());
    // ^ negative_binomial_distribution requires integral type
    #else
    real theta, lambda;
    theta = (real(1.0) - rho)/rho;
    if constexpr (std::is_same_v<real,double>) {
      lambda = curand_gamma_double(curand_rng(rngs), k);
    } else {
      lambda = curand_gamma(curand_rng(rngs), k);
    }
    return curand_poisson(curand_rng(rngs), lambda*theta);
    #endif
  }
};

struct simulate_poisson_functor {
  curandState_t* rngs;
  simulate_poisson_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE int operator()(const real lambda) {
    #ifndef __CUDA_ARCH__
    return std::poisson_distribution<int>(lambda)(stl<real>::rng());
    // ^ poisson_distribution requires integral type
    #else
    return curand_poisson(curand_rng(rngs), lambda);
    #endif
  }
};

struct simulate_uniform_functor {
  curandState_t* rngs;
  simulate_uniform_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real l, const real u) {
    #ifndef __CUDA_ARCH__
    return std::uniform_real_distribution<real>(l, u)(stl<real>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return l + (u - l)*curand_uniform_double(curand_rng(rngs));
    } else {
      return l + (u - l)*curand_uniform(curand_rng(rngs));
    }
    #endif
  }
};

struct simulate_uniform_int_functor {
  curandState_t* rngs;
  simulate_uniform_int_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE int operator()(const int l, const int u) {
    #ifndef __CUDA_ARCH__
    return std::uniform_int_distribution<int>(l, u)(stl<int>::rng());
    // ^ uniform_int_distribution requires integral type
    #else
    return int(l + (u - l + 1)*curand_uniform(curand_rng(rngs)));
    #endif
  }
};

struct simulate_weibull_functor {
  curandState_t* rngs;
  simulate_weibull_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real k, const real lambda) {
    #ifndef __CUDA_ARCH__
    return std::weibull_distribution<real>(k, lambda)(stl<real>::rng());
    #else
    real u;
    if constexpr (std::is_same_v<real,double>) {
      u = curand_uniform_double(curand_rng(rngs));
    } else {
      u = curand_uniform(curand_rng(rngs));
    }
    return lambda*std::pow(-std::log(real(1.0) - u), real(1.0)/k);
    #endif
  }
};

struct standard_gaussian_functor {
  curandState_t* rngs;
  standard_gaussian_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const int i, const int j) {
    #ifndef __CUDA_ARCH__
    return std::normal_distribution<real>()(stl<real>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return curand_normal_double(curand_rng(rngs));
    } else {
      return curand_normal(curand_rng(rngs));
    }
    #endif
  }
};

template<class T>
struct standard_wishart_functor {
  T k;
  int n;
  curandState_t* rngs;
  standard_wishart_functor(const T& k, const int n) :
      k(k),
      n(n),
      rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const int i, const int j) {
    if (i == j) {
      /* on diagonal */
      real nu = get(k) + (n - 1 - i); // i is 0-based here
      real x;
      #ifndef __CUDA_ARCH__
      x = std::chi_squared_distribution<real>(nu)(stl<real>::rng());
      #else
      if constexpr (std::is_same_v<real,double>) {
        x = real(2.0)*curand_gamma_double(curand_rng(rngs), real(0.5)*nu);
      } else {
        x = real(2.0)*curand_gamma(curand_rng(rngs), real(0.5)*nu);
      }
      #endif
      return std::sqrt(x);
    } else if (i > j) {
      /* in lower triangle */
      #ifndef __CUDA_ARCH__
      return std::normal_distribution<real>()(stl<real>::rng());
      #else
      if constexpr (std::is_same_v<real,double>) {
        return curand_normal_double(curand_rng(rngs));
      } else {
        return curand_normal(curand_rng(rngs));
      }
      #endif
    } else {
      /* in upper triangle */
      return real(0.0);
    }
  }
};

}
<commit_msg>Added double code path for simulate_uniform_int().<commit_after>/**
*@file
 */
#pragma once

#include "numbirch/utility.hpp"
#include "numbirch/cuda/cuda.hpp"
#include "numbirch/cuda/curand.hpp"

namespace numbirch {

struct simulate_bernoulli_functor {
  curandState_t* rngs;
  simulate_bernoulli_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE bool operator()(const real rho) {
    #ifndef __CUDA_ARCH__
    return std::bernoulli_distribution(rho)(stl<bool>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return curand_uniform_double(curand_rng(rngs)) <= rho;
    } else {
      return curand_uniform(curand_rng(rngs)) <= rho;
    }
    #endif
  }
};

struct simulate_beta_functor {
  curandState_t* rngs;
  simulate_beta_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real alpha, const real beta) {
    real u, v;
    #ifndef __CUDA_ARCH__
    auto& rng = stl<real>::rng();
    u = std::gamma_distribution<real>(alpha)(rng);
    v = std::gamma_distribution<real>(beta)(rng);
    #else
    if constexpr (std::is_same_v<real,double>) {
      u = curand_gamma_double(curand_rng(rngs), alpha);
      v = curand_gamma_double(curand_rng(rngs), beta);
    } else {
      u = curand_gamma(curand_rng(rngs), alpha);
      v = curand_gamma(curand_rng(rngs), beta);
    }
    #endif
    return u/(u + v);
  }
};

struct simulate_binomial_functor {
  curandState_t* rngs;
  simulate_binomial_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE int operator()(const real n, const real rho) {
    #ifndef __CUDA_ARCH__
    return std::binomial_distribution<int>(n, rho)(stl<int>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return curand_binomial_double(curand_rng(rngs), n, rho);
    } else {
      return curand_binomial(curand_rng(rngs), n, rho);
    }
    #endif
  }
};

struct simulate_chi_squared_functor {
  curandState_t* rngs;
  simulate_chi_squared_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real nu) {
    #ifndef __CUDA_ARCH__
    return std::chi_squared_distribution<real>(nu)(stl<real>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return real(2.0)*curand_gamma_double(curand_rng(rngs), real(0.5)*nu);
    } else {
      return real(2.0)*curand_gamma(curand_rng(rngs), real(0.5)*nu);
    }
    #endif
  }
};

struct simulate_exponential_functor {
  curandState_t* rngs;
  simulate_exponential_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real lambda) {
    #ifndef __CUDA_ARCH__
    return std::exponential_distribution<real>(lambda)(stl<real>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return -std::log(curand_uniform_double(curand_rng(rngs)))/lambda;
    } else {
      return -std::log(curand_uniform(curand_rng(rngs)))/lambda;
    }
    #endif
  }
};

struct simulate_gamma_functor {
  curandState_t* rngs;
  simulate_gamma_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real k, const real theta) {
    #ifndef __CUDA_ARCH__
    return std::gamma_distribution<real>(k, theta)(stl<real>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return curand_gamma(curand_rng(rngs), k)*theta;
    } else {
      return curand_gamma_double(curand_rng(rngs), k)*theta;
    }
    #endif
  }
};

struct simulate_gaussian_functor {
  curandState_t* rngs;
  simulate_gaussian_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real mu, const real sigma2) {
    #ifndef __CUDA_ARCH__
    return std::normal_distribution<real>(mu, std::sqrt(sigma2))(stl<real>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return mu + std::sqrt(sigma2)*curand_normal_double(curand_rng(rngs));
    } else {
      return mu + std::sqrt(sigma2)*curand_normal(curand_rng(rngs));
    }
    #endif
  }
};

struct simulate_negative_binomial_functor {
  curandState_t* rngs;
  simulate_negative_binomial_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real k, const real rho) {
    #ifndef __CUDA_ARCH__
    return std::negative_binomial_distribution<int>(k, rho)(stl<real>::rng());
    // ^ negative_binomial_distribution requires integral type
    #else
    real theta, lambda;
    theta = (real(1.0) - rho)/rho;
    if constexpr (std::is_same_v<real,double>) {
      lambda = curand_gamma_double(curand_rng(rngs), k);
    } else {
      lambda = curand_gamma(curand_rng(rngs), k);
    }
    return curand_poisson(curand_rng(rngs), lambda*theta);
    #endif
  }
};

struct simulate_poisson_functor {
  curandState_t* rngs;
  simulate_poisson_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE int operator()(const real lambda) {
    #ifndef __CUDA_ARCH__
    return std::poisson_distribution<int>(lambda)(stl<real>::rng());
    // ^ poisson_distribution requires integral type
    #else
    return curand_poisson(curand_rng(rngs), lambda);
    #endif
  }
};

struct simulate_uniform_functor {
  curandState_t* rngs;
  simulate_uniform_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real l, const real u) {
    #ifndef __CUDA_ARCH__
    return std::uniform_real_distribution<real>(l, u)(stl<real>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return l + (u - l)*curand_uniform_double(curand_rng(rngs));
    } else {
      return l + (u - l)*curand_uniform(curand_rng(rngs));
    }
    #endif
  }
};

struct simulate_uniform_int_functor {
  curandState_t* rngs;
  simulate_uniform_int_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE int operator()(const int l, const int u) {
    #ifndef __CUDA_ARCH__
    return std::uniform_int_distribution<int>(l, u)(stl<int>::rng());
    // ^ uniform_int_distribution requires integral type
    #else
    if constexpr (std::is_same_v<real,double>) {
      return l + int(real(u - l + 1)*curand_uniform_double(curand_rng(rngs)));
    } else {
      return l + int(real(u - l + 1)*curand_uniform(curand_rng(rngs)));
    }
    #endif
  }
};

struct simulate_weibull_functor {
  curandState_t* rngs;
  simulate_weibull_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const real k, const real lambda) {
    #ifndef __CUDA_ARCH__
    return std::weibull_distribution<real>(k, lambda)(stl<real>::rng());
    #else
    real u;
    if constexpr (std::is_same_v<real,double>) {
      u = curand_uniform_double(curand_rng(rngs));
    } else {
      u = curand_uniform(curand_rng(rngs));
    }
    return lambda*std::pow(-std::log(real(1.0) - u), real(1.0)/k);
    #endif
  }
};

struct standard_gaussian_functor {
  curandState_t* rngs;
  standard_gaussian_functor() : rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const int i, const int j) {
    #ifndef __CUDA_ARCH__
    return std::normal_distribution<real>()(stl<real>::rng());
    #else
    if constexpr (std::is_same_v<real,double>) {
      return curand_normal_double(curand_rng(rngs));
    } else {
      return curand_normal(curand_rng(rngs));
    }
    #endif
  }
};

template<class T>
struct standard_wishart_functor {
  T k;
  int n;
  curandState_t* rngs;
  standard_wishart_functor(const T& k, const int n) :
      k(k),
      n(n),
      rngs(numbirch::rngs) {
    //
  }
  NUMBIRCH_HOST_DEVICE real operator()(const int i, const int j) {
    if (i == j) {
      /* on diagonal */
      real nu = get(k) + (n - 1 - i); // i is 0-based here
      real x;
      #ifndef __CUDA_ARCH__
      x = std::chi_squared_distribution<real>(nu)(stl<real>::rng());
      #else
      if constexpr (std::is_same_v<real,double>) {
        x = real(2.0)*curand_gamma_double(curand_rng(rngs), real(0.5)*nu);
      } else {
        x = real(2.0)*curand_gamma(curand_rng(rngs), real(0.5)*nu);
      }
      #endif
      return std::sqrt(x);
    } else if (i > j) {
      /* in lower triangle */
      #ifndef __CUDA_ARCH__
      return std::normal_distribution<real>()(stl<real>::rng());
      #else
      if constexpr (std::is_same_v<real,double>) {
        return curand_normal_double(curand_rng(rngs));
      } else {
        return curand_normal(curand_rng(rngs));
      }
      #endif
    } else {
      /* in upper triangle */
      return real(0.0);
    }
  }
};

}
<|endoftext|>


<commit_before>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2019 Baldur Karlsson
 *
 * 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 OR COPYRIGHT HOLDERS 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 "renderdoccmd.h"

int main(int argc, char *argv[])
{
  return 0;
}
<commit_msg>Add support for GGP in "renderdoccmd replay"<commit_after>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2019 Baldur Karlsson
 *
 * 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 OR COPYRIGHT HOLDERS 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 "renderdoccmd.h"
#include <signal.h>
#include <string.h>
#include <unistd.h>

#include <ggp_c/ggp.h>
#include <replay/renderdoc_replay.h>

const uint64_t kMicrosecondsPerFrame = 16666L;

// struct appData: Global application data
static struct
{
  // GGP
  GgpEventQueue event_queue;
  uint32_t stream_started_handler_id;
  uint32_t stream_stopped_handler_id;
  // General
  bool quit;
} app_data = {0};

void Daemonise()
{
  // don't change dir, but close stdin/stdout
  daemon(1, 0);
}

WindowingData DisplayRemoteServerPreview(bool active, const rdcarray<WindowingSystem> &systems)
{
  static WindowingData remoteServerPreview = {WindowingSystem::Unknown};
  // No preview implemented.
  return remoteServerPreview;
}

// ClockNowMicroSeconds(): Return current time in microseconds
static inline uint64_t ClockNowMicroSeconds()
{
  struct timespec now = {};
  clock_gettime(CLOCK_MONOTONIC_RAW, &now);
  uint64_t nanoseconds = (now.tv_sec * 1000000000LL) + now.tv_nsec;
  uint64_t microseconds = nanoseconds / 1000LL;
  return microseconds;
}

// HandleStreamStarted(): Client connected handler
static void HandleStreamStarted(void *user_data)
{
  std::cout << "GGP client connected" << std::endl;
}

// HandleStreamStopped(): Client disconnected handler
static void HandleStreamStopped(const GgpStreamStoppedEvent *event, void *user_data)
{
  std::cout << "GGP client disconnected" << std::endl;
  // Exit the application if the client disconnects to exit.
  if(event->stream_stopped_reason == kGgpStreamStopped_Exited)
  {
    app_data.quit = true;
  }
  else if(event->stream_stopped_reason == kGgpStreamStopped_Unexpected)
  {
    GgpSuspended();
  }
}

// UnregisterCallback(): Handler unregistered
static void UnregisterCallback(void *user_data)
{
  std::cout << "Unregistered callback" << std::endl;
}

// Initialize(): Initialize application
static void Initialize()
{
  // Initialize event queue
  app_data.event_queue = GgpEventQueueCreate();
  std::cout << "GGP event queue created" << std::endl;
  // Add client connection handlers
  app_data.stream_started_handler_id = GgpAddStreamStartedHandler(
      app_data.event_queue, HandleStreamStarted, NULL, UnregisterCallback);
  app_data.stream_stopped_handler_id = GgpAddStreamStoppedHandler(
      app_data.event_queue, HandleStreamStopped, NULL, UnregisterCallback);
  // Signal that the session is ready to receive events.
  GgpHandlersRegistered();

  GgpReadyToStream();
  std::cout << "GGP ready to stream" << std::endl;
}

// Finalize(): Clean up application resources
static void Finalize()
{
  // Destroy the event queue
  GgpEventQueueDestroy(app_data.event_queue);
  std::cout << "GGP event queue destroyed" << std::endl;
  // Remove client connection handlers.
  GgpRemoveStreamStartedHandler(app_data.stream_started_handler_id);
  GgpRemoveStreamStoppedHandler(app_data.stream_stopped_handler_id);
  // Indicate that GGP should shutdown.
  GgpShutDown();
}

void DisplayRendererPreview(IReplayController *renderer, TextureDisplay &displayCfg, uint32_t width,
                            uint32_t height, uint32_t numLoops)
{
  Initialize();

  IReplayOutput *out = renderer->CreateOutput(CreateGgpWindowingData(), ReplayOutputType::Texture);
  out->SetTextureDisplay(displayCfg);

  // Wait until user closes the window, then exit
  while(!app_data.quit)
  {
    uint64_t whenToResume = ClockNowMicroSeconds() + kMicrosecondsPerFrame;
    while(GgpEventQueueProcessEvent(app_data.event_queue, 0))
    {
    }
    renderer->SetFrameEvent(10000000, true);
    out->Display();
    // Sleep for 1/60 second (one frame)
    uint64_t timeLeft = whenToResume - ClockNowMicroSeconds();
    if(timeLeft > 0)
    {
      struct timespec sleepTime = {};
      sleepTime.tv_nsec = timeLeft * 1000LL;
      nanosleep(&sleepTime, NULL);
    }
  }

  Finalize();
}

void sig_handler(int signo)
{
  if(usingKillSignal)
    killSignal = true;
  else
    exit(1);
}

int main(int argc, char *argv[])
{
  setlocale(LC_CTYPE, "");

  signal(SIGINT, sig_handler);
  signal(SIGTERM, sig_handler);

  GlobalEnvironment env;

  // add compiled-in support to version line
  {
    std::string support = "APIs supported at compile-time: ";
    int count = 0;

#if defined(RENDERDOC_SUPPORT_VULKAN)
    support += "Vulkan, ";
    count++;
#endif

    if(count == 0)
    {
      support += "None.";
    }
    else
    {
      // remove trailing ', '
      support.pop_back();
      support.pop_back();
      support += ".";
    }

    add_version_line(support);

    support = "Windowing systems supported at compile-time: ";
    count = 0;

    support += "GGP, ";
    count++;

#if defined(RENDERDOC_SUPPORT_VULKAN)
    support += "Vulkan KHR_display, ";
    count++;
#endif

    if(count == 0)
    {
      support += "None.";
    }
    else
    {
      // remove trailing ', '
      support.pop_back();
      support.pop_back();
      support += ".";
    }

    add_version_line(support);
  }

  int ret = renderdoccmd(env, argc, argv);

  return ret;
}
<|endoftext|>


<commit_before>/*
    Copyright(c) 2016 Oleg Linkin <MaledictusDeMagog@gmail.com>

    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 OR COPYRIGHT HOLDERS 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 "bookmarksmodel.h"
#include <QtDebug>

namespace LinksBag
{
BookmarksModel::BookmarksModel(QObject *parent)
: QAbstractListModel(parent)
{
}

BookmarksModel::~BookmarksModel()
{
}

QVariant BookmarksModel::data(const QModelIndex& index, int role) const
{
    if(index.row() < 0 || index.row() > m_Bookmarks.count())
    {
        return QVariant();
    }

    auto bookmark = m_Bookmarks.at(index.row());
    switch(role)
    {
    case BRID:
        return bookmark.GetID();
    case BRUrl:
        return bookmark.GetUrl();
    case BRTitle:
        return bookmark.GetTitle();
    case BRDescription:
        return bookmark.GetDescription();
    case BRImageUrl:
        return bookmark.GetImageUrl();
    case BRFavorite:
        return bookmark.IsFavorite();
    case BRRead:
        return bookmark.IsRead();
    case BRTags:
        return bookmark.GetTags().join(',');
    case BRAddTime:
        return bookmark.GetAddTime();
    case BRUpdateTime:
        return bookmark.GetUpdateTime();
    case BRStatus:
        return bookmark.GetStatus();
    default:
        return QVariant();
    }
}

int BookmarksModel::rowCount(const QModelIndex&) const
{
    return m_Bookmarks.count();
}

QHash<int, QByteArray> BookmarksModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles [BRID] = "bookmarkID";
    roles [BRUrl] = "bookmarkUrl";
    roles [BRTitle] = "bookmarkTitle";
    roles [BRDescription] = "bookmarkDescription";
    roles [BRImageUrl] = "bookmarkImageUrl";
    roles [BRFavorite] = "bookmarkFavorite";
    roles [BRRead] = "bookmarkRead";
    roles [BRTags] = "bookmarkTags";
    roles [BRAddTime] = "bookmarkAddTime";
    roles [BRUpdateTime] = "bookmarkUpdateTime";
    roles [BRStatus] = "bookmarkStatus";

    return roles;
}

void BookmarksModel::Clear()
{
    m_Bookmarks.clear();
}

void BookmarksModel::RemoveBookmark(const QString& id)
{
    auto it = std::find_if(m_Bookmarks.begin(), m_Bookmarks.end(),
            [id](decltype(m_Bookmarks.front()) bookmark)
            {
                return id == bookmark.GetID();
            });
    if(it != m_Bookmarks.end())
    {
        const int pos = std::distance(m_Bookmarks.begin(), it);
        beginRemoveRows(QModelIndex(), pos, pos);
        m_Bookmarks.removeAt(pos);
        endRemoveRows();
    }
}

void BookmarksModel::AddBookmarks(const Bookmarks_t& bookmarks)
{
    Bookmarks_t bmss = bookmarks;
    for(int i = bmss.count() - 1; !m_Bookmarks.isEmpty() && i >= 0; --i)
    {
        auto bms = bmss.at(i);
        auto it = std::find_if(m_Bookmarks.begin(), m_Bookmarks.end(),
                [bms](decltype(m_Bookmarks.front()) bookmark)
                {
                    return bms.GetID() == bookmark.GetID();
                });
        if (it != m_Bookmarks.end())
        {
            const int pos = std::distance(m_Bookmarks.begin(), it);
            switch(bms.GetStatus())
            {
            case Bookmark::SDeleted:
                RemoveBookmark(bms.GetID());
                break;
            case Bookmark::SArchived:
            {
                Bookmark bm = m_Bookmarks[pos];
                bm.SetIsRead(true);

                emit dataChanged(index(pos), index(pos));
                break;
            }
            default:
            {
                Bookmark bm = m_Bookmarks[pos];
                bm.SetUrl(bms.GetUrl());
                bm.SetTitle(bms.GetTitle());
                bm.SetDescription(bms.GetDescription());
                bm.SetIsFavorite(bms.IsFavorite());
                bm.SetIsRead(bms.IsRead());
                bm.SetAddTime(bms.GetAddTime());
                bm.SetUpdateTime(bms.GetUpdateTime());
                bm.SetTags(bms.GetTags());
                bm.SetImageUrl(bms.GetImageUrl());
                bm.SetStatus(bms.GetStatus());

                emit dataChanged(index(pos), index(pos));
                break;
            }
            }
        }
    }

    beginInsertRows(QModelIndex(), rowCount(), rowCount() + bmss.count() - 1);
    m_Bookmarks.append(bmss);
    endInsertRows();
}

void BookmarksModel::SetBookmarks(const Bookmarks_t& bookmarks)
{
    beginResetModel();
    m_Bookmarks = bookmarks;
    endResetModel();
}

void BookmarksModel::MarkBookmarkAsFavorite(const QString& id, bool favorite)
{
    for(int i = 0, size = m_Bookmarks.count(); i < size; ++i)
    {
        auto& bm = m_Bookmarks[i];
        if(bm.GetID() == id)
        {
            bm.SetIsFavorite(favorite);
            emit dataChanged(index(i, 0), index(i, 0));
            break;
        }
    }
}

void BookmarksModel::MarkBookmarkAsRead(const QString& id, bool read)
{
    for(int i = 0, size = m_Bookmarks.count(); i < size; ++i)
    {
        auto& bm = m_Bookmarks[i];
        if(bm.GetID() == id)
        {
            bm.SetIsRead(read);
            emit dataChanged(index(i, 0), index(i, 0));
            break;
        }
    }
}

Bookmarks_t BookmarksModel::GetBookmarks() const
{
    return m_Bookmarks;
}

QVariantMap BookmarksModel::getBookmark(const QString& id) const
{
    auto it = std::find_if(m_Bookmarks.begin(), m_Bookmarks.end(),
            [id](decltype(m_Bookmarks.front()) bookmark)
            {
                return bookmark.GetID() == id;
            });
    if(it == m_Bookmarks.end())
    {
        return QVariantMap();
    }

    return it->ToMap();
}
} // namespace LinksBag
<commit_msg>Fix addbookmarks method in model<commit_after>/*
    Copyright(c) 2016 Oleg Linkin <MaledictusDeMagog@gmail.com>

    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 OR COPYRIGHT HOLDERS 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 "bookmarksmodel.h"
#include <QtDebug>

namespace LinksBag
{
BookmarksModel::BookmarksModel(QObject *parent)
: QAbstractListModel(parent)
{
}

BookmarksModel::~BookmarksModel()
{
}

QVariant BookmarksModel::data(const QModelIndex& index, int role) const
{
    if(index.row() < 0 || index.row() > m_Bookmarks.count())
    {
        return QVariant();
    }

    auto bookmark = m_Bookmarks.at(index.row());
    switch(role)
    {
    case BRID:
        return bookmark.GetID();
    case BRUrl:
        return bookmark.GetUrl();
    case BRTitle:
        return bookmark.GetTitle();
    case BRDescription:
        return bookmark.GetDescription();
    case BRImageUrl:
        return bookmark.GetImageUrl();
    case BRFavorite:
        return bookmark.IsFavorite();
    case BRRead:
        return bookmark.IsRead();
    case BRTags:
        return bookmark.GetTags().join(',');
    case BRAddTime:
        return bookmark.GetAddTime();
    case BRUpdateTime:
        return bookmark.GetUpdateTime();
    case BRStatus:
        return bookmark.GetStatus();
    default:
        return QVariant();
    }
}

int BookmarksModel::rowCount(const QModelIndex&) const
{
    return m_Bookmarks.count();
}

QHash<int, QByteArray> BookmarksModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles [BRID] = "bookmarkID";
    roles [BRUrl] = "bookmarkUrl";
    roles [BRTitle] = "bookmarkTitle";
    roles [BRDescription] = "bookmarkDescription";
    roles [BRImageUrl] = "bookmarkImageUrl";
    roles [BRFavorite] = "bookmarkFavorite";
    roles [BRRead] = "bookmarkRead";
    roles [BRTags] = "bookmarkTags";
    roles [BRAddTime] = "bookmarkAddTime";
    roles [BRUpdateTime] = "bookmarkUpdateTime";
    roles [BRStatus] = "bookmarkStatus";

    return roles;
}

void BookmarksModel::Clear()
{
    m_Bookmarks.clear();
}

void BookmarksModel::RemoveBookmark(const QString& id)
{
    auto it = std::find_if(m_Bookmarks.begin(), m_Bookmarks.end(),
            [id](decltype(m_Bookmarks.front()) bookmark)
            {
                return id == bookmark.GetID();
            });
    if(it != m_Bookmarks.end())
    {
        const int pos = std::distance(m_Bookmarks.begin(), it);
        beginRemoveRows(QModelIndex(), pos, pos);
        m_Bookmarks.removeAt(pos);
        endRemoveRows();
    }
}

void BookmarksModel::AddBookmarks(const Bookmarks_t& bookmarks)
{
    Bookmarks_t bmss = bookmarks;
    for(int i = bmss.count() - 1; i >= 0; --i)
    {
        auto bms = bmss.at(i);
        auto it = std::find_if(m_Bookmarks.begin(), m_Bookmarks.end(),
                [bms](decltype(m_Bookmarks.front()) bookmark)
                {
                    return bms.GetID() == bookmark.GetID();
                });
        if (it != m_Bookmarks.end())
        {
            const int pos = std::distance(m_Bookmarks.begin(), it);
            switch(bms.GetStatus())
            {
            case Bookmark::SDeleted:
                RemoveBookmark(bms.GetID());
                break;
            case Bookmark::SArchived:
            {
                Bookmark bm = m_Bookmarks[pos];
                bm.SetIsRead(true);

                emit dataChanged(index(pos), index(pos));
                break;
            }
            default:
            {
                Bookmark bm = m_Bookmarks[pos];
                bm.SetUrl(bms.GetUrl());
                bm.SetTitle(bms.GetTitle());
                bm.SetDescription(bms.GetDescription());
                bm.SetIsFavorite(bms.IsFavorite());
                bm.SetIsRead(bms.IsRead());
                bm.SetAddTime(bms.GetAddTime());
                bm.SetUpdateTime(bms.GetUpdateTime());
                bm.SetTags(bms.GetTags());
                bm.SetImageUrl(bms.GetImageUrl());
                bm.SetStatus(bms.GetStatus());

                emit dataChanged(index(pos), index(pos));
                break;
            }
            }
        }
        else {
            beginInsertRows(QModelIndex(), rowCount(), rowCount());
            m_Bookmarks.append(bms);
            endInsertRows();
        }
    }
}

void BookmarksModel::SetBookmarks(const Bookmarks_t& bookmarks)
{
    beginResetModel();
    m_Bookmarks = bookmarks;
    endResetModel();
}

void BookmarksModel::MarkBookmarkAsFavorite(const QString& id, bool favorite)
{
    for(int i = 0, size = m_Bookmarks.count(); i < size; ++i)
    {
        auto& bm = m_Bookmarks[i];
        if(bm.GetID() == id)
        {
            bm.SetIsFavorite(favorite);
            emit dataChanged(index(i, 0), index(i, 0));
            break;
        }
    }
}

void BookmarksModel::MarkBookmarkAsRead(const QString& id, bool read)
{
    for(int i = 0, size = m_Bookmarks.count(); i < size; ++i)
    {
        auto& bm = m_Bookmarks[i];
        if(bm.GetID() == id)
        {
            bm.SetIsRead(read);
            emit dataChanged(index(i, 0), index(i, 0));
            break;
        }
    }
}

Bookmarks_t BookmarksModel::GetBookmarks() const
{
    return m_Bookmarks;
}

QVariantMap BookmarksModel::getBookmark(const QString& id) const
{
    auto it = std::find_if(m_Bookmarks.begin(), m_Bookmarks.end(),
            [id](decltype(m_Bookmarks.front()) bookmark)
            {
                return bookmark.GetID() == id;
            });
    if(it == m_Bookmarks.end())
    {
        return QVariantMap();
    }

    return it->ToMap();
}
} // namespace LinksBag
<|endoftext|>