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

#undef SC_DLLIMPLEMENTATION

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

#pragma hdrstop

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

#include <sfx2/app.hxx>
#include <sfx2/docfile.hxx>
#include <svtools/ehdl.hxx>
#include <svtools/sfxecode.hxx>
#include <vcl/msgbox.hxx>

#include "global.hxx"
#include "docsh.hxx"
#include "viewdata.hxx"
#include "scresid.hxx"
#include "instbdlg.hrc"
#include "globstr.hrc"

#define SC_INSTBDLG_CXX
#include "instbdlg.hxx"

const long SC_DLG_BROWSE_OK     = 0;
const long SC_DLG_BROWSE_CANCEL = 1;

//==================================================================

ScInsertTableDlg::ScInsertTableDlg( Window* pParent, ScViewData& rData, SCTAB nTabCount, bool bFromFile )

    :   ModalDialog ( pParent, ScResId( RID_SCDLG_INSERT_TABLE ) ),
        //
        aBtnBefore      ( this, ScResId( RB_BEFORE ) ),
        aBtnBehind      ( this, ScResId( RB_BEHIND ) ),
        aFlPos          ( this, ScResId( FL_POSITION ) ),
        aFtCount        ( this, ScResId( FT_COUNT ) ),
        aNfCount        ( this, ScResId( NF_COUNT ) ),
        aFtName         ( this, ScResId( FT_NAME ) ),
        aEdName         ( this, ScResId( ED_TABNAME ) ),
        aLbTables       ( this, ScResId( LB_TABLES ) ),
        aFtPath         ( this, ScResId( FT_PATH ) ),
        aBtnBrowse      ( this, ScResId( BTN_BROWSE ) ),
        aBtnLink        ( this, ScResId( CB_LINK ) ),
        aFlTable        ( this, ScResId( FL_TABLE ) ),
        aBtnNew         ( this, ScResId( RB_NEW ) ),
        aBtnFromFile    ( this, ScResId( RB_FROMFILE ) ),
        aBtnOk          ( this, ScResId( BTN_OK ) ),
        aBtnCancel      ( this, ScResId( BTN_CANCEL ) ),
        aBtnHelp        ( this, ScResId( BTN_HELP ) ),
        rViewData       ( rData ),
        rDoc            ( *rData.GetDocument() ),
        pDocShTables    ( NULL ),
        nSelTabIndex    ( 0 ),
        nTableCount     (nTabCount)
{
    Init_Impl( bFromFile );
    FreeResource();
}

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

__EXPORT ScInsertTableDlg::~ScInsertTableDlg()
{
    if (pDocShTables)
        pDocShTables->DoClose();
}

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

void ScInsertTableDlg::Init_Impl( bool bFromFile )
{
    aBtnBrowse      .SetClickHdl( LINK( this, ScInsertTableDlg, BrowseHdl_Impl ) );
    aBtnNew         .SetClickHdl( LINK( this, ScInsertTableDlg, ChoiceHdl_Impl ) );
    aBtnFromFile    .SetClickHdl( LINK( this, ScInsertTableDlg, ChoiceHdl_Impl ) );
    aLbTables       .SetSelectHdl( LINK( this, ScInsertTableDlg, SelectHdl_Impl ) );
    aNfCount        .SetModifyHdl( LINK( this, ScInsertTableDlg, CountHdl_Impl));
    aBtnOk          .SetClickHdl( LINK( this, ScInsertTableDlg, DoEnterHdl ));
    aBtnBefore.Check();

    ScMarkData& rMark    = rViewData.GetMarkData();
    SCTAB   nTabSelCount = rMark.GetSelectCount();

    aNfCount.SetText( String::CreateFromInt32(nTableCount) );
    aNfCount.SetMax( MAXTAB - rDoc.GetTableCount() + 1 );

    if(nTableCount==1)
    {
        String aName;
        rDoc.CreateValidTabName( aName );
        aEdName.SetText( aName );
    }
    else
    {
        String aName=aFlTable.GetText();
        aName.AppendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
        aEdName.SetText( aName );
        aFtName.Disable();
        aEdName.Disable();
    }

    if( bFromFile )
    {
        aBtnFromFile.Check();
        SetFromTo_Impl();
    }
    else
    {
        aBtnNew.Check();
        SetNewTable_Impl();
    }
}

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

short __EXPORT ScInsertTableDlg::Execute()
{
    // Parent fuer InsertDocumentDialog und Doc-Manager setzen:

    Window* pOldDefParent = Application::GetDefDialogParent();
    Application::SetDefDialogParent( this );

    bool bExecute = true;
    if( aBtnFromFile.IsChecked() )
        bExecute = BrowseHdl_Impl( &aBtnBrowse ) == SC_DLG_BROWSE_OK;

    short nRet = bExecute ? ModalDialog::Execute() : RET_CANCEL;

    Application::SetDefDialogParent( pOldDefParent );

    return nRet;
}

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

void ScInsertTableDlg::SetNewTable_Impl()
{
    if (aBtnNew.IsChecked() )
    {
        aNfCount    .Enable();
        aFtCount    .Enable();
        aLbTables   .Disable();
        aFtPath     .Disable();
        aBtnBrowse  .Disable();
        aBtnLink    .Disable();

        if(nTableCount==1)
        {
            aEdName.Enable();
            aFtName.Enable();
        }
    }
}

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

void ScInsertTableDlg::SetFromTo_Impl()
{
    if (aBtnFromFile.IsChecked() )
    {
        aEdName     .Disable();
        aFtName     .Disable();
        aFtCount    .Disable();
        aNfCount    .Disable();
        aLbTables   .Enable();
        aFtPath     .Enable();
        aBtnBrowse  .Enable();
        aBtnLink    .Enable();
    }
}

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

void ScInsertTableDlg::FillTables_Impl( ScDocument* pSrcDoc )
{
    aLbTables.SetUpdateMode( FALSE );
    aLbTables.Clear();

    if ( pSrcDoc )
    {
        SCTAB nCount = pSrcDoc->GetTableCount();
        String aName;

        for ( SCTAB i=0; i<nCount; i++ )
        {
            pSrcDoc->GetName( i, aName );
            aLbTables.InsertEntry( aName );
        }
    }

    aLbTables.SetUpdateMode( TRUE );

    if(aLbTables.GetEntryCount()==1)
        aLbTables.SelectEntryPos(0);
}

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

const String* ScInsertTableDlg::GetFirstTable( USHORT* pN )
{
    const String* pStr = NULL;

    if ( aBtnNew.IsChecked() )
    {
        aStrCurSelTable = aEdName.GetText();
        pStr = &aStrCurSelTable;
    }
    else if ( nSelTabIndex < aLbTables.GetSelectEntryCount() )
    {
        aStrCurSelTable = aLbTables.GetSelectEntry( 0 );
        pStr = &aStrCurSelTable;
        if ( pN )
            *pN = aLbTables.GetSelectEntryPos( 0 );
        nSelTabIndex = 1;
    }

    return pStr;
}

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

const String* ScInsertTableDlg::GetNextTable( USHORT* pN )
{
    const String* pStr = NULL;

    if ( !aBtnNew.IsChecked() && nSelTabIndex < aLbTables.GetSelectEntryCount() )
    {
        aStrCurSelTable = aLbTables.GetSelectEntry( nSelTabIndex );
        pStr = &aStrCurSelTable;
        if ( pN )
            *pN = aLbTables.GetSelectEntryPos( nSelTabIndex );
        nSelTabIndex++;
    }

    return pStr;
}

//------------------------------------------------------------------------
// Handler:
//------------------------------------------------------------------------

IMPL_LINK( ScInsertTableDlg, CountHdl_Impl, NumericField*, EMPTYARG )
{
    nTableCount = static_cast<SCTAB>(aNfCount.GetValue());
    if ( nTableCount==1)
    {
        String aName;
        rDoc.CreateValidTabName( aName );
        aEdName.SetText( aName );
        aFtName.Enable();
        aEdName.Enable();
    }
    else
    {
        String aName=aFlTable.GetText();
        aName.AppendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
        aEdName.SetText( aName );
        aFtName.Disable();
        aEdName.Disable();
    }

    DoEnable_Impl();
    return 0;
}

//------------------------------------------------------------------------
IMPL_LINK( ScInsertTableDlg, ChoiceHdl_Impl, RadioButton*, EMPTYARG )
{
    if ( aBtnNew.IsChecked() )
        SetNewTable_Impl();
    else
        SetFromTo_Impl();

    DoEnable_Impl();
    return 0;
}

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

