<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 INCLUDED_SFX2_SOURCE_INC_TEMPLDGI_HXX
#define INCLUDED_SFX2_SOURCE_INC_TEMPLDGI_HXX

class SfxTemplateControllerItem;

#include <vcl/button.hxx>
#include <vcl/toolbox.hxx>
#include <vcl/lstbox.hxx>
#include <svl/lstner.hxx>
#include <svtools/treelistbox.hxx>
#include <svl/eitem.hxx>

#include <rsc/rscsfx.hxx>
#include <tools/rtti.hxx>

#include <sfx2/childwin.hxx>
#include <sfx2/templdlg.hxx>

class SfxStyleFamilies;
class SfxStyleFamilyItem;
class SfxTemplateItem;
class SfxBindings;
class SfxStyleSheetBase;
class SfxStyleSheetBasePool;
class SvTreeListBox ;
class StyleTreeListBox_Impl;
class SfxTemplateDialog_Impl;
class SfxCommonTemplateDialog_Impl;
class SfxDockingWindow;

namespace com { namespace sun { namespace star { namespace frame { class XModuleManager2; } } } }

// class DropListBox_Impl ------------------------------------------------

class DropListBox_Impl : public SvTreeListBox
{
private:
    DECL_LINK(OnAsyncExecuteDrop, void *);

protected:
    SfxCommonTemplateDialog_Impl* pDialog;
    sal_uInt16                    nModifier;

public:
    DropListBox_Impl( vcl::Window* pParent, const ResId& rId, SfxCommonTemplateDialog_Impl* pD )
        : SvTreeListBox(pParent, rId)
        , pDialog(pD)
        , nModifier(0)
    {}
    DropListBox_Impl( vcl::Window* pParent, WinBits nWinBits, SfxCommonTemplateDialog_Impl* pD )
        : SvTreeListBox(pParent, nWinBits)
        , pDialog(pD)
        , nModifier(0)
    {}
    virtual void     MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
    virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) SAL_OVERRIDE;
    using SvTreeListBox::ExecuteDrop;
    virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) SAL_OVERRIDE;

    sal_uInt16           GetModifier() const { return nModifier; }

    virtual bool     Notify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
};

typedef std::vector<OUString> ExpandedEntries_t;

/*  [Description]

    TreeListBox class for displaying the hierarchical view of the templates
*/

class StyleTreeListBox_Impl : public DropListBox_Impl
{
private:
    SvTreeListEntry*                pCurEntry;
    Link                            aDoubleClickLink;
    Link                            aDropLink;
    OUString                        aParent;
    OUString                        aStyle;

protected:
    virtual void    Command( const CommandEvent& rMEvt ) SAL_OVERRIDE;
    virtual bool    Notify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
    virtual bool    DoubleClickHdl() SAL_OVERRIDE;
    virtual bool    ExpandingHdl() SAL_OVERRIDE;
    virtual void    ExpandedHdl() SAL_OVERRIDE;
    virtual TriState NotifyMoving(SvTreeListEntry*  pTarget,
                                     SvTreeListEntry*  pEntry,
                                     SvTreeListEntry*& rpNewParent,
                                     sal_uIntPtr&        rNewChildPos) SAL_OVERRIDE;
public:
    StyleTreeListBox_Impl( SfxCommonTemplateDialog_Impl* pParent, WinBits nWinStyle = 0);

    void            SetDoubleClickHdl(const Link &rLink) { aDoubleClickLink = rLink; }
    void            SetDropHdl(const Link &rLink) { aDropLink = rLink; }
    using SvTreeListBox::GetParent;
    const OUString& GetParent() const { return aParent; }
    const OUString& GetStyle() const { return aStyle; }
    void            MakeExpanded_Impl(ExpandedEntries_t& rEntries) const;

    virtual PopupMenu* CreateContextMenu( void ) SAL_OVERRIDE;
};

// class SfxActionListBox ------------------------------------------------

class SfxActionListBox : public DropListBox_Impl
{
protected:
public:
    SfxActionListBox( SfxCommonTemplateDialog_Impl* pParent, WinBits nWinBits );

    virtual PopupMenu*  CreateContextMenu( void ) SAL_OVERRIDE;
};

// class SfxCommonTemplateDialog_Impl ------------------------------------

class SfxCommonTemplateDialog_Impl : public SfxListener
{
private:
    class DeletionWatcher;
    friend class DeletionWatcher;
    bool mbIgnoreSelect;

    void    ReadResource();
    void    ClearResource();
    void impl_clear();
    DeletionWatcher * impl_setDeletionWatcher(DeletionWatcher* pNewWatcher);

protected:
#define MAX_FAMILIES            5
#define COUNT_BOUND_FUNC        13

#define UPDATE_FAMILY_LIST      0x0001
#define UPDATE_FAMILY           0x0002

    friend class DropListBox_Impl;
    friend class SfxTemplateControllerItem;

    SfxBindings*                pBindings;
    SfxTemplateControllerItem*  pBoundItems[COUNT_BOUND_FUNC];

    vcl::Window*                     pWindow;
    SfxModule*                  pModule;
    Idle*                       pIdle;

    ResId*                      m_pStyleFamiliesId;
    SfxStyleFamilies*           pStyleFamilies;
    SfxTemplateItem*            pFamilyState[MAX_FAMILIES];
    SfxStyleSheetBasePool*      pStyleSheetPool;
    StyleTreeListBox_Impl*      pTreeBox;
    SfxObjectShell*             pCurObjShell;
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager2 >
                                xModuleManager;
    DeletionWatcher*            m_pDeletionWatcher;

    SfxActionListBox            aFmtLb;
    ListBox                     aFilterLb;
    Size                        aSize;

    sal_uInt16                      nActFamily; // Id in the ToolBox = Position - 1
    sal_uInt16                      nActFilter; // FilterIdx
    sal_uInt16                      nAppFilter; // Filter, which has set the application (for automatic)

    bool                        bDontUpdate             :1,
                                bIsWater                :1,
                                bEnabled                :1,
                                bUpdate                 :1,
                                bUpdateFamily           :1,
                                bCanEdit                :1,
                                bCanDel                 :1,
                                bCanNew                 :1,
                                bCanHide                :1,
                                bCanShow                :1,
                                bWaterDisabled          :1,
                                bNewByExampleDisabled   :1,
                                bUpdateByExampleDisabled:1,
                                bTreeDrag               :1,
                                bHierarchical           :1,
                                m_bWantHierarchical     :1,
                                bBindingUpdate          :1;

    DECL_LINK( FilterSelectHdl, ListBox * );
    DECL_LINK( FmtSelectHdl, SvTreeListBox * );
    DECL_LINK( ApplyHdl, Control * );
    DECL_LINK( DropHdl, StyleTreeListBox_Impl * );
    DECL_LINK( TimeOut, Timer * );

    virtual void        EnableItem( sal_uInt16 /*nMesId*/, bool /*bCheck*/ = true ) {}
    virtual void        CheckItem( sal_uInt16 /*nMesId*/, bool /*bCheck*/ = true ) {}
    virtual bool        IsCheckedItem( sal_uInt16 /*nMesId*/ ) { return true; }
    virtual void        LoadedFamilies() {}
    void                Update() { UpdateStyles_Impl(UPDATE_FAMILY_LIST); }
    void                InvalidateBindings();
    virtual void        InsertFamilyItem( sal_uInt16 nId, const SfxStyleFamilyItem* pIten ) = 0;
    virtual void        EnableFamilyItem( sal_uInt16 nId, bool bEnabled = true ) = 0;
    virtual void        ClearFamilyList() = 0;
    virtual void        ReplaceUpdateButtonByMenu();

    void                NewHdl( void* );
    void                EditHdl( void* );
    void                DeleteHdl( void* );
    void                HideHdl( void* );
    void                ShowHdl( void* );

    bool                Execute_Impl( sal_uInt16 nId, const OUString& rStr, const OUString& rRefStr,
                                      sal_uInt16 nFamily, sal_uInt16 nMask = 0,
                                      sal_uInt16* pIdx = NULL, const sal_uInt16* pModifier = NULL );

    void                        UpdateStyles_Impl(sal_uInt16 nFlags);
    const SfxStyleFamilyItem*   GetFamilyItem_Impl() const;
    bool                    IsInitialized() const { return nActFamily != 0xffff; }
    void                        ResetFocus();
    void                        EnableDelete();
    void                        Initialize();
    void                        EnableHierarchical(bool);

    void                FilterSelect( sal_uInt16 nFilterIdx, bool bForce = false );
    void                SetFamilyState( sal_uInt16 nSlotId, const SfxTemplateItem* );
    void                SetWaterCanState( const SfxBoolItem* pItem );

    void                SelectStyle( const OUString& rStyle );
    bool            HasSelectedStyle() const;
    SfxStyleSheetBase  *GetSelectedStyle() const;
    void                FillTreeBox();
    void                Update_Impl();
    void                UpdateFamily_Impl();

    // In which FamilyState do I have to look , in order to get the
    // information of the ith Family in the pStyleFamilies.
    sal_uInt16              StyleNrToInfoOffset( sal_uInt16 i );

    void                Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) SAL_OVERRIDE;

    void                FamilySelect( sal_uInt16 nId );
    void                SetFamily( sal_uInt16 nId );
    void                ActionSelect( sal_uInt16 nId );

    sal_Int32           LoadFactoryStyleFilter( SfxObjectShell* i_pObjSh );
    void                SaveFactoryStyleFilter( SfxObjectShell* i_pObjSh, sal_Int32 i_nFilter );
    SfxObjectShell *    SaveSelection();

public:
    TYPEINFO_OVERRIDE();

    SfxCommonTemplateDialog_Impl( SfxBindings* pB, vcl::Window*, bool );
    virtual ~SfxCommonTemplateDialog_Impl();

    DECL_LINK( MenuSelectHdl, Menu * );

    virtual void        EnableEdit( bool b = true ) { bCanEdit = b; }
    void                EnableDel( bool b = true )  { bCanDel = b; }
    void                EnableNew( bool b = true )  { bCanNew = b; }
    void                EnableHide( bool b = true )  { bCanHide = b; }
    void                EnableShow( bool b = true )  { bCanShow = b; }

    vcl::Window*        GetWindow() { return pWindow; }

    void                EnableTreeDrag( bool b = true );
    void                EnableExample_Impl( sal_uInt16 nId, bool bEnable );
    SfxStyleFamily      GetActualFamily() const;
    OUString            GetSelectedEntry() const;
    SfxObjectShell*     GetObjectShell() const { return pCurObjShell; }

    inline bool         CanEdit( void ) const   { return bCanEdit; }
    inline bool         CanDel( void ) const    { return bCanDel; }
    inline bool         CanNew( void ) const    { return bCanNew; }
    inline bool         CanHide( void ) const    { return bCanHide; }
    inline bool         CanShow( void ) const    { return bCanShow; }

    // normally for derivates from SvTreeListBoxes, but in this case the dialog handles context menus
    PopupMenu*           CreateContextMenu( void );
};

class DropToolBox_Impl : public ToolBox, public DropTargetHelper
{
    SfxTemplateDialog_Impl&     rParent;
protected:
    virtual sal_Int8    AcceptDrop( const AcceptDropEvent& rEvt ) SAL_OVERRIDE;
    virtual sal_Int8    ExecuteDrop( const ExecuteDropEvent& rEvt ) SAL_OVERRIDE;
public:
    DropToolBox_Impl(vcl::Window* pParent, SfxTemplateDialog_Impl* pTemplateDialog);
    virtual ~DropToolBox_Impl();
};
// class SfxTemplateDialog_Impl ------------------------------------------

class SfxTemplateDialog_Impl :  public SfxCommonTemplateDialog_Impl
{
private:
    friend class SfxTemplateControllerItem;
    friend class DropToolBox_Impl;
    friend class SfxTemplatePanelControl;

