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

#ifndef SC_DRWLAYER_HXX
#define SC_DRWLAYER_HXX

#ifndef _SV_GRAPH_HXX //autogen
#include <vcl/graph.hxx>
#endif
#ifndef _FM_FMMODEL_HXX
#include <svx/fmmodel.hxx>
#endif
//REMOVE    #ifndef _SVSTOR_HXX
//REMOVE    #include <so3/svstor.hxx>
//REMOVE    #endif
#ifndef SC_SCGLOB_HXX
#include "global.hxx"
#endif

class ScDocument;
class SfxViewShell;
class SfxObjectShell;
class ScDrawObjData;
class ScIMapInfo;
class IMapObject;
class ScMarkData;
class SdrOle2Obj;
class ScRange;
class ScAddress;

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

class ScTabDeletedHint : public SfxHint
{
private:
    SCTAB   nTab;
public:
            TYPEINFO();
            ScTabDeletedHint( SCTAB nTabNo = SCTAB_MAX );
    virtual ~ScTabDeletedHint();

    SCTAB   GetTab()    { return nTab; }
};

class ScTabSizeChangedHint : public SfxHint
{
private:
    SCTAB   nTab;
public:
            TYPEINFO();
            ScTabSizeChangedHint( SCTAB nTabNo = SCTAB_MAX );
    virtual ~ScTabSizeChangedHint();

    SCTAB   GetTab()    { return nTab; }
};

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

class ScDrawLayer: public FmFormModel
{
private:
//REMOVE        SotStorageRef   xPictureStorage;
    String          aName;
    ScDocument*     pDoc;
    SdrUndoGroup*   pUndoGroup;
    BOOL            bRecording;
    BOOL            bAdjustEnabled;
    BOOL            bHyphenatorSet;

private:
    void            MoveAreaTwips( SCTAB nTab, const Rectangle& rArea, const Point& rMove,
                                const Point& rTopLeft );
    void            MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
                                SCsCOL nDx,SCsROW nDy );
    void            RecalcPos( SdrObject* pObj, ScDrawObjData* pData, BOOL bNegativePage );

public:
                    ScDrawLayer( ScDocument* pDocument, const String& rName );
    virtual         ~ScDrawLayer();

    virtual SdrPage*  AllocPage(FASTBOOL bMasterPage);
    virtual SdrModel* AllocModel() const;
    virtual void    SetChanged( sal_Bool bFlg = sal_True );

    virtual Window* GetCurDocViewWin();
    virtual SvStream* GetDocumentStream(SdrDocumentStreamInfo& rStreamInfo) const;

    virtual SdrLayerID GetControlExportLayerId( const SdrObject & ) const;

//REMOVE        void            ReleasePictureStorage();

    BOOL            HasObjects() const;

    BOOL            ScAddPage( SCTAB nTab );
    void            ScRemovePage( SCTAB nTab );
    void            ScRenamePage( SCTAB nTab, const String& rNewName );
    void            ScMovePage( USHORT nOldPos, USHORT nNewPos );
                    // inkl. Inhalt, bAlloc=FALSE -> nur Inhalt
    void            ScCopyPage( USHORT nOldPos, USHORT nNewPos, BOOL bAlloc );

    ScDocument*     GetDocument() const { return pDoc; }

    void            UpdateBasic();              // DocShell-Basic in DrawPages setzen
    void            UseHyphenator();

//BFS03 void            Load( SvStream& rStream );
//BFS03 void            Store( SvStream& rStream ) const;

    BOOL            GetPrintArea( ScRange& rRange, BOOL bSetHor, BOOL bSetVer ) const;

                    //      automatische Anpassungen

    void            EnableAdjust( BOOL bSet = TRUE )    { bAdjustEnabled = bSet; }

    void            BeginCalcUndo();
    SdrUndoGroup*   GetCalcUndo();
    BOOL            IsRecording()           { return bRecording; }
    void            AddCalcUndo( SdrUndoAction* pUndo );

    void            MoveArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
                                SCsCOL nDx,SCsROW nDy, BOOL bInsDel );
    void            WidthChanged( SCTAB nTab, SCCOL nCol, long nDifTwips );
    void            HeightChanged( SCTAB nTab, SCROW nRow, long nDifTwips );

    BOOL            HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow );

    void            DeleteObjectsInArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1,
                                            SCCOL nCol2,SCROW nRow2 );
    void            DeleteObjectsInSelection( const ScMarkData& rMark );
    void            DeleteObjects( SCTAB nTab );

    void            CopyToClip( ScDocument* pClipDoc, SCTAB nTab, const Rectangle& rRange );
    void            CopyFromClip( ScDrawLayer* pClipModel,
                                    SCTAB nSourceTab, const Rectangle& rSourceRange,
                                    const ScAddress& rDestPos, const Rectangle& rDestRange );

    void            SetPageSize( USHORT nPageNo, const Size& rSize );
    ULONG           GetDefTextHeight() const;

                    //  mirror or move between positive and negative positions for RTL
    void            MirrorRTL( SdrObject* pObj );
    static void     MirrorRectRTL( Rectangle& rRect );      // for bounding rectangles etc.

                    //  GetVisibleName: name for navigator etc: GetPersistName or GetName
                    //  (ChartListenerCollection etc. must use GetPersistName directly)
    static String   GetVisibleName( SdrObject* pObj );

    SdrObject*      GetNamedObject( const String& rName, USHORT nId, SCTAB& rFoundTab ) const;
                    // if pnCounter != NULL, the search for a name starts with this index + 1,
                    // and the index really used is returned.
    String          GetNewGraphicName( long* pnCounter = NULL ) const;
    void            EnsureGraphicNames();

    // Verankerung setzen und ermitteln
    static void     SetAnchor( SdrObject*, ScAnchorType );
    static ScAnchorType GetAnchor( const SdrObject* );

    // Positionen fuer Detektivlinien
    static ScDrawObjData* GetObjData( SdrObject* pObj, BOOL bCreate=FALSE );

    // The sheet information in ScDrawObjData isn't updated when sheets are inserted/deleted.
    // Use this method to get an object with positions on the specified sheet (should be the
    // sheet on which the object is inserted).
    static ScDrawObjData* GetObjDataTab( SdrObject* pObj, SCTAB nTab );

    // Image-Map
    static ScIMapInfo* GetIMapInfo( SdrObject* pObj );
    static IMapObject* GetHitIMapObject( SdrObject* pObject,
                            const Point& rWinPoint, const Window& rCmpWnd );

private:
    static SfxObjectShell* pGlobalDrawPersist;          // fuer AllocModel
public:
    static void     SetGlobalDrawPersist(SfxObjectShell* pPersist);
protected:
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > createUnoModel();
};

#endif

<commit_msg>INTEGRATION: CWS aw024 (1.14.34); FILE MERGED 2006/08/03 17:49:16 aw 1.14.34.5: RESYNC: (1.17-1.18); FILE MERGED 2006/01/26 23:17:06 aw 1.14.34.4: RESYNC: (1.16-1.17); FILE MERGED 2005/11/18 19:05:16 aw 1.14.34.3: RESYNC: (1.15-1.16); FILE MERGED 2005/09/19 23:14:25 aw 1.14.34.2: RESYNC: (1.14-1.15); FILE MERGED 2004/12/27 09:54:35 aw 1.14.34.1: #i39525<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: drwlayer.hxx,v $
 *
 *  $Revision: 1.19 $
 *
 *  last change: $Author: ihi $ $Date: 2006-11-14 15:46:19 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_DRWLAYER_HXX
#define SC_DRWLAYER_HXX

#ifndef _SV_GRAPH_HXX //autogen
#include <vcl/graph.hxx>
#endif
#ifndef _FM_FMMODEL_HXX
#include <svx/fmmodel.hxx>
#endif
//REMOVE    #ifndef _SVSTOR_HXX
//REMOVE    #include <so3/svstor.hxx>
//REMOVE    #endif
#ifndef SC_SCGLOB_HXX
#include "global.hxx"
#endif

class ScDocument;
class SfxViewShell;
class SfxObjectShell;
class ScDrawObjData;
class ScIMapInfo;
class IMapObject;
class ScMarkData;
class SdrOle2Obj;
class ScRange;
class ScAddress;

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

class ScTabDeletedHint : public SfxHint
{
private:
    SCTAB   nTab;
public:
            TYPEINFO();
            ScTabDeletedHint( SCTAB nTabNo = SCTAB_MAX );
    virtual ~ScTabDeletedHint();

    SCTAB   GetTab()    { return nTab; }
};

class ScTabSizeChangedHint : public SfxHint
{
private:
    SCTAB   nTab;
public:
            TYPEINFO();
            ScTabSizeChangedHint( SCTAB nTabNo = SCTAB_MAX );
    virtual ~ScTabSizeChangedHint();

    SCTAB   GetTab()    { return nTab; }
};

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

class ScDrawLayer: public FmFormModel
{
private:
//REMOVE        SotStorageRef   xPictureStorage;
    String          aName;
    ScDocument*     pDoc;
    SdrUndoGroup*   pUndoGroup;
    BOOL            bRecording;
    BOOL            bAdjustEnabled;
    BOOL            bHyphenatorSet;

private:
    void            MoveAreaTwips( SCTAB nTab, const Rectangle& rArea, const Point& rMove,
                                const Point& rTopLeft );
    void            MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
                                SCsCOL nDx,SCsROW nDy );
    void            RecalcPos( SdrObject* pObj, ScDrawObjData* pData, BOOL bNegativePage );

public:
                    ScDrawLayer( ScDocument* pDocument, const String& rName );
    virtual         ~ScDrawLayer();

    virtual SdrPage*  AllocPage(FASTBOOL bMasterPage);
    virtual SdrModel* AllocModel() const;
    virtual void    SetChanged( sal_Bool bFlg = sal_True );

    virtual Window* GetCurDocViewWin();
    virtual SvStream* GetDocumentStream(SdrDocumentStreamInfo& rStreamInfo) const;

    virtual SdrLayerID GetControlExportLayerId( const SdrObject & ) const;