IMPL_LINK( ScInsertTableDlg, BrowseHdl_Impl, PushButton*, EMPTYARG )
{
        //  Dialog-Parent ist schon in Execute gesetzt worden

    SfxApplication* pApp = SFX_APP();
    SfxMedium* pMed = pApp->InsertDocumentDialog( 0, String::CreateFromAscii( ScDocShell::Factory().GetShortName() ) );

    if ( pMed )
    {
        //  ERRCTX_SFX_OPENDOC -> "Fehler beim Laden des Dokumentes"
        SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() );

        if (pDocShTables)
            pDocShTables->DoClose();        // delete passiert beim Zuweisen auf die Ref

        pMed->UseInteractionHandler( TRUE );    // to enable the filter options dialog

        pDocShTables = new ScDocShell;
        aDocShTablesRef = pDocShTables;

        Pointer aOldPtr( GetPointer() );
        SetPointer( Pointer( POINTER_WAIT ) );
        pDocShTables->DoLoad( pMed );
        SetPointer( aOldPtr );

        ULONG nErr = pDocShTables->GetErrorCode();
        if (nErr)
            ErrorHandler::HandleError( nErr );              // auch Warnings

        if ( !pDocShTables->GetError() )                    // nur Errors
        {
            FillTables_Impl( pDocShTables->GetDocument() );
            aFtPath.SetText( pDocShTables->GetTitle( SFX_TITLE_FULLNAME ) );
        }
        else
        {
            pDocShTables->DoClose();
            aDocShTablesRef.Clear();
            pDocShTables = NULL;

            FillTables_Impl( NULL );
            aFtPath.SetText( EMPTY_STRING );
        }
    }

    DoEnable_Impl();
    return pMed ? SC_DLG_BROWSE_OK : SC_DLG_BROWSE_CANCEL;
}

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

IMPL_LINK( ScInsertTableDlg, SelectHdl_Impl, MultiListBox*, EMPTYARG )
{
    DoEnable_Impl();
    return 0;
}

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

void ScInsertTableDlg::DoEnable_Impl()
{
    if ( aBtnNew.IsChecked() || ( pDocShTables && aLbTables.GetSelectEntryCount() ) )
        aBtnOk.Enable();
    else
        aBtnOk.Disable();
}

IMPL_LINK( ScInsertTableDlg, DoEnterHdl, PushButton*, EMPTYARG )
{
    if(nTableCount > 1 || rDoc.ValidTabName(aEdName.GetText()))
    {
        EndDialog(RET_OK);
    }
    else
    {
        String aErrMsg ( ScGlobal::GetRscString( STR_INVALIDTABNAME ) );
        USHORT nRet = ErrorBox( this,WinBits( WB_OK | WB_DEF_OK ),aErrMsg).Execute();
    }
    return 0;
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.9.346); FILE MERGED 2005/09/05 15:06:32 rt 1.9.346.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: instbdlg.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 22:10:05 $
 *
 *  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
 *
 ************************************************************************/

#undef SC_DLLIMPLEMENTATION

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

#pragma hdrstop

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

#include <sfx2/app.hxx>
#include <sfx2/docfile.hxx>
#include <svtools/ehdl.hxx>
#include <svtools/sfxecode.hxx>
#include <vcl/msgbox.hxx>

#include "global.hxx"
#include "docsh.hxx"
#include "viewdata.hxx"
#include "scresid.hxx"
#include "instbdlg.hrc"
#include "globstr.hrc"

#define SC_INSTBDLG_CXX
#include "instbdlg.hxx"

const long SC_DLG_BROWSE_OK     = 0;
const long SC_DLG_BROWSE_CANCEL = 1;

//==================================================================

ScInsertTableDlg::ScInsertTableDlg( Window* pParent, ScViewData& rData, SCTAB nTabCount, bool bFromFile )

    :   ModalDialog ( pParent, ScResId( RID_SCDLG_INSERT_TABLE ) ),
        //
        aBtnBefore      ( this, ScResId( RB_BEFORE ) ),
        aBtnBehind      ( this, ScResId( RB_BEHIND ) ),
        aFlPos          ( this, ScResId( FL_POSITION ) ),
        aFtCount        ( this, ScResId( FT_COUNT ) ),
        aNfCount        ( this, ScResId( NF_COUNT ) ),
        aFtName         ( this, ScResId( FT_NAME ) ),
        aEdName         ( this, ScResId( ED_TABNAME ) ),
        aLbTables       ( this, ScResId( LB_TABLES ) ),
        aFtPath         ( this, ScResId( FT_PATH ) ),
        aBtnBrowse      ( this, ScResId( BTN_BROWSE ) ),
        aBtnLink        ( this, ScResId( CB_LINK ) ),
        aFlTable        ( this, ScResId( FL_TABLE ) ),
        aBtnNew         ( this, ScResId( RB_NEW ) ),
        aBtnFromFile    ( this, ScResId( RB_FROMFILE ) ),
        aBtnOk          ( this, ScResId( BTN_OK ) ),
        aBtnCancel      ( this, ScResId( BTN_CANCEL ) ),
        aBtnHelp        ( this, ScResId( BTN_HELP ) ),
        rViewData       ( rData ),
        rDoc            ( *rData.GetDocument() ),
        pDocShTables    ( NULL ),
        nSelTabIndex    ( 0 ),
        nTableCount     (nTabCount)
{
    Init_Impl( bFromFile );
    FreeResource();
}

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

__EXPORT ScInsertTableDlg::~ScInsertTableDlg()
{
    if (pDocShTables)
        pDocShTables->DoClose();
}

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

void ScInsertTableDlg::Init_Impl( bool bFromFile )
{
    aBtnBrowse      .SetClickHdl( LINK( this, ScInsertTableDlg, BrowseHdl_Impl ) );
    aBtnNew         .SetClickHdl( LINK( this, ScInsertTableDlg, ChoiceHdl_Impl ) );
    aBtnFromFile    .SetClickHdl( LINK( this, ScInsertTableDlg, ChoiceHdl_Impl ) );
    aLbTables       .SetSelectHdl( LINK( this, ScInsertTableDlg, SelectHdl_Impl ) );
    aNfCount        .SetModifyHdl( LINK( this, ScInsertTableDlg, CountHdl_Impl));
    aBtnOk          .SetClickHdl( LINK( this, ScInsertTableDlg, DoEnterHdl ));
    aBtnBefore.Check();

    ScMarkData& rMark    = rViewData.GetMarkData();
    SCTAB   nTabSelCount = rMark.GetSelectCount();

    aNfCount.SetText( String::CreateFromInt32(nTableCount) );
    aNfCount.SetMax( MAXTAB - rDoc.GetTableCount() + 1 );

    if(nTableCount==1)
    {
        String aName;
        rDoc.CreateValidTabName( aName );
        aEdName.SetText( aName );
    }
    else
    {
        String aName=aFlTable.GetText();
        aName.AppendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
        aEdName.SetText( aName );
        aFtName.Disable();
        aEdName.Disable();
    }

    if( bFromFile )
    {
        aBtnFromFile.Check();
        SetFromTo_Impl();
    }
    else
    {
        aBtnNew.Check();
        SetNewTable_Impl();
    }
}

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

short __EXPORT ScInsertTableDlg::Execute()
{
    // Parent fuer InsertDocumentDialog und Doc-Manager setzen:

    Window* pOldDefParent = Application::GetDefDialogParent();
    Application::SetDefDialogParent( this );

    bool bExecute = true;
    if( aBtnFromFile.IsChecked() )
        bExecute = BrowseHdl_Impl( &aBtnBrowse ) == SC_DLG_BROWSE_OK;

    short nRet = bExecute ? ModalDialog::Execute() : RET_CANCEL;

    Application::SetDefDialogParent( pOldDefParent );

    return nRet;
}

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

void ScInsertTableDlg::SetNewTable_Impl()
{
    if (aBtnNew.IsChecked() )
    {
        aNfCount    .Enable();
        aFtCount    .Enable();
        aLbTables   .Disable();
        aFtPath     .Disable();
        aBtnBrowse  .Disable();
        aBtnLink    .Disable();

        if(nTableCount==1)
        {
            aEdName.Enable();
            aFtName.Enable();
        }
    }
}

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

void ScInsertTableDlg::SetFromTo_Impl()
{
    if (aBtnFromFile.IsChecked() )
    {
        aEdName     .Disable();
        aFtName     .Disable();
        aFtCount    .Disable();
        aNfCount    .Disable();
        aLbTables   .Enable();
        aFtPath     .Enable();
        aBtnBrowse  .Enable();
        aBtnLink    .Enable();
    }
}

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

void ScInsertTableDlg::FillTables_Impl( ScDocument* pSrcDoc )
{
    aLbTables.SetUpdateMode( FALSE );
    aLbTables.Clear();

    if ( pSrcDoc )
    {
        SCTAB nCount = pSrcDoc->GetTableCount();
        String aName;

        for ( SCTAB i=0; i<nCount; i++ )
        {
            pSrcDoc->GetName( i, aName );
            aLbTables.InsertEntry( aName );
        }
    }

    aLbTables.SetUpdateMode( TRUE );

    if(aLbTables.GetEntryCount()==1)
        aLbTables.SelectEntryPos(0);
}

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

const String* ScInsertTableDlg::GetFirstTable( USHORT* pN )
{
    const String* pStr = NULL;

    if ( aBtnNew.IsChecked() )
    {
        aStrCurSelTable = aEdName.GetText();
        pStr = &aStrCurSelTable;
    }
    else if ( nSelTabIndex < aLbTables.GetSelectEntryCount() )
    {
        aStrCurSelTable = aLbTables.GetSelectEntry( 0 );
        pStr = &aStrCurSelTable;
        if ( pN )
            *pN = aLbTables.GetSelectEntryPos( 0 );
        nSelTabIndex = 1;
    }

    return pStr;
}

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