    vcl::Window* m_pFloat;
    bool            m_bZoomIn;
    DropToolBox_Impl    m_aActionTbL;
    ToolBox             m_aActionTbR;

    DECL_LINK( ToolBoxLSelect, ToolBox * );
    DECL_LINK( ToolBoxRSelect, ToolBox * );
    DECL_LINK( ToolBoxRClick, ToolBox * );
    DECL_LINK( MenuSelectHdl, Menu* );

protected:
    virtual void    EnableEdit( bool = true ) SAL_OVERRIDE;
    virtual void    EnableItem( sal_uInt16 nMesId, bool bCheck = true ) SAL_OVERRIDE;
    virtual void    CheckItem( sal_uInt16 nMesId, bool bCheck = true ) SAL_OVERRIDE;
    virtual bool    IsCheckedItem( sal_uInt16 nMesId ) SAL_OVERRIDE;
    virtual void    LoadedFamilies() SAL_OVERRIDE;
    virtual void    InsertFamilyItem( sal_uInt16 nId, const SfxStyleFamilyItem* pIten ) SAL_OVERRIDE;
    virtual void    EnableFamilyItem( sal_uInt16 nId, bool bEnabled = true ) SAL_OVERRIDE;
    virtual void    ClearFamilyList() SAL_OVERRIDE;
    virtual void    ReplaceUpdateButtonByMenu() SAL_OVERRIDE;

    void            Resize();
    Size            GetMinOutputSizePixel();

    void            updateFamilyImages();
    void            updateNonFamilyImages();

public:
    friend class SfxTemplateDialog;
    TYPEINFO_OVERRIDE();

    SfxTemplateDialog_Impl( SfxBindings*, SfxTemplatePanelControl* pDlgWindow );
    virtual ~SfxTemplateDialog_Impl();

    void Initialize();
};

#endif // INCLUDED_SFX2_SOURCE_INC_TEMPLDGI_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>cleanup templdgi.hxx<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 INCLUDED_SFX2_SOURCE_INC_TEMPLDGI_HXX
#define INCLUDED_SFX2_SOURCE_INC_TEMPLDGI_HXX

class SfxTemplateControllerItem;

#include <vcl/button.hxx>
#include <vcl/toolbox.hxx>
#include <vcl/lstbox.hxx>
#include <svl/lstner.hxx>
#include <svtools/treelistbox.hxx>
#include <svl/eitem.hxx>

#include <rsc/rscsfx.hxx>
#include <tools/rtti.hxx>

#include <sfx2/childwin.hxx>
#include <sfx2/templdlg.hxx>

class SfxStyleFamilies;
class SfxStyleFamilyItem;
class SfxTemplateItem;
class SfxBindings;
class SfxStyleSheetBase;
class SfxStyleSheetBasePool;
class SvTreeListBox ;
class StyleTreeListBox_Impl;
class SfxTemplateDialog_Impl;
class SfxCommonTemplateDialog_Impl;
class SfxDockingWindow;

namespace com { namespace sun { namespace star { namespace frame {
    class XModuleManager2;
}}}}

class DropListBox_Impl : public SvTreeListBox
{
private:
    DECL_LINK(OnAsyncExecuteDrop, void *);

protected:
    SfxCommonTemplateDialog_Impl* pDialog;
    sal_uInt16                    nModifier;

public:
    DropListBox_Impl( vcl::Window* pParent, const ResId& rId, SfxCommonTemplateDialog_Impl* pD )
        : SvTreeListBox(pParent, rId)
        , pDialog(pD)
        , nModifier(0)
    {}
    DropListBox_Impl( vcl::Window* pParent, WinBits nWinBits, SfxCommonTemplateDialog_Impl* pD )
        : SvTreeListBox(pParent, nWinBits)
        , pDialog(pD)
        , nModifier(0)
    {}
    virtual void     MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
    virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) SAL_OVERRIDE;
    using SvTreeListBox::ExecuteDrop;
    virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) SAL_OVERRIDE;

    sal_uInt16           GetModifier() const { return nModifier; }

    virtual bool     Notify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
};

typedef std::vector<OUString> ExpandedEntries_t;

/*  [Description]

    TreeListBox class for displaying the hierarchical view of the templates
*/

class StyleTreeListBox_Impl : public DropListBox_Impl
{
private:
    SvTreeListEntry*                pCurEntry;
    Link                            aDoubleClickLink;
    Link                            aDropLink;
    OUString                        aParent;
    OUString                        aStyle;

protected:
    virtual void    Command( const CommandEvent& rMEvt ) SAL_OVERRIDE;
    virtual bool    Notify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
    virtual bool    DoubleClickHdl() SAL_OVERRIDE;
    virtual bool    ExpandingHdl() SAL_OVERRIDE;
    virtual void    ExpandedHdl() SAL_OVERRIDE;
    virtual TriState NotifyMoving(SvTreeListEntry*  pTarget,
                                     SvTreeListEntry*  pEntry,
                                     SvTreeListEntry*& rpNewParent,
                                     sal_uIntPtr&        rNewChildPos) SAL_OVERRIDE;
public:
    StyleTreeListBox_Impl( SfxCommonTemplateDialog_Impl* pParent, WinBits nWinStyle = 0);

    void            SetDoubleClickHdl(const Link &rLink) { aDoubleClickLink = rLink; }
    void            SetDropHdl(const Link &rLink) { aDropLink = rLink; }
    using SvTreeListBox::GetParent;
    const OUString& GetParent() const { return aParent; }
    const OUString& GetStyle() const { return aStyle; }
    void            MakeExpanded_Impl(ExpandedEntries_t& rEntries) const;

    virtual PopupMenu* CreateContextMenu( void ) SAL_OVERRIDE;
};

// class SfxActionListBox ------------------------------------------------

class SfxActionListBox : public DropListBox_Impl
{
protected:
public:
    SfxActionListBox( SfxCommonTemplateDialog_Impl* pParent, WinBits nWinBits );

    virtual PopupMenu*  CreateContextMenu( void ) SAL_OVERRIDE;
};

// class SfxCommonTemplateDialog_Impl ------------------------------------

class SfxCommonTemplateDialog_Impl : public SfxListener
{
private:
    class DeletionWatcher;
    friend class DeletionWatcher;
    bool mbIgnoreSelect;

    void    ReadResource();
    void    ClearResource();
    void impl_clear();
    DeletionWatcher * impl_setDeletionWatcher(DeletionWatcher* pNewWatcher);

protected:
#define MAX_FAMILIES            5
#define COUNT_BOUND_FUNC        13

#define UPDATE_FAMILY_LIST      0x0001
#define UPDATE_FAMILY           0x0002

    friend class DropListBox_Impl;
    friend class SfxTemplateControllerItem;

    SfxBindings*                pBindings;
    SfxTemplateControllerItem*  pBoundItems[COUNT_BOUND_FUNC];

    vcl::Window*                     pWindow;
    SfxModule*                  pModule;
    Idle*                       pIdle;

    ResId*                      m_pStyleFamiliesId;
    SfxStyleFamilies*           pStyleFamilies;
    SfxTemplateItem*            pFamilyState[MAX_FAMILIES];
    SfxStyleSheetBasePool*      pStyleSheetPool;
    StyleTreeListBox_Impl*      pTreeBox;
    SfxObjectShell*             pCurObjShell;
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager2 >
                                xModuleManager;
    DeletionWatcher*            m_pDeletionWatcher;

    SfxActionListBox            aFmtLb;
    ListBox                     aFilterLb;
    Size                        aSize;

    sal_uInt16                      nActFamily; // Id in the ToolBox = Position - 1
    sal_uInt16                      nActFilter; // FilterIdx
    sal_uInt16                      nAppFilter; // Filter, which has set the application (for automatic)

    bool                        bDontUpdate             :1,
                                bIsWater                :1,
                                bEnabled                :1,
                                bUpdate                 :1,
                                bUpdateFamily           :1,
                                bCanEdit                :1,
                                bCanDel                 :1,
                                bCanNew                 :1,
                                bCanHide                :1,
                                bCanShow                :1,
                                bWaterDisabled          :1,
                                bNewByExampleDisabled   :1,
                                bUpdateByExampleDisabled:1,
                                bTreeDrag               :1,
                                bHierarchical           :1,
                                m_bWantHierarchical     :1,
                                bBindingUpdate          :1;

    DECL_LINK( FilterSelectHdl, ListBox * );
    DECL_LINK( FmtSelectHdl, SvTreeListBox * );
    DECL_LINK( ApplyHdl, Control * );
    DECL_LINK( DropHdl, StyleTreeListBox_Impl * );
    DECL_LINK( TimeOut, Timer * );

    virtual void        EnableItem( sal_uInt16 /*nMesId*/, bool /*bCheck*/ = true ) {}
    virtual void        CheckItem( sal_uInt16 /*nMesId*/, bool /*bCheck*/ = true ) {}
    virtual bool        IsCheckedItem( sal_uInt16 /*nMesId*/ ) { return true; }
    virtual void        LoadedFamilies() {}
    void                Update() { UpdateStyles_Impl(UPDATE_FAMILY_LIST); }
    void                InvalidateBindings();
    virtual void        InsertFamilyItem( sal_uInt16 nId, const SfxStyleFamilyItem* pIten ) = 0;
    virtual void        EnableFamilyItem( sal_uInt16 nId, bool bEnabled = true ) = 0;
    virtual void        ClearFamilyList() = 0;
    virtual void        ReplaceUpdateButtonByMenu();

    void                NewHdl( void* );
    void                EditHdl( void* );
    void                DeleteHdl( void* );
    void                HideHdl( void* );
    void                ShowHdl( void* );

    bool                Execute_Impl( sal_uInt16 nId, const OUString& rStr, const OUString& rRefStr,
                                      sal_uInt16 nFamily, sal_uInt16 nMask = 0,
                                      sal_uInt16* pIdx = NULL, const sal_uInt16* pModifier = NULL );

    void                        UpdateStyles_Impl(sal_uInt16 nFlags);
    const SfxStyleFamilyItem*   GetFamilyItem_Impl() const;
    bool                    IsInitialized() const { return nActFamily != 0xffff; }
    void                        ResetFocus();
    void                        EnableDelete();
    void                        Initialize();
    void                        EnableHierarchical(bool);

    void                FilterSelect( sal_uInt16 nFilterIdx, bool bForce = false );
    void                SetFamilyState( sal_uInt16 nSlotId, const SfxTemplateItem* );
    void                SetWaterCanState( const SfxBoolItem* pItem );

    void                SelectStyle( const OUString& rStyle );
    bool            HasSelectedStyle() const;
    SfxStyleSheetBase  *GetSelectedStyle() const;
    void                FillTreeBox();
    void                Update_Impl();
    void                UpdateFamily_Impl();

    // In which FamilyState do I have to look , in order to get the
    // information of the ith Family in the pStyleFamilies.
    sal_uInt16              StyleNrToInfoOffset( sal_uInt16 i );

    void                Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) SAL_OVERRIDE;

    void                FamilySelect( sal_uInt16 nId );
    void                SetFamily( sal_uInt16 nId );
    void                ActionSelect( sal_uInt16 nId );

    sal_Int32           LoadFactoryStyleFilter( SfxObjectShell* i_pObjSh );
    void                SaveFactoryStyleFilter( SfxObjectShell* i_pObjSh, sal_Int32 i_nFilter );
    SfxObjectShell *    SaveSelection();

