<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: bibcont.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 19:13:23 $
 *
 *  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 ADDRCONT_HXX
#define ADDRCONT_HXX

#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif

#ifndef _SV_SPLITWIN_HXX
#include <vcl/splitwin.hxx>
#endif

#ifndef _SV_TIMER_HXX //autogen wg. Timer
#include <vcl/timer.hxx>
#endif
#ifndef _BIBSHORTCUTHANDLER_HXX
#include "bibshortcuthandler.hxx"
#endif

#include "bibmod.hxx"

#define TOP_WINDOW                          1
#define BOTTOM_WINDOW                       2

class BibDataManager;

class BibWindowContainer : public BibWindow     //Window
{
    private:
        // !BibShortCutHandler is also always a Window!
        BibShortCutHandler*     pChild;

    protected:
        virtual void            Resize();

    public:
        BibWindowContainer( Window* pParent, WinBits nStyle = WB_3DLOOK );
        BibWindowContainer( Window* pParent, BibShortCutHandler* pChild, WinBits nStyle = WB_3DLOOK);
        ~BibWindowContainer();

        inline Window*          GetChild();

        virtual void            GetFocus();

        virtual BOOL            HandleShortCutKey( const KeyEvent& rKeyEvent ); // returns true, if key was handled
};

inline Window* BibWindowContainer::GetChild()
{
    return pChild? pChild->GetWindow() : NULL;
}

class BibBookContainer: public BibSplitWindow
{
    private:

        ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >             xTopFrameRef;
        ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >             xBottomFrameRef;

        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >              xTopPeerRef;
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >              xBottomPeerRef;
        sal_Bool                    bFirstTime;

        BibWindowContainer*     pTopWin;
        BibWindowContainer*     pBottomWin;
        BibDataManager*         pDatMan;
        HdlBibModul             pBibMod;
        Timer                   aTimer;

        DECL_LINK( SplitHdl, Timer*);

    protected:

        virtual void            Split();

        virtual long            PreNotify( NotifyEvent& rNEvt );
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >
                                GetTopComponentInterface( sal_Bool bCreate = sal_True );
        void                    SetTopComponentInterface( ::com::sun::star::awt::XWindowPeer* pIFace );

        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > GetBottomComponentInterface( sal_Bool bCreate = sal_True );
        void                    SetBottomComponentInterface( ::com::sun::star::awt::XWindowPeer* pIFace );

    public:

        BibBookContainer(Window* pParent,BibDataManager*, WinBits nStyle = WB_3DLOOK );
        ~BibBookContainer();

        inline BibWindow*       GetTopWin() {return pTopWin;}
        inline BibWindow*       GetBottomWin() {return pBottomWin;}

        // !BibShortCutHandler is also always a Window!
        void                    createTopFrame( BibShortCutHandler* pWin );

        void                    createBottomFrame( BibShortCutHandler* pWin );

        virtual void            GetFocus();

        virtual sal_Bool        HandleShortCutKey( const KeyEvent& rKeyEvent ); // returns true, if key was handled
};

#endif
<commit_msg>INTEGRATION: CWS wae4extensions (1.7.388); FILE MERGED 2007/09/27 07:18:22 fs 1.7.388.1: #i81612# warning-free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: bibcont.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: ihi $ $Date: 2008-01-14 14:38:07 $
 *
 *  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 ADDRCONT_HXX
#define ADDRCONT_HXX

#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif

#ifndef _SV_SPLITWIN_HXX
#include <vcl/splitwin.hxx>
#endif

#ifndef _SV_TIMER_HXX //autogen wg. Timer
#include <vcl/timer.hxx>
#endif
#ifndef _BIBSHORTCUTHANDLER_HXX
#include "bibshortcuthandler.hxx"
#endif

#include "bibmod.hxx"

#define TOP_WINDOW                          1
#define BOTTOM_WINDOW                       2

class BibDataManager;

class BibWindowContainer : public BibWindow     //Window
{
    private:
        // !BibShortCutHandler is also always a Window!
        BibShortCutHandler*     pChild;

    protected:
        virtual void            Resize();

    public:
        BibWindowContainer( Window* pParent, WinBits nStyle = WB_3DLOOK );
        BibWindowContainer( Window* pParent, BibShortCutHandler* pChild, WinBits nStyle = WB_3DLOOK);
        ~BibWindowContainer();

        inline Window*          GetChild();

        virtual void            GetFocus();

        virtual BOOL            HandleShortCutKey( const KeyEvent& rKeyEvent ); // returns true, if key was handled

        using Window::GetChild;
};

inline Window* BibWindowContainer::GetChild()
{
    return pChild? pChild->GetWindow() : NULL;
}

class BibBookContainer: public BibSplitWindow
{
    private:

        ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >             xTopFrameRef;
        ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >             xBottomFrameRef;

        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >              xTopPeerRef;
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >              xBottomPeerRef;

        BibDataManager*         pDatMan;
        BibWindowContainer*     pTopWin;
        BibWindowContainer*     pBottomWin;
        sal_Bool                    bFirstTime;
        HdlBibModul             pBibMod;
        Timer                   aTimer;

        DECL_LINK( SplitHdl, Timer*);

    protected:

        virtual void            Split();

        virtual long            PreNotify( NotifyEvent& rNEvt );
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >
                                GetTopComponentInterface( sal_Bool bCreate = sal_True );
        void                    SetTopComponentInterface( ::com::sun::star::awt::XWindowPeer* pIFace );

        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > GetBottomComponentInterface( sal_Bool bCreate = sal_True );
        void                    SetBottomComponentInterface( ::com::sun::star::awt::XWindowPeer* pIFace );

    public:

        BibBookContainer(Window* pParent,BibDataManager*, WinBits nStyle = WB_3DLOOK );
        ~BibBookContainer();

        inline BibWindow*       GetTopWin() {return pTopWin;}
        inline BibWindow*       GetBottomWin() {return pBottomWin;}

        // !BibShortCutHandler is also always a Window!
        void                    createTopFrame( BibShortCutHandler* pWin );

        void                    createBottomFrame( BibShortCutHandler* pWin );

        virtual void            GetFocus();

        virtual sal_Bool        HandleShortCutKey( const KeyEvent& rKeyEvent ); // returns true, if key was handled
};

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: groupboxwiz.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 19:30:50 $
 *
 *  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 _EXTENSIONS_DBP_GROUPBOXWIZ_HXX_
#define _EXTENSIONS_DBP_GROUPBOXWIZ_HXX_

#ifndef _EXTENSIONS_DBP_CONTROLWIZARD_HXX
#include "controlwizard.hxx"
#endif
#ifndef _EXTENSIONS_DBP_COMMONPAGESDBP_HXX_
#include "commonpagesdbp.hxx"
#endif

//.........................................................................
namespace dbp
{
//.........................................................................

    //=====================================================================
    //= OOptionGroupSettings
    //=====================================================================
    struct OOptionGroupSettings : public OControlWizardSettings
    {
        StringArray     aLabels;
        StringArray     aValues;
        String          sDefaultField;
        String          sDBField;
        String          sName;
    };

    //=====================================================================
    //= OGroupBoxWizard
    //=====================================================================
    class OGroupBoxWizard : public OControlWizard
    {
    protected:
        OOptionGroupSettings        m_aSettings;

        sal_Bool        m_bVisitedDefault   : 1;
        sal_Bool        m_bVisitedDB        : 1;

    public:
        OGroupBoxWizard(
            Window* _pParent,
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxObjectModel,
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB
        );

        OOptionGroupSettings& getSettings() { return m_aSettings; }

    protected:
        // OWizardMachine overridables
        virtual ::svt::OWizardPage* createPage( WizardState _nState );
        virtual WizardState         determineNextState( WizardState _nCurrentState );
        virtual void                enterState( WizardState _nState );

        virtual sal_Bool onFinish(sal_Int32 _nResult);

        virtual sal_Bool approveControl(sal_Int16 _nClassId);

    protected:
        void createRadios();
    };

    //=====================================================================
    //= OGBWPage
    //=====================================================================
    class OGBWPage : public OControlWizardPage
    {
    public:
        OGBWPage( OControlWizard* _pParent, const ResId& _rId ) : OControlWizardPage(_pParent, _rId) { }

    protected:
        OOptionGroupSettings& getSettings() { return static_cast<OGroupBoxWizard*>(getDialog())->getSettings(); }
    };

    //=====================================================================
    //= ORadioSelectionPage
    //=====================================================================
    class ORadioSelectionPage : public OGBWPage
    {
    protected:
        FixedLine       m_aFrame;
        FixedText       m_aRadioNameLabel;
        Edit            m_aRadioName;
        PushButton      m_aMoveRight;
        PushButton      m_aMoveLeft;
        FixedText       m_aExistingRadiosLabel;
        ListBox         m_aExistingRadios;

    public:
        ORadioSelectionPage( OControlWizard* _pParent );

    protected:
        // TabPage overridables
        void ActivatePage();

        // OWizardPage overridables
        virtual void        initializePage();
        virtual sal_Bool    commitPage(COMMIT_REASON _eReason);
        virtual sal_Bool    determineNextButtonState();

        DECL_LINK( OnMoveEntry, PushButton* );
        DECL_LINK( OnEntrySelected, ListBox* );
        DECL_LINK( OnNameModified, Edit* );

        void implCheckMoveButtons();
    };

    //=====================================================================
    //= ODefaultFieldSelectionPage
    //=====================================================================
    class ODefaultFieldSelectionPage : public OMaybeListSelectionPage
    {
    protected:
        FixedLine       m_aFrame;
        FixedText       m_aDefaultSelectionLabel;
        RadioButton     m_aDefSelYes;
        RadioButton     m_aDefSelNo;
        ListBox         m_aDefSelection;

    public:
        ODefaultFieldSelectionPage( OControlWizard* _pParent );

    protected:
        // OWizardPage overridables
        virtual void        initializePage();
        virtual sal_Bool    commitPage(COMMIT_REASON _eReason);

        OOptionGroupSettings& getSettings() { return static_cast<OGroupBoxWizard*>(getDialog())->getSettings(); }
    };

    //=====================================================================
    //= OOptionValuesPage
    //=====================================================================
    class OOptionValuesPage : public OGBWPage
    {
    protected:
        FixedLine       m_aFrame;
        FixedText       m_aDescription;
        FixedText       m_aValueLabel;
        Edit            m_aValue;
        FixedText       m_aOptionsLabel;
        ListBox         m_aOptions;

        StringArray     m_aUncommittedValues;
        WizardState     m_nLastSelection;

    public:
        OOptionValuesPage( OControlWizard* _pParent );