//REMOVE        void            ReleasePictureStorage();

    BOOL            HasObjects() const;

    BOOL            ScAddPage( SCTAB nTab );
    void            ScRemovePage( SCTAB nTab );
    void            ScRenamePage( SCTAB nTab, const String& rNewName );
    void            ScMovePage( USHORT nOldPos, USHORT nNewPos );
                    // inkl. Inhalt, bAlloc=FALSE -> nur Inhalt
    void            ScCopyPage( USHORT nOldPos, USHORT nNewPos, BOOL bAlloc );

    ScDocument*     GetDocument() const { return pDoc; }

    void            UpdateBasic();              // DocShell-Basic in DrawPages setzen
    void            UseHyphenator();

    BOOL            GetPrintArea( ScRange& rRange, BOOL bSetHor, BOOL bSetVer ) const;

                    //      automatische Anpassungen

    void            EnableAdjust( BOOL bSet = TRUE )    { bAdjustEnabled = bSet; }

    void            BeginCalcUndo();
    SdrUndoGroup*   GetCalcUndo();
    BOOL            IsRecording()           { return bRecording; }
    void            AddCalcUndo( SdrUndoAction* pUndo );

    void            MoveArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
                                SCsCOL nDx,SCsROW nDy, BOOL bInsDel );
    void            WidthChanged( SCTAB nTab, SCCOL nCol, long nDifTwips );
    void            HeightChanged( SCTAB nTab, SCROW nRow, long nDifTwips );

    BOOL            HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow );

    void            DeleteObjectsInArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1,
                                            SCCOL nCol2,SCROW nRow2 );
    void            DeleteObjectsInSelection( const ScMarkData& rMark );
    void            DeleteObjects( SCTAB nTab );

    void            CopyToClip( ScDocument* pClipDoc, SCTAB nTab, const Rectangle& rRange );
    void            CopyFromClip( ScDrawLayer* pClipModel,
                                    SCTAB nSourceTab, const Rectangle& rSourceRange,
                                    const ScAddress& rDestPos, const Rectangle& rDestRange );

    void            SetPageSize( USHORT nPageNo, const Size& rSize );
    ULONG           GetDefTextHeight() const;

                    //  mirror or move between positive and negative positions for RTL
    void            MirrorRTL( SdrObject* pObj );
    static void     MirrorRectRTL( Rectangle& rRect );      // for bounding rectangles etc.

                    //  GetVisibleName: name for navigator etc: GetPersistName or GetName
                    //  (ChartListenerCollection etc. must use GetPersistName directly)
    static String   GetVisibleName( SdrObject* pObj );

    SdrObject*      GetNamedObject( const String& rName, USHORT nId, SCTAB& rFoundTab ) const;
                    // if pnCounter != NULL, the search for a name starts with this index + 1,
                    // and the index really used is returned.
    String          GetNewGraphicName( long* pnCounter = NULL ) const;
    void            EnsureGraphicNames();

    // Verankerung setzen und ermitteln
    static void     SetAnchor( SdrObject*, ScAnchorType );
    static ScAnchorType GetAnchor( const SdrObject* );

    // Positionen fuer Detektivlinien
    static ScDrawObjData* GetObjData( SdrObject* pObj, BOOL bCreate=FALSE );

    // The sheet information in ScDrawObjData isn't updated when sheets are inserted/deleted.
    // Use this method to get an object with positions on the specified sheet (should be the
    // sheet on which the object is inserted).
    static ScDrawObjData* GetObjDataTab( SdrObject* pObj, SCTAB nTab );

    // Image-Map
    static ScIMapInfo* GetIMapInfo( SdrObject* pObj );
    static IMapObject* GetHitIMapObject( SdrObject* pObject,
                            const Point& rWinPoint, const Window& rCmpWnd );

private:
    static SfxObjectShell* pGlobalDrawPersist;          // fuer AllocModel
public:
    static void     SetGlobalDrawPersist(SfxObjectShell* pPersist);
protected:
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > createUnoModel();
};

#endif

<|endoftext|>


<commit_before>/******************************************************************************
  This source file is part of the Avogadro project.
  This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#include "noncovalent.h"

#include <avogadro/core/array.h>
#include <avogadro/core/atom.h>
#include <avogadro/core/atomutilities.h>
#include <avogadro/core/bond.h>
#include <avogadro/core/elements.h>
#include <avogadro/core/neighborperceiver.h>
#include <avogadro/qtgui/molecule.h>
#include <avogadro/rendering/dashedlinegeometry.h>
#include <avogadro/rendering/geometrynode.h>
#include <avogadro/rendering/groupnode.h>

#include <QtCore/QSettings>
#include <QtGui/QColor>
#include <QtWidgets/QDoubleSpinBox>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QTabWidget>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>

#include <algorithm>
#include <cmath>
#include <sstream>

// bond angles
#define M_TETRAHEDRAL (acosf(-1.0f / 3.0f))
#define M_TRIGONAL (2.0f * M_PI / 3.0f)

namespace Avogadro {
namespace QtPlugins {

using Core::Array;
using Core::AtomHybridization;
using Core::AtomUtilities;
using Core::Bond;
using Core::Elements;
using Core::NeighborPerceiver;
using QtGui::Molecule;
using QtGui::PluginLayerManager;
using Rendering::DashedLineGeometry;
using Rendering::GeometryNode;
using Rendering::GroupNode;

NonCovalent::NonCovalent(QObject *p) : ScenePlugin(p)
{
  m_layerManager = PluginLayerManager(m_name);

  QSettings settings;
  m_angleTolerancesDegrees = {
  	settings.value("nonCovalent/angleTolerance0", 40.0).toDouble(),
  	settings.value("nonCovalent/angleTolerance1", 40.0).toDouble(),
  	settings.value("nonCovalent/angleTolerance2", 40.0).toDouble()
  };
  m_maximumDistances = {
  	settings.value("nonCovalent/maximumDistance0", 1.0).toDouble(),
  	settings.value("nonCovalent/maximumDistance1", 2.0).toDouble(),
  	settings.value("nonCovalent/maximumDistance2", 2.0).toDouble()
  };
  QColor hydrogenBColor = settings.value("nonCovalent/lineColor0", QColor(64, 192, 255)).value<QColor>();
  QColor halogenBColor = settings.value("nonCovalent/lineColor1", QColor(128, 255, 64)).value<QColor>();
  QColor chalcogenBColor = settings.value("nonCovalent/lineColor2", QColor(255, 192, 64)).value<QColor>();
  m_lineColors = {
    Vector3ub(hydrogenBColor.red(), hydrogenBColor.green(), hydrogenBColor.blue()),
    Vector3ub(halogenBColor.red(), halogenBColor.green(), halogenBColor.blue()),
    Vector3ub(chalcogenBColor.red(), chalcogenBColor.green(), chalcogenBColor.blue())
  };
  m_lineWidth = settings.value("nonCovalent/lineWidth0", 5.0).toFloat();
}

NonCovalent::~NonCovalent() {}

enum InteractionTypes {
  NONE = -1,
  HYDROGEN_BOND = 0,
  HALOGEN_BOND = 1,
  CHALCOGEN_BOND = 2
};

static enum InteractionTypes getInteractionType(const Molecule &molecule, Index i)
{
  unsigned char inum = molecule.atomicNumber(i);
  switch (inum) {
    case 1: // hydrogen bond
      for (const Bond *b : molecule.bonds(i)) {
        Index j = b->getOtherAtom(i).index();
        unsigned char jnum = molecule.atomicNumber(j);
        switch (jnum) {
          case 7: case 8: case 9: // F, O, N
            return HYDROGEN_BOND;
        }
      }
      break;
    case 9: case 17: case 35: case 53: // halogen bond
      for (const Bond *b : molecule.bonds(i)) {
        Index j = (b->atom1().index() == i ? b->atom2() : b->atom1()).index();
        unsigned char jnum = molecule.atomicNumber(j);
        switch (jnum) {
          case 6: case 7: case 8: case 9:
          case 16: case 17: case 35: case 53: // F, O, N, Cl, Br, C, I, S
            return HALOGEN_BOND;
        }
      }
      break;
    case 8: case 16: case 34: case 52: // chalcogen bond
      for (const Bond *b : molecule.bonds(i)) {
        Index j = (b->atom1().index() == i ? b->atom2() : b->atom1()).index();
        unsigned char jnum = molecule.atomicNumber(j);
        switch (jnum) {
          case 6: // C
            return CHALCOGEN_BOND;
        }
      }
      break;
  }
  return NONE;
}

static bool checkPairDonorIsValid(const Molecule &molecule, Index n, int interactionType)
{
  unsigned char nnum = molecule.atomicNumber(n);
  switch (interactionType) {
    case HYDROGEN_BOND:
      switch (nnum) {
        case 7: case 8: case 9: case 17: // F, O, N, Cl
          return true;
      }
      break;
    case HALOGEN_BOND:
      switch (nnum) {
        case 7: case 8: case 9: case 17: // F, O, N, Cl
          return true;
      }
      break;
    case CHALCOGEN_BOND:
      switch (nnum) {
        case 7: case 8: case 9: case 16:
        case 17: case 34: case 52: // F, O, N, Cl, S, Se, Te
          return true;
      }
      break;
  }
  return false;
}

static bool checkAtomPairNotBonded(const Molecule &molecule, Index i, Index n)
{
  Array<const Bond *> bonds = molecule.bonds(i);
  /* Return true if all of the bonds from i are to atoms other than n */
  return std::all_of(bonds.begin(), bonds.end(), [i, n](const Bond *b) {
    return b->getOtherAtom(i).index() != n;
  });
}

static float computeAngle(Vector3 a, Vector3 b)
{
  return acos(a.normalized().dot(b.normalized()));
}

static bool checkHoleVector(
    const Molecule &molecule, Index i, const Vector3 &in, float angleTolerance
) {
  Array<const Bond *> bonds = molecule.bonds(i);
  Vector3 pos = molecule.atomPosition3d(i);
  /* Return true if any of the bonds to i forms a small enough angle
   * with 'in' at the opposite side of atom 'i' */
  for (const Bond *b: bonds) {
    Index n = b->getOtherAtom(i).index();
      Vector3 npos = molecule.atomPosition3d(n);
      float oppositeAngle = M_PI - computeAngle(in, npos - pos);
      if (oppositeAngle <= angleTolerance)
        return true;
  }
  return false;
}