public:
    TYPEINFO_OVERRIDE();

    SfxCommonTemplateDialog_Impl( SfxBindings* pB, vcl::Window*, bool );
    virtual ~SfxCommonTemplateDialog_Impl();

    DECL_LINK( MenuSelectHdl, Menu * );

    virtual void        EnableEdit( bool b = true ) { bCanEdit = b; }
    void                EnableDel( bool b = true )  { bCanDel = b; }
    void                EnableNew( bool b = true )  { bCanNew = b; }
    void                EnableHide( bool b = true )  { bCanHide = b; }
    void                EnableShow( bool b = true )  { bCanShow = b; }

    vcl::Window*        GetWindow() { return pWindow; }

    void                EnableTreeDrag( bool b = true );
    void                EnableExample_Impl( sal_uInt16 nId, bool bEnable );
    SfxStyleFamily      GetActualFamily() const;
    OUString            GetSelectedEntry() const;
    SfxObjectShell*     GetObjectShell() const { return pCurObjShell; }

    inline bool         CanEdit( void ) const   { return bCanEdit; }
    inline bool         CanDel( void ) const    { return bCanDel; }
    inline bool         CanNew( void ) const    { return bCanNew; }
    inline bool         CanHide( void ) const    { return bCanHide; }
    inline bool         CanShow( void ) const    { return bCanShow; }

    // normally for derivates from SvTreeListBoxes, but in this case the dialog handles context menus
    PopupMenu*           CreateContextMenu( void );
};

class DropToolBox_Impl : public ToolBox, public DropTargetHelper
{
    SfxTemplateDialog_Impl&     rParent;
protected:
    virtual sal_Int8    AcceptDrop( const AcceptDropEvent& rEvt ) SAL_OVERRIDE;
    virtual sal_Int8    ExecuteDrop( const ExecuteDropEvent& rEvt ) SAL_OVERRIDE;
public:
    DropToolBox_Impl(vcl::Window* pParent, SfxTemplateDialog_Impl* pTemplateDialog);
    virtual ~DropToolBox_Impl();
};

class SfxTemplateDialog_Impl :  public SfxCommonTemplateDialog_Impl
{
private:
    friend class SfxTemplateControllerItem;
    friend class DropToolBox_Impl;
    friend class SfxTemplatePanelControl;

    vcl::Window* m_pFloat;
    bool            m_bZoomIn;
    DropToolBox_Impl    m_aActionTbL;
    ToolBox             m_aActionTbR;

    DECL_LINK( ToolBoxLSelect, ToolBox * );
    DECL_LINK( ToolBoxRSelect, ToolBox * );
    DECL_LINK( ToolBoxRClick, ToolBox * );
    DECL_LINK( MenuSelectHdl, Menu* );

protected:
    virtual void    EnableEdit( bool = true ) SAL_OVERRIDE;
    virtual void    EnableItem( sal_uInt16 nMesId, bool bCheck = true ) SAL_OVERRIDE;
    virtual void    CheckItem( sal_uInt16 nMesId, bool bCheck = true ) SAL_OVERRIDE;
    virtual bool    IsCheckedItem( sal_uInt16 nMesId ) SAL_OVERRIDE;
    virtual void    LoadedFamilies() SAL_OVERRIDE;
    virtual void    InsertFamilyItem( sal_uInt16 nId, const SfxStyleFamilyItem* pIten ) SAL_OVERRIDE;
    virtual void    EnableFamilyItem( sal_uInt16 nId, bool bEnabled = true ) SAL_OVERRIDE;
    virtual void    ClearFamilyList() SAL_OVERRIDE;
    virtual void    ReplaceUpdateButtonByMenu() SAL_OVERRIDE;

    void            Resize();
    Size            GetMinOutputSizePixel();

    void            updateFamilyImages();
    void            updateNonFamilyImages();

public:
    friend class SfxTemplateDialog;
    TYPEINFO_OVERRIDE();

    SfxTemplateDialog_Impl( SfxBindings*, SfxTemplatePanelControl* pDlgWindow );
    virtual ~SfxTemplateDialog_Impl();

    void Initialize();
};

#endif // INCLUDED_SFX2_SOURCE_INC_TEMPLDGI_HXX

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


<commit_before>#include "Mixer.h"
#include "SDL.h"
#include "IPlayer.h"
#include "Sample.h"
#include "ISynth.h"
#include "SequenceRow.h"
#include "ITrackState.h"
#include "IOscillator.h"
#include <math.h>
#include <cstdio>
#include <cstdlib>
#include <algorithm>

#ifndef TUNING
#define TUNING 440.0
#endif

#ifndef SAMPLERATE
#define SAMPLERATE 44100
#endif

Mixer::Mixer(IPlayer& player, ISynth& synth)
	: mPlayer(player), mSynth(synth), mSampleRate(0), mThread(NULL), mAudioOpened(false), mBuffer(NULL)
{
	mConvert = static_cast<SDL_AudioCVT*>(SDL_malloc(sizeof(SDL_AudioCVT)));
}

Mixer::~Mixer()
{
	mThreadRunning = false;

	if (mThread != NULL)
	{
		SDL_WaitThread(mThread, NULL);
	}

	free(mConvert);

	deinitAudio();
}

void Mixer::runThread()
{
	initAudio();
	SDL_PauseAudio(0);
}

/*void Mixer::runQueueThread()
{
	SDL_Thread *mThread = SDL_CreateThread(queueThread, "", this);
}*/

void Mixer::initAudio()
{
	SDL_AudioSpec want, have;

	SDL_memset(&want, 0, sizeof(want));

	want.freq = SAMPLERATE;
	want.format = AUDIO_S16SYS;
	want.channels = 2;
	want.samples = 1024;
	want.callback = static_cast<SDL_AudioCallback>(audioCallback);
	want.userdata = this;

	if (mAudioOpened)
		SDL_CloseAudio();

	mAudioOpened = false;

	if (SDL_OpenAudio(&want, &have) < 0)
	{
		/*fprintf(stderr, "Failed to open audio: %s\n", SDL_GetError());
		exit(1);*/
		return;
	}

	mAudioOpened = true;

	mSampleRate = have.freq;
	mSamples = 0;
	mBufferSize = have.samples;

	mBuffer = new Sample16[mBufferSize];

	SDL_BuildAudioCVT(mConvert, want.format, want.channels, have.freq, have.format, have.channels, have.freq);

	//printf("Got %d Hz format=%d (wanted %d Hz/%d) buffer = %d\n", have.freq, have.format, want.freq, want.format, want.samples);
}

void Mixer::deinitAudio()
{
	if (mAudioOpened)
		SDL_CloseAudio();

	if (mBuffer != NULL)
		delete[] mBuffer;
}

void Mixer::audioCallback(void* userdata, unsigned char* stream, int len)
{
	Mixer& mixer = *static_cast<Mixer*>(userdata);
	IPlayer& player = mixer.getPlayer();

	Sample16 *data = reinterpret_cast<Sample16*>(stream);
	int length = mixer.mBufferSize; //len / sizeof(Sample16);
	int chunk = mixer.getSampleRate() / player.getPlayerState().songRate;
	float hzConversion = static_cast<float>(TUNING / 2) / (float)mixer.getSampleRate(); // 1.0 = 440 Hz
	int samples = std::min(length, (chunk - mixer.getSamples() % chunk) % chunk);

	/*
	 * Render "leftovers" before the next sequence tick
	 */

	if (samples > 0)
	{
		mixer.getSynth().render(data, samples);
		mixer.getSynth().update(samples);
		mixer.getSamples() += samples;

		player.lock();
		player.getPlayerState().setUpdated(PlayerState::OscillatorProbe);
		player.unlock();
	}

	/*
	 * Fill the rest of the buffer and handle ticks
	 */

	for (int i = samples ; i < length ; i += chunk)
	{
		player.lock();

		player.runTick();
		player.advanceTick();

		for (int track = 0 ; track < SequenceRow::maxTracks ; ++track)
		{
			ITrackState& trackState = player.getTrackState(track);
			IOscillator& oscillator = mixer.getSynth().getOscillator(track);

			if (trackState.triggered)
			{
				trackState.triggered = false;
				oscillator.triggerNote();
			}

			oscillator.handleTrackState(trackState);
			oscillator.setFrequency(trackState.trackState.frequency * trackState.macroState.frequency * hzConversion);

			if (trackState.enabled)
				oscillator.setVolume(trackState.trackState.volume * trackState.macroState.volume / ITrackState::maxVolume);
			else
				oscillator.setVolume(0);
		}

		chunk = mixer.getSampleRate() / player.getPlayerState().songRate;

		player.unlock();

		int toBeWritten = std::min(length - i, chunk);

		mixer.getSynth().render(data + i, toBeWritten);
		mixer.getSynth().update(toBeWritten);
		mixer.getSamples() += toBeWritten;

		player.lock();
		player.getPlayerState().setUpdated(PlayerState::OscillatorProbe);
		player.unlock();
	}

	mixer.mConvert->len = length * sizeof(Sample16);
	mixer.mConvert->buf = stream;
	SDL_ConvertAudio(mixer.mConvert);
}

/*void Mixer::queueAudio()
{
	Player& player = getPlayer();
	int chunk = getSampleRate() / 50; // 50 Hz
	Sample16 *data = new Sample16[chunk];
	float hzConversion = 440.0f / (float)getSampleRate(); // 1.0 = 440 Hz

	player.lock();

	player.runTick();
	player.advanceTick();

	for (int track = 0 ; track < SequenceRow::maxTracks ; ++track)
	{
		TrackState& trackState = player.getTrackState(track);
		Oscillator& oscillator = getSynth().getOscillator(track);
		oscillator.setFrequency(trackState.trackState.frequency * trackState.macroState.frequency * hzConversion);
		oscillator.setVolume(trackState.trackState.volume);
	}

	player.unlock();

	getSynth().render(data, chunk);
	getSynth().update(chunk);
	getSamples() += chunk;

	SDL_QueueAudio(1, data, sizeof(Sample16) * chunk);

	delete[]data;
}

int Mixer::queueThread(void *userdata)
{
	Mixer& mixer = *static_cast<Mixer*>(userdata);

	while(mixer.isThreadRunning())
	{
		mixer.queueAudio();
		SDL_Delay(20);
	}

	return 0;
}*/

int Mixer::getSampleRate() const
{
	return mSampleRate;
}

IPlayer& Mixer::getPlayer()
{
	return mPlayer;
}

ISynth& Mixer::getSynth()
{
	return mSynth;
}

int& Mixer::getSamples()
{
	return mSamples;
}

bool Mixer::isThreadRunning() const
{
	return mThreadRunning;
}
<commit_msg>Audio deinit did not unset flag for opened audio<commit_after>#include "Mixer.h"
#include "SDL.h"
#include "IPlayer.h"
#include "Sample.h"
#include "ISynth.h"
#include "SequenceRow.h"
#include "ITrackState.h"
#include "IOscillator.h"
#include <math.h>
#include <cstdio>
#include <cstdlib>
#include <algorithm>

#ifndef TUNING
#define TUNING 440.0
#endif

#ifndef SAMPLERATE
#define SAMPLERATE 44100
#endif

Mixer::Mixer(IPlayer& player, ISynth& synth)
	: mPlayer(player), mSynth(synth), mSampleRate(0), mThread(NULL), mAudioOpened(false), mBuffer(NULL)
{
	mConvert = static_cast<SDL_AudioCVT*>(SDL_malloc(sizeof(SDL_AudioCVT)));
}

Mixer::~Mixer()
{
	mThreadRunning = false;

	if (mThread != NULL)
	{
		SDL_WaitThread(mThread, NULL);
	}

	deinitAudio();

	free(mConvert);
}

void Mixer::runThread()
{
	initAudio();
	SDL_PauseAudio(0);
}

/*void Mixer::runQueueThread()
{
	SDL_Thread *mThread = SDL_CreateThread(queueThread, "", this);
}*/