    protected:
        // TabPage overridables
        void ActivatePage();

        // OWizardPage overridables
        virtual void        initializePage();
        virtual sal_Bool    commitPage(COMMIT_REASON _eReason);

        void implTraveledOptions();

        DECL_LINK( OnOptionSelected, ListBox* );
    };

    //=====================================================================
    //= OOptionDBFieldPage
    //=====================================================================
    class OOptionDBFieldPage : public ODBFieldPage
    {
    public:
        OOptionDBFieldPage( OControlWizard* _pParent );

    protected:
        OOptionGroupSettings& getSettings() { return static_cast<OGroupBoxWizard*>(getDialog())->getSettings(); }

        // ODBFieldPage overridables
        virtual String& getDBFieldSetting();
    };

    //=====================================================================
    //= OFinalizeGBWPage
    //=====================================================================
    class OFinalizeGBWPage : public OGBWPage
    {
    protected:
        FixedLine       m_aFrame;
        FixedText       m_aNameLabel;
        Edit            m_aName;
        FixedText       m_aThatsAll;

    public:
        OFinalizeGBWPage( OControlWizard* _pParent );

    protected:
        // TabPage overridables
        void ActivatePage();

        // OWizardPage overridables
        virtual void        initializePage();
        virtual sal_Bool    commitPage(COMMIT_REASON _eReason);
        virtual sal_Bool    determineNextButtonState();
    };

//.........................................................................
}   // namespace dbp
//.........................................................................

#endif // _EXTENSIONS_DBP_GROUPBOXWIZ_HXX_

<commit_msg>INTEGRATION: CWS odbmacros2 (1.8.424); FILE MERGED 2008/02/11 11:14:56 fs 1.8.424.3: IWizardPage is COMMIT_REASON is deprecated - replace usages with CommitPageReason, while I have an svtools-incompatible CWS 2008/01/30 13:19:50 fs 1.8.424.2: canAdvance made const 2008/01/15 09:52:42 fs 1.8.424.1: some re-factoring of OWizardMachine, RoadmapWizard and derived classes, to prepare the migration UI for #i49133#<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: groupboxwiz.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-06 18:41:35 $
 *
 *  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 _EXTENSIONS_DBP_GROUPBOXWIZ_HXX_
#define _EXTENSIONS_DBP_GROUPBOXWIZ_HXX_

#ifndef _EXTENSIONS_DBP_CONTROLWIZARD_HXX
#include "controlwizard.hxx"
#endif
#ifndef _EXTENSIONS_DBP_COMMONPAGESDBP_HXX_
#include "commonpagesdbp.hxx"
#endif

//.........................................................................
namespace dbp
{
//.........................................................................

    //=====================================================================
    //= OOptionGroupSettings
    //=====================================================================
    struct OOptionGroupSettings : public OControlWizardSettings
    {
        StringArray     aLabels;
        StringArray     aValues;
        String          sDefaultField;
        String          sDBField;
        String          sName;
    };

    //=====================================================================
    //= OGroupBoxWizard
    //=====================================================================
    class OGroupBoxWizard : public OControlWizard
    {
    protected:
        OOptionGroupSettings        m_aSettings;

        sal_Bool        m_bVisitedDefault   : 1;
        sal_Bool        m_bVisitedDB        : 1;

    public:
        OGroupBoxWizard(
            Window* _pParent,
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxObjectModel,
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB
        );

        OOptionGroupSettings& getSettings() { return m_aSettings; }

    protected:
        // OWizardMachine overridables
        virtual ::svt::OWizardPage* createPage( WizardState _nState );
        virtual WizardState         determineNextState( WizardState _nCurrentState ) const;
        virtual void                enterState( WizardState _nState );

        virtual sal_Bool onFinish(sal_Int32 _nResult);

        virtual sal_Bool approveControl(sal_Int16 _nClassId);

    protected:
        void createRadios();
    };

    //=====================================================================
    //= OGBWPage
    //=====================================================================
    class OGBWPage : public OControlWizardPage
    {
    public:
        OGBWPage( OControlWizard* _pParent, const ResId& _rId ) : OControlWizardPage(_pParent, _rId) { }

    protected:
        OOptionGroupSettings& getSettings() { return static_cast<OGroupBoxWizard*>(getDialog())->getSettings(); }
    };

    //=====================================================================
    //= ORadioSelectionPage
    //=====================================================================
    class ORadioSelectionPage : public OGBWPage
    {
    protected:
        FixedLine       m_aFrame;
        FixedText       m_aRadioNameLabel;
        Edit            m_aRadioName;
        PushButton      m_aMoveRight;
        PushButton      m_aMoveLeft;
        FixedText       m_aExistingRadiosLabel;
        ListBox         m_aExistingRadios;

    public:
        ORadioSelectionPage( OControlWizard* _pParent );

    protected:
        // TabPage overridables
        void ActivatePage();

        // OWizardPage overridables
        virtual void        initializePage();
        virtual sal_Bool    commitPage( CommitPageReason _eReason );
        virtual bool        canAdvance() const;

        DECL_LINK( OnMoveEntry, PushButton* );
        DECL_LINK( OnEntrySelected, ListBox* );
        DECL_LINK( OnNameModified, Edit* );

        void implCheckMoveButtons();
    };

    //=====================================================================
    //= ODefaultFieldSelectionPage
    //=====================================================================
    class ODefaultFieldSelectionPage : public OMaybeListSelectionPage
    {
    protected:
        FixedLine       m_aFrame;
        FixedText       m_aDefaultSelectionLabel;
        RadioButton     m_aDefSelYes;
        RadioButton     m_aDefSelNo;
        ListBox         m_aDefSelection;

    public:
        ODefaultFieldSelectionPage( OControlWizard* _pParent );

    protected:
        // OWizardPage overridables
        virtual void        initializePage();
        virtual sal_Bool    commitPage( CommitPageReason _eReason );

        OOptionGroupSettings& getSettings() { return static_cast<OGroupBoxWizard*>(getDialog())->getSettings(); }
    };

    //=====================================================================
    //= OOptionValuesPage
    //=====================================================================
    class OOptionValuesPage : public OGBWPage
    {
    protected:
        FixedLine       m_aFrame;
        FixedText       m_aDescription;
        FixedText       m_aValueLabel;
        Edit            m_aValue;
        FixedText       m_aOptionsLabel;
        ListBox         m_aOptions;

        StringArray     m_aUncommittedValues;
        WizardState     m_nLastSelection;

    public:
        OOptionValuesPage( OControlWizard* _pParent );

    protected:
        // TabPage overridables
        void ActivatePage();

        // OWizardPage overridables
        virtual void        initializePage();
        virtual sal_Bool    commitPage( CommitPageReason _eReason );

        void implTraveledOptions();

        DECL_LINK( OnOptionSelected, ListBox* );
    };

    //=====================================================================
    //= OOptionDBFieldPage
    //=====================================================================
    class OOptionDBFieldPage : public ODBFieldPage
    {
    public:
        OOptionDBFieldPage( OControlWizard* _pParent );

    protected:
        OOptionGroupSettings& getSettings() { return static_cast<OGroupBoxWizard*>(getDialog())->getSettings(); }

        // ODBFieldPage overridables
        virtual String& getDBFieldSetting();
    };

    //=====================================================================
    //= OFinalizeGBWPage
    //=====================================================================
    class OFinalizeGBWPage : public OGBWPage
    {
    protected:
        FixedLine       m_aFrame;
        FixedText       m_aNameLabel;
        Edit            m_aName;
        FixedText       m_aThatsAll;

    public:
        OFinalizeGBWPage( OControlWizard* _pParent );

    protected:
        // TabPage overridables
        void ActivatePage();

        // OWizardPage overridables
        virtual void        initializePage();
        virtual sal_Bool    commitPage( CommitPageReason _eReason );
        virtual bool        canAdvance() const;
    };

//.........................................................................
}   // namespace dbp
//.........................................................................

#endif // _EXTENSIONS_DBP_GROUPBOXWIZ_HXX_

<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include <cling/UserInterface/UserInterface.h>

#include <cling/MetaProcessor/MetaProcessor.h>
#include "textinput/TextInput.h"
#include "textinput/StreamReader.h"
#include "textinput/TerminalDisplay.h"

#include "llvm/Support/raw_ostream.h"

//---------------------------------------------------------------------------
// Construct an interface for an interpreter
//---------------------------------------------------------------------------
cling::UserInterface::UserInterface(Interpreter& interp,
                                    const char* prompt /*= "[cling] $"*/):
m_MetaProcessor(new MetaProcessor(interp))
{
}

//---------------------------------------------------------------------------
// Destruct the interface
//---------------------------------------------------------------------------
cling::UserInterface::~UserInterface()
{
  delete m_MetaProcessor;
}

//---------------------------------------------------------------------------
// Interact with the user using a prompt
//---------------------------------------------------------------------------
void cling::UserInterface::runInteractively(bool nologo /* = false */)
{
  if (!nologo) {
    PrintLogo();
  }
  static const char* histfile = ".cling_history";
  std::string Prompt("[cling]$ ");

  using namespace textinput;
  StreamReader* R = StreamReader::Create();
  TerminalDisplay* D = TerminalDisplay::Create();
  TextInput TI(*R, *D, histfile);
  TI.SetPrompt(Prompt.c_str());
  std::string line;
  MetaProcessorOpts& MPOpts = m_MetaProcessor->getMetaProcessorOpts();

  while (!MPOpts.Quitting) {
    TextInput::EReadResult RR = TI.ReadInput();
    TI.TakeInput(line);
    if (RR == TextInput::kRREOF) {
      MPOpts.Quitting = true;
      continue;
    }

    int indent = m_MetaProcessor->process(line.c_str());
    Prompt = "[cling]";
    if (MPOpts.RawInput)
      Prompt.append("! ");
    else
      Prompt.append("$ ");

    if (indent > 0)
      // Continuation requested.
      Prompt.append('?' + std::string(indent * 3, ' '));

    TI.SetPrompt(Prompt.c_str());

  }
}

void cling::UserInterface::PrintLogo() {
  llvm::outs() << "\n";
  llvm::outs() << "****************** CLING ******************" << "\n";
  llvm::outs() << "* Type C++ code and press enter to run it *" << "\n";
  llvm::outs() << "*             Type .q to exit             *" << "\n";
  llvm::outs() << "*******************************************" << "\n";
}
<commit_msg>Fix Savannah #95065: flush llvm::outs() before TextInput interaction.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include <cling/UserInterface/UserInterface.h>