static bool checkPairVector(
    const Molecule &molecule, Index n, const Vector3 &in, float angleTolerance
) {
  AtomHybridization hybridization = AtomUtilities::perceiveHybridization(molecule.atom(n));
  Array<const Bond *> bonds = molecule.bonds(n);
  size_t bondCount = bonds.size();
  std::vector<Vector3> bondVectors;
  Vector3 pos = molecule.atomPosition3d(n);
  /* Compute all bond vectors around atom n */
  for (const Bond *b: bonds)
    bondVectors.push_back(molecule.atomPosition3d(b->getOtherAtom(n).index()) - pos);
  float pairAngle;
  switch (hybridization) {
    case Core::SP3:
      switch (bondCount) {
        case 0:
          pairAngle = 0.0f;
          break;
        case 1:
          pairAngle = fabs(computeAngle(bondVectors[0], in) - M_TETRAHEDRAL);
          break;
        case 2: {
          Vector3 pairVector = AtomUtilities::generateNewBondVector(
            molecule.atom(n), bondVectors, hybridization
          );
          pairAngle = computeAngle(pairVector, in);
          bondVectors.push_back(pairVector);
          pairVector = AtomUtilities::generateNewBondVector(
            molecule.atom(n), bondVectors, hybridization
          );
          pairAngle = std::min(pairAngle, computeAngle(pairVector, in));
          break;
        }
        case 3: {
          Vector3 pairVector = AtomUtilities::generateNewBondVector(
            molecule.atom(n), bondVectors, hybridization
          );
          pairAngle = computeAngle(pairVector, in);
          break;
        }
        default:
          return false;
      }
      break;
    case Core::SP2:
      switch (bondCount) {
        case 0:
          pairAngle = 0.0f;
          break;
        case 1:
          pairAngle = fabs(computeAngle(bondVectors[0], in) - M_TRIGONAL);
          break;
        case 2: {
          Vector3 pairVector = AtomUtilities::generateNewBondVector(
            molecule.atom(n), bondVectors, hybridization
          );
          pairAngle = computeAngle(pairVector, in);
          break;
        }
        default:
          return false;
      }
      break;
    case Core::SP:
      switch (bondCount) {
        case 0:
          pairAngle = 0.0f;
          break;
        case 1: {
          pairAngle = fabs(computeAngle(bondVectors[0], in) - M_PI);
          break;
        }
        default:
          return false;
      }
    default:
      return true;
  }
  return pairAngle <= angleTolerance;
}

void NonCovalent::process(const Molecule &molecule, Rendering::GroupNode &node)
{
  std::vector<Index> enabledAtoms;
  Array<Vector3> enabledPositions;
  Array<double> atomRadii;
  const size_t atomCount = molecule.atomCount();
  for (Index i = 0; i < atomCount; ++i) {
    enabledAtoms.push_back(i);
    enabledPositions.push_back(molecule.atomPosition3d(i));
    atomRadii.push_back(Elements::radiusVDW(molecule.atomicNumber(i)));
  }
  float absoluteMaxDistance = *std::max_element(
  	m_maximumDistances.begin(), m_maximumDistances.end()
  );
  NeighborPerceiver perceiver(enabledPositions, absoluteMaxDistance);

  GeometryNode *geometry = new GeometryNode;
  node.addChild(geometry);
  DashedLineGeometry *lines = new DashedLineGeometry;
  lines->identifier().molecule = &molecule;
  lines->identifier().type = Rendering::BondType;
  lines->setLineWidth(m_lineWidth);
  geometry->addDrawable(lines);
  Array<Index> neighbors;
  for (Index i: enabledAtoms) {
    enum InteractionTypes interactionType = getInteractionType(molecule, i);
    if (interactionType == NONE)
      continue;
    Vector3 pos = molecule.atomPosition3d(i);
    double radius = atomRadii[i];
    perceiver.getNeighborsInclusiveInPlace(neighbors, pos);
    for (Index ni : neighbors) {
      Index n = enabledAtoms[ni];
      if (!checkPairDonorIsValid(molecule, n, interactionType))
        continue;

      Vector3 npos = molecule.atomPosition3d(n);
      double nradius = atomRadii[n];
      Vector3 distance_vector = npos - pos;

      if (distance_vector.norm() > m_maximumDistances[interactionType] + radius + nradius)
        continue;
      if (!checkAtomPairNotBonded(molecule, i, n))
        continue;

      float angleTolerance = m_angleTolerancesDegrees[interactionType] * M_PI / 180.0;
      if (!checkHoleVector(molecule, i, distance_vector, angleTolerance))
        continue;
      if (!checkPairVector(molecule, n, -distance_vector, angleTolerance))
        continue;

      lines->addDashedLine(pos.cast<float>(), npos.cast<float>(), m_lineColors[interactionType], 8);
    }
  }
}

QWidget *NonCovalent::setupWidget()
{
  QWidget *widget = new QWidget(qobject_cast<QWidget *>(this->parent()));
  QVBoxLayout *v = new QVBoxLayout;
  QTabWidget *tabs = new QTabWidget;

  for (Index i = 0; i < 3; i++) {
  	// angle tolerance
		QDoubleSpinBox *angle_spin = new QDoubleSpinBox;
		angle_spin->setRange(0.0, 180.0);
		angle_spin->setSingleStep(1.0);
		angle_spin->setDecimals(0);
		angle_spin->setSuffix(tr(" °"));
		angle_spin->setValue(m_angleTolerancesDegrees[i]);
		QObject::connect(angle_spin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
			[this, i](float width){ return setAngleTolerance(width, i); }
		);

		// maximum distance
		QDoubleSpinBox *distance_spin = new QDoubleSpinBox;
		distance_spin->setRange(1.0, 10.0);
		distance_spin->setSingleStep(0.1);
		distance_spin->setDecimals(1);
		distance_spin->setSuffix(tr(" Å"));
		distance_spin->setValue(m_maximumDistances[i]);
		QObject::connect(distance_spin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
			[this, i](float width){ return setMaximumDistance(width, i); }
		);

  	// line width
		QDoubleSpinBox* lineWidth_spin = new QDoubleSpinBox;
		lineWidth_spin->setRange(1.0, 10.0);
		lineWidth_spin->setSingleStep(0.5);
		lineWidth_spin->setDecimals(1);
		lineWidth_spin->setValue(m_lineWidth);
		QObject::connect(lineWidth_spin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &NonCovalent::setLineWidth);

		QFormLayout *form = new QFormLayout;
  	form->addRow(QObject::tr("Angle tolerance:"), angle_spin);
  	form->addRow(QObject::tr("Maximum distance:"), distance_spin);
  	form->addRow(QObject::tr("Line width:"), lineWidth_spin);

  	QWidget *page = new QWidget;
  	page->setLayout(form);
  	tabs->addTab(page, INTERACTION_NAMES[i]);
  }

  v->addWidget(tabs);
  v->addStretch(1);
  widget->setLayout(v);
  return widget;
}

void NonCovalent::setAngleTolerance(float angleTolerance, Index index)
{
  m_angleTolerancesDegrees[index] = float(angleTolerance);
  emit drawablesChanged();

  QSettings settings;
  std::ostringstream stream;
  stream << "nonCovalent/angleTolerance" << index;
  settings.setValue(QString(stream.str().c_str()), angleTolerance);
}

void NonCovalent::setMaximumDistance(float maximumDistance, Index index)
{
  m_maximumDistances[index] = float(maximumDistance);
  emit drawablesChanged();

  QSettings settings;
  std::ostringstream stream;
  stream << "nonCovalent/maximumDistance" << index;
  settings.setValue(QString(stream.str().c_str()), maximumDistance);
}