const String* ScInsertTableDlg::GetNextTable( USHORT* pN )
{
    const String* pStr = NULL;

    if ( !aBtnNew.IsChecked() && nSelTabIndex < aLbTables.GetSelectEntryCount() )
    {
        aStrCurSelTable = aLbTables.GetSelectEntry( nSelTabIndex );
        pStr = &aStrCurSelTable;
        if ( pN )
            *pN = aLbTables.GetSelectEntryPos( nSelTabIndex );
        nSelTabIndex++;
    }

    return pStr;
}

//------------------------------------------------------------------------
// Handler:
//------------------------------------------------------------------------

IMPL_LINK( ScInsertTableDlg, CountHdl_Impl, NumericField*, EMPTYARG )
{
    nTableCount = static_cast<SCTAB>(aNfCount.GetValue());
    if ( nTableCount==1)
    {
        String aName;
        rDoc.CreateValidTabName( aName );
        aEdName.SetText( aName );
        aFtName.Enable();
        aEdName.Enable();
    }
    else
    {
        String aName=aFlTable.GetText();
        aName.AppendAscii(RTL_CONSTASCII_STRINGPARAM("..."));
        aEdName.SetText( aName );
        aFtName.Disable();
        aEdName.Disable();
    }

    DoEnable_Impl();
    return 0;
}

//------------------------------------------------------------------------
IMPL_LINK( ScInsertTableDlg, ChoiceHdl_Impl, RadioButton*, EMPTYARG )
{
    if ( aBtnNew.IsChecked() )
        SetNewTable_Impl();
    else
        SetFromTo_Impl();

    DoEnable_Impl();
    return 0;
}

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

IMPL_LINK( ScInsertTableDlg, BrowseHdl_Impl, PushButton*, EMPTYARG )
{
        //  Dialog-Parent ist schon in Execute gesetzt worden

    SfxApplication* pApp = SFX_APP();
    SfxMedium* pMed = pApp->InsertDocumentDialog( 0, String::CreateFromAscii( ScDocShell::Factory().GetShortName() ) );

    if ( pMed )
    {
        //  ERRCTX_SFX_OPENDOC -> "Fehler beim Laden des Dokumentes"
        SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() );

        if (pDocShTables)
            pDocShTables->DoClose();        // delete passiert beim Zuweisen auf die Ref

        pMed->UseInteractionHandler( TRUE );    // to enable the filter options dialog

        pDocShTables = new ScDocShell;
        aDocShTablesRef = pDocShTables;

        Pointer aOldPtr( GetPointer() );
        SetPointer( Pointer( POINTER_WAIT ) );
        pDocShTables->DoLoad( pMed );
        SetPointer( aOldPtr );

        ULONG nErr = pDocShTables->GetErrorCode();
        if (nErr)
            ErrorHandler::HandleError( nErr );              // auch Warnings

        if ( !pDocShTables->GetError() )                    // nur Errors
        {
            FillTables_Impl( pDocShTables->GetDocument() );
            aFtPath.SetText( pDocShTables->GetTitle( SFX_TITLE_FULLNAME ) );
        }
        else
        {
            pDocShTables->DoClose();
            aDocShTablesRef.Clear();
            pDocShTables = NULL;

            FillTables_Impl( NULL );
            aFtPath.SetText( EMPTY_STRING );
        }
    }

    DoEnable_Impl();
    return pMed ? SC_DLG_BROWSE_OK : SC_DLG_BROWSE_CANCEL;
}

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

IMPL_LINK( ScInsertTableDlg, SelectHdl_Impl, MultiListBox*, EMPTYARG )
{
    DoEnable_Impl();
    return 0;
}

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

void ScInsertTableDlg::DoEnable_Impl()
{
    if ( aBtnNew.IsChecked() || ( pDocShTables && aLbTables.GetSelectEntryCount() ) )
        aBtnOk.Enable();
    else
        aBtnOk.Disable();
}

IMPL_LINK( ScInsertTableDlg, DoEnterHdl, PushButton*, EMPTYARG )
{
    if(nTableCount > 1 || rDoc.ValidTabName(aEdName.GetText()))
    {
        EndDialog(RET_OK);
    }
    else
    {
        String aErrMsg ( ScGlobal::GetRscString( STR_INVALIDTABNAME ) );
        USHORT nRet = ErrorBox( this,WinBits( WB_OK | WB_DEF_OK ),aErrMsg).Execute();
    }
    return 0;
}

<|endoftext|>


<commit_before>#include <curl/curl.h>
# include <iostream>
#include <stdio.h>

#include <sys/stat.h>
#include <fcntl.h>
#include <url/params.hpp>
#include <yadisk/client.hpp>
#include <boost/algorithm/string/join.hpp>

#include <sstream>
using std::stringstream;

#include "callbacks.hpp"
#include "quote.hpp"

namespace yadisk
{
    static const std::string api_url = "https://cloud-api.yandex.net/v1/disk/resources";

    Client::Client(string token_) : token{token_} {}

    auto Client::upload(url::path to, fs::path from, bool overwrite, std::list<string> fields) -> json {
   	 CURL *curl;

  	struct stat file_info;

  	FILE *fd;
 	url::params_t url_params;
	struct curl_slist *header_list = nullptr;
	std::string auth_header;

 	fs::path p(fs::current_path());
	url_params["path"] = quote(to.string(), curl);
	url_params["overwrite"] = overwrite;
	url_params["fields"] = boost::algorithm::join(fields, ",");
	std::string url = api_url + "/upload?" + url_params.string();

	struct curl_slist *head_list = nullptr;
  	auth_head = "Authorization: OAuth " + token;
	head_list = curl_slist_append(head_list, auth_head.c_str());

  	fd = fopen("C:\\file.txt", "w");  //открытие файла для загрузки
 	if(!fd)
    	return 1; //не может продолжить
   	// получаем размер файла
  	if(fstat(fileno(fd), &file_info)!=0;
    	return 1; /* can't continue */

  	curl = curl_easy_init();
	//  if(curl) {
     	//выбор места для загрузки
    	curl_easy_setopt(curl, CURLOPT_URL,url.c_str());
    	curl_easy_setopt(curl, CURLOPT_READDATA, &response);
    	curl_easy_setopt(curl, CURLOPT_READFUNCTION, write<stringstream>);
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, head_list);
    	auto res = curl_easy_perform(curl);
     	curl_easy_cleanup(curl);
     	if (res != CURLE_OK) return json();
	auto ans = json::parse(res);
	return ans;
    	 //загрузка по URL
    	curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
 	curl_easy_setopt(curl, CURLOPT_PUT, 1L);
     	//чтения файла
    	curl_easy_setopt(curl, CURLOPT_READDATA, fd);
    	//устанавливаем размер файла для отправки
    	curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,(curl_off_t)file_info.st_size);
     	//для облегчения трассировки
    	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    	auto response_code = curl_easy_perform(curl);
	curl_slist_free_all(head_list);
	curl_easy_cleanup(curl);
	if (response_code != CURLE_OK) return json();
	auto answer = json::parse(response_code);
	return answer;
     	return 0;
}
}
<commit_msg>Update client.cpp<commit_after>
    auto Client::upload(url::path to, fs::path from, bool overwrite, std::list<string> fields) -> json {
   	 CURL *curl;

  	struct stat file_info;

  	FILE *fd;
 	url::params_t url_params;
	struct curl_slist *header_list = nullptr;
	std::string auth_header;

 	fs::path p(fs::current_path());
	url_params["path"] = quote(to.string(), curl);
	url_params["overwrite"] = overwrite;
	url_params["fields"] = boost::algorithm::join(fields, ",");
	std::string url = api_url + "/upload?" + url_params.string();

	struct curl_slist *head_list = nullptr;
  	auth_head = "Authorization: OAuth " + token;
	head_list = curl_slist_append(head_list, auth_head.c_str());

  	fd = fopen("C:\\file.txt", "w");  //открытие файла для загрузки
 	if(!fd)
    	return 1; //не может продолжить
   	// получаем размер файла
  	if(fstat(fileno(fd), &file_info)!=0;
    	return 1; /* can't continue */

  	curl = curl_easy_init();
	//  if(curl) {
     	//выбор места для загрузки
    	curl_easy_setopt(curl, CURLOPT_URL,url.c_str());
    	curl_easy_setopt(curl, CURLOPT_READDATA, &response);
    	curl_easy_setopt(curl, CURLOPT_READFUNCTION, write<stringstream>);
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, head_list);
    	auto res = curl_easy_perform(curl);
     	curl_easy_cleanup(curl);
     	return http_response_code == 200;
	return ans;
    	 //загрузка по URL
    	curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
 	curl_easy_setopt(curl, CURLOPT_PUT, 1L);
     	//чтения файла
    	curl_easy_setopt(curl, CURLOPT_READDATA, fd);
    	//устанавливаем размер файла для отправки
    	curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,(curl_off_t)file_info.st_size);
     	//для облегчения трассировки
    	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    	auto response_code = curl_easy_perform(curl);
	curl_slist_free_all(head_list);
	curl_easy_cleanup(curl);
	if (response_code != CURLE_OK) return json();
	return http_response_code == 201;
     	return 0;
}

<|endoftext|>


<commit_before>/**
 * @file kmeans.cpp
 * @brief mex interface for kmeans
 * @author Kota Yamaguchi
 * @date 2011
 */
#include "mexopencv.hpp"
using namespace std;
using namespace cv;