#include <cling/MetaProcessor/MetaProcessor.h>
#include "textinput/TextInput.h"
#include "textinput/StreamReader.h"
#include "textinput/TerminalDisplay.h"

#include "llvm/Support/raw_ostream.h"

//---------------------------------------------------------------------------
// Construct an interface for an interpreter
//---------------------------------------------------------------------------
cling::UserInterface::UserInterface(Interpreter& interp,
                                    const char* prompt /*= "[cling] $"*/):
m_MetaProcessor(new MetaProcessor(interp))
{
}

//---------------------------------------------------------------------------
// Destruct the interface
//---------------------------------------------------------------------------
cling::UserInterface::~UserInterface()
{
  delete m_MetaProcessor;
}

//---------------------------------------------------------------------------
// Interact with the user using a prompt
//---------------------------------------------------------------------------
void cling::UserInterface::runInteractively(bool nologo /* = false */)
{
  if (!nologo) {
    PrintLogo();
  }
  static const char* histfile = ".cling_history";
  std::string Prompt("[cling]$ ");

  using namespace textinput;
  StreamReader* R = StreamReader::Create();
  TerminalDisplay* D = TerminalDisplay::Create();
  TextInput TI(*R, *D, histfile);
  TI.SetPrompt(Prompt.c_str());
  std::string line;
  MetaProcessorOpts& MPOpts = m_MetaProcessor->getMetaProcessorOpts();

  while (!MPOpts.Quitting) {
    llvm::outs().flush();
    TextInput::EReadResult RR = TI.ReadInput();
    TI.TakeInput(line);
    if (RR == TextInput::kRREOF) {
      MPOpts.Quitting = true;
      continue;
    }

    int indent = m_MetaProcessor->process(line.c_str());
    Prompt = "[cling]";
    if (MPOpts.RawInput)
      Prompt.append("! ");
    else
      Prompt.append("$ ");

    if (indent > 0)
      // Continuation requested.
      Prompt.append('?' + std::string(indent * 3, ' '));

    TI.SetPrompt(Prompt.c_str());

  }
}

void cling::UserInterface::PrintLogo() {
  llvm::outs() << "\n";
  llvm::outs() << "****************** CLING ******************" << "\n";
  llvm::outs() << "* Type C++ code and press enter to run it *" << "\n";
  llvm::outs() << "*             Type .q to exit             *" << "\n";
  llvm::outs() << "*******************************************" << "\n";
}
<|endoftext|>


<commit_before>//mandala
#include "resource_mgr.hpp"

namespace mandala
{
	resource_mgr_t resources;

	size_t resource_mgr_t::count() const
	{
		size_t count = 0;

		for (const auto& resources : type_resources)
		{
			count += resources.second.size();
		}

		return count;
	}

	void resource_mgr_t::prune()
	{
		for (auto& type_resource : type_resources)
		{
			auto& resources = type_resource.second;

			auto resources_itr = resources.begin();

			while (resources_itr != resources.end())
			{
				if (resources_itr->second.unique())
				{
					resources_itr = resources.erase(resources_itr);
				}
				else
				{
					++resources_itr;
				}
			}
		}
	}

	void resource_mgr_t::purge()
	{
		type_resources.clear();
	}
}
<commit_msg>added leak checking for resource_mgr.purge()<commit_after>#if defined(DEBUG)
//std
#include <vector>

//boost
#include <boost\weak_ptr.hpp>
#endif

//mandala
#include "resource_mgr.hpp"

namespace mandala
{
	resource_mgr_t resources;

	size_t resource_mgr_t::count() const
	{
		size_t count = 0;

		for (const auto& resources : type_resources)
		{
			count += resources.second.size();
		}

		return count;
	}

	void resource_mgr_t::prune()
	{
		for (auto& type_resource : type_resources)
		{
			auto& resources = type_resource.second;

			auto resources_itr = resources.begin();

			while (resources_itr != resources.end())
			{
				if (resources_itr->second.unique())
				{
					resources_itr = resources.erase(resources_itr);
				}
				else
				{
					++resources_itr;
				}
			}
		}
	}

	void resource_mgr_t::purge()
	{
#if defined(DEBUG)
        std::vector<boost::weak_ptr<resource_t>> resources;

        for (auto& type_resource : type_resources)
        {
            for (auto& resource : type_resource.second)
            {
                resources.push_back(resource.second);
            }
        }
#endif

		type_resources.clear();

#if defined(DEBUG)
        for (auto& resource : resources)
        {
            assert(resource.expired());
        }
#endif
	}
}
<|endoftext|>


<commit_before>#ifndef SPOTIFY_BACKSTAGE_SPOTIFYBACKSTAGE_HPP
#define SPOTIFY_BACKSTAGE_SPOTIFYBACKSTAGE_HPP

#include <memory>
#include <string>
#include <utility>
#include <vector>

namespace spotify_backstage
{

struct EqState;
struct Track;

class SpotifyBackstage
{
public:
    SpotifyBackstage(const std::string& username, const std::string& password);

    ~SpotifyBackstage();

    EqState getEqState();

    std::vector<Track> getPlayQueue();

    void enqueue(const std::string& uri);

    void play();

    void stop();

    void next();

    std::vector<Track> search(const std::string& query, int num_results, int offset);

    void setEqOn(bool on);

    void setGain(double gain);

    void setBass(double bass);

    void setMid(double mid);

    void setTreble(double treble);

    int getCurrentOutputDevice();

    std::vector<std::pair<int, std::string>> getOutputDevices();

    void setOutputDevice(int dev);

private:
    class Impl;
    std::unique_ptr<Impl> impl_;
};

struct EqState
{
    EqState(bool on, double g, double b, double m, double t)
      : is_on(on), gain(g), bass(b), mid(m), treble(t)
    {
    }

    bool is_on;
    double gain;
    double bass;
    double mid;
    double treble;
};

struct Track
{
    Track(const std::string& artist_p, const std::string& album_p, const std::string& track_p,
        int duration_sec_p, const std::string& uri_p)
      : artist(artist_p), album(album_p), track(track_p), duration_sec(duration_sec_p), uri(uri_p)
    {
    }

    std::string artist;
    std::string album;
    std::string track;
    int duration_sec;
    std::string uri;
};

}

#endif
<commit_msg>Add documentation to SpotifyBackstage.hpp<commit_after>#ifndef SPOTIFY_BACKSTAGE_SPOTIFYBACKSTAGE_HPP
#define SPOTIFY_BACKSTAGE_SPOTIFYBACKSTAGE_HPP

#include <memory>
#include <string>
#include <utility>
#include <vector>

namespace spotify_backstage
{

struct EqState;
struct Track;

/**
 * SpotifyBackstage implements the API to spotify-backstage library.
 * It offers a Spotify-powered music backend including playback, queuing tracks, Spotify search, etc.
 * The API is used by creating a SpotifyBackstage instance.
 *
 * Features:
 * - Play queue: Enqueue tracks to the play queue. spotify-backstage will play them in the order they were added.
 * - Search: Search tracks from Spotify catalog.
 * - Equalizer: Simple three channel equalizer.
 * - Output device selection: Ability to select the output device for the audio.
 */
class SpotifyBackstage
{
public:
    /**
     * Ctor.
     *
     * @param username Spotify username
     * @param password Password for username
     */
    SpotifyBackstage(const std::string& username, const std::string& password);

    ~SpotifyBackstage();

    /** Get the current state of the equalizer */
    EqState getEqState();

    /** Get the current play queue */
    std::vector<Track> getPlayQueue();

    /**
     * Enqueue a track to the play queue.
     *
     * @param uri Spotify URI of the track to enqueue.
     */
    void enqueue(const std::string& uri);

    /**
     * Start playback. The track currently at the head of the play queue will start playing.
     * Once the track is finished, it's removed from the play queue and the next track in the queue is played.
     * The playback will continue for as long as there are tracks in the play queue, or stop() is called.
     */
    void play();

    /** Stop playback. */
    void stop();

    /**
     * Stop the playback, remove the track currently at the head of the play queue from the queue,
     * and start playing the next track in the queue (if the queue is not empty).
     */
    void next();

    /**
     * Search tracks from the Spotify catalog.
     *
     * @param query Search query string.
     * @param num_results Max number of tracks to return.
     * @param offset Offset in the full result list from which to start taking the returned tracks.
     *               This parameter is useful if you want to do more than one search with the same
     *               query string. For example,
     *
     *               Get the first 10 results for "Neil Young":
     *               search("Neil Young", 10, 0);
     *
     *               Get the next 10 results:
     *               search("Neil Young", 10, 10);
     */
    std::vector<Track> search(const std::string& query, int num_results, int offset);

    /**
     * Set equalizer on/off.
     *
     * @param on true = on, false = off.
     */
    void setEqOn(bool on);

    /**
     * Set equalizer gain.
     *
     * @gain The gain. 1.0 = 100%.
     */
    void setGain(double gain);

    /**
     * Set equalizer bass channel level.
     *
     * @param bass The level. 1.0 = 100%.
     */
    void setBass(double bass);

    /**
     * Set equalizer mid channel level.
     *
     * @param mid The level. 1.0 = 100%.
     */
    void setMid(double mid);

    /**
     * Set equalizer treble channel level.
     *
     * @param treble The level. 1.0 = 100%.
     */
    void setTreble(double treble);

    /** Get the index of the currently selected audio output device. */
    int getCurrentOutputDevice();

    /**
     * Get a list of audio output devices available in the system.
     * The items in the list contain the device's index and name.
     */
    std::vector<std::pair<int, std::string>> getOutputDevices();

    /**
     * Set the audio output device.
     *
     * @param dev Index of the device to set.
     */
    void setOutputDevice(int dev);

private:
    class Impl;
    std::unique_ptr<Impl> impl_;
};

/**
 * EqState encapsulates the state of the equalizer.
 * With the gain and the channel levels, value 1.0 = 100%.
 */
struct EqState
{
    EqState(bool on, double g, double b, double m, double t)
      : is_on(on), gain(g), bass(b), mid(m), treble(t)
    {
    }

    /** Is the equalizer on? */
    bool is_on;

    /** Equalizer gain */
    double gain;

    /** Bass channel level */
    double bass;

    /** Mid channel level */
    double mid;

    /** Treble channel level */
    double treble;
};

/**
 * Track contains information of a single Spotify track.
 */
struct Track
{
    Track(const std::string& artist_p, const std::string& album_p, const std::string& track_p,
        int duration_sec_p, const std::string& uri_p)
      : artist(artist_p), album(album_p), track(track_p), duration_sec(duration_sec_p), uri(uri_p)
    {
    }

    /** Artist(s) */
    std::string artist;

    /** Album */
    std::string album;