void NonCovalent::setLineWidth(float width)
{
  m_lineWidth = width;
  emit drawablesChanged();

  QSettings settings;
  settings.setValue("nonCovalent/lineWidth", width);
}

} // namespace QtPlugins
} // namespace Avogadro
<commit_msg>Apply requested change<commit_after>/******************************************************************************
  This source file is part of the Avogadro project.
  This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#include "noncovalent.h"

#include <avogadro/core/array.h>
#include <avogadro/core/atom.h>
#include <avogadro/core/atomutilities.h>
#include <avogadro/core/bond.h>
#include <avogadro/core/elements.h>
#include <avogadro/core/neighborperceiver.h>
#include <avogadro/qtgui/molecule.h>
#include <avogadro/rendering/dashedlinegeometry.h>
#include <avogadro/rendering/geometrynode.h>
#include <avogadro/rendering/groupnode.h>

#include <QtCore/QSettings>
#include <QtGui/QColor>
#include <QtWidgets/QDoubleSpinBox>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QTabWidget>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>

#include <algorithm>
#include <cmath>
#include <sstream>

// bond angles
#define M_TETRAHEDRAL (acosf(-1.0f / 3.0f))
#define M_TRIGONAL (2.0f * M_PI / 3.0f)

namespace Avogadro {
namespace QtPlugins {

using Core::Array;
using Core::AtomHybridization;
using Core::AtomUtilities;
using Core::Bond;
using Core::Elements;
using Core::NeighborPerceiver;
using QtGui::Molecule;
using QtGui::PluginLayerManager;
using Rendering::DashedLineGeometry;
using Rendering::GeometryNode;
using Rendering::GroupNode;

NonCovalent::NonCovalent(QObject *p) : ScenePlugin(p)
{
  m_layerManager = PluginLayerManager(m_name);

  QSettings settings;
  m_angleTolerancesDegrees = {
  	settings.value("nonCovalent/angleTolerance0", 40.0).toDouble(),
  	settings.value("nonCovalent/angleTolerance1", 40.0).toDouble(),
  	settings.value("nonCovalent/angleTolerance2", 40.0).toDouble()
  };
  m_maximumDistances = {
  	settings.value("nonCovalent/maximumDistance0", 1.0).toDouble(),
  	settings.value("nonCovalent/maximumDistance1", 2.0).toDouble(),
  	settings.value("nonCovalent/maximumDistance2", 2.0).toDouble()
  };
  QColor hydrogenBColor = settings.value("nonCovalent/lineColor0", QColor(64, 192, 255)).value<QColor>();
  QColor halogenBColor = settings.value("nonCovalent/lineColor1", QColor(128, 255, 64)).value<QColor>();
  QColor chalcogenBColor = settings.value("nonCovalent/lineColor2", QColor(255, 192, 64)).value<QColor>();
  m_lineColors = {
    Vector3ub(hydrogenBColor.red(), hydrogenBColor.green(), hydrogenBColor.blue()),
    Vector3ub(halogenBColor.red(), halogenBColor.green(), halogenBColor.blue()),
    Vector3ub(chalcogenBColor.red(), chalcogenBColor.green(), chalcogenBColor.blue())
  };
  m_lineWidth = settings.value("nonCovalent/lineWidth0", 5.0).toFloat();
}

NonCovalent::~NonCovalent() {}

enum InteractionTypes {
  NONE = -1,
  HYDROGEN_BOND = 0,
  HALOGEN_BOND = 1,
  CHALCOGEN_BOND = 2
};

static enum InteractionTypes getInteractionType(const Molecule &molecule, Index i)
{
  unsigned char inum = molecule.atomicNumber(i);
  switch (inum) {
    case 1: // hydrogen bond
      for (const Bond *b : molecule.bonds(i)) {
        Index j = b->getOtherAtom(i).index();
        unsigned char jnum = molecule.atomicNumber(j);
        switch (jnum) {
          case 7: case 8: case 9: // F, O, N
            return HYDROGEN_BOND;
        }
      }
      break;
    case 9: case 17: case 35: case 53: // halogen bond
      for (const Bond *b : molecule.bonds(i)) {
        Index j = (b->atom1().index() == i ? b->atom2() : b->atom1()).index();
        unsigned char jnum = molecule.atomicNumber(j);
        switch (jnum) {
          case 6: case 7: case 8: case 9:
          case 16: case 17: case 35: case 53: // F, O, N, Cl, Br, C, I, S
            return HALOGEN_BOND;
        }
      }
      break;
    case 8: case 16: case 34: case 52: // chalcogen bond
      for (const Bond *b : molecule.bonds(i)) {
        Index j = (b->atom1().index() == i ? b->atom2() : b->atom1()).index();
        unsigned char jnum = molecule.atomicNumber(j);
        switch (jnum) {
          case 6: // C
            return CHALCOGEN_BOND;
        }
      }
      break;
  }
  return NONE;
}

static bool checkPairDonorIsValid(const Molecule &molecule, Index n, int interactionType)
{
  unsigned char nnum = molecule.atomicNumber(n);
  switch (interactionType) {
    case HYDROGEN_BOND:
      switch (nnum) {
        case 7: case 8: case 9: case 17: // F, O, N, Cl
          return true;
      }
      break;
    case HALOGEN_BOND:
      switch (nnum) {
        case 7: case 8: case 9: case 17: // F, O, N, Cl
          return true;
      }
      break;
    case CHALCOGEN_BOND:
      switch (nnum) {
        case 7: case 8: case 9: case 16:
        case 17: case 34: case 52: // F, O, N, Cl, S, Se, Te
          return true;
      }
      break;
  }
  return false;
}

static bool checkAtomPairNotBonded(const Molecule &molecule, Index i, Index n)
{
  Array<const Bond *> bonds = molecule.bonds(i);
  /* Return true if all of the bonds from i are to atoms other than n */
  return std::all_of(bonds.begin(), bonds.end(), [i, n](const Bond *b) {
    return b->getOtherAtom(i).index() != n;
  });
}

static float computeAngle(Vector3 a, Vector3 b)
{
  return acos(a.normalized().dot(b.normalized()));
}

static bool checkHoleVector(
    const Molecule &molecule, Index i, const Vector3 &in, float angleTolerance
) {
  Array<const Bond *> bonds = molecule.bonds(i);
  Vector3 pos = molecule.atomPosition3d(i);
  /* Return true if any of the bonds to i forms a small enough angle
   * with 'in' at the opposite side of atom 'i' */
  for (const Bond *b: bonds) {
    Index n = b->getOtherAtom(i).index();
      Vector3 npos = molecule.atomPosition3d(n);
      float oppositeAngle = M_PI - computeAngle(in, npos - pos);
      if (oppositeAngle <= angleTolerance)
        return true;
  }
  return false;
}

static bool checkPairVector(
    const Molecule &molecule, Index n, const Vector3 &in, float angleTolerance
) {
  AtomHybridization hybridization = AtomUtilities::perceiveHybridization(molecule.atom(n));
  Array<const Bond *> bonds = molecule.bonds(n);
  size_t bondCount = bonds.size();
  std::vector<Vector3> bondVectors;
  Vector3 pos = molecule.atomPosition3d(n);
  /* Compute all bond vectors around atom n */
  for (const Bond *b: bonds)
    bondVectors.push_back(molecule.atomPosition3d(b->getOtherAtom(n).index()) - pos);
  float pairAngle;
  switch (hybridization) {
    case Core::SP3:
      switch (bondCount) {
        case 0:
          pairAngle = 0.0f;
          break;
        case 1:
          pairAngle = fabs(computeAngle(bondVectors[0], in) - M_TETRAHEDRAL);
          break;
        case 2: {
          Vector3 pairVector = AtomUtilities::generateNewBondVector(
            molecule.atom(n), bondVectors, hybridization
          );
          pairAngle = computeAngle(pairVector, in);
          bondVectors.push_back(pairVector);
          pairVector = AtomUtilities::generateNewBondVector(
            molecule.atom(n), bondVectors, hybridization
          );
          pairAngle = std::min(pairAngle, computeAngle(pairVector, in));
          break;
        }
        case 3: {
          Vector3 pairVector = AtomUtilities::generateNewBondVector(
            molecule.atom(n), bondVectors, hybridization
          );
          pairAngle = computeAngle(pairVector, in);
          break;
        }
        default:
          return false;
      }
      break;
    case Core::SP2:
      switch (bondCount) {
        case 0:
          pairAngle = 0.0f;
          break;
        case 1:
          pairAngle = fabs(computeAngle(bondVectors[0], in) - M_TRIGONAL);
          break;
        case 2: {
          Vector3 pairVector = AtomUtilities::generateNewBondVector(
            molecule.atom(n), bondVectors, hybridization
          );
          pairAngle = computeAngle(pairVector, in);
          break;
        }
        default:
          return false;
      }
      break;
    case Core::SP:
      switch (bondCount) {
        case 0:
          pairAngle = 0.0f;
          break;
        case 1: {
          pairAngle = fabs(computeAngle(bondVectors[0], in) - M_PI);
          break;
        }
        default:
          return false;
      }
    default:
      return true;
  }
  return pairAngle <= angleTolerance;
}

void NonCovalent::process(const Molecule &molecule, Rendering::GroupNode &node)
{
  std::vector<Index> enabledAtoms;
  Array<Vector3> enabledPositions;
  Array<double> atomRadii;
  const size_t atomCount = molecule.atomCount();
  for (Index i = 0; i < atomCount; ++i) {
    enabledAtoms.push_back(i);
    enabledPositions.push_back(molecule.atomPosition3d(i));
    atomRadii.push_back(Elements::radiusVDW(molecule.atomicNumber(i)));
  }
  float absoluteMaxDistance = *std::max_element(
  	m_maximumDistances.begin(), m_maximumDistances.end()
  );
  NeighborPerceiver perceiver(enabledPositions, absoluteMaxDistance);

  GeometryNode *geometry = new GeometryNode;
  node.addChild(geometry);
  DashedLineGeometry *lines = new DashedLineGeometry;
  lines->identifier().molecule = &molecule;
  lines->identifier().type = Rendering::BondType;
  lines->setLineWidth(m_lineWidth);
  geometry->addDrawable(lines);
  Array<Index> neighbors;
  for (Index i: enabledAtoms) {
    enum InteractionTypes interactionType = getInteractionType(molecule, i);
    if (interactionType == NONE)
      continue;
    Vector3 pos = molecule.atomPosition3d(i);
    double radius = atomRadii[i];
    perceiver.getNeighborsInclusiveInPlace(neighbors, pos);
    for (Index ni : neighbors) {
      Index n = enabledAtoms[ni];
      if (!checkPairDonorIsValid(molecule, n, interactionType))
        continue;

      Vector3 npos = molecule.atomPosition3d(n);
      double nradius = atomRadii[n];
      Vector3 distance_vector = npos - pos;

      if (distance_vector.norm() > m_maximumDistances[interactionType] + radius + nradius)
        continue;
      if (!checkAtomPairNotBonded(molecule, i, n))
        continue;

      float angleTolerance = m_angleTolerancesDegrees[interactionType] * M_PI / 180.0;
      if (!checkHoleVector(molecule, i, distance_vector, angleTolerance))
        continue;
      if (!checkPairVector(molecule, n, -distance_vector, angleTolerance))
        continue;

      lines->addDashedLine(pos.cast<float>(), npos.cast<float>(), m_lineColors[interactionType], 8);
    }
  }
}