/** KMeans initalization types for option processing
 */
const ConstMap<std::string,int> Initialization = ConstMap<std::string,int>
	("Random",KMEANS_RANDOM_CENTERS)
	("PP",KMEANS_PP_CENTERS);

/**
 * Main entry called from Matlab
 * @param nlhs number of left-hand-side arguments
 * @param plhs pointers to mxArrays in the left-hand-side
 * @param nrhs number of right-hand-side arguments
 * @param prhs pointers to mxArrays in the right-hand-side
 */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
	// Check the number of arguments
	if (nrhs<2 || ((nrhs%2)!=0) || nlhs>3)
        mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");

	// Argument vector
	vector<MxArray> rhs(prhs,prhs+nrhs);
	Mat samples(rhs[0].toMat(CV_32F));
	int clusterCount = rhs[1].toInt();
	Mat labels;
	TermCriteria criteria;
	int attempts=10;
	int flags = KMEANS_RANDOM_CENTERS;
	Mat centers;
	for (int i=2; i<nrhs; i+=2) {
		string key = rhs[i].toString();
		if (key=="InitialLabels")
			labels = rhs[i+1].toMat(CV_32S);
		else if (key=="Criteria")
			criteria = rhs[i+1].toTermCriteria();
		else if (key=="Attempts")
			attempts = rhs[i+1].toInt();
		else if (key=="Initialization")
			flags = Initialization[rhs[i+1].toString()];
		else
			mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
	}
	flags |= (labels.empty()) ? 0 : KMEANS_USE_INITIAL_LABELS;

	// Process
	double d = kmeans(samples, clusterCount, labels, criteria, attempts, flags,
		centers);
	plhs[0] = MxArray(labels);
	if (nlhs>1)
		plhs[1] = MxArray(centers);
	if (nlhs>2)
		plhs[2] = MxArray(d);
}
<commit_msg>Fixed a version compatibility<commit_after>/**
 * @file kmeans.cpp
 * @brief mex interface for kmeans
 * @author Kota Yamaguchi
 * @date 2011
 */
#include "mexopencv.hpp"
using namespace std;
using namespace cv;

/** KMeans initalization types for option processing
 */
const ConstMap<std::string,int> Initialization = ConstMap<std::string,int>
	("Random",KMEANS_RANDOM_CENTERS)
	("PP",KMEANS_PP_CENTERS);

/**
 * Main entry called from Matlab
 * @param nlhs number of left-hand-side arguments
 * @param plhs pointers to mxArrays in the left-hand-side
 * @param nrhs number of right-hand-side arguments
 * @param prhs pointers to mxArrays in the right-hand-side
 */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
	// Check the number of arguments
	if (nrhs<2 || ((nrhs%2)!=0) || nlhs>3)
        mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");

	// Argument vector
	vector<MxArray> rhs(prhs,prhs+nrhs);
	Mat samples(rhs[0].toMat(CV_32F));
	int clusterCount = rhs[1].toInt();
	Mat labels;
	TermCriteria criteria;
	int attempts=10;
	int flags = KMEANS_RANDOM_CENTERS;
	Mat centers;
	for (int i=2; i<nrhs; i+=2) {
		string key = rhs[i].toString();
		if (key=="InitialLabels")
			labels = rhs[i+1].toMat(CV_32S);
		else if (key=="Criteria")
			criteria = rhs[i+1].toTermCriteria();
		else if (key=="Attempts")
			attempts = rhs[i+1].toInt();
		else if (key=="Initialization")
			flags = Initialization[rhs[i+1].toString()];
		else
			mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
	}
	flags |= (labels.empty()) ? 0 : KMEANS_USE_INITIAL_LABELS;

	// Process
#if CV_MINOR_VERSION >= 2
	double d = kmeans(samples, clusterCount, labels, criteria, attempts, flags,
		centers);
#else
	centers = Mat(samples.rows,clusterCount,CV_32FC1);
	double d = kmeans(samples, clusterCount, labels, criteria, attempts, flags,
		&centers);
#endif
	plhs[0] = MxArray(labels);
	if (nlhs>1)
		plhs[1] = MxArray(centers);
	if (nlhs>2)
		plhs[2] = MxArray(d);
}
<|endoftext|>


<commit_before><commit_msg>App: [skip ci] implement the private class OriginExtension to simulate a geometric group behaviour<commit_after><|endoftext|>


<commit_before>#include "Atm_player.hpp"

/* Add optional parameters for the state machine to begin()
 * Add extra initialization code
 */

Atm_player& Atm_player::begin( int pin /* = - 1 */ ) {
  // clang-format off
  const static state_t state_table[] PROGMEM = {
    /*             ON_ENTER    ON_LOOP  ON_EXIT  EVT_START  EVT_STOP  EVT_TOGGLE  EVT_TIMER  EVT_EOPAT  EVT_REPEAT   ELSE */
    /*   IDLE */   ENT_IDLE, ATM_SLEEP,      -1,     START,       -1,      START,        -1,        -1,         -1,    -1,
    /*  START */  ENT_START,        -1,      -1,        -1,       -1,         -1,        -1,        -1,         -1, SOUND,
    /*  SOUND */  ENT_SOUND,        -1,      -1,        -1,     IDLE,       IDLE,     QUIET,        -1,         -1,    -1,
    /*  QUIET */  ENT_QUIET,        -1,      -1,        -1,     IDLE,       IDLE,      NEXT,        -1,         -1,    -1,
    /*   NEXT */   ENT_NEXT,        -1,      -1,        -1,     IDLE,       IDLE,        -1,    REPEAT,         -1, SOUND,
    /* REPEAT */ ENT_REPEAT,        -1,      -1,        -1,     IDLE,       IDLE,        -1,        -1,     FINISH, START,
    /* FINISH */ ENT_FINISH,        -1,      -1,        -1,     IDLE,         -1,        -1,        -1,       IDLE, START,
  };
  // clang-format on
  Machine::begin( state_table, ELSE );
  Atm_player::pin = pin;
  speed( 100 );
  pitch( 100 );
  repeat( 1 );
  return *this;
}

/* Add C++ code for each event (input)
 * The code must return 1 if the event should be triggered
 */

int Atm_player::event( int id ) {
  switch ( id ) {
    case EVT_START:
      return 0;
    case EVT_TIMER:
      return timer.expired( this );
    case EVT_EOPAT:
      return ( step * 6 ) >= patternsize;
    case EVT_REPEAT:
      return counter_repeat.expired();
  }
  return 0;
}

/* Add C++ code for each action
 * This generates the 'output' for the state machine
 */

void Atm_player::action( int id ) {
  switch ( id ) {
    case ENT_FINISH:
      push( connectors, ON_FINISH, 0, 0, 0 );
      return;
    case ENT_IDLE:
      if ( pin >= 0 ) noTone( pin );
      counter_repeat.set( repeatCount );
      return;
    case ENT_START:
      step = 0;
      counter_repeat.decrement();
      return;
    case ENT_SOUND:
      push( connectors, ON_NOTE, true, pattern[step * 3] * pitchFactor, 1 );
      if ( pin >= 0 ) tone( pin, pattern[step * 3] * pitchFactor );
      timer.set( pattern[step * 3 + 1] * speedFactor );
      return;
    case ENT_QUIET:
      push( connectors, ON_NOTE, false, pattern[step * 3] * pitchFactor, 0 );
      if ( pin >= 0 ) noTone( pin );
      timer.set( pattern[step * 3 + 2] * speedFactor );
      return;
    case ENT_NEXT:
      step++;
      return;
    case ENT_REPEAT:
      return;
  }
}

/* How many times to repeat the pattern
 *
 */

Atm_player& Atm_player::repeat( uint16_t v ) {
  counter_repeat.set( repeatCount = v );
  return *this;
}

Atm_player& Atm_player::speed( float v ) {
  speedFactor = 100 / v;
  return *this;
}

Atm_player& Atm_player::pitch( float v ) {
  pitchFactor = v / 100;
  return *this;
}

/* Sets the pattern and pattern length (in bytes)
 *
 */

Atm_player& Atm_player::play( int* pat, int patsize ) {
  pattern = pat;
  patternsize = patsize;
  counter_repeat.set( repeatCount );
  step = 0;
  return *this;
}

Atm_player& Atm_player::play( int freq, int period, int pause /* = 0 */ ) {
  stub[0] = freq;
  stub[1] = period;
  stub[2] = pause;
  pattern = stub;
  patternsize = 6;
  step = 0;
  return *this;
}

/* Optionally override the default trigger() method
 * Control what triggers your machine can and cannot process
 */

Atm_player& Atm_player::trigger( int event ) {
  Machine::trigger( event );
  return *this;
}

/* Optionally override the default state() method
 * Control what the machine returns when another process requests its state()
 */

int Atm_player::state( void ) {
  return Machine::state();
}

/* Nothing customizable below this line
 ************************************************************************************************
*/

/* onFinish() push connector variants ( slots 1, autostore 0, broadcast 0 )
 *
 * Usage in action() handler: push( connectors, ON_FINISH, 0, v, up)
 */

Atm_player& Atm_player::onFinish( Machine& machine, int event ) { onPush( connectors, ON_FINISH, 0, 1, 1, 0, machine, event ); return *this; }
Atm_player& Atm_player::onFinish( atm_cb_push_t callback, int idx ) { onPush( connectors, ON_FINISH, 0, 1, 1, 0, callback, idx ); return *this; }