    /** Track name */
    std::string track;

    /** Track duration in seconds */
    int duration_sec;

    /** Track's Spotify URI */
    std::string uri;
};

}

#endif
<|endoftext|>


<commit_before>
#include "stdafx.h"

Storage::Variant::Variant() : type(Null), data(0) {}

Storage::Variant::~Variant()
{
  free();
}

void Storage::Variant::free()
{
  switch(type)
  {
  case Str:
    if(str)
      delete str;
    break;
  case Data:
    if(data)
      delete data;
    break;
  }
}

Storage::Data::Data(const char* data, uint length) : data((char*)malloc(length)), length(length)
{
  memcpy(this->data, data, length);
}

Storage::Data::~Data()
{
  if(data)
    ::free(data);
}

Storage::Str::Str(const wchar* data, uint length) : length(length)
{
  uint size = (length + 1) * sizeof(wchar);
  this->data = (wchar*)malloc(size);
  memcpy(this->data, data, size);
  this->data[length] = L'\0';
}

Storage::Str::~Str()
{
  if(data)
    ::free(data);
}

Storage::Storage() : parent(0)
{
  current = this;
}

Storage::Storage(Storage* parent) : parent(parent)
{
  current = this;
}

Storage::~Storage()
{
  free();
}

void Storage::free()
{
  for(std::unordered_map<std::string, Storage*>::iterator i = storages.begin(), end = storages.end(); i != end; ++i)
    delete i->second;
  for(std::vector<Storage*>::iterator i = array.begin(), end = array.end(); i != end; ++i)
    delete *i;
  entries.clear();
  storages.clear();
  array.resize(0);
}

Storage* Storage::getCurrentStorage()
{
  current->current = current;
  return current;
}

void Storage::setCurrentStorage(Storage* storage)
{
  current = storage ? storage : this;
}

bool Storage::enterSection(const char* name)
{
  std::string key(name);
  std::unordered_map<std::string, Storage*>::iterator i = current->storages.find(key);
  if(i == current->storages.end())
  {
    Storage* storage = new Storage(current);
    current->storages[key] = storage;
    current = storage;
    return true;
  }
  else
  {
    current = i->second;
    return true;
  }
}

Storage* Storage::getSection(const char* name)
{
  if(!enterSection(name))
    return 0;
  Storage* storage = getCurrentStorage();
  leave();
  return storage;
}

bool Storage::leave()
{
  if(!current->parent)
    return false;
  current = current->parent;
  return true;
}

bool Storage::enterNumSection(uint pos)
{
  if(pos >= current->array.size())
    setNumSectionCount(pos + 1);
  current = current->array[pos];
  return true;
}

Storage* Storage::getNumSection(uint pos)
{
  if(!enterNumSection(pos))
    return 0;
  Storage* storage = getCurrentStorage();
  leave();
  return storage;
}

bool Storage::deleteSection(const char* name)
{
  std::string key(name);
  std::unordered_map<std::string, Storage*>::iterator i = current->storages.find(key);
  if(i == current->storages.end())
    return false;
  else
  {
    delete i->second;
    current->storages.erase(i);
    return true;
  }
}

bool Storage::deleteNumSection(uint pos)
{
  if(pos >= current->array.size())
    return false;
  delete current->array[pos];
  current->array.erase(current->array.begin() + pos);
  return true;
}

bool Storage::swapNumSections(uint pos1, uint pos2)
{
  uint size = (uint) current->array.size();
  if(pos1 >= size || pos2 >= size)
    return false;
  Storage* tmp = current->array[pos1];
  current->array[pos1] = current->array[pos2];
  current->array[pos2] = tmp;
  return true;
}

uint Storage::getNumSectionCount() const
{
  return (uint)current->array.size();
}

bool Storage::setNumSectionCount(uint size)
{
  if(size < current->array.size())
  {
    for(uint i = size, count = (uint)current->array.size(); i < count; ++i)
      delete current->array[i];
    current->array.resize(size);
  }
  else if(size > current->array.size())
  {
    uint i = (uint)current->array.size();
    current->array.resize(size);
    for(; i < size; ++i)
      current->array[i] = new Storage(current);
  }
  return true;
}

const wchar* Storage::getStr(const char* name, uint* length, const wchar* default, uint defaultLength) const
{
  std::unordered_map<std::string, Variant>::const_iterator i = current->entries.find(std::string(name));
  if(i == current->entries.end())
  {
    if(length)
      *length = defaultLength;
    return default;
  }
  const Variant& val(i->second);
  if(val.type != Variant::Str)
  {
    if(length)
      *length = defaultLength;
    return default;
  }
  if(length)
    *length = val.str->length;
  return val.str->data;
}

int Storage::getInt(const char* name, int default) const
{
  std::unordered_map<std::string, Variant>::const_iterator i = current->entries.find(std::string(name));
  if(i == current->entries.end())
    return default;
  const Variant& val(i->second);
  if(val.type != Variant::Int)
    return default;
  return val._int;
}

uint Storage::getUInt(const char* name, uint default) const
{
  std::unordered_map<std::string, Variant>::const_iterator i = current->entries.find(std::string(name));
  if(i == current->entries.end())
    return default;
  const Variant& val(i->second);
  if(val.type != Variant::UInt)
    return default;
  return val._uint;
}

bool Storage::getData(const char* name, char** data, uint* length, const char* defaultData, uint defaultLength) const
{
  std::unordered_map<std::string, Variant>::iterator i = current->entries.find(std::string(name));
  if(i == current->entries.end())
  {
    *data = (char*)defaultData;
    if(length)
      *length = defaultLength;
    return false;
  }
  const Variant& val(i->second);
  if(val.type != Variant::Data)
  {
    *data = (char*)defaultData;
    if(length)
      *length = defaultLength;
    return false;
  }
  *data = (char*)val.data->data;
  if(length)
    *length = val.data->length;
  return true;
}

bool Storage::setStr(const char* name, const wchar* value, uint length)
{
  Variant& val(current->entries[std::string(name)]);
  val.free();
  val.type = Variant::Str;
  val.str = new Str(value, length ? length : (uint)wcslen(value));
  return true;
}

bool Storage::setInt(const char* name, int value)
{
  Variant& val(current->entries[std::string(name)]);
  val.free();
  val.type = Variant::Int;
  val._int = value;
  return true;
}

bool Storage::setUInt(const char* name, uint value)
{
  Variant& val(current->entries[std::string(name)]);
  val.free();
  val.type = Variant::UInt;
  val._uint = value;
  return true;
}

bool Storage::setData(const char* name, char* data, uint length)
{
  Variant& val(current->entries[std::string(name)]);
  val.free();
  val.type = Variant::Data;
  val.data = new Data(data, length);
  return true;
}

bool Storage::deleteEntry(const char* name)
{
  std::unordered_map<std::string, Variant>::iterator i = current->entries.find(std::string(name));
  if(i == current->entries.end())
    return false;
  current->entries.erase(i);
  return true;
}

bool Storage::save()
{
  if(filename.empty())
    return false;
  HANDLE hFile = CreateFile(filename.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hFile == INVALID_HANDLE_VALUE)
    return false;
  uint header = 1; // minimal header
  bool ret = write(hFile, &header, sizeof(header)) && save(hFile);
  CloseHandle(hFile);
  return ret;
}

bool Storage::load(const wchar* file)
{
  HANDLE hFile = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hFile == INVALID_HANDLE_VALUE)
    return false;
  uint header;
  bool ret = read(hFile, &header, sizeof(header)) && header == 1 && load(hFile);
  CloseHandle(hFile);
  if(ret)
    filename = file;
  return ret;
}

bool Storage::read(HANDLE hFile, void* buffer, unsigned size) const
{
  DWORD bi;
  return ReadFile(hFile, buffer, size, &bi, NULL) && bi == size;
}

bool Storage::write(HANDLE hFile, const void* buffer, unsigned size) const
{
  DWORD bi;
  return WriteFile(hFile, buffer, size, &bi, NULL) ? true : false;
}

bool Storage::load(HANDLE hFile)
{
  free();

  // read all entries
  uint size;
  if(!read(hFile, &size, sizeof(size)))
    return false;
  std::vector<char> keybuffer;
  uint keysize;
  for(uint i = 0; i < size; ++i)
  {
    if(!read(hFile, &keysize, sizeof(keysize)))
      return false;
    keybuffer.resize(keysize + 1);
    if(!read(hFile, &keybuffer[0], keysize))
      return false;
    keybuffer[keysize] = '\0';
    Variant& var(entries[std::string(&keybuffer[0])]);
    if(!read(hFile, &var.type, sizeof(var.type)))
      return false;
    switch(var.type)
    {
    case Variant::Int:
    case Variant::UInt:
      if(!read(hFile, &var._int, sizeof(int)))
        return false;
      break;
    case Variant::Str:
      {
        var.str = new Str;
        if(!read(hFile, &var.str->length, sizeof(var.str->length)))
          return false;
        uint size = var.str->length * sizeof(wchar);
        var.str->data = (wchar*)malloc(size + sizeof(wchar));
        if(!read(hFile, var.str->data, size) )
          return false;
        var.str->data[var.str->length] = L'\0';
      }
      break;
    case Variant::Data:
      var.data = new Data;
      if(!read(hFile, &var.data->length, sizeof(var.data->length)))
        return false;
      var.data->data = (char*)malloc(var.data->length);
      if(!read(hFile, var.data->data, var.data->length) )
        return false;
      break;
    }
  }

  // read substorages
  if(!read(hFile, &size, sizeof(size)))
    return false;
  for(uint i = 0; i < size; ++i)
  {
    if(!read(hFile, &keysize, sizeof(keysize)))
      return false;
    keybuffer.resize(keysize + 1);
    if(!read(hFile, &keybuffer[0], keysize))
      return false;
    keybuffer[keysize] = '\0';

    Storage*& storage = storages[std::string(&keybuffer[0])];
    storage = new Storage(this);
    if(!storage->load(hFile))
      return false;
  }

  // read array
  if(!read(hFile, &size, sizeof(size)))
    return false;
  array.resize(size);
  for(uint i = 0; i < size; ++i)
  {
    Storage*& storage = array[i];
    storage = new Storage(this);
    if(!storage->load(hFile))
      return false;
  }

  return true;
}