QWidget *NonCovalent::setupWidget()
{
  QWidget *widget = new QWidget(qobject_cast<QWidget *>(this->parent()));
  QVBoxLayout *v = new QVBoxLayout;
  QTabWidget *tabs = new QTabWidget;

  for (Index i = 0; i < 3; i++) {
  	// angle tolerance
		QDoubleSpinBox *angle_spin = new QDoubleSpinBox;
		angle_spin->setRange(0.0, 180.0);
		angle_spin->setSingleStep(1.0);
		angle_spin->setDecimals(0);
		angle_spin->setSuffix(tr(" °"));
		angle_spin->setValue(m_angleTolerancesDegrees[i]);
		QObject::connect(angle_spin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
			[this, i](float width){ return setAngleTolerance(width, i); }
		);

		// maximum distance
		QDoubleSpinBox *distance_spin = new QDoubleSpinBox;
		distance_spin->setRange(1.0, 10.0);
		distance_spin->setSingleStep(0.1);
		distance_spin->setDecimals(1);
		distance_spin->setSuffix(tr(" Å"));
		distance_spin->setValue(m_maximumDistances[i]);
		QObject::connect(distance_spin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
			[this, i](float width){ return setMaximumDistance(width, i); }
		);

  	// line width
		QDoubleSpinBox* lineWidth_spin = new QDoubleSpinBox;
		lineWidth_spin->setRange(1.0, 10.0);
		lineWidth_spin->setSingleStep(0.5);
		lineWidth_spin->setDecimals(1);
		lineWidth_spin->setValue(m_lineWidth);
		QObject::connect(lineWidth_spin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &NonCovalent::setLineWidth);

		QFormLayout *form = new QFormLayout;
  	form->addRow(QObject::tr("Angle tolerance:"), angle_spin);
  	form->addRow(QObject::tr("Maximum distance:"), distance_spin);
  	form->addRow(QObject::tr("Line width:"), lineWidth_spin);

  	QWidget *page = new QWidget;
  	page->setLayout(form);
  	tabs->addTab(page, INTERACTION_NAMES[i]);
  }

  v->addWidget(tabs);
  v->addStretch(1);
  widget->setLayout(v);
  return widget;
}

void NonCovalent::setAngleTolerance(float angleTolerance, Index index)
{
  m_angleTolerancesDegrees[index] = float(angleTolerance);
  emit drawablesChanged();

  QSettings settings;
  settings.setValue(QString("nonCovalent/angleTolerance%1").arg(index), angleTolerance);
}

void NonCovalent::setMaximumDistance(float maximumDistance, Index index)
{
  m_maximumDistances[index] = float(maximumDistance);
  emit drawablesChanged();

  QSettings settings;
  settings.setValue(QString("nonCovalent/maximumDistance%1").arg(index), maximumDistance);
}

void NonCovalent::setLineWidth(float width)
{
  m_lineWidth = width;
  emit drawablesChanged();

  QSettings settings;
  settings.setValue("nonCovalent/lineWidth", width);
}

} // namespace QtPlugins
} // namespace Avogadro
<|endoftext|>


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

#ifndef SC_OUTLINETAB_HXX
#define SC_OUTLINETAB_HXX

#ifndef SC_COLLECT_HXX
#include "collect.hxx"
#endif

#define SC_OL_MAXDEPTH      7

class SvStream;
class ScMultipleReadHeader;
class ScMultipleWriteHeader;

class ScOutlineEntry : public DataObject
{
    SCCOLROW    nStart;
    SCSIZE      nSize;
    BOOL        bHidden;
    BOOL        bVisible;

public:
                            ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize,
                                                BOOL bNewHidden = FALSE );
                            ScOutlineEntry( const ScOutlineEntry& rEntry );
                            ScOutlineEntry( SvStream& rStream, ScMultipleReadHeader& rHdr );

    void                    Store( SvStream& rStream, ScMultipleWriteHeader& rHdr );

    virtual DataObject*     Clone() const;

    SCCOLROW                GetStart() const    { return nStart; }
    SCSIZE                  GetSize() const     { return nSize; }
    SCCOLROW                GetEnd() const      { return nStart+nSize-1; }
    BOOL                    IsHidden() const    { return bHidden; }             // Gruppe versteckt
    BOOL                    IsVisible() const   { return bVisible; }            // Control sichtbar?

    void                    Move( SCsCOLROW nDelta );
    void                    SetSize( SCSIZE nNewSize );
    void                    SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize );
    void                    SetHidden( BOOL bNewHidden );
    void                    SetVisible( BOOL bNewVisible );
};

class ScOutlineCollection : public SortedCollection
{
public:
                            ScOutlineCollection();

    virtual short           Compare(DataObject* pKey1, DataObject* pKey2) const;

    USHORT                  FindStart( SCCOLROW nMinStart );
};

class ScOutlineArray
{
friend class ScSubOutlineIterator;

private:
    USHORT                  nDepth;
    ScOutlineCollection     aCollections[SC_OL_MAXDEPTH];

    BOOL                    DecDepth();
    void                    FindEntry( SCCOLROW nSearchPos, USHORT& rFindLevel, USHORT& rFindIndex,
                                        USHORT nMaxLevel = SC_OL_MAXDEPTH );
    void                    RemoveSub( SCCOLROW nStartPos, SCCOLROW nEndPos, USHORT nLevel );
    void                    PromoteSub( SCCOLROW nStartPos, SCCOLROW nEndPos, USHORT nStartLevel );

public:
                            ScOutlineArray();
                            ScOutlineArray( const ScOutlineArray& rArray );

    USHORT                  GetDepth() const         { return nDepth; }

    BOOL                    FindTouchedLevel( SCCOLROW nBlockStart, SCCOLROW nBlockEnd,
                                                USHORT& rFindLevel ) const;

    BOOL                    Insert( SCCOLROW nStartPos, SCCOLROW nEndPos, BOOL& rSizeChanged,
                                    BOOL bHidden = FALSE, BOOL bVisible = TRUE );
    BOOL                    Remove( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, BOOL& rSizeChanged );

    ScOutlineEntry*         GetEntry( USHORT nLevel, USHORT nIndex ) const;
    USHORT                  GetCount( USHORT nLevel ) const;
    ScOutlineEntry*         GetEntryByPos( USHORT nLevel, SCCOLROW nPos ) const;

    BOOL                    GetEntryIndex( USHORT nLevel, SCCOLROW nPos, USHORT& rnIndex ) const;
    BOOL                    GetEntryIndexInRange(
                                USHORT nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd,
                                USHORT& rnIndex ) const;

    void                    SetVisibleBelow( USHORT nLevel, USHORT nEntry, BOOL bValue,
                                                BOOL bSkipHidden = FALSE );

    void                    GetRange( SCCOLROW& rStart, SCCOLROW& rEnd ) const;
    void                    ExtendBlock( USHORT nLevel, SCCOLROW& rBlkStart, SCCOLROW& rBlkEnd );

    BOOL                    TestInsertSpace( SCSIZE nSize, SCCOLROW nMaxVal ) const;
    void                    InsertSpace( SCCOLROW nStartPos, SCSIZE nSize );
    BOOL                    DeleteSpace( SCCOLROW nStartPos, SCSIZE nSize );

    BOOL                    ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos,
                                            BOOL bShow, BYTE* pHiddenFlags );

    void                    Load( SvStream& rStream );
    void                    Store( SvStream& rStream );

    void                    RemoveAll();
};

class ScOutlineTable
{
private:
    ScOutlineArray          aColOutline;
    ScOutlineArray          aRowOutline;

public:
                            ScOutlineTable();
                            ScOutlineTable( const ScOutlineTable& rOutline );

    const ScOutlineArray*   GetColArray() const     { return &aColOutline; }
    ScOutlineArray*         GetColArray()           { return &aColOutline; }
    const ScOutlineArray*   GetRowArray() const     { return &aRowOutline; }
    ScOutlineArray*         GetRowArray()           { return &aRowOutline; }

    BOOL                    TestInsertCol( SCSIZE nSize );
    void                    InsertCol( SCCOL nStartCol, SCSIZE nSize );
    BOOL                    DeleteCol( SCCOL nStartCol, SCSIZE nSize ); // TRUE: Undo nur ueber Original
    BOOL                    TestInsertRow( SCSIZE nSize );
    void                    InsertRow( SCROW nStartRow, SCSIZE nSize );
    BOOL                    DeleteRow( SCROW nStartRow, SCSIZE nSize );

    void                    Load( SvStream& rStream );
    void                    Store( SvStream& rStream );
};

class ScSubOutlineIterator
{
private:
    ScOutlineArray*         pArray;
    SCCOLROW                nStart;
    SCCOLROW                nEnd;
    USHORT                  nSubLevel;
    USHORT                  nSubEntry;
    USHORT                  nCount;
    USHORT                  nDepth;

public:
                            ScSubOutlineIterator( ScOutlineArray* pOutlineArray );
                            ScSubOutlineIterator( ScOutlineArray* pOutlineArray,
                                                    USHORT nLevel, USHORT nEntry );
    ScOutlineEntry*         GetNext();
    USHORT                  LastLevel() const;
    USHORT                  LastEntry() const;
    void                    DeleteLast();
};

#endif

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

#ifndef SC_OUTLINETAB_HXX
#define SC_OUTLINETAB_HXX

#ifndef SC_COLLECT_HXX
#include "collect.hxx"
#endif
#ifndef SC_COMPRESSEDARRAY_HXX
#include "compressedarray.hxx"
#endif

#define SC_OL_MAXDEPTH      7

class SvStream;
class ScMultipleReadHeader;
class ScMultipleWriteHeader;

class ScOutlineEntry : public DataObject
{
    SCCOLROW    nStart;
    SCSIZE      nSize;
    BOOL        bHidden;
    BOOL        bVisible;

public:
                            ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize,
                                                BOOL bNewHidden = FALSE );
                            ScOutlineEntry( const ScOutlineEntry& rEntry );
                            ScOutlineEntry( SvStream& rStream, ScMultipleReadHeader& rHdr );

    void                    Store( SvStream& rStream, ScMultipleWriteHeader& rHdr );

    virtual DataObject*     Clone() const;

    SCCOLROW                GetStart() const    { return nStart; }
    SCSIZE                  GetSize() const     { return nSize; }
    SCCOLROW                GetEnd() const      { return nStart+nSize-1; }
    BOOL                    IsHidden() const    { return bHidden; }             // Gruppe versteckt
    BOOL                    IsVisible() const   { return bVisible; }            // Control sichtbar?

    void                    Move( SCsCOLROW nDelta );
    void                    SetSize( SCSIZE nNewSize );
    void                    SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize );
    void                    SetHidden( BOOL bNewHidden );
    void                    SetVisible( BOOL bNewVisible );
};

class ScOutlineCollection : public SortedCollection
{
public:
                            ScOutlineCollection();