/* onNote() push connector variants ( slots 2, autostore 0, broadcast 0 )
 *
 * Usage in action() handler: push( connectors, ON_NOTE, sub, v, up)
 */

Atm_player& Atm_player::onNote( Machine& machine, int event ) { onPush( connectors, ON_NOTE, 0, 2, 1, 0, machine, event ); return *this; }
Atm_player& Atm_player::onNote( atm_cb_push_t callback, int idx ) { onPush( connectors, ON_NOTE, 0, 2, 1, 0, callback, idx ); return *this; }
Atm_player& Atm_player::onNote( int sub, Machine& machine, int event ) { onPush( connectors, ON_NOTE, sub, 2, 0, 0, machine, event ); return *this; }
Atm_player& Atm_player::onNote( int sub, atm_cb_push_t callback, int idx ) { onPush( connectors, ON_NOTE, sub, 2, 0, 0, callback, idx ); return *this; }

/* State trace method
 * Sets the symbol table and the default logging method for serial monitoring
 */

Atm_player& Atm_player::trace( Stream& stream ) {
  Machine::setTrace( &stream, atm_serial_debug::trace,
                     "PLAYER\0EVT_START\0EVT_STOP\0EVT_TOGGLE\0EVT_TIMER\0EVT_EOPAT\0EVT_REPEAT\0ELSE\0IDLE\0START\0SOUND\0QUIET\0NEXT\0REPEAT\0FINISH" );
  return *this;
}
<commit_msg>begin() set player to play a 50ms 880hz tone by default<commit_after>#include "Atm_player.hpp"

/* Add optional parameters for the state machine to begin()
 * Add extra initialization code
 */

Atm_player& Atm_player::begin( int pin /* = - 1 */ ) {
  // clang-format off
  const static state_t state_table[] PROGMEM = {
    /*             ON_ENTER    ON_LOOP  ON_EXIT  EVT_START  EVT_STOP  EVT_TOGGLE  EVT_TIMER  EVT_EOPAT  EVT_REPEAT   ELSE */
    /*   IDLE */   ENT_IDLE, ATM_SLEEP,      -1,     START,       -1,      START,        -1,        -1,         -1,    -1,
    /*  START */  ENT_START,        -1,      -1,        -1,       -1,         -1,        -1,        -1,         -1, SOUND,
    /*  SOUND */  ENT_SOUND,        -1,      -1,        -1,     IDLE,       IDLE,     QUIET,        -1,         -1,    -1,
    /*  QUIET */  ENT_QUIET,        -1,      -1,        -1,     IDLE,       IDLE,      NEXT,        -1,         -1,    -1,
    /*   NEXT */   ENT_NEXT,        -1,      -1,        -1,     IDLE,       IDLE,        -1,    REPEAT,         -1, SOUND,
    /* REPEAT */ ENT_REPEAT,        -1,      -1,        -1,     IDLE,       IDLE,        -1,        -1,     FINISH, START,
    /* FINISH */ ENT_FINISH,        -1,      -1,        -1,     IDLE,         -1,        -1,        -1,       IDLE, START,
  };
  // clang-format on
  Machine::begin( state_table, ELSE );
  Atm_player::pin = pin;
  speed( 100 );
  pitch( 100 );
  repeat( 1 );
  play( 880, 50 );
  return *this;
}

/* Add C++ code for each event (input)
 * The code must return 1 if the event should be triggered
 */

int Atm_player::event( int id ) {
  switch ( id ) {
    case EVT_START:
      return 0;
    case EVT_TIMER:
      return timer.expired( this );
    case EVT_EOPAT:
      return ( step * 6 ) >= patternsize;
    case EVT_REPEAT:
      return counter_repeat.expired();
  }
  return 0;
}

/* Add C++ code for each action
 * This generates the 'output' for the state machine
 */

void Atm_player::action( int id ) {
  switch ( id ) {
    case ENT_FINISH:
      push( connectors, ON_FINISH, 0, 0, 0 );
      return;
    case ENT_IDLE:
      if ( pin >= 0 ) noTone( pin );
      counter_repeat.set( repeatCount );
      return;
    case ENT_START:
      step = 0;
      counter_repeat.decrement();
      return;
    case ENT_SOUND:
      push( connectors, ON_NOTE, true, pattern[step * 3] * pitchFactor, 1 );
      if ( pin >= 0 ) tone( pin, pattern[step * 3] * pitchFactor );
      timer.set( pattern[step * 3 + 1] * speedFactor );
      return;
    case ENT_QUIET:
      push( connectors, ON_NOTE, false, pattern[step * 3] * pitchFactor, 0 );
      if ( pin >= 0 ) noTone( pin );
      timer.set( pattern[step * 3 + 2] * speedFactor );
      return;
    case ENT_NEXT:
      step++;
      return;
    case ENT_REPEAT:
      return;
  }
}

/* How many times to repeat the pattern
 *
 */

Atm_player& Atm_player::repeat( uint16_t v ) {
  counter_repeat.set( repeatCount = v );
  return *this;
}

Atm_player& Atm_player::speed( float v ) {
  speedFactor = 100 / v;
  return *this;
}

Atm_player& Atm_player::pitch( float v ) {
  pitchFactor = v / 100;
  return *this;
}

/* Sets the pattern and pattern length (in bytes)
 *
 */

Atm_player& Atm_player::play( int* pat, int patsize ) {
  pattern = pat;
  patternsize = patsize;
  counter_repeat.set( repeatCount );
  step = 0;
  return *this;
}

Atm_player& Atm_player::play( int freq, int period, int pause /* = 0 */ ) {
  stub[0] = freq;
  stub[1] = period;
  stub[2] = pause;
  pattern = stub;
  patternsize = 6;
  step = 0;
  return *this;
}

/* Optionally override the default trigger() method
 * Control what triggers your machine can and cannot process
 */

Atm_player& Atm_player::trigger( int event ) {
  Machine::trigger( event );
  return *this;
}

/* Optionally override the default state() method
 * Control what the machine returns when another process requests its state()
 */

int Atm_player::state( void ) {
  return Machine::state();
}

/* Nothing customizable below this line
 ************************************************************************************************
*/

/* onFinish() push connector variants ( slots 1, autostore 0, broadcast 0 )
 *
 * Usage in action() handler: push( connectors, ON_FINISH, 0, v, up)
 */

Atm_player& Atm_player::onFinish( Machine& machine, int event ) { onPush( connectors, ON_FINISH, 0, 1, 1, 0, machine, event ); return *this; }
Atm_player& Atm_player::onFinish( atm_cb_push_t callback, int idx ) { onPush( connectors, ON_FINISH, 0, 1, 1, 0, callback, idx ); return *this; }

/* onNote() push connector variants ( slots 2, autostore 0, broadcast 0 )
 *
 * Usage in action() handler: push( connectors, ON_NOTE, sub, v, up)
 */

Atm_player& Atm_player::onNote( Machine& machine, int event ) { onPush( connectors, ON_NOTE, 0, 2, 1, 0, machine, event ); return *this; }
Atm_player& Atm_player::onNote( atm_cb_push_t callback, int idx ) { onPush( connectors, ON_NOTE, 0, 2, 1, 0, callback, idx ); return *this; }
Atm_player& Atm_player::onNote( int sub, Machine& machine, int event ) { onPush( connectors, ON_NOTE, sub, 2, 0, 0, machine, event ); return *this; }
Atm_player& Atm_player::onNote( int sub, atm_cb_push_t callback, int idx ) { onPush( connectors, ON_NOTE, sub, 2, 0, 0, callback, idx ); return *this; }

/* State trace method
 * Sets the symbol table and the default logging method for serial monitoring
 */

Atm_player& Atm_player::trace( Stream& stream ) {
  Machine::setTrace( &stream, atm_serial_debug::trace,
                     "PLAYER\0EVT_START\0EVT_STOP\0EVT_TOGGLE\0EVT_TIMER\0EVT_EOPAT\0EVT_REPEAT\0ELSE\0IDLE\0START\0SOUND\0QUIET\0NEXT\0REPEAT\0FINISH" );
  return *this;
}
<|endoftext|>


<commit_before>// AtomHandler for fluxbox
// Copyright (c) 2002-2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//                    2003 Simon Bowden    (rathnor at users.sourceforge.net)
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: AtomHandler.hh,v 1.13 2004/01/09 02:06:55 fluxgen Exp $

#ifndef ATOMHANDLER_HH
#define ATOMHANDLER_HH

#include <X11/Xlib.h>

class FluxboxWindow;
class WinClient;
class BScreen;

class AtomHandler {
public:

    virtual ~AtomHandler() { }

    virtual void initForScreen(BScreen &screen) = 0;
    virtual void setupFrame(FluxboxWindow &win) = 0;
    virtual void setupClient(WinClient &winclient) = 0;

    virtual void updateClientList(BScreen &screen) = 0;
    virtual void updateWorkspaceNames(BScreen &screen) = 0;
    virtual void updateCurrentWorkspace(BScreen &screen) = 0;
    virtual void updateWorkspaceCount(BScreen &screen) = 0;