bool Storage::save(HANDLE hFile) const
{
  // save all entries
  uint size = (uint)entries.size();
  if(!write(hFile, &size, sizeof(size)))
    return false;
  for(std::unordered_map<std::string, Variant>::const_iterator i = entries.begin(), end = entries.end(); i != end; ++i)
  {
    const std::string& key(i->first);
    const Variant& var(i->second);
    uint keysize = (uint)key.size();
    if(!write(hFile, &keysize, sizeof(keysize)) ||
       !write(hFile, key.c_str(), keysize) ||
       !write(hFile, &var.type, sizeof(var.type)) )
      return false;
    switch(var.type)
    {
    case Variant::Int:
    case Variant::UInt:
      if(!write(hFile, &var._int, sizeof(int)))
        return false;
      break;
    case Variant::Str:
      if(!write(hFile, &var.str->length, sizeof(var.str->length)) ||
         !write(hFile, var.str->data, var.str->length * sizeof(wchar)) )
        return false;
      break;
    case Variant::Data:
      if(!write(hFile, &var.data->length, sizeof(var.data->length)) ||
         !write(hFile, var.data->data, var.data->length) )
        return false;
      break;
    }
  }

  // save substorages
  size = (uint)storages.size();
  if(!write(hFile, &size, sizeof(size)))
    return false;
  for(std::unordered_map<std::string, Storage*>::const_iterator i = storages.begin(), end = storages.end(); i != end; ++i)
  {
    const std::string& key(i->first);
    Storage* storage(i->second);
    uint keysize = (uint)key.size();
    if(!write(hFile, &keysize, sizeof(keysize)) ||
       !write(hFile, key.c_str(), keysize) ||
       !storage->save(hFile))
      return false;
  }

  // save array
  size = (uint)array.size();
  if(!write(hFile, &size, sizeof(size)))
    return false;
  for(std::vector<Storage*>::const_iterator i = array.begin(), end = array.end(); i != end; ++i)
    if(!(*i)->save(hFile))
      return false;

  return true;
}
<commit_msg>Dock: Fix issue with not working settings saving<commit_after>
#include "stdafx.h"

Storage::Variant::Variant() : type(Null), data(0) {}

Storage::Variant::~Variant()
{
  free();
}

void Storage::Variant::free()
{
  switch(type)
  {
  case Str:
    if(str)
      delete str;
    break;
  case Data:
    if(data)
      delete data;
    break;
  }
}

Storage::Data::Data(const char* data, uint length) : data((char*)malloc(length)), length(length)
{
  memcpy(this->data, data, length);
}

Storage::Data::~Data()
{
  if(data)
    ::free(data);
}

Storage::Str::Str(const wchar* data, uint length) : length(length)
{
  uint size = (length + 1) * sizeof(wchar);
  this->data = (wchar*)malloc(size);
  memcpy(this->data, data, size);
  this->data[length] = L'\0';
}

Storage::Str::~Str()
{
  if(data)
    ::free(data);
}

Storage::Storage() : parent(0)
{
  current = this;
}

Storage::Storage(Storage* parent) : parent(parent)
{
  current = this;
}

Storage::~Storage()
{
  free();
}

void Storage::free()
{
  for(std::unordered_map<std::string, Storage*>::iterator i = storages.begin(), end = storages.end(); i != end; ++i)
    delete i->second;
  for(std::vector<Storage*>::iterator i = array.begin(), end = array.end(); i != end; ++i)
    delete *i;
  entries.clear();
  storages.clear();
  array.resize(0);
}

Storage* Storage::getCurrentStorage()
{
  current->current = current;
  return current;
}

void Storage::setCurrentStorage(Storage* storage)
{
  current = storage ? storage : this;
}

bool Storage::enterSection(const char* name)
{
  std::string key(name);
  std::unordered_map<std::string, Storage*>::iterator i = current->storages.find(key);
  if(i == current->storages.end())
  {
    Storage* storage = new Storage(current);
    current->storages[key] = storage;
    current = storage;
    return true;
  }
  else
  {
    current = i->second;
    return true;
  }
}

Storage* Storage::getSection(const char* name)
{
  if(!enterSection(name))
    return 0;
  Storage* storage = getCurrentStorage();
  leave();
  return storage;
}

bool Storage::leave()
{
  if(!current->parent)
    return false;
  current = current->parent;
  return true;
}

bool Storage::enterNumSection(uint pos)
{
  if(pos >= current->array.size())
    setNumSectionCount(pos + 1);
  current = current->array[pos];
  return true;
}

Storage* Storage::getNumSection(uint pos)
{
  if(!enterNumSection(pos))
    return 0;
  Storage* storage = getCurrentStorage();
  leave();
  return storage;
}

bool Storage::deleteSection(const char* name)
{
  std::string key(name);
  std::unordered_map<std::string, Storage*>::iterator i = current->storages.find(key);
  if(i == current->storages.end())
    return false;
  else
  {
    delete i->second;
    current->storages.erase(i);
    return true;
  }
}

bool Storage::deleteNumSection(uint pos)
{
  if(pos >= current->array.size())
    return false;
  delete current->array[pos];
  current->array.erase(current->array.begin() + pos);
  return true;
}

bool Storage::swapNumSections(uint pos1, uint pos2)
{
  uint size = (uint) current->array.size();
  if(pos1 >= size || pos2 >= size)
    return false;
  Storage* tmp = current->array[pos1];
  current->array[pos1] = current->array[pos2];
  current->array[pos2] = tmp;
  return true;
}

uint Storage::getNumSectionCount() const
{
  return (uint)current->array.size();
}

bool Storage::setNumSectionCount(uint size)
{
  if(size < current->array.size())
  {
    for(uint i = size, count = (uint)current->array.size(); i < count; ++i)
      delete current->array[i];
    current->array.resize(size);
  }
  else if(size > current->array.size())
  {
    uint i = (uint)current->array.size();
    current->array.resize(size);
    for(; i < size; ++i)
      current->array[i] = new Storage(current);
  }
  return true;
}

const wchar* Storage::getStr(const char* name, uint* length, const wchar* default, uint defaultLength) const
{
  std::unordered_map<std::string, Variant>::const_iterator i = current->entries.find(std::string(name));
  if(i == current->entries.end())
  {
    if(length)
      *length = defaultLength;
    return default;
  }
  const Variant& val(i->second);
  if(val.type != Variant::Str)
  {
    if(length)
      *length = defaultLength;
    return default;
  }
  if(length)
    *length = val.str->length;
  return val.str->data;
}

int Storage::getInt(const char* name, int default) const
{
  std::unordered_map<std::string, Variant>::const_iterator i = current->entries.find(std::string(name));
  if(i == current->entries.end())
    return default;
  const Variant& val(i->second);
  if(val.type != Variant::Int)
    return default;
  return val._int;
}

uint Storage::getUInt(const char* name, uint default) const
{
  std::unordered_map<std::string, Variant>::const_iterator i = current->entries.find(std::string(name));
  if(i == current->entries.end())
    return default;
  const Variant& val(i->second);
  if(val.type != Variant::UInt)
    return default;
  return val._uint;
}

bool Storage::getData(const char* name, char** data, uint* length, const char* defaultData, uint defaultLength) const
{
  std::unordered_map<std::string, Variant>::iterator i = current->entries.find(std::string(name));
  if(i == current->entries.end())
  {
    *data = (char*)defaultData;
    if(length)
      *length = defaultLength;
    return false;
  }
  const Variant& val(i->second);
  if(val.type != Variant::Data)
  {
    *data = (char*)defaultData;
    if(length)
      *length = defaultLength;
    return false;
  }
  *data = (char*)val.data->data;
  if(length)
    *length = val.data->length;
  return true;
}

bool Storage::setStr(const char* name, const wchar* value, uint length)
{
  Variant& val(current->entries[std::string(name)]);
  val.free();
  val.type = Variant::Str;
  val.str = new Str(value, length ? length : (uint)wcslen(value));
  return true;
}

bool Storage::setInt(const char* name, int value)
{
  Variant& val(current->entries[std::string(name)]);
  val.free();
  val.type = Variant::Int;
  val._int = value;
  return true;
}

bool Storage::setUInt(const char* name, uint value)
{
  Variant& val(current->entries[std::string(name)]);
  val.free();
  val.type = Variant::UInt;
  val._uint = value;
  return true;
}

bool Storage::setData(const char* name, char* data, uint length)
{
  Variant& val(current->entries[std::string(name)]);
  val.free();
  val.type = Variant::Data;
  val.data = new Data(data, length);
  return true;
}

bool Storage::deleteEntry(const char* name)
{
  std::unordered_map<std::string, Variant>::iterator i = current->entries.find(std::string(name));
  if(i == current->entries.end())
    return false;
  current->entries.erase(i);
  return true;
}

bool Storage::save()
{
  if(filename.empty())
    return false;
  HANDLE hFile = CreateFile(filename.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hFile == INVALID_HANDLE_VALUE)
    return false;
  uint header = 1; // minimal header
  bool ret = write(hFile, &header, sizeof(header)) && save(hFile);
  CloseHandle(hFile);
  return ret;
}

bool Storage::load(const wchar* file)
{
  filename = file;
  HANDLE hFile = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hFile == INVALID_HANDLE_VALUE)
    return false;
  uint header;
  bool ret = read(hFile, &header, sizeof(header)) && header == 1 && load(hFile);
  CloseHandle(hFile);
  return ret;
}

bool Storage::read(HANDLE hFile, void* buffer, unsigned size) const
{
  DWORD bi;
  return ReadFile(hFile, buffer, size, &bi, NULL) && bi == size;
}

bool Storage::write(HANDLE hFile, const void* buffer, unsigned size) const
{
  DWORD bi;
  return WriteFile(hFile, buffer, size, &bi, NULL) ? true : false;
}