    virtual short           Compare(DataObject* pKey1, DataObject* pKey2) const;

    USHORT                  FindStart( SCCOLROW nMinStart );
};

class ScOutlineArray
{
friend class ScSubOutlineIterator;

private:
    USHORT                  nDepth;
    ScOutlineCollection     aCollections[SC_OL_MAXDEPTH];

    BOOL                    DecDepth();
    void                    FindEntry( SCCOLROW nSearchPos, USHORT& rFindLevel, USHORT& rFindIndex,
                                        USHORT nMaxLevel = SC_OL_MAXDEPTH );
    void                    RemoveSub( SCCOLROW nStartPos, SCCOLROW nEndPos, USHORT nLevel );
    void                    PromoteSub( SCCOLROW nStartPos, SCCOLROW nEndPos, USHORT nStartLevel );

public:
                            ScOutlineArray();
                            ScOutlineArray( const ScOutlineArray& rArray );

    USHORT                  GetDepth() const         { return nDepth; }

    BOOL                    FindTouchedLevel( SCCOLROW nBlockStart, SCCOLROW nBlockEnd,
                                                USHORT& rFindLevel ) const;

    BOOL                    Insert( SCCOLROW nStartPos, SCCOLROW nEndPos, BOOL& rSizeChanged,
                                    BOOL bHidden = FALSE, BOOL bVisible = TRUE );
    BOOL                    Remove( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, BOOL& rSizeChanged );

    ScOutlineEntry*         GetEntry( USHORT nLevel, USHORT nIndex ) const;
    USHORT                  GetCount( USHORT nLevel ) const;
    ScOutlineEntry*         GetEntryByPos( USHORT nLevel, SCCOLROW nPos ) const;

    BOOL                    GetEntryIndex( USHORT nLevel, SCCOLROW nPos, USHORT& rnIndex ) const;
    BOOL                    GetEntryIndexInRange(
                                USHORT nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd,
                                USHORT& rnIndex ) const;

    void                    SetVisibleBelow( USHORT nLevel, USHORT nEntry, BOOL bValue,
                                                BOOL bSkipHidden = FALSE );

    void                    GetRange( SCCOLROW& rStart, SCCOLROW& rEnd ) const;
    void                    ExtendBlock( USHORT nLevel, SCCOLROW& rBlkStart, SCCOLROW& rBlkEnd );

    BOOL                    TestInsertSpace( SCSIZE nSize, SCCOLROW nMaxVal ) const;
    void                    InsertSpace( SCCOLROW nStartPos, SCSIZE nSize );
    BOOL                    DeleteSpace( SCCOLROW nStartPos, SCSIZE nSize );

    BOOL                    ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos,
                                BOOL bShow,
                                const ScBitMaskCompressedArray< SCCOLROW, BYTE>& rHiddenFlags );

    void                    Load( SvStream& rStream );
    void                    Store( SvStream& rStream );

    void                    RemoveAll();
};

class ScOutlineTable
{
private:
    ScOutlineArray          aColOutline;
    ScOutlineArray          aRowOutline;

public:
                            ScOutlineTable();
                            ScOutlineTable( const ScOutlineTable& rOutline );

    const ScOutlineArray*   GetColArray() const     { return &aColOutline; }
    ScOutlineArray*         GetColArray()           { return &aColOutline; }
    const ScOutlineArray*   GetRowArray() const     { return &aRowOutline; }
    ScOutlineArray*         GetRowArray()           { return &aRowOutline; }

    BOOL                    TestInsertCol( SCSIZE nSize );
    void                    InsertCol( SCCOL nStartCol, SCSIZE nSize );
    BOOL                    DeleteCol( SCCOL nStartCol, SCSIZE nSize ); // TRUE: Undo nur ueber Original
    BOOL                    TestInsertRow( SCSIZE nSize );
    void                    InsertRow( SCROW nStartRow, SCSIZE nSize );
    BOOL                    DeleteRow( SCROW nStartRow, SCSIZE nSize );

    void                    Load( SvStream& rStream );
    void                    Store( SvStream& rStream );
};

class ScSubOutlineIterator
{
private:
    ScOutlineArray*         pArray;
    SCCOLROW                nStart;
    SCCOLROW                nEnd;
    USHORT                  nSubLevel;
    USHORT                  nSubEntry;
    USHORT                  nCount;
    USHORT                  nDepth;

public:
                            ScSubOutlineIterator( ScOutlineArray* pOutlineArray );
                            ScSubOutlineIterator( ScOutlineArray* pOutlineArray,
                                                    USHORT nLevel, USHORT nEntry );
    ScOutlineEntry*         GetNext();
    USHORT                  LastLevel() const;
    USHORT                  LastEntry() const;
    void                    DeleteLast();
};

#endif

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#ifndef SC_PRINTOPT_HXX
#define SC_PRINTOPT_HXX

#include <svl/poolitem.hxx>
#include <unotools/configitem.hxx>
#include "scdllapi.h"

class SC_DLLPUBLIC ScPrintOptions
{
private:
    sal_Bool    bSkipEmpty;
    sal_Bool    bAllSheets;
    sal_Bool    bForceBreaks;

public:
                ScPrintOptions();
                ScPrintOptions( const ScPrintOptions& rCpy );
                ~ScPrintOptions();

    sal_Bool    GetSkipEmpty() const            { return bSkipEmpty; }
    void    SetSkipEmpty( sal_Bool bVal )       { bSkipEmpty = bVal; }
    sal_Bool    GetAllSheets() const            { return bAllSheets; }
    void    SetAllSheets( sal_Bool bVal )       { bAllSheets = bVal; }
    sal_Bool    GetForceBreaks() const          { return bForceBreaks; }
    void    SetForceBreaks( sal_Bool bVal )     { bForceBreaks = bVal; }

    void    SetDefaults();

    const ScPrintOptions&   operator=  ( const ScPrintOptions& rCpy );
    bool                    operator== ( const ScPrintOptions& rOpt ) const;
    bool                    operator!= ( const ScPrintOptions& rOpt ) const;
};

// item for the dialog / options page

class SC_DLLPUBLIC ScTpPrintItem : public SfxPoolItem
{
public:
                TYPEINFO();
                ScTpPrintItem( sal_uInt16 nWhich,
                               const ScPrintOptions& rOpt );
                ScTpPrintItem( const ScTpPrintItem& rItem );
                ~ScTpPrintItem();

    virtual OUString        GetValueText() const;
    virtual int             operator==( const SfxPoolItem& ) const;
    virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const;

    const ScPrintOptions&   GetPrintOptions() const { return theOptions; }

private:
    ScPrintOptions theOptions;
};

// config item

class ScPrintCfg : public ScPrintOptions, public utl::ConfigItem
{
    com::sun::star::uno::Sequence<OUString> GetPropertyNames();

public:
            ScPrintCfg();

    void            SetOptions( const ScPrintOptions& rNew );

    virtual void    Commit();
    virtual void Notify( const ::com::sun::star::uno::Sequence< OUString >& aPropertyNames );
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>warning C4805 unsafe mix of type sal_Bool and type bool<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#ifndef SC_PRINTOPT_HXX
#define SC_PRINTOPT_HXX

#include <svl/poolitem.hxx>
#include <unotools/configitem.hxx>
#include "scdllapi.h"

class SC_DLLPUBLIC ScPrintOptions
{
private:
    sal_Bool    bSkipEmpty;
    sal_Bool    bAllSheets;
    sal_Bool    bForceBreaks;

public:
                ScPrintOptions();
                ScPrintOptions( const ScPrintOptions& rCpy );
                ~ScPrintOptions();

    sal_Bool    GetSkipEmpty() const            { return bSkipEmpty; }
    void    SetSkipEmpty( sal_Bool bVal )       { bSkipEmpty = bVal; }
    sal_Bool    GetAllSheets() const            { return bAllSheets; }
    void    SetAllSheets( sal_Bool bVal )       { bAllSheets = bVal; }
    bool    GetForceBreaks() const              { return bForceBreaks; }
    void    SetForceBreaks( sal_Bool bVal )     { bForceBreaks = bVal; }

    void    SetDefaults();

    const ScPrintOptions&   operator=  ( const ScPrintOptions& rCpy );
    bool                    operator== ( const ScPrintOptions& rOpt ) const;
    bool                    operator!= ( const ScPrintOptions& rOpt ) const;
};

// item for the dialog / options page

class SC_DLLPUBLIC ScTpPrintItem : public SfxPoolItem
{
public:
                TYPEINFO();
                ScTpPrintItem( sal_uInt16 nWhich,
                               const ScPrintOptions& rOpt );
                ScTpPrintItem( const ScTpPrintItem& rItem );
                ~ScTpPrintItem();

    virtual OUString        GetValueText() const;
    virtual int             operator==( const SfxPoolItem& ) const;
    virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const;

    const ScPrintOptions&   GetPrintOptions() const { return theOptions; }

private:
    ScPrintOptions theOptions;
};

// config item

class ScPrintCfg : public ScPrintOptions, public utl::ConfigItem
{
    com::sun::star::uno::Sequence<OUString> GetPropertyNames();

public:
            ScPrintCfg();

    void            SetOptions( const ScPrintOptions& rNew );