void Mixer::initAudio()
{
	SDL_AudioSpec want, have;

	SDL_memset(&want, 0, sizeof(want));

	want.freq = SAMPLERATE;
	want.format = AUDIO_S16SYS;
	want.channels = 2;
	want.samples = 1024;
	want.callback = static_cast<SDL_AudioCallback>(audioCallback);
	want.userdata = this;

	if (mAudioOpened)
		SDL_CloseAudio();

	mAudioOpened = false;

	if (SDL_OpenAudio(&want, &have) < 0)
	{
		/*fprintf(stderr, "Failed to open audio: %s\n", SDL_GetError());
		exit(1);*/
		return;
	}

	mAudioOpened = true;

	mSampleRate = have.freq;
	mSamples = 0;
	mBufferSize = have.samples;

	mBuffer = new Sample16[mBufferSize];

	SDL_BuildAudioCVT(mConvert, want.format, want.channels, have.freq, have.format, have.channels, have.freq);

	//printf("Got %d Hz format=%d (wanted %d Hz/%d) buffer = %d\n", have.freq, have.format, want.freq, want.format, want.samples);
}

void Mixer::deinitAudio()
{
	if (mAudioOpened)
		SDL_CloseAudio();

	mAudioOpened = false;

	if (mBuffer != NULL)
		delete[] mBuffer;
}

void Mixer::audioCallback(void* userdata, unsigned char* stream, int len)
{
	Mixer& mixer = *static_cast<Mixer*>(userdata);
	IPlayer& player = mixer.getPlayer();

	Sample16 *data = reinterpret_cast<Sample16*>(stream);
	int length = mixer.mBufferSize; //len / sizeof(Sample16);
	int chunk = mixer.getSampleRate() / player.getPlayerState().songRate;
	float hzConversion = static_cast<float>(TUNING / 2) / (float)mixer.getSampleRate(); // 1.0 = 440 Hz
	int samples = std::min(length, (chunk - mixer.getSamples() % chunk) % chunk);

	/*
	 * Render "leftovers" before the next sequence tick
	 */

	if (samples > 0)
	{
		mixer.getSynth().render(data, samples);
		mixer.getSynth().update(samples);
		mixer.getSamples() += samples;

		player.lock();
		player.getPlayerState().setUpdated(PlayerState::OscillatorProbe);
		player.unlock();
	}

	/*
	 * Fill the rest of the buffer and handle ticks
	 */

	for (int i = samples ; i < length ; i += chunk)
	{
		player.lock();

		player.runTick();
		player.advanceTick();

		for (int track = 0 ; track < SequenceRow::maxTracks ; ++track)
		{
			ITrackState& trackState = player.getTrackState(track);
			IOscillator& oscillator = mixer.getSynth().getOscillator(track);

			if (trackState.triggered)
			{
				trackState.triggered = false;
				oscillator.triggerNote();
			}

			oscillator.handleTrackState(trackState);
			oscillator.setFrequency(trackState.trackState.frequency * trackState.macroState.frequency * hzConversion);

			if (trackState.enabled)
				oscillator.setVolume(trackState.trackState.volume * trackState.macroState.volume / ITrackState::maxVolume);
			else
				oscillator.setVolume(0);
		}

		chunk = mixer.getSampleRate() / player.getPlayerState().songRate;

		player.unlock();

		int toBeWritten = std::min(length - i, chunk);

		mixer.getSynth().render(data + i, toBeWritten);
		mixer.getSynth().update(toBeWritten);
		mixer.getSamples() += toBeWritten;

		player.lock();
		player.getPlayerState().setUpdated(PlayerState::OscillatorProbe);
		player.unlock();
	}

	mixer.mConvert->len = length * sizeof(Sample16);
	mixer.mConvert->buf = stream;
	SDL_ConvertAudio(mixer.mConvert);
}

/*void Mixer::queueAudio()
{
	Player& player = getPlayer();
	int chunk = getSampleRate() / 50; // 50 Hz
	Sample16 *data = new Sample16[chunk];
	float hzConversion = 440.0f / (float)getSampleRate(); // 1.0 = 440 Hz

	player.lock();

	player.runTick();
	player.advanceTick();

	for (int track = 0 ; track < SequenceRow::maxTracks ; ++track)
	{
		TrackState& trackState = player.getTrackState(track);
		Oscillator& oscillator = getSynth().getOscillator(track);
		oscillator.setFrequency(trackState.trackState.frequency * trackState.macroState.frequency * hzConversion);
		oscillator.setVolume(trackState.trackState.volume);
	}

	player.unlock();

	getSynth().render(data, chunk);
	getSynth().update(chunk);
	getSamples() += chunk;

	SDL_QueueAudio(1, data, sizeof(Sample16) * chunk);

	delete[]data;
}

int Mixer::queueThread(void *userdata)
{
	Mixer& mixer = *static_cast<Mixer*>(userdata);

	while(mixer.isThreadRunning())
	{
		mixer.queueAudio();
		SDL_Delay(20);
	}

	return 0;
}*/

int Mixer::getSampleRate() const
{
	return mSampleRate;
}

IPlayer& Mixer::getPlayer()
{
	return mPlayer;
}

ISynth& Mixer::getSynth()
{
	return mSynth;
}

int& Mixer::getSamples()
{
	return mSamples;
}