bool Storage::load(HANDLE hFile)
{
  free();

  // read all entries
  uint size;
  if(!read(hFile, &size, sizeof(size)))
    return false;
  std::vector<char> keybuffer;
  uint keysize;
  for(uint i = 0; i < size; ++i)
  {
    if(!read(hFile, &keysize, sizeof(keysize)))
      return false;
    keybuffer.resize(keysize + 1);
    if(!read(hFile, &keybuffer[0], keysize))
      return false;
    keybuffer[keysize] = '\0';
    Variant& var(entries[std::string(&keybuffer[0])]);
    if(!read(hFile, &var.type, sizeof(var.type)))
      return false;
    switch(var.type)
    {
    case Variant::Int:
    case Variant::UInt:
      if(!read(hFile, &var._int, sizeof(int)))
        return false;
      break;
    case Variant::Str:
      {
        var.str = new Str;
        if(!read(hFile, &var.str->length, sizeof(var.str->length)))
          return false;
        uint size = var.str->length * sizeof(wchar);
        var.str->data = (wchar*)malloc(size + sizeof(wchar));
        if(!read(hFile, var.str->data, size) )
          return false;
        var.str->data[var.str->length] = L'\0';
      }
      break;
    case Variant::Data:
      var.data = new Data;
      if(!read(hFile, &var.data->length, sizeof(var.data->length)))
        return false;
      var.data->data = (char*)malloc(var.data->length);
      if(!read(hFile, var.data->data, var.data->length) )
        return false;
      break;
    }
  }

  // read substorages
  if(!read(hFile, &size, sizeof(size)))
    return false;
  for(uint i = 0; i < size; ++i)
  {
    if(!read(hFile, &keysize, sizeof(keysize)))
      return false;
    keybuffer.resize(keysize + 1);
    if(!read(hFile, &keybuffer[0], keysize))
      return false;
    keybuffer[keysize] = '\0';

    Storage*& storage = storages[std::string(&keybuffer[0])];
    storage = new Storage(this);
    if(!storage->load(hFile))
      return false;
  }

  // read array
  if(!read(hFile, &size, sizeof(size)))
    return false;
  array.resize(size);
  for(uint i = 0; i < size; ++i)
  {
    Storage*& storage = array[i];
    storage = new Storage(this);
    if(!storage->load(hFile))
      return false;
  }

  return true;
}

bool Storage::save(HANDLE hFile) const
{
  // save all entries
  uint size = (uint)entries.size();
  if(!write(hFile, &size, sizeof(size)))
    return false;
  for(std::unordered_map<std::string, Variant>::const_iterator i = entries.begin(), end = entries.end(); i != end; ++i)
  {
    const std::string& key(i->first);
    const Variant& var(i->second);
    uint keysize = (uint)key.size();
    if(!write(hFile, &keysize, sizeof(keysize)) ||
       !write(hFile, key.c_str(), keysize) ||
       !write(hFile, &var.type, sizeof(var.type)) )
      return false;
    switch(var.type)
    {
    case Variant::Int:
    case Variant::UInt:
      if(!write(hFile, &var._int, sizeof(int)))
        return false;
      break;
    case Variant::Str:
      if(!write(hFile, &var.str->length, sizeof(var.str->length)) ||
         !write(hFile, var.str->data, var.str->length * sizeof(wchar)) )
        return false;
      break;
    case Variant::Data:
      if(!write(hFile, &var.data->length, sizeof(var.data->length)) ||
         !write(hFile, var.data->data, var.data->length) )
        return false;
      break;
    }
  }

  // save substorages
  size = (uint)storages.size();
  if(!write(hFile, &size, sizeof(size)))
    return false;
  for(std::unordered_map<std::string, Storage*>::const_iterator i = storages.begin(), end = storages.end(); i != end; ++i)
  {
    const std::string& key(i->first);
    Storage* storage(i->second);
    uint keysize = (uint)key.size();
    if(!write(hFile, &keysize, sizeof(keysize)) ||
       !write(hFile, key.c_str(), keysize) ||
       !storage->save(hFile))
      return false;
  }

  // save array
  size = (uint)array.size();
  if(!write(hFile, &size, sizeof(size)))
    return false;
  for(std::vector<Storage*>::const_iterator i = array.begin(), end = array.end(); i != end; ++i)
    if(!(*i)->save(hFile))
      return false;

  return true;
}
<|endoftext|>


<commit_before>/*
The OpenTRV project licenses this file to you
under the Apache Licence, Version 2.0 (the "Licence");
you may not use this file except in compliance
with the Licence. You may obtain a copy of the Licence at

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

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

Author(s) / Copyright (s): Damon Hart-Davis 2016
*/

/*
 * OTRadValve TempControl tests.
 */

#include <gtest/gtest.h>
#include <stdio.h>
#include <stdlib.h>

#include "OTSIM900Link.h"

// Test for general sanity of OTSIM900Link.
// Make sure that an instance can be created and does not die horribly.
// Underlying simulated serial/SIM900 never accepts data or responds, eg like a dead card.
TEST(OTSIM900Link,basicsDeadCard)
{
    const bool verbose = false;

    class NULLSerialStream final : public Stream
      {
      public:
        void begin(unsigned long) { }
        void begin(unsigned long, uint8_t);
        void end();

        virtual size_t write(uint8_t c) override { if(verbose) { fprintf(stderr, "%c\n", (char) c); } return(0); }
        virtual int available() override { return(-1); }
        virtual int read() override { return(-1); }
        virtual int peek() override { return(-1); }
        virtual void flush() override { }
      };
    OTSIM900Link::OTSIM900Link<0, 0, 0, NULLSerialStream> l0;
    EXPECT_TRUE(l0.begin());
    EXPECT_EQ(OTSIM900Link::GET_STATE, l0._getState());
    // Try to hang just by calling poll() repeatedly.
    for(int i = 0; i < 100; ++i) { l0.poll(); }
    EXPECT_GE(OTSIM900Link::START_UP, l0._getState()) << "should keep trying to start with GET_STATE, RETRY_GET_STATE and START_UP";
    // ...
    l0.end();
}

// Test for general sanity of OTSIM900Link.
// Make sure that an instance can be created and does not die horribly.
// Underlying simulated serial/SIM900 accepts output, does not respond.
namespace B1
{
const bool verbose = true;

// Does a trivial simulation of SIM900, responding to start of 'A' of AT command.
// Exercises every major non-PANIC state of the OTSIM900Link implementation.
class TrivialSimulator final : public Stream
  {
  public:
    // Events exposed.
    static bool haveSeenCommandStart;

  private:
    // Command being collected from OTSIM900Link.
    bool waitingForCommand = true;
    bool collectingCommand = false;
    // Entire request starting "AT"; no trailing CR or LF stored.
    std::string command;

    // Reply (postfix) being returned to OTSIM900Link: empty if none.
    std::string reply;

  public:
    void begin(unsigned long) { }
    void begin(unsigned long, uint8_t);
    void end();

    virtual size_t write(uint8_t uc) override
      {
      const char c = (char)uc;
      if(waitingForCommand)
        {
        // Look for leading 'A' of 'AT' to start a command.
        if('A' == c)
          {
          waitingForCommand = false;
          collectingCommand = true;
          command = 'A';
          haveSeenCommandStart = true; // Note at least one command start.
          }
        }
      else
        {
        // Look for CR (or LF) to terminate a command.
        if(('\r' == c) || ('\n' == c))
          {
          waitingForCommand = true;
          collectingCommand = false;
          if(verbose) { fprintf(stderr, "command received: %s\n", command.c_str()); }
          // Respond to particular commands...
          if("AT" == command) { reply = "AT\r"; }
          // DHD20161101: "No PIN" response (deliberately not typical SIM900 response) resulted in SIGSEGV from not checking getResponse() result for NULL.
          // Should futz/vary the response to check sensitivity.
          // TODO: have at least one response be expected SIM900 answer for no-PIN SIM.
          else if("AT+CPIN?" == command) { reply = (random() & 1) ? "No PIN" : "OK READY"; }
          }
        else if(collectingCommand) { command += c; }
        }
      if(verbose) { if(isprint(c)) { fprintf(stderr, "<%c\n", c); } else { fprintf(stderr, "< %d\n", (int)c); } }
      return(1);
      }
    virtual int read() override
        {
        if(0 == reply.size()) { return(-1); }
        const char c = reply[0];
        if(verbose) { if(isprint(c)) { fprintf(stderr, ">%c\n", c); } else { fprintf(stderr, "> %d\n", (int)c); } }
        reply.erase(0, 1);
        return(c);
        }
    virtual int available() override { return(-1); }
    virtual int peek() override { return(-1); }
    virtual void flush() override { }
  };
// Events exposed.
bool TrivialSimulator::haveSeenCommandStart;
}
TEST(OTSIM900Link,basicsSimpleSimulator)
{
//    const bool verbose = true;

    //srandomdev(); // Seed random() for use in simulator.

    ASSERT_FALSE(B1::TrivialSimulator::haveSeenCommandStart);
    OTSIM900Link::OTSIM900Link<0, 0, 0, B1::TrivialSimulator> l0;
    EXPECT_TRUE(l0.begin());
    EXPECT_EQ(OTSIM900Link::GET_STATE, l0._getState());
    // Try to hang just by calling poll() repeatedly.
    for(int i = 0; i < 100; ++i) { l0.poll(); }
    EXPECT_TRUE(B1::TrivialSimulator::haveSeenCommandStart) << "should see some attempt to communicate with SIM900";
    EXPECT_LE(OTSIM900Link::WAIT_FOR_REGISTRATION, l0._getState()) << "should make it to at least WAIT_FOR_REGISTRATION";
    // ...
    l0.end();
}

<commit_msg>Added to test harness<commit_after>/*
The OpenTRV project licenses this file to you
under the Apache Licence, Version 2.0 (the "Licence");
you may not use this file except in compliance
with the Licence. You may obtain a copy of the Licence at

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

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

Author(s) / Copyright (s): Damon Hart-Davis 2016
*/

/*
 * OTRadValve TempControl tests.
 */

#include <gtest/gtest.h>
#include <stdio.h>
#include <stdlib.h>

#include "OTSIM900Link.h"

// Test for general sanity of OTSIM900Link.
// Make sure that an instance can be created and does not die horribly.
// Underlying simulated serial/SIM900 never accepts data or responds, eg like a dead card.
TEST(OTSIM900Link,basicsDeadCard)
{
    const bool verbose = false;

    class NULLSerialStream final : public Stream
      {
      public:
        void begin(unsigned long) { }
        void begin(unsigned long, uint8_t);
        void end();

        virtual size_t write(uint8_t c) override { if(verbose) { fprintf(stderr, "%c\n", (char) c); } return(0); }
        virtual int available() override { return(-1); }
        virtual int read() override { return(-1); }
        virtual int peek() override { return(-1); }
        virtual void flush() override { }
      };
    OTSIM900Link::OTSIM900Link<0, 0, 0, NULLSerialStream> l0;
    EXPECT_TRUE(l0.begin());
    EXPECT_EQ(OTSIM900Link::GET_STATE, l0._getState());
    // Try to hang just by calling poll() repeatedly.
    for(int i = 0; i < 100; ++i) { l0.poll(); }
    EXPECT_GE(OTSIM900Link::START_UP, l0._getState()) << "should keep trying to start with GET_STATE, RETRY_GET_STATE and START_UP";
    // ...
    l0.end();
}

// Test for general sanity of OTSIM900Link.
// Make sure that an instance can be created and does not die horribly.
// Underlying simulated serial/SIM900 accepts output, does not respond.
namespace B1
{
const bool verbose = true;

// Does a trivial simulation of SIM900, responding to start of 'A' of AT command.
// Exercises every major non-PANIC state of the OTSIM900Link implementation.
class TrivialSimulator final : public Stream
  {
  public:
    // Events exposed.
    static bool haveSeenCommandStart;