    virtual void    Commit();
    virtual void Notify( const ::com::sun::star::uno::Sequence< OUString >& aPropertyNames );
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


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

#ifndef SC_RANGELST_HXX
#define SC_RANGELST_HXX

#ifndef SC_SCGLOB_HXX
#include "global.hxx"
#endif

#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif
#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

class ScDocument;

typedef ScRange* ScRangePtr;
DECLARE_LIST( ScRangeListBase, ScRangePtr );
class ScRangeList : public ScRangeListBase, public SvRefBase
{
public:
                    ScRangeList() {}
                    ScRangeList( const ScRangeList& rList );
    virtual         ~ScRangeList();
    ScRangeList&    operator=(const ScRangeList& rList);
    void            RemoveAll();
    ScRangeList*    Clone() const;
    void            Append( const ScRange& rRange )
                    {
                        ScRangePtr pR = new ScRange( rRange );
                        Insert( pR, LIST_APPEND );
                    }
    USHORT          Parse( const String&, ScDocument* = NULL,
                            USHORT nMask = SCA_VALID );
    void            Format( String&, USHORT nFlags = 0, ScDocument* = NULL ) const;
    void            Join( const ScRange&, BOOL bIsInList = FALSE );
    BOOL            UpdateReference( UpdateRefMode, ScDocument*,
                                    const ScRange& rWhere,
                                    SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
    ScRange*        Find( const ScAddress& ) const;
    ScRange*        Find( const ScRange& ) const;
    BOOL            Load( SvStream&, USHORT nVer );
    BOOL            Store( SvStream& ) const;
    BOOL            operator==( const ScRangeList& ) const;
    BOOL            Intersects( const ScRange& ) const;
    BOOL            In( const ScRange& ) const;
    ULONG           GetCellCount() const;
};
SV_DECL_IMPL_REF( ScRangeList );

// RangePairList: erster Range (aRange[0]) eigentlicher Range, zweiter
// Range (aRange[1]) Daten zu diesem Range, z.B. Rows eines ColName
DECLARE_LIST( ScRangePairListBase, ScRangePair* );
class ScRangePairList : public ScRangePairListBase, public SvRefBase
{
#if defined( ICC ) && defined( OS2 )
    friend static int _Optlink ICCQsortRPairCompare( const void*, const void*);
#endif
private:
    static int
#ifdef WNT
        __cdecl
#endif
                    QsortNameCompare( const void*, const void* );

public:
    virtual         ~ScRangePairList();
    ScRangePairList*    Clone() const;
    void            Append( const ScRangePair& rRangePair )
                    {
                        ScRangePair* pR = new ScRangePair( rRangePair );
                        Insert( pR, LIST_APPEND );
                    }
    void            Join( const ScRangePair&, BOOL bIsInList = FALSE );
    BOOL            UpdateReference( UpdateRefMode, ScDocument*,
                                    const ScRange& rWhere,
                                    SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
    ScRangePair*    Find( const ScAddress& ) const;
    ScRangePair*    Find( const ScRange& ) const;
    BOOL            Load( SvStream&, USHORT nVer );
    BOOL            Store( SvStream& ) const;
    ScRangePair**   CreateNameSortedArray( ULONG& nCount, ScDocument* ) const;
    BOOL            operator==( const ScRangePairList& ) const;
};
SV_DECL_IMPL_REF( ScRangePairList );

#if defined( ICC ) && defined( SC_RANGELST_CXX ) && defined( OS2 )
    static int _Optlink ICCQsortRPairCompare( const void* a, const void* b)
                    { ScRangePairList::QsortNameCompare(a,b); }
#endif

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.452); FILE MERGED 2005/09/05 15:00:54 rt 1.3.452.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: rangelst.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 17:49:48 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_RANGELST_HXX
#define SC_RANGELST_HXX

#ifndef SC_SCGLOB_HXX
#include "global.hxx"
#endif

#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif
#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

class ScDocument;

typedef ScRange* ScRangePtr;
DECLARE_LIST( ScRangeListBase, ScRangePtr );
class ScRangeList : public ScRangeListBase, public SvRefBase
{
public:
                    ScRangeList() {}
                    ScRangeList( const ScRangeList& rList );
    virtual         ~ScRangeList();
    ScRangeList&    operator=(const ScRangeList& rList);
    void            RemoveAll();
    ScRangeList*    Clone() const;
    void            Append( const ScRange& rRange )
                    {
                        ScRangePtr pR = new ScRange( rRange );
                        Insert( pR, LIST_APPEND );
                    }
    USHORT          Parse( const String&, ScDocument* = NULL,
                            USHORT nMask = SCA_VALID );
    void            Format( String&, USHORT nFlags = 0, ScDocument* = NULL ) const;
    void            Join( const ScRange&, BOOL bIsInList = FALSE );
    BOOL            UpdateReference( UpdateRefMode, ScDocument*,
                                    const ScRange& rWhere,
                                    SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
    ScRange*        Find( const ScAddress& ) const;
    ScRange*        Find( const ScRange& ) const;
    BOOL            Load( SvStream&, USHORT nVer );
    BOOL            Store( SvStream& ) const;
    BOOL            operator==( const ScRangeList& ) const;
    BOOL            Intersects( const ScRange& ) const;
    BOOL            In( const ScRange& ) const;
    ULONG           GetCellCount() const;
};
SV_DECL_IMPL_REF( ScRangeList );

// RangePairList: erster Range (aRange[0]) eigentlicher Range, zweiter
// Range (aRange[1]) Daten zu diesem Range, z.B. Rows eines ColName
DECLARE_LIST( ScRangePairListBase, ScRangePair* );
class ScRangePairList : public ScRangePairListBase, public SvRefBase
{
#if defined( ICC ) && defined( OS2 )
    friend static int _Optlink ICCQsortRPairCompare( const void*, const void*);
#endif
private:
    static int
#ifdef WNT
        __cdecl
#endif
                    QsortNameCompare( const void*, const void* );

public:
    virtual         ~ScRangePairList();
    ScRangePairList*    Clone() const;
    void            Append( const ScRangePair& rRangePair )
                    {
                        ScRangePair* pR = new ScRangePair( rRangePair );
                        Insert( pR, LIST_APPEND );
                    }
    void            Join( const ScRangePair&, BOOL bIsInList = FALSE );
    BOOL            UpdateReference( UpdateRefMode, ScDocument*,
                                    const ScRange& rWhere,
                                    SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
    ScRangePair*    Find( const ScAddress& ) const;
    ScRangePair*    Find( const ScRange& ) const;
    BOOL            Load( SvStream&, USHORT nVer );
    BOOL            Store( SvStream& ) const;
    ScRangePair**   CreateNameSortedArray( ULONG& nCount, ScDocument* ) const;
    BOOL            operator==( const ScRangePairList& ) const;
};
SV_DECL_IMPL_REF( ScRangePairList );

#if defined( ICC ) && defined( SC_RANGELST_CXX ) && defined( OS2 )
    static int _Optlink ICCQsortRPairCompare( const void* a, const void* b)
                    { ScRangePairList::QsortNameCompare(a,b); }
#endif

#endif
<|endoftext|>


<commit_before>/*************************************************************************/
/*  range.cpp                                                            */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* 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 "range.h"

void Range::_value_changed_notify() {

	_value_changed(shared->val);
	emit_signal("value_changed", shared->val);
	update();
	_change_notify("value");
}

void Range::Shared::emit_value_changed() {

	for (Set<Range *>::Element *E = owners.front(); E; E = E->next()) {
		Range *r = E->get();
		if (!r->is_inside_tree())
			continue;
		r->_value_changed_notify();
	}
}

void Range::_changed_notify(const char *p_what) {

	emit_signal("changed", shared->val);
	update();
	_change_notify(p_what);
}

void Range::Shared::emit_changed(const char *p_what) {

	for (Set<Range *>::Element *E = owners.front(); E; E = E->next()) {
		Range *r = E->get();
		if (!r->is_inside_tree())
			continue;
		r->_changed_notify(p_what);
	}
}

void Range::set_value(double p_val) {

	if (_rounded_values) {
		p_val = Math::round(p_val);
	}

	if (p_val > shared->max - shared->page)
		p_val = shared->max - shared->page;

	if (p_val < shared->min)
		p_val = shared->min;

	if (shared->val == p_val)
		return;

	shared->val = p_val;

	shared->emit_value_changed();
}
void Range::set_min(double p_min) {

	shared->min = p_min;
	set_value(shared->val);

	shared->emit_changed("min");
}
void Range::set_max(double p_max) {

	shared->max = p_max;
	set_value(shared->val);

	shared->emit_changed("max");
}
void Range::set_step(double p_step) {

	shared->step = p_step;
	shared->emit_changed("step");
}
void Range::set_page(double p_page) {

	shared->page = p_page;
	set_value(shared->val);

	shared->emit_changed("page");
}

double Range::get_value() const {

	return shared->val;
}
double Range::get_min() const {

	return shared->min;
}
double Range::get_max() const {

	return shared->max;
}
double Range::get_step() const {

	return shared->step;
}
double Range::get_page() const {

	return shared->page;
}

void Range::set_as_ratio(double p_value) {

	double v;

	if (shared->exp_ratio && get_min() > 0) {

		double exp_min = Math::log(get_min()) / Math::log((double)2);
		double exp_max = Math::log(get_max()) / Math::log((double)2);
		v = Math::pow(2, exp_min + (exp_max - exp_min) * p_value);
	} else {

		double percent = (get_max() - get_min()) * p_value;
		if (get_step() > 0) {
			double steps = round(percent / get_step());
			v = steps * get_step() + get_min();
		} else {
			v = percent + get_min();
		}
	}
	set_value(v);
}
double Range::get_as_ratio() const {

	if (shared->exp_ratio && get_min() > 0) {

		double exp_min = Math::log(get_min()) / Math::log((double)2);
		double exp_max = Math::log(get_max()) / Math::log((double)2);
		double v = Math::log(get_value()) / Math::log((double)2);

		return (v - exp_min) / (exp_max - exp_min);

	} else {

		return (get_value() - get_min()) / (get_max() - get_min());
	}
}

void Range::_share(Node *p_range) {

	Range *r = Object::cast_to<Range>(p_range);
	ERR_FAIL_COND(!r);
	share(r);
}

void Range::share(Range *p_range) {

	ERR_FAIL_NULL(p_range);

	p_range->_ref_shared(shared);
	p_range->_changed_notify();
	p_range->_value_changed_notify();
}

void Range::unshare() {

	Shared *nshared = memnew(Shared);
	nshared->min = shared->min;
	nshared->max = shared->max;
	nshared->val = shared->val;
	nshared->step = shared->step;
	nshared->page = shared->page;
	_unref_shared();
	_ref_shared(nshared);
}

void Range::_ref_shared(Shared *p_shared) {

	if (shared && p_shared == shared)
		return;

	_unref_shared();
	shared = p_shared;
	shared->owners.insert(this);
}

void Range::_unref_shared() {

	shared->owners.erase(this);
	if (shared->owners.size() == 0) {
		memdelete(shared);
		shared = NULL;
	}
}

void Range::_bind_methods() {

	ClassDB::bind_method(D_METHOD("get_value"), &Range::get_value);
	ClassDB::bind_method(D_METHOD("get_min"), &Range::get_min);
	ClassDB::bind_method(D_METHOD("get_max"), &Range::get_max);
	ClassDB::bind_method(D_METHOD("get_step"), &Range::get_step);
	ClassDB::bind_method(D_METHOD("get_page"), &Range::get_page);
	ClassDB::bind_method(D_METHOD("get_as_ratio"), &Range::get_as_ratio);
	ClassDB::bind_method(D_METHOD("set_value", "value"), &Range::set_value);
	ClassDB::bind_method(D_METHOD("set_min", "minimum"), &Range::set_min);
	ClassDB::bind_method(D_METHOD("set_max", "maximum"), &Range::set_max);
	ClassDB::bind_method(D_METHOD("set_step", "step"), &Range::set_step);
	ClassDB::bind_method(D_METHOD("set_page", "pagesize"), &Range::set_page);
	ClassDB::bind_method(D_METHOD("set_as_ratio", "value"), &Range::set_as_ratio);
	ClassDB::bind_method(D_METHOD("set_use_rounded_values", "enabled"), &Range::set_use_rounded_values);
	ClassDB::bind_method(D_METHOD("is_using_rounded_values"), &Range::is_using_rounded_values);
	ClassDB::bind_method(D_METHOD("set_exp_ratio", "enabled"), &Range::set_exp_ratio);
	ClassDB::bind_method(D_METHOD("is_ratio_exp"), &Range::is_ratio_exp);

	ClassDB::bind_method(D_METHOD("share", "with"), &Range::_share);
	ClassDB::bind_method(D_METHOD("unshare"), &Range::unshare);

	ADD_SIGNAL(MethodInfo("value_changed", PropertyInfo(Variant::REAL, "value")));
	ADD_SIGNAL(MethodInfo("changed"));

	ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_value"), "set_min", "get_min");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_value"), "set_max", "get_max");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "step"), "set_step", "get_step");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "page"), "set_page", "get_page");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "value"), "set_value", "get_value");
	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exp_edit"), "set_exp_ratio", "is_ratio_exp");
	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rounded"), "set_use_rounded_values", "is_using_rounded_values");
}