    virtual void updateFrameClose(FluxboxWindow &win) = 0;
    virtual void updateClientClose(WinClient &winclient) = 0;
    virtual void updateWorkspace(FluxboxWindow &win) = 0;
    virtual void updateState(FluxboxWindow &win) = 0;
    virtual void updateHints(FluxboxWindow &win) = 0;
    virtual void updateLayer(FluxboxWindow &win) = 0;

    virtual bool checkClientMessage(const XClientMessageEvent &ce,
                                    BScreen * screen, WinClient * const winclient) = 0;

    virtual bool propertyNotify(WinClient &winclient, Atom the_property) = 0;

    /// should this object be updated or not?
    bool update() const { return m_update; }
protected:
    AtomHandler():m_update(true) { }

    void disableUpdate() { m_update = false; }
    void enableUpdate() { m_update = true; }
private:
    bool m_update; ///< do we get update or not
};

#endif // ATOMHANDLER_HH
<commit_msg>updateFocusedWindow, updateWorkarea<commit_after>// AtomHandler for fluxbox
// Copyright (c) 2002-2004 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//               2003-2004 Simon Bowden    (rathnor at users.sourceforge.net)
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: AtomHandler.hh,v 1.14 2004/01/19 18:22:37 fluxgen Exp $

#ifndef ATOMHANDLER_HH
#define ATOMHANDLER_HH

#include <X11/Xlib.h>

class FluxboxWindow;
class WinClient;
class BScreen;

class AtomHandler {
public:

    virtual ~AtomHandler() { }

    virtual void initForScreen(BScreen &screen) = 0;
    virtual void setupFrame(FluxboxWindow &win) = 0;
    virtual void setupClient(WinClient &winclient) = 0;

    virtual void updateFocusedWindow(BScreen &screen, Window win) = 0;
    virtual void updateClientList(BScreen &screen) = 0;
    virtual void updateWorkspaceNames(BScreen &screen) = 0;
    virtual void updateCurrentWorkspace(BScreen &screen) = 0;
    virtual void updateWorkspaceCount(BScreen &screen) = 0;
    virtual void updateWorkarea(BScreen &screen) = 0;

    virtual void updateFrameClose(FluxboxWindow &win) = 0;
    virtual void updateClientClose(WinClient &winclient) = 0;
    virtual void updateWorkspace(FluxboxWindow &win) = 0;
    virtual void updateState(FluxboxWindow &win) = 0;
    virtual void updateHints(FluxboxWindow &win) = 0;
    virtual void updateLayer(FluxboxWindow &win) = 0;

    virtual bool checkClientMessage(const XClientMessageEvent &ce,
                                    BScreen * screen, WinClient * const winclient) = 0;

    virtual bool propertyNotify(WinClient &winclient, Atom the_property) = 0;

    /// should this object be updated or not?
    bool update() const { return m_update; }
protected:
    AtomHandler():m_update(true) { }

    void disableUpdate() { m_update = false; }
    void enableUpdate() { m_update = true; }
private:
    bool m_update; ///< do we get update or not
};

#endif // ATOMHANDLER_HH
<|endoftext|>


<commit_before>
// local includes
#include "BasicSieve.h"
#include "SievePrimes.h"

// ================================================================================================
// Constructor
// ================================================================================================
BasicSieve::BasicSieve() : CalcMethod(), sieve(), sievePos(0), curr(1), currSqrt(1) {
    for(size_t i = 0; i < kNumSievePrimes; ++i)
        sieve.AddPrime(kSievePrimes[i]);

    primes.resize(kNumSievePrimes);
    for(size_t i = 0; i < kNumSievePrimes; ++i)
        primes[i] = kSievePrimes[i];

    NextNumber();
}

// ================================================================================================
// Compute primes up to a limit
// ================================================================================================
void BasicSieve::ComputePrimes(U64 limit) {
    while(curr <= limit) {
        // Check to see if curr is prime
        bool isPrime = true;
        // We don't need to check the primes that went into the sieve
        for(size_t i = kNumSievePrimes; i < primes.size() && primes[i] <= currSqrt; ++i) {
            if(curr % primes[i] == 0) {
                isPrime = false;
                break;
            }
        }
        if(isPrime)
            primes.push_back(curr);

        NextNumber();
    }
}

// ================================================================================================
void BasicSieve::NextNumber() {
    // Move on to the next number
    curr += sieve.Offset(sievePos);
    // Update the offset index
    if(++sievePos == sieve.NumOffsets())
        sievePos = 0;

    // Update the square root
    while(currSqrt * currSqrt <= curr)
        ++currSqrt;
}

<commit_msg>Checked one too many potential divisors<commit_after>
// local includes
#include "BasicSieve.h"
#include "SievePrimes.h"

// ================================================================================================
// Constructor
// ================================================================================================
BasicSieve::BasicSieve() : CalcMethod(), sieve(), sievePos(0), curr(1), currSqrt(1) {
    for(size_t i = 0; i < kNumSievePrimes; ++i)
        sieve.AddPrime(kSievePrimes[i]);

    primes.resize(kNumSievePrimes);
    for(size_t i = 0; i < kNumSievePrimes; ++i)
        primes[i] = kSievePrimes[i];

    NextNumber();
}

// ================================================================================================
// Compute primes up to a limit
// ================================================================================================
void BasicSieve::ComputePrimes(U64 limit) {
    while(curr <= limit) {
        // Check to see if curr is prime
        bool isPrime = true;
        // We don't need to check the primes that went into the sieve
        for(size_t i = kNumSievePrimes; i < primes.size() && primes[i] < currSqrt; ++i) {
            if(curr % primes[i] == 0) {
                isPrime = false;
                break;
            }
        }
        if(isPrime)
            primes.push_back(curr);

        NextNumber();
    }
}

// ================================================================================================
void BasicSieve::NextNumber() {
    // Move on to the next number
    curr += sieve.Offset(sievePos);
    // Update the offset index
    if(++sievePos == sieve.NumOffsets())
        sievePos = 0;

    // Update the square root
    while(currSqrt * currSqrt <= curr)
        ++currSqrt;
}

<|endoftext|>


<commit_before>#include "BenchmarkC.h"
#include <stdlib.h>     /* malloc, calloc, realloc, free */
#include <cstddef> // std::size_t
#include <iostream>

BenchmarkC::BenchmarkC(const int runtime)
	: Benchmark(runtime) {
}

BenchmarkResults BenchmarkC::allocation() {
	std::cout << "C ALLOCATION" << std::endl;

	setStartTimer();

	int operations = 0;
	while(!outOfTime()){
		malloc(sizeof(int));
		malloc(sizeof(bool));
		malloc(sizeof(foo));

		++operations;
	}

	BenchmarkResults results = buildResults(operations, m_runtime, 0, 0);

	printResults(results);

	return results;
}

/*	Theres no way to benchmark only free calls.
	One option could be allocate and store all pointers in a stack but then the benchmarking would be biased
	The onyl thing we can do is allocate memory and then free it afterwards.

*/
BenchmarkResults BenchmarkC::freeing() {
	std::cout << "C FREEING" << std::endl;

	setStartTimer();
	int * i;
	bool * b;
	foo * f;
	std::size_t operations = 0;
	double elapsedTime = 0;
	while(elapsedTime < (m_runtime * 1e3)){
		if (operations % 2 == 0){
			i = (int*) malloc(sizeof(int));
			b = (bool*)malloc(sizeof(bool));
			f = (foo*) malloc(sizeof(foo));

		}else {
			timespec before_free, after_free;
			setTimer(before_free);
			free(f);
			free(b);
			free(i);
			setTimer(after_free);
			elapsedTime += calculateElapsedTime(before_free, after_free);
		}
		++operations;
	}

	BenchmarkResults results = buildResults(operations/2, m_runtime, 0, 0);

	printResults(results);

	return results;
}

BenchmarkResults BenchmarkC::read() {
	return buildResults(0, 0, 0, 0);
}

BenchmarkResults BenchmarkC::write() {
	return buildResults(0, 0, 0, 0);
}

BenchmarkResults BenchmarkC::all() {
	return buildResults(0, 0, 0, 0);
}<commit_msg>Added read benchmark<commit_after>#include "BenchmarkC.h"
#include <stdlib.h>     /* malloc, calloc, realloc, free */
#include <cstddef> // std::size_t
#include <iostream>

BenchmarkC::BenchmarkC(const int runtime)
	: Benchmark(runtime) {
}

BenchmarkResults BenchmarkC::allocation() {
	std::cout << "C ALLOCATION" << std::endl;

	setStartTimer();

	int operations = 0;
	while(!outOfTime()){
		malloc(sizeof(int));
		malloc(sizeof(bool));
		malloc(sizeof(foo));

		++operations;
	}

	BenchmarkResults results = buildResults(operations, m_runtime, 0, 0);

	printResults(results);

	return results;
}