  private:
    // Command being collected from OTSIM900Link.
    bool waitingForCommand = true;
    bool collectingCommand = false;
    // Entire request starting "AT"; no trailing CR or LF stored.
    std::string command;

    // Reply (postfix) being returned to OTSIM900Link: empty if none.
    std::string reply;

  public:
    void begin(unsigned long) { }
    void begin(unsigned long, uint8_t);
    void end();

    virtual size_t write(uint8_t uc) override
      {
      const char c = (char)uc;
      if(waitingForCommand)
        {
        // Look for leading 'A' of 'AT' to start a command.
        if('A' == c)
          {
          waitingForCommand = false;
          collectingCommand = true;
          command = 'A';
          haveSeenCommandStart = true; // Note at least one command start.
          }
        }
      else
        {
        // Look for CR (or LF) to terminate a command.
        if(('\r' == c) || ('\n' == c))
          {
          waitingForCommand = true;
          collectingCommand = false;
          if(verbose) { fprintf(stderr, "command received: %s\n", command.c_str()); }
          // Respond to particular commands...
          if("AT" == command) { reply = "AT\r"; }  // Relevant states: GET_STATE, RETRY_GET_STATE, START_UP
          // DHD20161101: "No PIN" response (deliberately not typical SIM900 response) resulted in SIGSEGV from not checking getResponse() result for NULL.
          // Should futz/vary the response to check sensitivity.
          // TODO: have at least one response be expected SIM900 answer for no-PIN SIM.
          else if("AT+CPIN?" == command) { reply = (random() & 1) ? "No PIN\r" : "OK READY\r"; }  // Relevant states: CHECK_PIN
          else if("AT+CREG?" == command) { reply = (random() & 1) ? "+CREG: 0,0\r" : "+CREG: 0,5\r"; } // Relevant states: WAIT_FOR_REGISTRATION
//          else if("AT+CSTT=" == command) { reply = (random() & 1) ? "gbfhs\r" : "\n  OK\r"; } // Relevant states: SET_APN FIXME need to pass OTSIM900Link a config!
          }
        else if(collectingCommand) { command += c; }
        }
      if(verbose) { if(isprint(c)) { fprintf(stderr, "<%c\n", c); } else { fprintf(stderr, "< %d\n", (int)c); } }
      return(1);
      }
    virtual int read() override
        {
        if(0 == reply.size()) { return(-1); }
        const char c = reply[0];
        if(verbose) { if(isprint(c)) { fprintf(stderr, ">%c\n", c); } else { fprintf(stderr, "> %d\n", (int)c); } }
        reply.erase(0, 1);
        return(c);
        }
    virtual int available() override { return(-1); }
    virtual int peek() override { return(-1); }
    virtual void flush() override { }
  };
// Events exposed.
bool TrivialSimulator::haveSeenCommandStart;
}
TEST(OTSIM900Link,basicsSimpleSimulator)
{
//    const bool verbose = true;

    //srandomdev(); // Seed random() for use in simulator.

    ASSERT_FALSE(B1::TrivialSimulator::haveSeenCommandStart);
    OTSIM900Link::OTSIM900Link<0, 0, 0, B1::TrivialSimulator> l0;
    EXPECT_TRUE(l0.begin());
    EXPECT_EQ(OTSIM900Link::GET_STATE, l0._getState());
    // Try to hang just by calling poll() repeatedly.
    for(int i = 0; i < 100; ++i) { l0.poll(); }
    EXPECT_TRUE(B1::TrivialSimulator::haveSeenCommandStart) << "should see some attempt to communicate with SIM900";
    EXPECT_LE(OTSIM900Link::WAIT_FOR_REGISTRATION, l0._getState()) << "should make it to at least WAIT_FOR_REGISTRATION";
    // ...
    l0.end();
}

<|endoftext|>


<commit_before>/*
The OpenTRV project licenses this file to you
under the Apache Licence, Version 2.0 (the "Licence");
you may not use this file except in compliance
with the Licence. You may obtain a copy of the Licence at

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

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

Author(s) / Copyright (s): Damon Hart-Davis 2016
*/

/*
 * OTRadValve SIM900 tests.
 */

#include <gtest/gtest.h>
#include <stdio.h>
#include <stdlib.h>

#include "OTSIM900Link.h"

// Test the getter function definitely does what it should.
TEST(OTSIM900Link, getterFunction)
{
    const char SIM900_PIN[] = "1111";
    const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config(false, SIM900_PIN, NULL, NULL, NULL);
    EXPECT_EQ(SIM900_PIN[0], SIM900Config.get((const uint8_t *)SIM900Config.PIN));
}

// Test for general sanity of OTSIM900Link.
// Make sure that an instance can be created and does not die horribly.
// Underlying simulated serial/SIM900 never accepts data or responds, eg like a dead card.
TEST(OTSIM900Link,basicsDeadCard)
{
    const bool verbose = false;

    class NULLSerialStream final : public Stream
      {
      public:
        void begin(unsigned long) { }
        void begin(unsigned long, uint8_t);
        void end();

        virtual size_t write(uint8_t c) override { if(verbose) { fprintf(stderr, "%c\n", (char) c); } return(0); }
        virtual int available() override { return(-1); }
        virtual int read() override { return(-1); }
        virtual int peek() override { return(-1); }
        virtual void flush() override { }
      };
    const char SIM900_PIN[] = "1111";
    const char SIM900_APN[] = "apn";
    const char SIM900_UDP_ADDR[] = "0.0.0.0"; // ORS server
    const char SIM900_UDP_PORT[] = "9999";
    const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config(false, SIM900_PIN, SIM900_APN, SIM900_UDP_ADDR, SIM900_UDP_PORT);
    const OTRadioLink::OTRadioChannelConfig l0Config(&SIM900Config, true);
    OTSIM900Link::OTSIM900Link<0, 0, 0, NULLSerialStream> l0;
    EXPECT_TRUE(l0.configure(1, &l0Config));
    EXPECT_TRUE(l0.begin());
    EXPECT_EQ(OTSIM900Link::GET_STATE, l0._getState());
    // Try to hang just by calling poll() repeatedly.
    for(int i = 0; i < 100; ++i) { l0.poll(); }
    EXPECT_GE(OTSIM900Link::GET_STATE, l0._getState()) << "should keep trying to start with GET_STATE, RETRY_GET_STATE";
    // ...
    l0.end();
}

// Walk through state space of OTSIM900Link.
// Make sure that an instance can be created and does not die horribly.
// Is meant to mainly walk through all the normal expected SIM900 behaviour when all is well.
// Other tests can look at error handling including unexpected/garbage responses.
namespace B1
{
const bool verbose = true;

// Does a simple simulation of SIM900, responding sensibly to all commands needed by the OTSIM900Link impl.
// Allows for exercise of every major non-PANIC state of the OTSIM900Link implementation.
class GoodSimulator final : public Stream
  {
  public:
    // Events exposed.
    static bool haveSeenCommandStart;

  private:
    // Command being collected from OTSIM900Link.
    bool waitingForCommand = true;
    bool collectingCommand = false;
    // Entire request starting "AT"; no trailing CR or LF stored.
    std::string command;

    // Reply (postfix) being returned to OTSIM900Link: empty if none.
    std::string reply;

  public:
    void begin(unsigned long) { }
    void begin(unsigned long, uint8_t);
    void end();

    virtual size_t write(uint8_t uc) override
      {
      const char c = (char)uc;
      if(waitingForCommand)
        {
        // Look for leading 'A' of 'AT' to start a command.
        if('A' == c)
          {
          waitingForCommand = false;
          collectingCommand = true;
          command = 'A';
          haveSeenCommandStart = true; // Note at least one command start.
          }
        }
      else
        {
        // Look for CR (or LF) to terminate a command.
        if(('\r' == c) || ('\n' == c))
          {
          waitingForCommand = true;
          collectingCommand = false;
          if(verbose) { fprintf(stderr, "command received: %s\n", command.c_str()); }
          // Respond to particular commands...
          if("AT" == command) { reply = "AT\r"; }  // Relevant states: GET_STATE, RETRY_GET_STATE, START_UP
          else if("AT+CPIN?" == command) { reply = /* (random() & 1) ? "No PIN\r" : */ "READY\r"; }  // Relevant states: CHECK_PIN
          else if("AT+CREG?" == command) { reply = /* (random() & 1) ? "+CREG: 0,0\r" : */ "+CREG: 0,5\r"; } // Relevant states: WAIT_FOR_REGISTRATION
          else if("AT+CSTT=apn" == command) { reply = /* (random() & 1) ? "gbfhs\r" : */ "AT+CSTT\r\n\r\nOK\r"; } // Relevant states: SET_APN
          }
        else if(collectingCommand) { command += c; }
        }
      if(verbose) { if(isprint(c)) { fprintf(stderr, "<%c\n", c); } else { fprintf(stderr, "< %d\n", (int)c); } }
      return(1);
      }
    virtual int read() override
        {
        if(0 == reply.size()) { return(-1); }
        const char c = reply[0];
        if(verbose) { if(isprint(c)) { fprintf(stderr, ">%c\n", c); } else { fprintf(stderr, "> %d\n", (int)c); } }
        reply.erase(0, 1);
        return(c);
        }
    virtual int available() override { return(-1); }
    virtual int peek() override { return(-1); }
    virtual void flush() override { }
  };
// Events exposed.
bool GoodSimulator::haveSeenCommandStart;
}
TEST(OTSIM900Link,basicsSimpleSimulator)
{
//    const bool verbose = B1::verbose;

    srandom(::testing::UnitTest::GetInstance()->random_seed()); // Seed random() for use in simulator; --gtest_shuffle will force it to change.

    const char SIM900_PIN[] = "1111";
    const char SIM900_APN[] = "apn";
    const char SIM900_UDP_ADDR[] = "0.0.0.0"; // ORS server
    const char SIM900_UDP_PORT[] = "9999";
    const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config(false, SIM900_PIN, SIM900_APN, SIM900_UDP_ADDR, SIM900_UDP_PORT);
    const OTRadioLink::OTRadioChannelConfig l0Config(&SIM900Config, true);

    ASSERT_FALSE(B1::GoodSimulator::haveSeenCommandStart);
    OTSIM900Link::OTSIM900Link<0, 0, 0, B1::GoodSimulator> l0;
    EXPECT_TRUE(l0.configure(1, &l0Config));
    EXPECT_TRUE(l0.begin());
    EXPECT_EQ(OTSIM900Link::GET_STATE, l0._getState());
    // Try to hang just by calling poll() repeatedly.
    for(int i = 0; i < 100; ++i) { l0.poll(); }
    EXPECT_TRUE(B1::GoodSimulator::haveSeenCommandStart) << "should see some attempt to communicate with SIM900";
    EXPECT_LE(OTSIM900Link::WAIT_FOR_REGISTRATION, l0._getState()) << "should make it to at least WAIT_FOR_REGISTRATION";
    // ...
    l0.end();
}