bool Mixer::isThreadRunning() const
{
	return mThreadRunning;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>
#include <fstream>
#include <queue>
#include <cstring>
#include <string>
#include <set>
#include <map>
using namespace std;
const int COLUMN = 80;
const int ROW = 35;
queue<int> query(const string &sentence, const string &pattern) {
    int t_len = sentence.length();
	int p_len = pattern.length();
	// next[i] indicates the max-prefix of pattern[0, i](inclusive).
	vector<int> next(p_len);
	next[0] = 0;
	for (int i = 1; i < p_len; i++) {
		/* P is also the next element of end of max-prefix.
		 * e.g.char *s = ababac; s[5] = 'c', next[5 - 1] = 3, s[next[5 - 1]] = 'b'
		 */
		int p = next[i - 1];
		/* p > 0 means that there is at least one prefix in s[0, i - 1]
		 * pattern[p] != pattern[i] means the prefix doesn't match
	     */
		while (p > 0 && pattern[p] != pattern[i])
			/* IMPORTANT: if ABC XYZ has max-prefix 3, ABC has max-prefix 1
			 * then A = Z, which is a smaller prefix, but maybe match new element
			 */
			p = next[p - 1];
		/*	if p == 0 and pattern[p] != pattern[i] then there is no prefix for the element
		 *	else if pattern[p] == pattern[i] then we find a new prefix.
		 */
		if (pattern[p] != pattern[i]) next[i] = 0;
		else next[i] = p + 1;
	}
 	int i = 0, j = 0;
	queue<int> pos;
	while (i < t_len && j < p_len) {
		// if sentence and pattern corresponsive element match, then increase them.
		if (sentence[i] == pattern[j]) i++, j++;
		// if they don't match at all and j == 0 then sentence should move its index.
		else if (j == 0) i++;
		// Maybe there is other similar pattern in sentence, we only move j to next[j - 1]
		else j = next[j - 1];
		if (j == p_len) {
			pos.push(i - j);
			j = 0;
		}
	}
	return pos;
}

map<int, queue<int> > query(const vector<string> &article,
		const string pattern, int &cnt) {
    map<int, queue<int> > res;
	for (int i = 0; i < article.size(); i++) {
		res[i] = query(article[i], pattern);
		cnt += res[i].size();
	}
	return res;
}

ostream& newline(ostream &out) {
    static int num = 0;
    out << endl;
    if (++num > ROW) {
        getchar();
        system("clear");
        num = 0;
    }
    return out;
}

void print(ostream &out, const string& sentence, queue<int> pos) {
	int len = sentence.length();
	// Because of the screen limitation there is at most COLUMN character in a line.
	int line = len / COLUMN + (len % COLUMN ? 1: 0);
	int p = -1;
	if (!pos.empty()) {
		p = pos.front(); pos.pop();
	}
	// Divide the whole sentence into len / COLUMN( + 1) line.
	for (int i = 0; i < line; i++) {
		int offset = i * COLUMN;
		newline(out) << sentence.substr(offset, COLUMN);
		bool flag = true;
		// when the postion is in this line we print "^"
		while (p >= i * COLUMN && p < (i + 1) * COLUMN) {
			if (flag) {
				newline(out); flag = !flag;
			}
			// offset indicates the distance between "^"
			for (int blank = 0; blank < p - offset; blank++) out << " ";
			out << "^";
			if (!pos.empty()) {
			// update offset
				offset = p + 1; p = pos.front(); pos.pop();
			} else {
				p = -1;
			}
		}
	}
}

int main(int argc, char *argv[]) {
	if (argc < 2) {
		cout << "Need File name. Please try again." << endl;
		return -1;
	}
	ifstream fin(argv[1]);
	vector<string> article;
	string sentence;
	while (getline(fin, sentence))
		article.push_back(sentence);
	int cnt = 0;
	clock_t start = clock();
    map<int, queue<int> > line = query(article, argv[2], cnt);
	clock_t end = clock();
	printf("Find pattern %d, Elapse time: %.2f",
			cnt, (double)(end - start) / CLOCKS_PER_SEC);
	for (int i = 0; i < article.size(); i++)
		if (!line[i].empty()) {
            newline(cout);
			newline(cout) << "line (" << i << ")";
			print(cout, article[i], line[i]);
		}
	cout << endl;
	return 0;
}
<commit_msg>replace int with size_t in for loop<commit_after>#include <iostream>
#include <cstdlib>
#include <fstream>
#include <queue>
#include <cstring>
#include <string>
#include <set>
#include <map>
using namespace std;
const int COLUMN = 80;
const int ROW = 35;
queue<int> query(const string &sentence, const string &pattern) {
    int t_len = sentence.length();
	int p_len = pattern.length();
	// next[i] indicates the max-prefix of pattern[0, i](inclusive).
	vector<int> next(p_len);
	next[0] = 0;
	for (int i = 1; i < p_len; i++) {
		/* P is also the next element of end of max-prefix.
		 * e.g.char *s = ababac; s[5] = 'c', next[5 - 1] = 3, s[next[5 - 1]] = 'b'
		 */
		int p = next[i - 1];
		/* p > 0 means that there is at least one prefix in s[0, i - 1]
		 * pattern[p] != pattern[i] means the prefix doesn't match
	     */
		while (p > 0 && pattern[p] != pattern[i])
			/* IMPORTANT: if ABC XYZ has max-prefix 3, ABC has max-prefix 1
			 * then A = Z, which is a smaller prefix, but maybe match new element
			 */
			p = next[p - 1];
		/*	if p == 0 and pattern[p] != pattern[i] then there is no prefix for the element
		 *	else if pattern[p] == pattern[i] then we find a new prefix.
		 */
		if (pattern[p] != pattern[i]) next[i] = 0;
		else next[i] = p + 1;
	}
 	int i = 0, j = 0;
	queue<int> pos;
	while (i < t_len && j < p_len) {
		// if sentence and pattern corresponsive element match, then increase them.
		if (sentence[i] == pattern[j]) i++, j++;
		// if they don't match at all and j == 0 then sentence should move its index.
		else if (j == 0) i++;
		// Maybe there is other similar pattern in sentence, we only move j to next[j - 1]
		else j = next[j - 1];
		if (j == p_len) {
			pos.push(i - j);
			j = 0;
		}
	}
	return pos;
}

map<int, queue<int> > query(const vector<string> &article,
		const string pattern, int &cnt) {
    map<int, queue<int> > res;
	for (size_t i = 0; i < article.size(); i++) {
		res[i] = query(article[i], pattern);
		cnt += res[i].size();
	}
	return res;
}

ostream& newline(ostream &out) {
    static int num = 0;
    out << endl;
    if (++num > ROW) {
        getchar();
        system("clear");
        num = 0;
    }
    return out;
}

void print(ostream &out, const string& sentence, queue<int> pos) {
	int len = sentence.length();
	// Because of the screen limitation there is at most COLUMN character in a line.
	int line = len / COLUMN + (len % COLUMN ? 1: 0);
	int p = -1;
	if (!pos.empty()) {
		p = pos.front(); pos.pop();
	}
	// Divide the whole sentence into len / COLUMN( + 1) line.
	for (int i = 0; i < line; i++) {
		int offset = i * COLUMN;
		newline(out) << sentence.substr(offset, COLUMN);
		bool flag = true;
		// when the postion is in this line we print "^"
		while (p >= i * COLUMN && p < (i + 1) * COLUMN) {
			if (flag) {
				newline(out); flag = !flag;
			}
			// offset indicates the distance between "^"
			for (int blank = 0; blank < p - offset; blank++) out << " ";
			out << "^";
			if (!pos.empty()) {
			// update offset
				offset = p + 1; p = pos.front(); pos.pop();
			} else {
				p = -1;
			}
		}
	}
}

int main(int argc, char *argv[]) {
	if (argc < 2) {
		cout << "Need File name. Please try again." << endl;
		return -1;
	}
	ifstream fin(argv[1]);
	vector<string> article;
	string sentence;
	while (getline(fin, sentence))
		article.push_back(sentence);
	int cnt = 0;
	clock_t start = clock();
    map<int, queue<int> > line = query(article, argv[2], cnt);
	clock_t end = clock();
	printf("Find pattern %d, Elapse time: %.2f",
			cnt, (double)(end - start) / CLOCKS_PER_SEC);
	for (size_t i = 0; i < article.size(); i++)
		if (!line[i].empty()) {
            newline(cout);
			newline(cout) << "line (" << i << ")";
			print(cout, article[i], line[i]);
		}
	cout << endl;
	return 0;
}
<|endoftext|>


<commit_before>// Music.cpp
// 29. April 2017
// Created by:
// 		Bryan Burkhardt (bmburkhardt@alaska.edu)
// 		Alexander Eckert (aeckert@alaska.edu)
// 		Jeremiah Jacobson (jjjacobson2@alaska.edu)
// 		Jarye Murphy (jmurphy11@alaska.edu)
// 		Cameron Showalter (@alaska.edu)
//
// Source file for Music class

#include <iostream>
#include <memory>
#include <cmath>

#include "../include/Music.hpp"

Music::Music() {
	dirmgr = std::make_unique<DirectoryManager>();
	songList_ = std::move(dirmgr->getPlaylist());
	//if couldn't find song, don't try to play one
	if (songList_[songListIndex_] != "") {
		_music.openFromFile(songList_[songListIndex_]);
	}

	volSave_ = 100;
	isMuted_ = false;
}

void Music::callPlayPause() {
	if (_music.getStatus() != _music.Playing) {
		_music.play();
		std::cout << "Playing song: " << songList_[songListIndex_] << std::endl;
	}
	else {
		_music.pause();
	}
}

void Music::callNextSong() {
	if (songList_.size() != 0) {
		_music.stop();
		//if you're at the end, just go to the beginning (if press next)
		if (songListIndex_ == songList_.size() - 1) {
			songListIndex_ = 0;
		}
		else {
			songListIndex_ += 1;
		}
		_music.openFromFile(songList_[songListIndex_]);
		_music.play();
		std::cout << "Next song: " << songList_[songListIndex_] << " vecIndex: " << songListIndex_ << std::endl;
	}
}

void Music::callPrevSong() {
	if (songList_.size() != 0) {
		_music.stop();

		//if you're at the begining, just go to the end(if press prev)
		if (songListIndex_ == 0) {
			songListIndex_ = (unsigned int) (songList_.size() - 1);
		}
		else {
			songListIndex_ -= 1;
		}
		_music.openFromFile(songList_[songListIndex_]);
		_music.play();
		std::cout << "Previous song: " << songList_[songListIndex_] << " vecIndex: " << songListIndex_ << std::endl;
	}
}

void Music::callIncreaseVolume() {
	//first unmutes if muted
	if (isMuted_) {
		isMuted_ = false;
		_music.setVolume(volSave_); // unmute the music by restoring the volume to previous value
	}
	//if we change the " +1" for music.getVolume, make sure to reduce the "<= 99" in the if statement (100 - number) -CS
	if (_music.getVolume() <= 99) {
		_music.setVolume(ceil(_music.getVolume() + 1));
		std::cout << "The volume is " << _music.getVolume() << std::endl;
	}
}

void Music::callDecreaseVolume() {
	//first unmutes if muted
	if (isMuted_) {
		isMuted_ = false;
		_music.setVolume(volSave_); // unmute the music by restoring the volume to previous value
	}
	//if we change the " -1" for music.getVolume, make sure to change the ">= 1" in the if statement to the same value -CS
	if (_music.getVolume() >= 1) {
		_music.setVolume(floor(_music.getVolume() - 1));
		std::cout << "The volume is " << _music.getVolume() << std::endl;
	}
}

void Music::callMuteUnmute() {
	//if its not muted than set the volume to 0
	if (!isMuted_) {
		isMuted_ = true;
		volSave_ = (unsigned int) _music.getVolume();
		_music.setVolume(0);
		std::cout << "Muted player." << std::endl;
	}
	else {
		isMuted_ = false;
		_music.setVolume(volSave_); // unmute the music by restoring the volume to previous value
		std::cout << "Unmuted player." << std::endl;
	}
}<commit_msg>cast to float the volume<commit_after>// Music.cpp
// 29. April 2017
// Created by:
// 		Bryan Burkhardt (bmburkhardt@alaska.edu)
// 		Alexander Eckert (aeckert@alaska.edu)
// 		Jeremiah Jacobson (jjjacobson2@alaska.edu)
// 		Jarye Murphy (jmurphy11@alaska.edu)
// 		Cameron Showalter (@alaska.edu)
//
// Source file for Music class

#include <iostream>
#include <memory>
#include <cmath>

#include "../include/Music.hpp"

Music::Music() {
	dirmgr = std::make_unique<DirectoryManager>();
	songList_ = std::move(dirmgr->getPlaylist());
	//if couldn't find song, don't try to play one
	if (songList_[songListIndex_] != "") {
		_music.openFromFile(songList_[songListIndex_]);
	}

	volSave_ = 100;
	isMuted_ = false;
}

void Music::callPlayPause() {
	if (_music.getStatus() != _music.Playing) {
		_music.play();
		std::cout << "Playing song: " << songList_[songListIndex_] << std::endl;
	}
	else {
		_music.pause();
	}
}

void Music::callNextSong() {
	if (songList_.size() != 0) {
		_music.stop();
		//if you're at the end, just go to the beginning (if press next)
		if (songListIndex_ == songList_.size() - 1) {
			songListIndex_ = 0;
		}
		else {
			songListIndex_ += 1;
		}
		_music.openFromFile(songList_[songListIndex_]);
		_music.play();
		std::cout << "Next song: " << songList_[songListIndex_] << " vecIndex: " << songListIndex_ << std::endl;
	}
}

void Music::callPrevSong() {
	if (songList_.size() != 0) {
		_music.stop();

		//if you're at the begining, just go to the end(if press prev)
		if (songListIndex_ == 0) {
			songListIndex_ = (unsigned int) (songList_.size() - 1);
		}
		else {
			songListIndex_ -= 1;
		}
		_music.openFromFile(songList_[songListIndex_]);
		_music.play();
		std::cout << "Previous song: " << songList_[songListIndex_] << " vecIndex: " << songListIndex_ << std::endl;
	}
}

void Music::callIncreaseVolume() {
	//first unmutes if muted
	if (isMuted_) {
		isMuted_ = false;
		_music.setVolume(volSave_); // unmute the music by restoring the volume to previous value
	}
	//if we change the " +1" for music.getVolume, make sure to reduce the "<= 99" in the if statement (100 - number) -CS
	if (_music.getVolume() <= 99) {
		_music.setVolume((float) ceil(_music.getVolume() + 1));
		std::cout << "The volume is " << _music.getVolume() << std::endl;
	}
}

void Music::callDecreaseVolume() {
	//first unmutes if muted
	if (isMuted_) {
		isMuted_ = false;
		_music.setVolume(volSave_); // unmute the music by restoring the volume to previous value
	}
	//if we change the " -1" for music.getVolume, make sure to change the ">= 1" in the if statement to the same value -CS
	if (_music.getVolume() >= 1) {
		_music.setVolume((float) floor(_music.getVolume() - 1));
		std::cout << "The volume is " << _music.getVolume() << std::endl;
	}
}

void Music::callMuteUnmute() {
	//if its not muted than set the volume to 0
	if (!isMuted_) {
		isMuted_ = true;
		volSave_ = (unsigned int) _music.getVolume();
		_music.setVolume(0);
		std::cout << "Muted player." << std::endl;
	}
	else {
		isMuted_ = false;
		_music.setVolume(volSave_); // unmute the music by restoring the volume to previous value
		std::cout << "Unmuted player." << std::endl;
	}
}<|endoftext|>


<commit_before>
<commit_msg>Update Parse.cpp<commit_after>
#include "Parse.h"
//#define delimitor ";#"                    // token separators

using namespace std;

Parse::Parse() { }

void Parse::run()
{
    string input;
    Runcmd* inputCommand = NULL;
    while(true)
    {
        cout << "$ ";
        getline(cin, input);
        inputCommand = parse(input);
        if (inputCommand != NULL)
        {
            inputCommand->run();
            inputCommand = NULL;

        }

    }

}

Runcmd* Parse::parse(string& s)
{
    if (s.size() == 0) return NULL;
    if (s.find_first_not_of(" ") == string::npos) return NULL;

    if (s.find('#') != string::npos)
    {
        int loc = s.find('#');
        s = s.substr(0,loc);
        return parse(s);

    }

    for (unsigned i = 0; i < s.length(); i++)
    {
        if(s.at(i) == ';' )
        {

            int size = s.length();
            string lhs = s.substr(0,i);
            string rhs = s.substr(i+1,size);

            Semicolon* b = new Semicolon(parse(rhs),parse(lhs));
            return b;
        }

        if (s.at(i) == '|' && s.at(i+1) == '|')
        {

            int size = s.length();
            string lhs = s.substr(0,i);
            string rhs = s.substr(i+2,size);

            Or* c = new Or(parse(rhs),parse(lhs));
            return c;

        }

        if (s.at(i) == '&' && s.at(i+1) == '&')
        {

            int size = s.length();
            string lhs = s.substr(0,i);
            string rhs = s.substr(i+2,size);

            And* d = new And(parse(rhs),parse(lhs));
            return d;

        }

        if (s.at(i) == 'e' && s.at(i+1) == 'x' && s.at(i+2) == 'i' && s.at(i+3) == 't')
        {

            Exit* ex = new Exit();
            return ex;

        }

    }

    Execvpcmd* f = new Execvpcmd(s);
    return f;

}
<|endoftext|>


<commit_before>// This file is part of the HörTech Open Master Hearing Aid (openMHA)
// Copyright © 2005 2006 2010 2012 2013 2014 2015 2017 HörTech gGmbH
//
// openMHA is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// openMHA 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 Affero General Public License, version 3 for more details.
//
// You should have received a copy of the GNU Affero General Public License,
// version 3 along with openMHA.  If not, see <http://www.gnu.org/licenses/>.

#include "mha_plugin.hh"
#include "mha_signal.hh"
#include "mha_defs.h"
#include "mha_events.h"

namespace matrixmixer {

class cfg_t {
    public:
        cfg_t(std::vector<std::vector<float> > imixer,
              unsigned int ci,
              unsigned int co,
              unsigned int fragsize,
          unsigned int nfft);
    mha_wave_t* process(mha_wave_t*);
    mha_spec_t* process(mha_spec_t*);
private:
    MHASignal::waveform_t m;
    MHASignal::waveform_t wout;
    MHASignal::spectrum_t sout;
};

class matmix_t : public MHAPlugin::plugin_t<cfg_t> {
public:
    matmix_t(const algo_comm_t&,
             const std::string&,
             const std::string&);
    void prepare(mhaconfig_t&);
    mha_wave_t* process(mha_wave_t*);
    mha_spec_t* process(mha_spec_t*);
private:
    void update_m();
    MHAEvents::patchbay_t<matmix_t> patchbay;
    MHAParser::mfloat_t mixer;
    unsigned int ci;
    unsigned int co;
};

matmix_t::matmix_t(const algo_comm_t& iac,
                   const std::string&,
                   const std::string&)
    : MHAPlugin::plugin_t<cfg_t>("Matrix mixer",iac),
      mixer("mixer matrix, one row vector for each output channel","[[1 0];[0 1]]"),
      ci(0),
      co(0)
{
    insert_item("m",&mixer);
    patchbay.connect(&mixer.writeaccess,this,&matmix_t::update_m);
}

void matmix_t::prepare(mhaconfig_t& tf)
{
    co = mixer.data.size();
    ci = mixer.data[0].size();
    if( tf.channels != ci )
        throw MHA_Error(__FILE__,__LINE__,
                        "Matrixmixer: The mixer matrix has %d inputs, but the plugin received %d.",
                        ci,tf.channels);
    tf.channels = co;
    tftype = tf;
    update_m();
}

mha_wave_t* matmix_t::process(mha_wave_t* s)
{
    poll_config();
    return cfg->process(s);
}

mha_spec_t* matmix_t::process(mha_spec_t* s)
{
    poll_config();
    return cfg->process(s);
}

mha_wave_t* cfg_t::process(mha_wave_t* s)
{
    unsigned int ki,ko,kfr;
    if( s->num_frames != wout.num_frames )
        throw MHA_Error(__FILE__,__LINE__,
                        "matrixmixer: Invalid input fragment size (%d, expected %d).",
                        s->num_frames,wout.num_frames);
    if( s->num_channels != m.num_frames )
        throw MHA_Error(__FILE__,__LINE__,
                        "matrixmixer: Invalid input channel count (%d, expected %d).",
                        s->num_channels,m.num_frames);
    clear(wout);
    for(ko=0; ko<m.num_channels; ko++)
        for(ki=0; ki<m.num_frames; ki++)
            if( m(ki,ko) != 0 )
                for(kfr=0; kfr<wout.num_frames;kfr++)
                    wout(kfr,ko) += value(s,kfr,ki) * m(ki,ko);
    return &wout;
}

mha_spec_t* cfg_t::process(mha_spec_t* s)
{
    mha_complex_t temp;
    unsigned int ki,ko,kfr;
    if( s->num_frames != sout.num_frames )
        throw MHA_Error(__FILE__,__LINE__,
                        "matrixmixer: Invalid input fragment size (%d, expected %d).",
                        s->num_frames,wout.num_frames);
    if( s->num_channels != m.num_frames )
        throw MHA_Error(__FILE__,__LINE__,
                        "matrixmixer: Invalid input channel count (%d, expected %d).",
                        s->num_channels,m.num_frames);
    clear(sout);
    for(ko=0; ko<m.num_channels; ko++)
        for(ki=0; ki<m.num_frames; ki++)
            if( m(ki,ko) != 0 )
                for(kfr=0; kfr<sout.num_frames;kfr++){
        temp = value(s,kfr,ki);
        temp *= m(ki,ko);
                    sout(kfr,ko) += temp;
    }
    return &sout;
}

cfg_t::cfg_t(std::vector<std::vector<float> > imixer,
             unsigned int ci,
             unsigned int co,
             unsigned int fragsize,
             unsigned int nfft)
    : m(ci,co),
      wout(fragsize,co),
      sout(nfft/2+1,co)
{
    unsigned int ki, ko;
    if( co != imixer.size() ){
        throw MHA_Error(__FILE__,__LINE__,
                        "Mismatching number of input channels (co:%d, m:%d).",
                        co,imixer.size());
    }
    for(ko = 0; ko < co; ko++)
        if( imixer[ko].size() != ci ){
            throw MHA_Error(__FILE__,__LINE__,
                            "Mismatching number of input channels (ci:%d, m[%d]:%d).",
                            ci,ko,imixer[ko].size());
        }
    for(ko=0;ko<co;ko++)
        for(ki=0;ki<ci;ki++)
            m(ki,ko) = imixer[ko][ki];
}

void matmix_t::update_m(void)
{
    unsigned int lci = 1, lco = 1;
    if( (ci == 0) && (co == 0) ){
        lco = mixer.data.size();
        if( lco )
            lci = mixer.data[0].size();
    }else{
        lci = ci;
        lco = co;
    }
    push_config(new cfg_t(mixer.data,lci,lco,tftype.fragsize,tftype.fftlen));
}

}

MHAPLUGIN_CALLBACKS(matrixmixer,matrixmixer::matmix_t,wave,wave)
MHAPLUGIN_PROC_CALLBACK(matrixmixer,matrixmixer::matmix_t,spec,spec)
MHAPLUGIN_DOCUMENTATION(matrixmixer,"signalflow","")

// Local Variables:
// compile-command: "make"
// c-basic-offset: 4
// indent-tabs-mode: nil
// coding: utf-8-unix
// End:
<commit_msg>Add documentation to matrixmixer.<commit_after>// This file is part of the HörTech Open Master Hearing Aid (openMHA)
// Copyright © 2005 2006 2010 2012 2013 2014 2015 2017 2018 HörTech gGmbH
//
// openMHA is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// openMHA 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 Affero General Public License, version 3 for more details.
//
// You should have received a copy of the GNU Affero General Public License,
// version 3 along with openMHA.  If not, see <http://www.gnu.org/licenses/>.

#include "mha_plugin.hh"
#include "mha_signal.hh"
#include "mha_defs.h"
#include "mha_events.h"

namespace matrixmixer {

class cfg_t {
    public:
        cfg_t(std::vector<std::vector<float> > imixer,
              unsigned int ci,
              unsigned int co,
              unsigned int fragsize,
          unsigned int nfft);
    mha_wave_t* process(mha_wave_t*);
    mha_spec_t* process(mha_spec_t*);
private:
    MHASignal::waveform_t m;
    MHASignal::waveform_t wout;
    MHASignal::spectrum_t sout;
};

class matmix_t : public MHAPlugin::plugin_t<cfg_t> {
public:
    matmix_t(const algo_comm_t&,
             const std::string&,
             const std::string&);
    void prepare(mhaconfig_t&);
    mha_wave_t* process(mha_wave_t*);
    mha_spec_t* process(mha_spec_t*);
private:
    void update_m();
    MHAEvents::patchbay_t<matmix_t> patchbay;
    MHAParser::mfloat_t mixer;
    unsigned int ci;
    unsigned int co;
};

matmix_t::matmix_t(const algo_comm_t& iac,
                   const std::string&,
                   const std::string&)
    : MHAPlugin::plugin_t<cfg_t>("Matrix mixer plugin, can mix all input"
                                 " channels into\n"
                                 "any number of output channels"
                                 " with configurable weights.",iac),
      mixer("Mixer matrix, one row vector for each output channel.\n"
            "The number of columns must match the number of input channels.",
            "[[1 0];[0 1]]"),
      ci(0),
      co(0)
{
    insert_item("m",&mixer);
    patchbay.connect(&mixer.writeaccess,this,&matmix_t::update_m);
}

void matmix_t::prepare(mhaconfig_t& tf)
{
    co = mixer.data.size();
    ci = mixer.data[0].size();
    if( tf.channels != ci )
        throw MHA_Error(__FILE__,__LINE__,
                        "Matrixmixer: The mixer matrix has %d inputs, but the plugin received %d.",
                        ci,tf.channels);
    tf.channels = co;
    tftype = tf;
    update_m();
}

mha_wave_t* matmix_t::process(mha_wave_t* s)
{
    poll_config();
    return cfg->process(s);
}

mha_spec_t* matmix_t::process(mha_spec_t* s)
{
    poll_config();
    return cfg->process(s);
}

mha_wave_t* cfg_t::process(mha_wave_t* s)
{
    unsigned int ki,ko,kfr;
    if( s->num_frames != wout.num_frames )
        throw MHA_Error(__FILE__,__LINE__,
                        "matrixmixer: Invalid input fragment size (%d, expected %d).",
                        s->num_frames,wout.num_frames);
    if( s->num_channels != m.num_frames )
        throw MHA_Error(__FILE__,__LINE__,
                        "matrixmixer: Invalid input channel count (%d, expected %d).",
                        s->num_channels,m.num_frames);
    clear(wout);
    for(ko=0; ko<m.num_channels; ko++)
        for(ki=0; ki<m.num_frames; ki++)
            if( m(ki,ko) != 0 )
                for(kfr=0; kfr<wout.num_frames;kfr++)
                    wout(kfr,ko) += value(s,kfr,ki) * m(ki,ko);
    return &wout;
}

mha_spec_t* cfg_t::process(mha_spec_t* s)
{
    mha_complex_t temp;
    unsigned int ki,ko,kfr;
    if( s->num_frames != sout.num_frames )
        throw MHA_Error(__FILE__,__LINE__,
                        "matrixmixer: Invalid input fragment size (%d, expected %d).",
                        s->num_frames,wout.num_frames);
    if( s->num_channels != m.num_frames )
        throw MHA_Error(__FILE__,__LINE__,
                        "matrixmixer: Invalid input channel count (%d, expected %d).",
                        s->num_channels,m.num_frames);
    clear(sout);
    for(ko=0; ko<m.num_channels; ko++)
        for(ki=0; ki<m.num_frames; ki++)
            if( m(ki,ko) != 0 )
                for(kfr=0; kfr<sout.num_frames;kfr++){
        temp = value(s,kfr,ki);
        temp *= m(ki,ko);
                    sout(kfr,ko) += temp;
    }
    return &sout;
}

cfg_t::cfg_t(std::vector<std::vector<float> > imixer,
             unsigned int ci,
             unsigned int co,
             unsigned int fragsize,
             unsigned int nfft)
    : m(ci,co),
      wout(fragsize,co),
      sout(nfft/2+1,co)
{
    unsigned int ki, ko;
    if( co != imixer.size() ){
        throw MHA_Error(__FILE__,__LINE__,
                        "Mismatching number of input channels (co:%d, m:%d).",
                        co,imixer.size());
    }
    for(ko = 0; ko < co; ko++)
        if( imixer[ko].size() != ci ){
            throw MHA_Error(__FILE__,__LINE__,
                            "Mismatching number of input channels (ci:%d, m[%d]:%d).",
                            ci,ko,imixer[ko].size());
        }
    for(ko=0;ko<co;ko++)
        for(ki=0;ki<ci;ki++)
            m(ki,ko) = imixer[ko][ki];
}

void matmix_t::update_m(void)
{
    unsigned int lci = 1, lco = 1;
    if( (ci == 0) && (co == 0) ){
        lco = mixer.data.size();
        if( lco )
            lci = mixer.data[0].size();
    }else{
        lci = ci;
        lco = co;
    }
    push_config(new cfg_t(mixer.data,lci,lco,tftype.fragsize,tftype.fftlen));
}

}

MHAPLUGIN_CALLBACKS(matrixmixer,matrixmixer::matmix_t,wave,wave)
MHAPLUGIN_PROC_CALLBACK(matrixmixer,matrixmixer::matmix_t,spec,spec)
MHAPLUGIN_DOCUMENTATION(matrixmixer,"signalflow",
"The \\texttt{matrixmixer} plugin can combine the signal from multiple input "
"channels into any number of output channels, with defined mixing weights."
"\n\n"
"Example: To combine the two channels of a stereo signal into a single (mono) "
"channel, configure the \\texttt{matrixmixer} plugin variable \\texttt{m} as"
"\n\n"
"\\verb|m = [[1.0 1.0]]|"
"\n\n"
"which sets causes the first and the second channel to be multiplied with a "
"weight of 1 before they are mixed (by adding them together) to form a "
"single output channel."
"\n\n"
"It is also possible to mix the channels with weights different from 1:"
"\n\n"
"\\verb|m = [[1 0.5]]|"
"\n\n"
"This attenuates the second channel by multiplying all samples in that channel "
"with 0.5 before mixing it with the first channel.  "
"The configuration variable \\texttt{m} expects a matrix of float values.  "
"The examples above showed a matrix with only one row, which resulted in only "
"one output channel being produced by the \\texttt{matrixmixer} plugin. "
"To produce more output channels, more rows can be specified for matrix "
"\\texttt{m}:"
"\n\n"
"\\verb|m = [[1 0];[0 1]]|"
"\n\n"
"This is the identity matrix for two channels. "
"This matrix does not change the signal. "
"The following setting would swap the first two channels:"
"\n\n"
"\\verb|m = [[0 1];[1 0]]|"
"\n\n"
"The next setting would create a 4-channel signal output from a stereo signal, "
"where the first two channels are the original stereo channels, the third is "
"the sum of the two stereo channels, and the fourth output channel is the "
"difference of the two stereo channels:"
"\n\n"
"\\verb|m = [[0 1];[1 0];[1 1];[1 -1]]|"
"\n\n"
"The following example would duplicate a single input channel to two output"
" channels:"
"\n\n"
"\\verb|m = [[1];[1]]|"
"\n\n"
"To summarize and generalize, you need to configure the variable \\texttt{m} "
"with a matrix with float values. "
"The matrix needs to have as many columns as the \\texttt{matrixmixer} "
"receives input channels, and as many rows as you want \\texttt{matrixmixer} "
"to produce output channels."
)

// Local Variables:
// compile-command: "make"
// c-basic-offset: 4
// indent-tabs-mode: nil
// coding: utf-8-unix
// End:
<|endoftext|>


<commit_before>#include <Report.hh>

#include <unordered_set>
#include <cassert>

namespace report {

//------------------------------------------------------------------------------
// Layer Impl.
//------------------------------------------------------------------------------

std::ostream& operator<<(std::ostream &os, const Layer& layer) {
    os << "report::Layer["
       << " dim=" << layer.layer_id.dimension
       << ", level=" << layer.layer_id.level
       << ", num_nodes=" << layer.num_nodes
       << ", proper_children=" << layer.num_proper_children
       << ", shared_children=" << layer.num_shared_children
       << ", proper_content=" << layer.num_proper_content
       << ", shared_content=" << layer.num_shared_content
       << " ]";
    return os;
}

//------------------------------------------------------------------------------
// Node Impl.
//------------------------------------------------------------------------------

bool Link::operator==(const Link &link) const {
    Node &src = *source_node;
    Node &tgt = *target_node;
    Node &link_src = *link.source_node;
    Node &link_tgt = *link.target_node;

    return (src == link_src) &&
           (tgt == link_tgt);
}

bool Link::operator<(const Link &link) const {
    return (*source_node < *link.source_node) ||
            (*source_node == *link.source_node && *target_node < *link.target_node);
}

std::ostream& operator<<(std::ostream &os, const Node& node) {
    os << "report::Node["
       << " key=" << (node.key % 1017013)
       << ", dim=" << node.layer->layer_id.dimension
       << ", lev=" << node.layer->layer_id.level
       << ", type=" << (node.type == Node::INTERNAL_NODE ? "internal" : "leaf")
       << " ] @" << (((uint64_t) &node) % 10013);
    return os;
}

//------------------------------------------------------------------------------
// Internal Node Impl.
//------------------------------------------------------------------------------

InternalNode::InternalNode(Layer *layer, uint64_t key):
    Node(Node::INTERNAL_NODE, layer, key)
{}

void InternalNode::insertChildLink(Node *child_node, bool shared, std::string label) {

    assert(child_node->layer->layer_id.dimension == layer->layer_id.dimension &&
           child_node->layer->layer_id.level - 1 == layer->layer_id.level);

    children.push_back(Link( this, child_node, (shared ? Link::SHARED : Link::PROPER) + Link::CHILD , label));

    if (shared) {
        layer->num_shared_children++;
    }
    else {
        layer->num_proper_children++;
    }

}

void InternalNode::setContent(Node *content_node, bool shared) {

    content = Link(this, content_node, (shared ? Link::SHARED : Link::PROPER) + Link::CONTENT , "");

    if (shared) {
        layer->num_shared_content++;
    }
    else {
        layer->num_proper_content++;
    }
}

//------------------------------------------------------------------------------
// LeafNode Impl.
//------------------------------------------------------------------------------

LeafNode::LeafNode(Layer *layer, uint64_t key):
    Node(Node::LEAF_NODE, layer, key),
    info("")
{}

void LeafNode::setInfo(std::string info) {
    this->info = info;
}

std::string LeafNode::getInfo() const {
    return info;
}

//------------------------------------------------------------------------------
// Report Impl.
//------------------------------------------------------------------------------

bool compare(const Layer* a, const Layer* b) {
    return (*a < *b);
}

Layer *Report::getLayer(LayerId key) {

    Layer query_layer(key);

    auto it = std::lower_bound(layers.begin(), layers.end(), &query_layer, compare);

    Layer *layer = nullptr;
    if (it == layers.end() || !((*it)->layer_id == query_layer.layer_id)) {
        layer = new Layer(key);
        layers.insert(it, layer);
    }
    else {
        layer = *it;
    }

    return layer;

}

Report::Report(int dimensions):
    dimensions(dimensions)
{}

Node* Report::getNode(uint64_t node_key) const {

    // key cannot exist on node_map
    auto it = node_map.find(node_key);
    if (it != node_map.end()) {
        return it->second;
    }
    else {
        return nullptr;
    }
}

Node* Report::insertNode(uint64_t node_key, int dimension, int level) {

    // key cannot exist on node_map
    auto it = node_map.find(node_key);
    assert(it == node_map.end());

    Layer *layer = this->getLayer(LayerId(dimension,level));
    layer->num_nodes++;

    Node *node;
    if (dimension == this->dimensions - 1) {
        node = new LeafNode(layer, node_key);
    }
    else {
        node = new InternalNode(layer, node_key);
    }

    node_map[node_key] = node;

    // std::cout << "   " << *node << std::endl;

    return node;

}

/*
void Report::insertParentChildLink(Node *node, uint64_t child_key, bool shared, std::string label) {

    auto it = node_map.find(child_key);

    Node *child_node = nullptr;
    if (it == node_map.end()) {

        LayerKey layer_key(node->layer->key.dimension, node->layer->key.level+1);

        Layer *child_layer = getLayer(layer_key);

        Node *child_node = new InternalNode(child_layer);

        node_map[child_key] = child_node;

    }
    else {
        child_node = it->second;
    }

    node->insertChildLink(child_node, shared, label);

}

void Report::setContentLink(Node *node, uint64_t content_key, bool shared) {

    auto it = node_map.find(content_key);

    Node *content_node = nullptr;
    if (it == node_map.end()) {

        content_node = this->insertNode(content_key, node->layer->key.dimension+1);

        node_map[content_key] = content_node;

    }
    else {
        content_node = it->second;
    }

    node->setContent(content_node, shared);
}
*/

bool compare_node_pointers(Node *a, Node *b) {
    return (a->layer->layer_id < b->layer->layer_id ||
                (a->layer->layer_id == b->layer->layer_id && a->key < b->key));
}

struct Map {

    void insert(Node* node) {
        node_set.insert(node);
    }

    void consolidate() {
        std::vector<Node*> nodes(node_set.begin(),node_set.end());
        std::sort(nodes.begin(),nodes.end(),compare_node_pointers);
        for (Node* node: nodes) {
            // std::cout << "Key: " << node->key << " -> " << keys.size() << std::endl;
            keys.push_back(node->key);
        }
    }

    uint64_t operator[](uint64_t old_key) {
        // std::cout << "Querying Node: " << old_key << std::endl;

        auto it = std::find(keys.begin(), keys.end(), old_key);
        if (it == keys.end()) {
            throw std::exception();
        }
        return (it - keys.begin());
    }

    std::vector<uint64_t> keys;
    std::unordered_set<Node*> node_set;
};

bool compare_nodes(Node* a, Node *b) {
    return *a < *b;
}

bool compare_links(Link* a, Link *b) {
    return *a < *b;
}

void Report::updateToHumanReadableKeys()
{
    Map map;
    for (auto it: node_map) {
        Node *node = it.second;
        map.insert(node);
    }
    map.consolidate();
    // std::cout << "Number of Nodes: " << map.node_set.size() << std::endl;

    // create nodes vector
    for (auto it: node_map) {
        Node *node = it.second;
        node->key = map[node->key];
    }
}

void Report::updateLayerIndices()
{
    int i=0;
    for (Layer *layer: this->layers) {
        layer->index = i++;
    }
}

void report_python(std::ostream &os, Report &report) {

    os << "#" << std::endl;
    os << "# g.insertNode(<key>, <dimension>, <level>, <info>)" << std::endl;
    os << "# g.insertLink(<src_key>, <dst_key>, <label>, <content-or-child>, <shared-or-proper>)" << std::endl;
    os << "#" << std::endl;

    os << std::endl;

    std::vector<Node*> nodes;
    std::vector<Link*> links;

    // create nodes vector
    for (auto it: report.node_map) {
        Node *node = it.second;
        nodes.push_back(node);
    }

    // create nodes vector
    for (auto it: report.node_map) {
        Node *node = it.second;
        InternalNode *internal_node = node->asInternalNode();
        if (internal_node) {
            for (Link &link: internal_node->children) {
                links.push_back(&link);
            }
            {
                Link &link = internal_node->content;
                links.push_back(&link);
            }
        }
    }

    // sort nodes and links
    std::sort(nodes.begin(), nodes.end(), compare_nodes);
    std::sort(links.begin(), links.end(), compare_links);

    os << "g = Graph()" << std::endl;
    for (Node *node: nodes) {
        os << "g.insertNode("
           << node->key << ", "
           << node->layer->layer_id.dimension << ", "
           << node->layer->layer_id.level << ", "
           << "\"" << node->getInfo() << "\"" << ")" << std::endl;
    }

    for (Link *link: links) {
        os << "g.insertLink("
           << link->source_node->key << ", "
           << link->target_node->key << ", "
           << "\"" << link->label << "\"" << ", "
           << link->isContentLink() << ", "
           << link->isShared() << ")" << std::endl;
    }

}

void report_graphviz(std::ostream &os, Report &report) {
    std::vector<Node*> nodes;
    std::vector<Link*> links;

    // create nodes vector
    for (auto it: report.node_map) {
        Node *node = it.second;
        nodes.push_back(node);
    }

    // create nodes vector
    for (auto it: report.node_map) {
        Node *node = it.second;
        InternalNode *internal_node = node->asInternalNode();
        if (internal_node) {

            // std::cout << *internal_node->layer << std::endl;

            // children
            for (Link &link: internal_node->children) {
//                if (link.source_node == nullptr || link.target_node == nullptr )
//                    throw std::runtime_error("link needs to have its endpoints right");

                links.push_back(&link);
            }

            { // content
                Link &link = internal_node->content;

                if (link.source_node == nullptr || link.target_node == nullptr )
                    throw std::runtime_error("link needs to have its endpoints right");

                links.push_back(&link);
            }
        }
    }

    // sort nodes and links
    std::sort(nodes.begin(), nodes.end(), compare_nodes);
    std::sort(links.begin(), links.end(), compare_links);

    os << "digraph G {"          << std::endl;
    os << "   size = \"10,10\";" << std::endl;

    for (Layer *layer: report.layers) {

        os << "{ rank=same; " << std::endl;

        for (Node *node: layer->nodes) {
            os << "   " << node->key << " ";
            if (node->type == Node::INTERNAL_NODE) {
                os << "[label=\""
                   << node->layer->layer_id.dimension
                   << "-"
                   << node->layer->layer_id.level << "\", "
                   << "style=filled, "
                   << "color=" << ((node->layer->layer_id.dimension % 2 == 0) ? "lightgoldenrod3" : "lightpink1")
                   << "];";
            }
            else {
                os << "[style=filled, color=lightgray, shape=box, label=\""
                   << node->getInfo() << "\"" << "];";
            }
            os << std::endl;
        }

        os << "}" << std::endl;
    }

    for (Link *link: links) {
        os << "   "
           << link->source_node->key << " -> "
           << link->target_node->key << " ";
        os << "[ color=" << (link->isContentLink() ? (link->isShared() ? "lightblue3" : "blue") :
                                                     (link->isShared() ? "gray" : "black")) << ", "
           << "style=" << (link->isProper() ? "solid" : "dashed") << ","
           << "arrowhead=" << (link->isContentLink() ? "normal" : "none") << ","
           << "label=\"" << link->label << "\"]";
        os << std::endl;
    }
    os << "}" << std::endl;
}

} // end report namespace
<commit_msg>Minor fix on Report.cc: commented out an old test<commit_after>#include <Report.hh>

#include <unordered_set>
#include <cassert>

namespace report {

//------------------------------------------------------------------------------
// Layer Impl.
//------------------------------------------------------------------------------

std::ostream& operator<<(std::ostream &os, const Layer& layer) {
    os << "report::Layer["
       << " dim=" << layer.layer_id.dimension
       << ", level=" << layer.layer_id.level
       << ", num_nodes=" << layer.num_nodes
       << ", proper_children=" << layer.num_proper_children
       << ", shared_children=" << layer.num_shared_children
       << ", proper_content=" << layer.num_proper_content
       << ", shared_content=" << layer.num_shared_content
       << " ]";
    return os;
}

//------------------------------------------------------------------------------
// Node Impl.
//------------------------------------------------------------------------------

bool Link::operator==(const Link &link) const {
    Node &src = *source_node;
    Node &tgt = *target_node;
    Node &link_src = *link.source_node;
    Node &link_tgt = *link.target_node;

    return (src == link_src) &&
           (tgt == link_tgt);
}

bool Link::operator<(const Link &link) const {
    return (*source_node < *link.source_node) ||
            (*source_node == *link.source_node && *target_node < *link.target_node);
}

std::ostream& operator<<(std::ostream &os, const Node& node) {
    os << "report::Node["
       << " key=" << (node.key % 1017013)
       << ", dim=" << node.layer->layer_id.dimension
       << ", lev=" << node.layer->layer_id.level
       << ", type=" << (node.type == Node::INTERNAL_NODE ? "internal" : "leaf")
       << " ] @" << (((uint64_t) &node) % 10013);
    return os;
}

//------------------------------------------------------------------------------
// Internal Node Impl.
//------------------------------------------------------------------------------

InternalNode::InternalNode(Layer *layer, uint64_t key):
    Node(Node::INTERNAL_NODE, layer, key)
{}

void InternalNode::insertChildLink(Node *child_node, bool shared, std::string label) {

    assert(child_node->layer->layer_id.dimension == layer->layer_id.dimension &&
           child_node->layer->layer_id.level - 1 == layer->layer_id.level);

    children.push_back(Link( this, child_node, (shared ? Link::SHARED : Link::PROPER) + Link::CHILD , label));

    if (shared) {
        layer->num_shared_children++;
    }
    else {
        layer->num_proper_children++;
    }

}

void InternalNode::setContent(Node *content_node, bool shared) {

    content = Link(this, content_node, (shared ? Link::SHARED : Link::PROPER) + Link::CONTENT , "");

    if (shared) {
        layer->num_shared_content++;
    }
    else {
        layer->num_proper_content++;
    }
}

//------------------------------------------------------------------------------
// LeafNode Impl.
//------------------------------------------------------------------------------

LeafNode::LeafNode(Layer *layer, uint64_t key):
    Node(Node::LEAF_NODE, layer, key),
    info("")
{}

void LeafNode::setInfo(std::string info) {
    this->info = info;
}

std::string LeafNode::getInfo() const {
    return info;
}

//------------------------------------------------------------------------------
// Report Impl.
//------------------------------------------------------------------------------

bool compare(const Layer* a, const Layer* b) {
    return (*a < *b);
}

Layer *Report::getLayer(LayerId key) {

    Layer query_layer(key);

    auto it = std::lower_bound(layers.begin(), layers.end(), &query_layer, compare);

    Layer *layer = nullptr;
    if (it == layers.end() || !((*it)->layer_id == query_layer.layer_id)) {
        layer = new Layer(key);
        layers.insert(it, layer);
    }
    else {
        layer = *it;
    }

    return layer;

}

Report::Report(int dimensions):
    dimensions(dimensions)
{}

Node* Report::getNode(uint64_t node_key) const {

    // key cannot exist on node_map
    auto it = node_map.find(node_key);
    if (it != node_map.end()) {
        return it->second;
    }
    else {
        return nullptr;
    }
}

Node* Report::insertNode(uint64_t node_key, int dimension, int level) {

    // key cannot exist on node_map
    auto it = node_map.find(node_key);
    assert(it == node_map.end());

    Layer *layer = this->getLayer(LayerId(dimension,level));
    layer->num_nodes++;

    Node *node;
    if (dimension == this->dimensions - 1) {
        node = new LeafNode(layer, node_key);
    }
    else {
        node = new InternalNode(layer, node_key);
    }

    node_map[node_key] = node;

    // std::cout << "   " << *node << std::endl;

    return node;

}

/*
void Report::insertParentChildLink(Node *node, uint64_t child_key, bool shared, std::string label) {

    auto it = node_map.find(child_key);

    Node *child_node = nullptr;
    if (it == node_map.end()) {

        LayerKey layer_key(node->layer->key.dimension, node->layer->key.level+1);

        Layer *child_layer = getLayer(layer_key);

        Node *child_node = new InternalNode(child_layer);

        node_map[child_key] = child_node;

    }
    else {
        child_node = it->second;
    }

    node->insertChildLink(child_node, shared, label);

}

void Report::setContentLink(Node *node, uint64_t content_key, bool shared) {

    auto it = node_map.find(content_key);

    Node *content_node = nullptr;
    if (it == node_map.end()) {

        content_node = this->insertNode(content_key, node->layer->key.dimension+1);

        node_map[content_key] = content_node;

    }
    else {
        content_node = it->second;
    }

    node->setContent(content_node, shared);
}
*/

bool compare_node_pointers(Node *a, Node *b) {
    return (a->layer->layer_id < b->layer->layer_id ||
                (a->layer->layer_id == b->layer->layer_id && a->key < b->key));
}

struct Map {

    void insert(Node* node) {
        node_set.insert(node);
    }

    void consolidate() {
        std::vector<Node*> nodes(node_set.begin(),node_set.end());
        std::sort(nodes.begin(),nodes.end(),compare_node_pointers);
        for (Node* node: nodes) {
            // std::cout << "Key: " << node->key << " -> " << keys.size() << std::endl;
            keys.push_back(node->key);
        }
    }

    uint64_t operator[](uint64_t old_key) {
        // std::cout << "Querying Node: " << old_key << std::endl;

        auto it = std::find(keys.begin(), keys.end(), old_key);
        if (it == keys.end()) {
            throw std::exception();
        }
        return (it - keys.begin());
    }

    std::vector<uint64_t> keys;
    std::unordered_set<Node*> node_set;
};

bool compare_nodes(Node* a, Node *b) {
    return *a < *b;
}

bool compare_links(Link* a, Link *b) {
    return *a < *b;
}

void Report::updateToHumanReadableKeys()
{
    Map map;
    for (auto it: node_map) {
        Node *node = it.second;
        map.insert(node);
    }
    map.consolidate();
    // std::cout << "Number of Nodes: " << map.node_set.size() << std::endl;

    // create nodes vector
    for (auto it: node_map) {
        Node *node = it.second;
        node->key = map[node->key];
    }
}

void Report::updateLayerIndices()
{
    int i=0;
    for (Layer *layer: this->layers) {
        layer->index = i++;
    }
}

void report_python(std::ostream &os, Report &report) {

    os << "#" << std::endl;
    os << "# g.insertNode(<key>, <dimension>, <level>, <info>)" << std::endl;
    os << "# g.insertLink(<src_key>, <dst_key>, <label>, <content-or-child>, <shared-or-proper>)" << std::endl;
    os << "#" << std::endl;

    os << std::endl;

    std::vector<Node*> nodes;
    std::vector<Link*> links;

    // create nodes vector
    for (auto it: report.node_map) {
        Node *node = it.second;
        nodes.push_back(node);
    }

    // create nodes vector
    for (auto it: report.node_map) {
        Node *node = it.second;
        InternalNode *internal_node = node->asInternalNode();
        if (internal_node) {
            for (Link &link: internal_node->children) {
                links.push_back(&link);
            }
            {
                Link &link = internal_node->content;
                links.push_back(&link);
            }
        }
    }

    // sort nodes and links
    std::sort(nodes.begin(), nodes.end(), compare_nodes);
    std::sort(links.begin(), links.end(), compare_links);

    os << "g = Graph()" << std::endl;
    for (Node *node: nodes) {
        os << "g.insertNode("
           << node->key << ", "
           << node->layer->layer_id.dimension << ", "
           << node->layer->layer_id.level << ", "
           << "\"" << node->getInfo() << "\"" << ")" << std::endl;
    }

    for (Link *link: links) {
        os << "g.insertLink("
           << link->source_node->key << ", "
           << link->target_node->key << ", "
           << "\"" << link->label << "\"" << ", "
           << link->isContentLink() << ", "
           << link->isShared() << ")" << std::endl;
    }

}

void report_graphviz(std::ostream &os, Report &report) {
    std::vector<Node*> nodes;
    std::vector<Link*> links;

    // create nodes vector
    for (auto it: report.node_map) {
        Node *node = it.second;
        nodes.push_back(node);
    }

    // create nodes vector
    for (auto it: report.node_map) {
        Node *node = it.second;
        InternalNode *internal_node = node->asInternalNode();
        if (internal_node) {

            // std::cout << *internal_node->layer << std::endl;

            // children
            for (Link &link: internal_node->children) {
//                if (link.source_node == nullptr || link.target_node == nullptr )
//                    throw std::runtime_error("link needs to have its endpoints right");

                links.push_back(&link);
            }

            { // content
                Link &link = internal_node->content;

                // if (link.source_node == nullptr || link.target_node == nullptr )
                //    throw std::runtime_error("link needs to have its endpoints right");

                links.push_back(&link);
            }
        }
    }

    // sort nodes and links
    std::sort(nodes.begin(), nodes.end(), compare_nodes);
    std::sort(links.begin(), links.end(), compare_links);

    os << "digraph G {"          << std::endl;
    os << "   size = \"10,10\";" << std::endl;

    for (Layer *layer: report.layers) {

        os << "{ rank=same; " << std::endl;

        for (Node *node: layer->nodes) {
            os << "   " << node->key << " ";
            if (node->type == Node::INTERNAL_NODE) {
                os << "[label=\""
                   << node->layer->layer_id.dimension
                   << "-"
                   << node->layer->layer_id.level << "\", "
                   << "style=filled, "
                   << "color=" << ((node->layer->layer_id.dimension % 2 == 0) ? "lightgoldenrod3" : "lightpink1")
                   << "];";
            }
            else {
                os << "[style=filled, color=lightgray, shape=box, label=\""
                   << node->getInfo() << "\"" << "];";
            }
            os << std::endl;
        }

        os << "}" << std::endl;
    }

    for (Link *link: links) {
        os << "   "
           << link->source_node->key << " -> "
           << link->target_node->key << " ";
        os << "[ color=" << (link->isContentLink() ? (link->isShared() ? "lightblue3" : "blue") :
                                                     (link->isShared() ? "gray" : "black")) << ", "
           << "style=" << (link->isProper() ? "solid" : "dashed") << ","
           << "arrowhead=" << (link->isContentLink() ? "normal" : "none") << ","
           << "label=\"" << link->label << "\"]";
        os << std::endl;
    }
    os << "}" << std::endl;
}

} // end report namespace
<|endoftext|>