/*	Theres no way to benchmark only free calls.
	One option could be allocate and store all pointers in a stack but then the benchmarking would be biased
	The onyl thing we can do is allocate memory and then free it afterwards.

*/
BenchmarkResults BenchmarkC::freeing() {
	std::cout << "C FREEING" << std::endl;

	setStartTimer();
	int * i;
	bool * b;
	foo * f;
	std::size_t operations = 0;
	double elapsedTime = 0;
	while(elapsedTime < (m_runtime * 1e3)){
		if (operations % 2 == 0){
			i = (int*) malloc(sizeof(int));
			b = (bool*)malloc(sizeof(bool));
			f = (foo*) malloc(sizeof(foo));

		}else {
			timespec before_free, after_free;
			setTimer(before_free);
			free(f);
			free(b);
			free(i);
			setTimer(after_free);
			elapsedTime += calculateElapsedTime(before_free, after_free);
		}
		++operations;
	}

	BenchmarkResults results = buildResults(operations/2, m_runtime, 0, 0);

	printResults(results);

	return results;
}

BenchmarkResults BenchmarkC::read() {
	std::cout << "C READ" << std::endl;

	setStartTimer();

	std::size_t operations = 0;
	double elapsedTime = 0;
	while(elapsedTime < (m_runtime * 1e3)){
		int * i = (int*) malloc(sizeof(int));
		bool * b = (bool*)malloc(sizeof(bool));
		foo * f = (foo*) malloc(sizeof(foo));

		timespec before_read, after_read;
		setTimer(before_read);
		int i_value = *i;
		bool b_value = *b;
		foo f_value = *f;
		setTimer(after_read);

		elapsedTime += calculateElapsedTime(before_read, after_read);
		++operations;
	}

	BenchmarkResults results = buildResults(operations/2, m_runtime, 0, 0);

	printResults(results);

	return results;
}

BenchmarkResults BenchmarkC::write() {
	return buildResults(0, 0, 0, 0);
}

BenchmarkResults BenchmarkC::all() {
	return buildResults(0, 0, 0, 0);
}<|endoftext|>


<commit_before>#include "Connection.hpp"

#include <cmath>
#include <utility>

#include <QtWidgets/QtWidgets>
#include <QtGlobal>

#include "Node.hpp"
#include "FlowScene.hpp"
#include "FlowView.hpp"

#include "NodeGeometry.hpp"
#include "NodeGraphicsObject.hpp"
#include "NodeDataModel.hpp"

#include "ConnectionState.hpp"
#include "ConnectionGeometry.hpp"
#include "ConnectionGraphicsObject.hpp"

using QtNodes::Connection;
using QtNodes::PortType;
using QtNodes::PortIndex;
using QtNodes::ConnectionState;
using QtNodes::Node;
using QtNodes::NodeData;
using QtNodes::NodeDataType;
using QtNodes::ConnectionGraphicsObject;
using QtNodes::ConnectionGeometry;
using QtNodes::TypeConverter;

Connection::
Connection(PortType portType,
           Node& node,
           PortIndex portIndex)
  : _uid(QUuid::createUuid())
  , _outPortIndex(INVALID)
  , _inPortIndex(INVALID)
  , _connectionState()
{
  setNodeToPort(node, portType, portIndex);

  setRequiredPort(oppositePort(portType));
}

Connection::
Connection(Node& nodeIn,
           PortIndex portIndexIn,
           Node& nodeOut,
           PortIndex portIndexOut,
           TypeConverter typeConverter)
  : _uid(QUuid::createUuid())
  , _outNode(&nodeOut)
  , _inNode(&nodeIn)
  , _outPortIndex(portIndexOut)
  , _inPortIndex(portIndexIn)
  , _connectionState()
  , _converter(std::move(typeConverter))
{
  setNodeToPort(nodeIn, PortType::In, portIndexIn);
  setNodeToPort(nodeOut, PortType::Out, portIndexOut);
}

Connection::
~Connection()
{
  if (complete())
  {
    connectionMadeIncomplete(*this);
  }

  propagateEmptyData();

  if (_inNode)
  {
    _inNode->nodeGraphicsObject().update();
  }

  if (_outNode)
  {
    _outNode->nodeGraphicsObject().update();
  }
}

QJsonObject
Connection::
save() const
{
  QJsonObject connectionJson;

  if (_inNode && _outNode)
  {
    connectionJson["in_id"] = _inNode->id().toString();
    connectionJson["in_index"] = _inPortIndex;

    connectionJson["out_id"] = _outNode->id().toString();
    connectionJson["out_index"] = _outPortIndex;

    if (_converter)
    {
      auto getTypeJson = [this](PortType type)
      {
        QJsonObject typeJson;
        NodeDataType nodeType = this->dataType(type);
        typeJson["id"] = nodeType.id;
        typeJson["name"] = nodeType.name;

        return typeJson;
      };

      QJsonObject converterTypeJson;

      converterTypeJson["in"] = getTypeJson(PortType::In);
      converterTypeJson["out"] = getTypeJson(PortType::Out);

      connectionJson["converter"] = converterTypeJson;
    }
  }

  return connectionJson;
}

QUuid
Connection::
id() const
{
  return _uid;
}

bool
Connection::
complete() const
{
  return _inNode != nullptr && _outNode != nullptr;
}

void
Connection::
setRequiredPort(PortType dragging)
{
  _connectionState.setRequiredPort(dragging);

  switch (dragging)
  {
    case PortType::Out:
      _outNode      = nullptr;
      _outPortIndex = INVALID;
      break;

    case PortType::In:
      _inNode      = nullptr;
      _inPortIndex = INVALID;
      break;

    default:
      break;
  }
}

PortType
Connection::
requiredPort() const
{
  return _connectionState.requiredPort();
}

void
Connection::
setGraphicsObject(std::unique_ptr<ConnectionGraphicsObject>&& graphics)
{
  _connectionGraphicsObject = std::move(graphics);

  // This function is only called when the ConnectionGraphicsObject
  // is newly created. At this moment both end coordinates are (0, 0)
  // in Connection G.O. coordinates. The position of the whole
  // Connection G. O. in scene coordinate system is also (0, 0).
  // By moving the whole object to the Node Port position
  // we position both connection ends correctly.

  if (requiredPort() != PortType::None)
  {

    PortType attachedPort = oppositePort(requiredPort());

    PortIndex attachedPortIndex = getPortIndex(attachedPort);

    auto node = getNode(attachedPort);

    QTransform nodeSceneTransform =
      node->nodeGraphicsObject().sceneTransform();

    QPointF pos = node->nodeGeometry().portScenePosition(attachedPortIndex,
                                                         attachedPort,
                                                         nodeSceneTransform);

    _connectionGraphicsObject->setPos(pos);
  }

  _connectionGraphicsObject->move();
}

PortIndex
Connection::
getPortIndex(PortType portType) const
{
  PortIndex result = INVALID;

  switch (portType)
  {
    case PortType::In:
      result = _inPortIndex;
      break;

    case PortType::Out:
      result = _outPortIndex;

      break;

    default:
      break;
  }

  return result;
}

void
Connection::
setNodeToPort(Node& node,
              PortType portType,
              PortIndex portIndex)
{
  bool wasIncomplete = !complete();

  auto& nodeWeak = getNode(portType);

  nodeWeak = &node;

  if (portType == PortType::Out)
    _outPortIndex = portIndex;
  else
    _inPortIndex = portIndex;

  _connectionState.setNoRequiredPort();

  updated(*this);
  if (complete() && wasIncomplete) {
    connectionCompleted(*this);
  }
}

void
Connection::
removeFromNodes() const
{
  if (_inNode)
    _inNode->nodeState().eraseConnection(PortType::In, _inPortIndex, id());

  if (_outNode)
    _outNode->nodeState().eraseConnection(PortType::Out, _outPortIndex, id());
}

ConnectionGraphicsObject&
Connection::
getConnectionGraphicsObject() const
{
  return *_connectionGraphicsObject;
}

ConnectionState&
Connection::
connectionState()
{
  return _connectionState;
}

ConnectionState const&
Connection::
connectionState() const
{
  return _connectionState;
}

ConnectionGeometry&
Connection::
connectionGeometry()
{
  return _connectionGeometry;
}

ConnectionGeometry const&
Connection::
connectionGeometry() const
{
  return _connectionGeometry;
}

Node*
Connection::
getNode(PortType portType) const
{
  switch (portType)
  {
    case PortType::In:
      return _inNode;
      break;

    case PortType::Out:
      return _outNode;
      break;

    default:
      // not possible
      break;
  }
  return nullptr;
}

Node*&
Connection::
getNode(PortType portType)
{
  switch (portType)
  {
    case PortType::In:
      return _inNode;
      break;

    case PortType::Out:
      return _outNode;
      break;

    default:
      // not possible
      break;
  }
  Q_UNREACHABLE();
}

void
Connection::
clearNode(PortType portType)
{
  if (complete())
  {
    connectionMadeIncomplete(*this);
  }

  getNode(portType) = nullptr;

  if (portType == PortType::In)
    _inPortIndex = INVALID;
  else
    _outPortIndex = INVALID;
}

NodeDataType
Connection::
dataType(PortType portType) const
{
  if (_inNode && _outNode)
  {
    auto const & model = (portType == PortType::In) ?
                        _inNode->nodeDataModel() :
                        _outNode->nodeDataModel();
    PortIndex index = (portType == PortType::In) ?
                      _inPortIndex :
                      _outPortIndex;

    return model->dataType(portType, index);
  }
  else
  {
    Node* validNode;
    PortIndex index = INVALID;

    if ((validNode = _inNode))
    {
      index    = _inPortIndex;
      portType = PortType::In;
    }
    else if ((validNode = _outNode))
    {
      index    = _outPortIndex;
      portType = PortType::Out;
    }

    if (validNode)
    {
      auto const &model = validNode->nodeDataModel();

      return model->dataType(portType, index);
    }
  }

  Q_UNREACHABLE();
}