void Range::set_use_rounded_values(bool p_enable) {

	_rounded_values = p_enable;
}

bool Range::is_using_rounded_values() const {

	return _rounded_values;
}

void Range::set_exp_ratio(bool p_enable) {

	shared->exp_ratio = p_enable;
}

bool Range::is_ratio_exp() const {

	return shared->exp_ratio;
}

Range::Range() {
	shared = memnew(Shared);
	shared->min = 0;
	shared->max = 100;
	shared->val = 0;
	shared->step = 1;
	shared->page = 0;
	shared->owners.insert(this);
	shared->exp_ratio = false;

	_rounded_values = false;
}

Range::~Range() {

	_unref_shared();
}
<commit_msg>Fix crash when unsharing a range that is not shared<commit_after>/*************************************************************************/
/*  range.cpp                                                            */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* 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 "range.h"

void Range::_value_changed_notify() {

	_value_changed(shared->val);
	emit_signal("value_changed", shared->val);
	update();
	_change_notify("value");
}

void Range::Shared::emit_value_changed() {

	for (Set<Range *>::Element *E = owners.front(); E; E = E->next()) {
		Range *r = E->get();
		if (!r->is_inside_tree())
			continue;
		r->_value_changed_notify();
	}
}

void Range::_changed_notify(const char *p_what) {

	emit_signal("changed", shared->val);
	update();
	_change_notify(p_what);
}

void Range::Shared::emit_changed(const char *p_what) {

	for (Set<Range *>::Element *E = owners.front(); E; E = E->next()) {
		Range *r = E->get();
		if (!r->is_inside_tree())
			continue;
		r->_changed_notify(p_what);
	}
}

void Range::set_value(double p_val) {

	if (_rounded_values) {
		p_val = Math::round(p_val);
	}

	if (p_val > shared->max - shared->page)
		p_val = shared->max - shared->page;

	if (p_val < shared->min)
		p_val = shared->min;

	if (shared->val == p_val)
		return;

	shared->val = p_val;

	shared->emit_value_changed();
}
void Range::set_min(double p_min) {

	shared->min = p_min;
	set_value(shared->val);

	shared->emit_changed("min");
}
void Range::set_max(double p_max) {

	shared->max = p_max;
	set_value(shared->val);

	shared->emit_changed("max");
}
void Range::set_step(double p_step) {

	shared->step = p_step;
	shared->emit_changed("step");
}
void Range::set_page(double p_page) {

	shared->page = p_page;
	set_value(shared->val);

	shared->emit_changed("page");
}

double Range::get_value() const {

	return shared->val;
}
double Range::get_min() const {

	return shared->min;
}
double Range::get_max() const {

	return shared->max;
}
double Range::get_step() const {

	return shared->step;
}
double Range::get_page() const {

	return shared->page;
}

void Range::set_as_ratio(double p_value) {

	double v;

	if (shared->exp_ratio && get_min() > 0) {

		double exp_min = Math::log(get_min()) / Math::log((double)2);
		double exp_max = Math::log(get_max()) / Math::log((double)2);
		v = Math::pow(2, exp_min + (exp_max - exp_min) * p_value);
	} else {

		double percent = (get_max() - get_min()) * p_value;
		if (get_step() > 0) {
			double steps = round(percent / get_step());
			v = steps * get_step() + get_min();
		} else {
			v = percent + get_min();
		}
	}
	set_value(v);
}
double Range::get_as_ratio() const {

	if (shared->exp_ratio && get_min() > 0) {

		double exp_min = Math::log(get_min()) / Math::log((double)2);
		double exp_max = Math::log(get_max()) / Math::log((double)2);
		double v = Math::log(get_value()) / Math::log((double)2);

		return (v - exp_min) / (exp_max - exp_min);

	} else {

		return (get_value() - get_min()) / (get_max() - get_min());
	}
}

void Range::_share(Node *p_range) {

	Range *r = Object::cast_to<Range>(p_range);
	ERR_FAIL_COND(!r);
	share(r);
}

void Range::share(Range *p_range) {

	ERR_FAIL_NULL(p_range);

	p_range->_ref_shared(shared);
	p_range->_changed_notify();
	p_range->_value_changed_notify();
}

void Range::unshare() {

	Shared *nshared = memnew(Shared);
	nshared->min = shared->min;
	nshared->max = shared->max;
	nshared->val = shared->val;
	nshared->step = shared->step;
	nshared->page = shared->page;
	_unref_shared();
	_ref_shared(nshared);
}

void Range::_ref_shared(Shared *p_shared) {

	if (shared && p_shared == shared)
		return;

	_unref_shared();
	shared = p_shared;
	shared->owners.insert(this);
}

void Range::_unref_shared() {

	if (shared) {
		shared->owners.erase(this);
		if (shared->owners.size() == 0) {
			memdelete(shared);
			shared = NULL;
		}
	}
}

void Range::_bind_methods() {

	ClassDB::bind_method(D_METHOD("get_value"), &Range::get_value);
	ClassDB::bind_method(D_METHOD("get_min"), &Range::get_min);
	ClassDB::bind_method(D_METHOD("get_max"), &Range::get_max);
	ClassDB::bind_method(D_METHOD("get_step"), &Range::get_step);
	ClassDB::bind_method(D_METHOD("get_page"), &Range::get_page);
	ClassDB::bind_method(D_METHOD("get_as_ratio"), &Range::get_as_ratio);
	ClassDB::bind_method(D_METHOD("set_value", "value"), &Range::set_value);
	ClassDB::bind_method(D_METHOD("set_min", "minimum"), &Range::set_min);
	ClassDB::bind_method(D_METHOD("set_max", "maximum"), &Range::set_max);
	ClassDB::bind_method(D_METHOD("set_step", "step"), &Range::set_step);
	ClassDB::bind_method(D_METHOD("set_page", "pagesize"), &Range::set_page);
	ClassDB::bind_method(D_METHOD("set_as_ratio", "value"), &Range::set_as_ratio);
	ClassDB::bind_method(D_METHOD("set_use_rounded_values", "enabled"), &Range::set_use_rounded_values);
	ClassDB::bind_method(D_METHOD("is_using_rounded_values"), &Range::is_using_rounded_values);
	ClassDB::bind_method(D_METHOD("set_exp_ratio", "enabled"), &Range::set_exp_ratio);
	ClassDB::bind_method(D_METHOD("is_ratio_exp"), &Range::is_ratio_exp);

	ClassDB::bind_method(D_METHOD("share", "with"), &Range::_share);
	ClassDB::bind_method(D_METHOD("unshare"), &Range::unshare);

	ADD_SIGNAL(MethodInfo("value_changed", PropertyInfo(Variant::REAL, "value")));
	ADD_SIGNAL(MethodInfo("changed"));

	ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_value"), "set_min", "get_min");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_value"), "set_max", "get_max");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "step"), "set_step", "get_step");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "page"), "set_page", "get_page");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "value"), "set_value", "get_value");
	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exp_edit"), "set_exp_ratio", "is_ratio_exp");
	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rounded"), "set_use_rounded_values", "is_using_rounded_values");
}

void Range::set_use_rounded_values(bool p_enable) {

	_rounded_values = p_enable;
}

bool Range::is_using_rounded_values() const {

	return _rounded_values;
}

void Range::set_exp_ratio(bool p_enable) {

	shared->exp_ratio = p_enable;
}

bool Range::is_ratio_exp() const {

	return shared->exp_ratio;
}

Range::Range() {
	shared = memnew(Shared);
	shared->min = 0;
	shared->max = 100;
	shared->val = 0;
	shared->step = 1;
	shared->page = 0;
	shared->owners.insert(this);
	shared->exp_ratio = false;

	_rounded_values = false;
}

Range::~Range() {

	_unref_shared();
}
<|endoftext|>