<commit_msg>Expanded test rig<commit_after>/*
The OpenTRV project licenses this file to you
under the Apache Licence, Version 2.0 (the "Licence");
you may not use this file except in compliance
with the Licence. You may obtain a copy of the Licence at

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

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

Author(s) / Copyright (s): Damon Hart-Davis 2016
*/

/*
 * OTRadValve SIM900 tests.
 */

#include <gtest/gtest.h>
#include <stdio.h>
#include <stdlib.h>

#include "OTSIM900Link.h"

// Test the getter function definitely does what it should.
TEST(OTSIM900Link, getterFunction)
{
    const char SIM900_PIN[] = "1111";
    const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config(false, SIM900_PIN, NULL, NULL, NULL);
    EXPECT_EQ(SIM900_PIN[0], SIM900Config.get((const uint8_t *)SIM900Config.PIN));
}

// Test for general sanity of OTSIM900Link.
// Make sure that an instance can be created and does not die horribly.
// Underlying simulated serial/SIM900 never accepts data or responds, eg like a dead card.
TEST(OTSIM900Link,basicsDeadCard)
{
    const bool verbose = false;

    class NULLSerialStream final : public Stream
      {
      public:
        void begin(unsigned long) { }
        void begin(unsigned long, uint8_t);
        void end();

        virtual size_t write(uint8_t c) override { if(verbose) { fprintf(stderr, "%c\n", (char) c); } return(0); }
        virtual int available() override { return(-1); }
        virtual int read() override { return(-1); }
        virtual int peek() override { return(-1); }
        virtual void flush() override { }
      };
    const char SIM900_PIN[] = "1111";
    const char SIM900_APN[] = "apn";
    const char SIM900_UDP_ADDR[] = "0.0.0.0"; // ORS server
    const char SIM900_UDP_PORT[] = "9999";
    const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config(false, SIM900_PIN, SIM900_APN, SIM900_UDP_ADDR, SIM900_UDP_PORT);
    const OTRadioLink::OTRadioChannelConfig l0Config(&SIM900Config, true);
    OTSIM900Link::OTSIM900Link<0, 0, 0, NULLSerialStream> l0;
    EXPECT_TRUE(l0.configure(1, &l0Config));
    EXPECT_TRUE(l0.begin());
    EXPECT_EQ(OTSIM900Link::GET_STATE, l0._getState());
    // Try to hang just by calling poll() repeatedly.
    for(int i = 0; i < 100; ++i) { l0.poll(); }
    EXPECT_GE(OTSIM900Link::GET_STATE, l0._getState()) << "should keep trying to start with GET_STATE, RETRY_GET_STATE";
    // ...
    l0.end();
}

// Walk through state space of OTSIM900Link.
// Make sure that an instance can be created and does not die horribly.
// Is meant to mainly walk through all the normal expected SIM900 behaviour when all is well.
// Other tests can look at error handling including unexpected/garbage responses.
namespace B1
{
const bool verbose = true;

// Does a simple simulation of SIM900, responding sensibly to all commands needed by the OTSIM900Link impl.
// Allows for exercise of every major non-PANIC state of the OTSIM900Link implementation.
class GoodSimulator final : public Stream
  {
  public:
    // Events exposed.
    static bool haveSeenCommandStart;

  private:
    // Command being collected from OTSIM900Link.
    bool waitingForCommand = true;
    bool collectingCommand = false;
    // Entire request starting "AT"; no trailing CR or LF stored.
    std::string command;

    // Reply (postfix) being returned to OTSIM900Link: empty if none.
    std::string reply;

  public:
    void begin(unsigned long) { }
    void begin(unsigned long, uint8_t);
    void end();

    virtual size_t write(uint8_t uc) override
      {
      const char c = (char)uc;
      if(waitingForCommand)
        {
        // Look for leading 'A' of 'AT' to start a command.
        if('A' == c)
          {
          waitingForCommand = false;
          collectingCommand = true;
          command = 'A';
          haveSeenCommandStart = true; // Note at least one command start.
          }
        }
      else
        {
        // Look for CR (or LF) to terminate a command.
        if(('\r' == c) || ('\n' == c))
          {
          waitingForCommand = true;
          collectingCommand = false;
          if(verbose) { fprintf(stderr, "command received: %s\n", command.c_str()); }
          // Respond to particular commands...
          if("AT" == command) { reply = "AT\r"; }  // Relevant states: GET_STATE, RETRY_GET_STATE, START_UP
          else if("AT+CPIN?" == command) { reply = /* (random() & 1) ? "No PIN\r" : */ "READY\r"; }  // Relevant states: CHECK_PIN
          else if("AT+CREG?" == command) { reply = /* (random() & 1) ? "+CREG: 0,0\r" : */ "+CREG: 0,5\r"; } // Relevant states: WAIT_FOR_REGISTRATION
          else if("AT+CSTT=apn" == command) { reply =  "AT+CSTT\r\n\r\nOK\r"; } // Relevant states: SET_APN
          else if("AT+CIPSTATUS" == command) { reply = ""; }  // Relevant states: START_GPRS, WAIT_FOR_UDP
          else if("AT+CIICR" == command) { reply = "AT+CIICR\r\n\r\nOK\r\n"; }  // Relevant states: START_GPRS
          else if("AT+CIFSR" == command) { reply = "AT+CIFSR\r\n\r\n172.16.101.199\r\n"; }  // Relevant States: GET_IP
          else if("AT+CIPSTART" == command) { reply = "AT+CIPSTART=\"UDP\",\"0.0.0.0\",\"9999\"\r\n\r\nOK\r\n\r\nCONNECT OK\r\n"; }  // Relevant states: OPEN_UDP fixme command probably wrong
          else if("AT+CIPSEND=3" == command) { reply = "AT+CIPSEND=3\r\n\r\n>"; }  // Relevant states:  SENDING
          else if("123" == command) { reply = "123\r\nSEND OK\r\n"; }  // Relevant states: SENDING
          else if("" == command) { reply = ""; }  // Relevant states:
          else if("" == command) { reply = ""; }  // Relevant states:
          }
        else if(collectingCommand) { command += c; }
        }
      if(verbose) { if(isprint(c)) { fprintf(stderr, "<%c\n", c); } else { fprintf(stderr, "< %d\n", (int)c); } }
      return(1);
      }
    virtual int read() override
        {
        if(0 == reply.size()) { return(-1); }
        const char c = reply[0];
        if(verbose) { if(isprint(c)) { fprintf(stderr, ">%c\n", c); } else { fprintf(stderr, "> %d\n", (int)c); } }
        reply.erase(0, 1);
        return(c);
        }
    virtual int available() override { return(-1); }
    virtual int peek() override { return(-1); }
    virtual void flush() override { }
  };
// Events exposed.
bool GoodSimulator::haveSeenCommandStart;
}
TEST(OTSIM900Link,basicsSimpleSimulator)
{
//    const bool verbose = B1::verbose;

    srandom(::testing::UnitTest::GetInstance()->random_seed()); // Seed random() for use in simulator; --gtest_shuffle will force it to change.

    const char SIM900_PIN[] = "1111";
    const char SIM900_APN[] = "apn";
    const char SIM900_UDP_ADDR[] = "0.0.0.0"; // ORS server
    const char SIM900_UDP_PORT[] = "9999";
    const OTSIM900Link::OTSIM900LinkConfig_t SIM900Config(false, SIM900_PIN, SIM900_APN, SIM900_UDP_ADDR, SIM900_UDP_PORT);
    const OTRadioLink::OTRadioChannelConfig l0Config(&SIM900Config, true);

    ASSERT_FALSE(B1::GoodSimulator::haveSeenCommandStart);
    OTSIM900Link::OTSIM900Link<0, 0, 0, B1::GoodSimulator> l0;
    EXPECT_TRUE(l0.configure(1, &l0Config));
    EXPECT_TRUE(l0.begin());
    EXPECT_EQ(OTSIM900Link::GET_STATE, l0._getState());
    // Try to hang just by calling poll() repeatedly.
    for(int i = 0; i < 100; ++i) { l0.poll(); }
    EXPECT_TRUE(B1::GoodSimulator::haveSeenCommandStart) << "should see some attempt to communicate with SIM900";
    EXPECT_LE(OTSIM900Link::WAIT_FOR_REGISTRATION, l0._getState()) << "should make it to at least WAIT_FOR_REGISTRATION";
    // ...
    l0.end();
}

<|endoftext|>


<commit_before>#include "recordattendancedlg.h"
#include "ui_recordattendancedlg.h"

#include <models/trainingmodel.h>

RecordAttendanceDlg::RecordAttendanceDlg(QSqlRecord record, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::RecordAttendanceDlg)
{
    ui->setupUi(this);

    attendanceModel = new AttendanceModel(record);

    ui->treeView->setModel(attendanceModel);

    connect(ui->btnSave, SIGNAL(clicked()), attendanceModel, SLOT(saveData()));
    connect(ui->btnSave, SIGNAL(clicked()), this, SLOT(close()));
    //QString trainingDatetime = new TrainingModel().filter()
}

RecordAttendanceDlg::~RecordAttendanceDlg()
{
    delete ui;
}
<commit_msg>Show datetime<commit_after>#include "recordattendancedlg.h"
#include "ui_recordattendancedlg.h"

#include <QDateTime>
#include <QSqlField>
#include <models/trainingmodel.h>

RecordAttendanceDlg::RecordAttendanceDlg(QSqlRecord record, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::RecordAttendanceDlg)
{
    ui->setupUi(this);

    attendanceModel = new AttendanceModel(record);

    ui->treeView->setModel(attendanceModel);

    connect(ui->btnSave, SIGNAL(clicked()), attendanceModel, SLOT(saveData()));
    connect(ui->btnSave, SIGNAL(clicked()), this, SLOT(close()));

    QDateTime datetime = record.field("datetime").value().toDateTime();
    ui->txtTrainingDatetime->setText(datetime.toString(tr("dd.MM.yyyy h:mm")));
}

RecordAttendanceDlg::~RecordAttendanceDlg()
{
    delete ui;
}
<|endoftext|>