void
Connection::
setTypeConverter(TypeConverter converter)
{
  _converter = std::move(converter);
}

void
Connection::
propagateData(std::shared_ptr<NodeData> nodeData) const
{
  if (_inNode)
  {
    if (_converter)
    {
      nodeData = _converter(nodeData);
    }

    _inNode->propagateData(nodeData, _inPortIndex);
  }
}

void
Connection::
propagateEmptyData() const
{
  std::shared_ptr<NodeData> emptyData;

  propagateData(emptyData);
}
<commit_msg>Adjust the behavior of Connection's destructor (#308)<commit_after>#include "Connection.hpp"

#include <cmath>
#include <utility>

#include <QtWidgets/QtWidgets>
#include <QtGlobal>

#include "Node.hpp"
#include "FlowScene.hpp"
#include "FlowView.hpp"

#include "NodeGeometry.hpp"
#include "NodeGraphicsObject.hpp"
#include "NodeDataModel.hpp"

#include "ConnectionState.hpp"
#include "ConnectionGeometry.hpp"
#include "ConnectionGraphicsObject.hpp"

using QtNodes::Connection;
using QtNodes::PortType;
using QtNodes::PortIndex;
using QtNodes::ConnectionState;
using QtNodes::Node;
using QtNodes::NodeData;
using QtNodes::NodeDataType;
using QtNodes::ConnectionGraphicsObject;
using QtNodes::ConnectionGeometry;
using QtNodes::TypeConverter;

Connection::
Connection(PortType portType,
           Node& node,
           PortIndex portIndex)
  : _uid(QUuid::createUuid())
  , _outPortIndex(INVALID)
  , _inPortIndex(INVALID)
  , _connectionState()
{
  setNodeToPort(node, portType, portIndex);

  setRequiredPort(oppositePort(portType));
}

Connection::
Connection(Node& nodeIn,
           PortIndex portIndexIn,
           Node& nodeOut,
           PortIndex portIndexOut,
           TypeConverter typeConverter)
  : _uid(QUuid::createUuid())
  , _outNode(&nodeOut)
  , _inNode(&nodeIn)
  , _outPortIndex(portIndexOut)
  , _inPortIndex(portIndexIn)
  , _connectionState()
  , _converter(std::move(typeConverter))
{
  setNodeToPort(nodeIn, PortType::In, portIndexIn);
  setNodeToPort(nodeOut, PortType::Out, portIndexOut);
}

Connection::
~Connection()
{
  if (complete())
  {
    connectionMadeIncomplete(*this);
  }

  if (_inNode)
  {
    _inNode->nodeGraphicsObject().update();
  }

  if (_outNode)
  {
    propagateEmptyData();
    _outNode->nodeGraphicsObject().update();
  }
}

QJsonObject
Connection::
save() const
{
  QJsonObject connectionJson;

  if (_inNode && _outNode)
  {
    connectionJson["in_id"] = _inNode->id().toString();
    connectionJson["in_index"] = _inPortIndex;

    connectionJson["out_id"] = _outNode->id().toString();
    connectionJson["out_index"] = _outPortIndex;

    if (_converter)
    {
      auto getTypeJson = [this](PortType type)
      {
        QJsonObject typeJson;
        NodeDataType nodeType = this->dataType(type);
        typeJson["id"] = nodeType.id;
        typeJson["name"] = nodeType.name;

        return typeJson;
      };

      QJsonObject converterTypeJson;

      converterTypeJson["in"] = getTypeJson(PortType::In);
      converterTypeJson["out"] = getTypeJson(PortType::Out);

      connectionJson["converter"] = converterTypeJson;
    }
  }

  return connectionJson;
}

QUuid
Connection::
id() const
{
  return _uid;
}

bool
Connection::
complete() const
{
  return _inNode != nullptr && _outNode != nullptr;
}

void
Connection::
setRequiredPort(PortType dragging)
{
  _connectionState.setRequiredPort(dragging);

  switch (dragging)
  {
    case PortType::Out:
      _outNode      = nullptr;
      _outPortIndex = INVALID;
      break;

    case PortType::In:
      _inNode      = nullptr;
      _inPortIndex = INVALID;
      break;

    default:
      break;
  }
}

PortType
Connection::
requiredPort() const
{
  return _connectionState.requiredPort();
}

void
Connection::
setGraphicsObject(std::unique_ptr<ConnectionGraphicsObject>&& graphics)
{
  _connectionGraphicsObject = std::move(graphics);

  // This function is only called when the ConnectionGraphicsObject
  // is newly created. At this moment both end coordinates are (0, 0)
  // in Connection G.O. coordinates. The position of the whole
  // Connection G. O. in scene coordinate system is also (0, 0).
  // By moving the whole object to the Node Port position
  // we position both connection ends correctly.

  if (requiredPort() != PortType::None)
  {

    PortType attachedPort = oppositePort(requiredPort());

    PortIndex attachedPortIndex = getPortIndex(attachedPort);

    auto node = getNode(attachedPort);

    QTransform nodeSceneTransform =
      node->nodeGraphicsObject().sceneTransform();

    QPointF pos = node->nodeGeometry().portScenePosition(attachedPortIndex,
                                                         attachedPort,
                                                         nodeSceneTransform);

    _connectionGraphicsObject->setPos(pos);
  }

  _connectionGraphicsObject->move();
}

PortIndex
Connection::
getPortIndex(PortType portType) const
{
  PortIndex result = INVALID;

  switch (portType)
  {
    case PortType::In:
      result = _inPortIndex;
      break;

    case PortType::Out:
      result = _outPortIndex;

      break;

    default:
      break;
  }

  return result;
}

void
Connection::
setNodeToPort(Node& node,
              PortType portType,
              PortIndex portIndex)
{
  bool wasIncomplete = !complete();

  auto& nodeWeak = getNode(portType);

  nodeWeak = &node;

  if (portType == PortType::Out)
    _outPortIndex = portIndex;
  else
    _inPortIndex = portIndex;

  _connectionState.setNoRequiredPort();

  updated(*this);
  if (complete() && wasIncomplete) {
    connectionCompleted(*this);
  }
}

void
Connection::
removeFromNodes() const
{
  if (_inNode)
    _inNode->nodeState().eraseConnection(PortType::In, _inPortIndex, id());

  if (_outNode)
    _outNode->nodeState().eraseConnection(PortType::Out, _outPortIndex, id());
}

ConnectionGraphicsObject&
Connection::
getConnectionGraphicsObject() const
{
  return *_connectionGraphicsObject;
}

ConnectionState&
Connection::
connectionState()
{
  return _connectionState;
}

ConnectionState const&
Connection::
connectionState() const
{
  return _connectionState;
}

ConnectionGeometry&
Connection::
connectionGeometry()
{
  return _connectionGeometry;
}

ConnectionGeometry const&
Connection::
connectionGeometry() const
{
  return _connectionGeometry;
}

Node*
Connection::
getNode(PortType portType) const
{
  switch (portType)
  {
    case PortType::In:
      return _inNode;
      break;

    case PortType::Out:
      return _outNode;
      break;

    default:
      // not possible
      break;
  }
  return nullptr;
}

Node*&
Connection::
getNode(PortType portType)
{
  switch (portType)
  {
    case PortType::In:
      return _inNode;
      break;

    case PortType::Out:
      return _outNode;
      break;

    default:
      // not possible
      break;
  }
  Q_UNREACHABLE();
}

void
Connection::
clearNode(PortType portType)
{
  if (complete())
  {
    connectionMadeIncomplete(*this);
  }

  getNode(portType) = nullptr;

  if (portType == PortType::In)
    _inPortIndex = INVALID;
  else
    _outPortIndex = INVALID;
}

NodeDataType
Connection::
dataType(PortType portType) const
{
  if (_inNode && _outNode)
  {
    auto const & model = (portType == PortType::In) ?
                        _inNode->nodeDataModel() :
                        _outNode->nodeDataModel();
    PortIndex index = (portType == PortType::In) ?
                      _inPortIndex :
                      _outPortIndex;

    return model->dataType(portType, index);
  }
  else
  {
    Node* validNode;
    PortIndex index = INVALID;

    if ((validNode = _inNode))
    {
      index    = _inPortIndex;
      portType = PortType::In;
    }
    else if ((validNode = _outNode))
    {
      index    = _outPortIndex;
      portType = PortType::Out;
    }

    if (validNode)
    {
      auto const &model = validNode->nodeDataModel();

      return model->dataType(portType, index);
    }
  }

  Q_UNREACHABLE();
}

void
Connection::
setTypeConverter(TypeConverter converter)
{
  _converter = std::move(converter);
}

void
Connection::
propagateData(std::shared_ptr<NodeData> nodeData) const
{
  if (_inNode)
  {
    if (_converter)
    {
      nodeData = _converter(nodeData);
    }

    _inNode->propagateData(nodeData, _inPortIndex);
  }
}

void
Connection::
propagateEmptyData() const
{
  std::shared_ptr<NodeData> emptyData;

  propagateData(emptyData);
}
<|endoftext|>