<commit_before>/*
 * 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 .
 */

#include "FocusManager.hxx"
#include "Panel.hxx"
#include "DeckTitleBar.hxx"
#include "sfx2/sidebar/Tools.hxx"
#include "TitleBar.hxx"
#include <vcl/button.hxx>
#include <vcl/toolbox.hxx>
#include <toolkit/helper/vclunohelper.hxx>

namespace sfx2 { namespace sidebar {

FocusManager::FocusLocation::FocusLocation (const PanelComponent eComponent, const sal_Int32 nIndex)
    : meComponent(eComponent),
      mnIndex(nIndex)
{
}

FocusManager::FocusManager (const ::boost::function<void(const Panel&)>& rShowPanelFunctor)
    : mpDeckTitleBar(),
      maPanels(),
      maButtons(),
      maShowPanelFunctor(rShowPanelFunctor)
{
}

FocusManager::~FocusManager (void)
{
    Clear();
}

void FocusManager::GrabFocus (void)
{
    FocusDeckTitle();
}

void FocusManager::Clear (void)
{
    SetDeckTitle(NULL);
    ClearPanels();
    ClearButtons();
}

void FocusManager::ClearPanels (void)
{
    ::std::vector<Panel*> aPanels;
    aPanels.swap(maPanels);
    for (::std::vector<Panel*>::iterator iPanel(aPanels.begin()),iEnd(aPanels.end());
         iPanel!=iEnd;
        ++iPanel)
    {
        UnregisterWindow(**iPanel);
        if ((*iPanel)->GetTitleBar() != NULL)
        {
            UnregisterWindow(*(*iPanel)->GetTitleBar());
            UnregisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
        }

        (*iPanel)->RemoveChildEventListener(LINK(this, FocusManager, ChildEventListener));
    }
}

void FocusManager::ClearButtons (void)
{
    ::std::vector<Window*> aButtons;
    for (::std::vector<Window*>::iterator iButton(aButtons.begin()),iEnd(aButtons.end());
         iButton!=iEnd;
        ++iButton)
    {
        UnregisterWindow(**iButton);
    }
}

void FocusManager::SetDeckTitle (DeckTitleBar* pDeckTitleBar)
{
    if (mpDeckTitleBar != NULL)
    {
        UnregisterWindow(*mpDeckTitleBar);
        UnregisterWindow(mpDeckTitleBar->GetToolBox());
    }
    mpDeckTitleBar = pDeckTitleBar;

    if (mpDeckTitleBar != NULL)
    {
        RegisterWindow(*mpDeckTitleBar);
        RegisterWindow(mpDeckTitleBar->GetToolBox());
    }
}

void FocusManager::SetPanels (const SharedPanelContainer& rPanels)
{
    ClearPanels();
    for(SharedPanelContainer::const_iterator iPanel(rPanels.begin()),iEnd(rPanels.end());
        iPanel!=iEnd;
        ++iPanel)
    {
        RegisterWindow(**iPanel);
        if ((*iPanel)->GetTitleBar() != NULL)
        {
            RegisterWindow(*(*iPanel)->GetTitleBar());
            RegisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
        }

        // Register also as child event listener at the panel.
        (*iPanel)->AddChildEventListener(LINK(this, FocusManager, ChildEventListener));

        maPanels.push_back(iPanel->get());
    }
}

void FocusManager::SetButtons (const ::std::vector<Button*>& rButtons)
{
    ClearButtons();
    for (::std::vector<Button*>::const_iterator iButton(rButtons.begin()),iEnd(rButtons.end());
         iButton!=iEnd;
         ++iButton)
    {
        RegisterWindow(**iButton);
        maButtons.push_back(*iButton);
    }
}

void FocusManager::RegisterWindow (Window& rWindow)
{
    rWindow.AddEventListener(LINK(this, FocusManager, WindowEventListener));
}

void FocusManager::UnregisterWindow (Window& rWindow)
{
    rWindow.RemoveEventListener(LINK(this, FocusManager, WindowEventListener));
}

FocusManager::FocusLocation FocusManager::GetFocusLocation (const Window& rWindow) const
{
    // Check the deck title.
    if (mpDeckTitleBar != NULL)
    {
        if (mpDeckTitleBar == &rWindow)
            return FocusLocation(PC_DeckTitle, -1);
        else if (&mpDeckTitleBar->GetToolBox() == &rWindow)
            return FocusLocation(PC_DeckToolBox, -1);
    }

    // Search the panels.
    for (sal_Int32 nIndex=0,nCount(maPanels.size()); nIndex<nCount; ++nIndex)
    {
        if (maPanels[nIndex] == &rWindow)
            return FocusLocation(PC_PanelContent, nIndex);
        TitleBar* pTitleBar = maPanels[nIndex]->GetTitleBar();
        if (pTitleBar == &rWindow)
            return FocusLocation(PC_PanelTitle, nIndex);
        if (pTitleBar!=NULL && &pTitleBar->GetToolBox()==&rWindow)
            return FocusLocation(PC_PanelToolBox, nIndex);
    }

    // Search the buttons.
    for (sal_Int32 nIndex=0,nCount(maButtons.size()); nIndex<nCount; ++nIndex)
        if (maButtons[nIndex] == &rWindow)
            return FocusLocation(PC_TabBar, nIndex);

    return FocusLocation(PC_None, -1);
}

bool FocusManager::IsAnyPanelFocused (void) const
{
    for (::std::vector<Panel*>::const_iterator iPanel(maPanels.begin()),iEnd(maPanels.end());
         iPanel!=iEnd;
         ++iPanel)
    {
        if ((*iPanel)->HasFocus())
            return true;
        else if ((*iPanel)->HasChildPathFocus())
            return true;
    }
    return false;
}

bool FocusManager::IsAnyButtonFocused (void) const
{
    for (::std::vector<Button*>::const_iterator iButton(maButtons.begin()),iEnd(maButtons.end());
         iButton!=iEnd;
         ++iButton)
    {
        if ((*iButton)->HasFocus())
            return true;
    }
    return false;
}

void FocusManager::FocusDeckTitle (void)
{
    if (IsDeckTitleVisible())
    {
        ToolBox& rToolBox = mpDeckTitleBar->GetToolBox();
        if (rToolBox.GetItemCount() > 0)
        {
            rToolBox.GrabFocus();
            rToolBox.Invalidate();
        }
    }
    else
        FocusPanel(0);
}

bool FocusManager::IsDeckTitleVisible (void) const
{
    return mpDeckTitleBar != NULL && mpDeckTitleBar->IsVisible();
}

void FocusManager::FocusPanel (const sal_Int32 nPanelIndex)
{
    Panel& rPanel (*maPanels[nPanelIndex]);
    TitleBar* pTitleBar = rPanel.GetTitleBar();
    if (pTitleBar!=NULL && pTitleBar->IsVisible())
    {
        rPanel.SetExpanded(true);
        pTitleBar->GrabFocus();
    }
    else
        FocusPanelContent(nPanelIndex);
    if (maShowPanelFunctor)
        maShowPanelFunctor(rPanel);
}

void FocusManager::FocusPanelContent (const sal_Int32 nPanelIndex)
{
    Window* pWindow = VCLUnoHelper::GetWindow(maPanels[nPanelIndex]->GetElementWindow());
    if (pWindow != NULL)
        pWindow->GrabFocus();
}

void FocusManager::FocusButton (const sal_Int32 nButtonIndex)
{
    maButtons[nButtonIndex]->GrabFocus();
    maButtons[nButtonIndex]->Invalidate();
}

void FocusManager::ClickButton (const sal_Int32 nButtonIndex)
{
    maButtons[nButtonIndex]->Click();
    if (nButtonIndex > 0)
        if ( ! maPanels.empty())
            FocusPanel(0);
    maButtons[nButtonIndex]->GetParent()->Invalidate();
}

void FocusManager::RemoveWindow (Window& rWindow)
{
    ::std::vector<Panel*>::iterator iPanel (::std::find(maPanels.begin(), maPanels.end(), &rWindow));
    if (iPanel != maPanels.end())
    {
        UnregisterWindow(rWindow);
        if ((*iPanel)->GetTitleBar() != NULL)
        {
            UnregisterWindow(*(*iPanel)->GetTitleBar());
            UnregisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
        }
        maPanels.erase(iPanel);
        return;
    }

    ::std::vector<Button*>::iterator iButton (::std::find(maButtons.begin(), maButtons.end(), &rWindow));
    if (iButton != maButtons.end())
    {
        UnregisterWindow(rWindow);
        maButtons.erase(iButton);
        return;
    }
}

bool FocusManager::MoveFocusInsidePanel (
    const FocusLocation aFocusLocation,
    const sal_Int32 nDirection)
{
    const bool bHasToolBoxItem (
        maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GetToolBox().GetItemCount() > 0);
    switch (aFocusLocation.meComponent)
    {
        case  PC_PanelTitle:
            if (nDirection > 0 && bHasToolBoxItem)
                maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GetToolBox().GrabFocus();
            else
                FocusPanelContent(aFocusLocation.mnIndex);
            return true;

        case PC_PanelToolBox:
            if (nDirection < 0 && bHasToolBoxItem)
                maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GrabFocus();
            else
                FocusPanelContent(aFocusLocation.mnIndex);
            return true;

        default:
            return false;
    }
}

void FocusManager::HandleKeyEvent (
    const KeyCode& rKeyCode,
    const Window& rWindow)
{
    const FocusLocation aLocation (GetFocusLocation(rWindow));

    switch (rKeyCode.GetCode())
    {
        case KEY_SPACE:
            switch (aLocation.meComponent)
            {
                case PC_PanelTitle:
                    // Toggle panel between expanded and collapsed.
                    maPanels[aLocation.mnIndex]->SetExpanded( ! maPanels[aLocation.mnIndex]->IsExpanded());
                    break;

                case PC_TabBar:
                    // Activate the button.
                    ClickButton(aLocation.mnIndex);
                    break;

                default:
                    break;
            }
            return;

        case KEY_RETURN:
            switch (aLocation.meComponent)
            {
                case PC_DeckToolBox:
                    FocusButton(0);
                    break;

                case PC_PanelTitle:
                    // Enter the panel.
                    FocusPanelContent(aLocation.mnIndex);
                    break;

                case PC_TabBar:
                    // Activate the button.
                    ClickButton(aLocation.mnIndex);
                    break;

                default:
                    break;
            }
            return;

        case KEY_TAB:
            switch (aLocation.meComponent)
            {
                case PC_PanelTitle:
                case PC_PanelToolBox:
                case PC_PanelContent:
                    if (rKeyCode.IsShift())
                        MoveFocusInsidePanel(aLocation, -1);
                    else
                        MoveFocusInsidePanel(aLocation, +1);
                    break;

                default:
                    break;
            }
            break;

        case KEY_LEFT:
        case KEY_UP:
            switch (aLocation.meComponent)
            {
                case PC_PanelTitle:
                case PC_PanelToolBox:
                case PC_PanelContent:
                    // Go to previous panel or the deck title.
                    if (aLocation.mnIndex > 0)
                        FocusPanel(aLocation.mnIndex-1);
                    else if (IsDeckTitleVisible())
                        FocusDeckTitle();
                    else
                        FocusButton(maButtons.size()-1);
                    break;

                case PC_DeckTitle:
                case PC_DeckToolBox:
                    // Focus the last button.
                    FocusButton(maButtons.size()-1);
                    break;

                case PC_TabBar:
                    // Go to previous tab bar item.
                    if (aLocation.mnIndex == 0)
                        FocusPanel(maPanels.size()-1);
                    else
                        FocusButton((aLocation.mnIndex + maButtons.size() - 1) % maButtons.size());
                    break;

                default:
                    break;
            }
            break;

        case KEY_RIGHT:
        case KEY_DOWN:
            switch(aLocation.meComponent)
            {
                case PC_PanelTitle:
                case PC_PanelToolBox:
                case PC_PanelContent:
                    // Go to next panel.
                    if (aLocation.mnIndex < static_cast<sal_Int32>(maPanels.size())-1)
                        FocusPanel(aLocation.mnIndex+1);
                    else
                        FocusButton(0);
                    break;

                case PC_DeckTitle:
                case PC_DeckToolBox:
                    // Focus the first panel.
                    FocusPanel(0);
                    break;

                case PC_TabBar:
                    // Go to next tab bar item.
                    if (aLocation.mnIndex < static_cast<sal_Int32>(maButtons.size())-1)
                        FocusButton(aLocation.mnIndex + 1);
                    else if (IsDeckTitleVisible())
                        FocusDeckTitle();
                    else
                        FocusPanel(0);
                    break;

                default:
                    break;
            }
            break;
    }
}

IMPL_LINK(FocusManager, WindowEventListener, VclSimpleEvent*, pEvent)
{
    if (pEvent == NULL)
        return 0;

    if ( ! pEvent->ISA(VclWindowEvent))
        return 0;

    VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
    Window* pSource = pWindowEvent->GetWindow();
    if (pSource == NULL)
        return 0;

    switch (pWindowEvent->GetId())
    {
        case VCLEVENT_WINDOW_KEYINPUT:
        {
            KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());
            HandleKeyEvent(pKeyEvent->GetKeyCode(), *pSource);
            return 1;
        }

        case VCLEVENT_OBJECT_DYING:
            RemoveWindow(*pSource);
            return 1;

        case VCLEVENT_WINDOW_GETFOCUS:
        case VCLEVENT_WINDOW_LOSEFOCUS:
            pSource->Invalidate();
    }

    return 0;
}

IMPL_LINK(FocusManager, ChildEventListener, VclSimpleEvent*, pEvent)
{
    if (pEvent == NULL)
        return 0;

    if ( ! pEvent->ISA(VclWindowEvent))
        return 0;

    VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
    Window* pSource = pWindowEvent->GetWindow();
    if (pSource == NULL)
        return 0;

    switch (pWindowEvent->GetId())
    {
        case VCLEVENT_WINDOW_KEYINPUT:
        {
            KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());

            // Go up the window hierarchy to find the parent of the
            // event source which is known to us.
            Window* pWindow = pSource;
            FocusLocation aLocation (PC_None, -1);
            while (true)
            {
                if (pWindow == NULL)
                    break;
                aLocation = GetFocusLocation(*pWindow);
                if (aLocation.meComponent != PC_None)
                    break;
                pWindow = pWindow->GetParent();
            }

            if (aLocation.meComponent != PC_None)
            {
                switch (pKeyEvent->GetKeyCode().GetCode())
                {
                    case KEY_ESCAPE:
                        // Return focus back to the panel title.
                        FocusPanel(aLocation.mnIndex);
                        break;

                    default:
                        break;
                }
            }
            break;
        }

        default:
            break;
    }

    return 1;
}

} } // end of namespace sfx2::sidebar
<commit_msg>Resolves: #i122230# Fixes for sidebar focus traveling<commit_after>/*
 * 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 .
 */

#include "FocusManager.hxx"
#include "Panel.hxx"
#include "DeckTitleBar.hxx"
#include "sfx2/sidebar/Tools.hxx"
#include "TitleBar.hxx"
#include <vcl/button.hxx>
#include <vcl/toolbox.hxx>
#include <toolkit/helper/vclunohelper.hxx>

namespace sfx2 { namespace sidebar {

FocusManager::FocusLocation::FocusLocation (const PanelComponent eComponent, const sal_Int32 nIndex)
    : meComponent(eComponent),
      mnIndex(nIndex)
{
}

FocusManager::FocusManager (const ::boost::function<void(const Panel&)>& rShowPanelFunctor)
    : mpDeckTitleBar(),
      maPanels(),
      maButtons(),
      maShowPanelFunctor(rShowPanelFunctor)
{
}

FocusManager::~FocusManager (void)
{
    Clear();
}

void FocusManager::GrabFocus (void)
{
    FocusDeckTitle();
}

void FocusManager::Clear (void)
{
    SetDeckTitle(NULL);
    ClearPanels();
    ClearButtons();
}

void FocusManager::ClearPanels (void)
{
    ::std::vector<Panel*> aPanels;
    aPanels.swap(maPanels);
    for (::std::vector<Panel*>::iterator iPanel(aPanels.begin()),iEnd(aPanels.end());
         iPanel!=iEnd;
        ++iPanel)
    {
        UnregisterWindow(**iPanel);
        if ((*iPanel)->GetTitleBar() != NULL)
        {
            UnregisterWindow(*(*iPanel)->GetTitleBar());
            UnregisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
        }

        (*iPanel)->RemoveChildEventListener(LINK(this, FocusManager, ChildEventListener));
    }
}

void FocusManager::ClearButtons (void)
{
    ::std::vector<Button*> aButtons;
    aButtons.swap(maButtons);
    for (::std::vector<Button*>::iterator iButton(aButtons.begin()),iEnd(aButtons.end());
         iButton!=iEnd;
        ++iButton)
    {
        UnregisterWindow(**iButton);
    }
}

void FocusManager::SetDeckTitle (DeckTitleBar* pDeckTitleBar)
{
    if (mpDeckTitleBar != NULL)
    {
        UnregisterWindow(*mpDeckTitleBar);
        UnregisterWindow(mpDeckTitleBar->GetToolBox());
    }
    mpDeckTitleBar = pDeckTitleBar;

    if (mpDeckTitleBar != NULL)
    {
        RegisterWindow(*mpDeckTitleBar);
        RegisterWindow(mpDeckTitleBar->GetToolBox());
    }
}

void FocusManager::SetPanels (const SharedPanelContainer& rPanels)
{
    ClearPanels();
    for(SharedPanelContainer::const_iterator iPanel(rPanels.begin()),iEnd(rPanels.end());
        iPanel!=iEnd;
        ++iPanel)
    {
        RegisterWindow(**iPanel);
        if ((*iPanel)->GetTitleBar() != NULL)
        {
            RegisterWindow(*(*iPanel)->GetTitleBar());
            RegisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
        }

        // Register also as child event listener at the panel.
        (*iPanel)->AddChildEventListener(LINK(this, FocusManager, ChildEventListener));

        maPanels.push_back(iPanel->get());
    }
}

void FocusManager::SetButtons (const ::std::vector<Button*>& rButtons)
{
    ClearButtons();
    for (::std::vector<Button*>::const_iterator iButton(rButtons.begin()),iEnd(rButtons.end());
         iButton!=iEnd;
         ++iButton)
    {
        RegisterWindow(**iButton);
        maButtons.push_back(*iButton);
    }
}

void FocusManager::RegisterWindow (Window& rWindow)
{
    rWindow.AddEventListener(LINK(this, FocusManager, WindowEventListener));
}

void FocusManager::UnregisterWindow (Window& rWindow)
{
    rWindow.RemoveEventListener(LINK(this, FocusManager, WindowEventListener));
}

FocusManager::FocusLocation FocusManager::GetFocusLocation (const Window& rWindow) const
{
    // Check the deck title.
    if (mpDeckTitleBar != NULL)
    {
        if (mpDeckTitleBar == &rWindow)
            return FocusLocation(PC_DeckTitle, -1);
        else if (&mpDeckTitleBar->GetToolBox() == &rWindow)
            return FocusLocation(PC_DeckToolBox, -1);
    }

    // Search the panels.
    for (sal_Int32 nIndex=0,nCount(maPanels.size()); nIndex<nCount; ++nIndex)
    {
        if (maPanels[nIndex] == &rWindow)
            return FocusLocation(PC_PanelContent, nIndex);
        TitleBar* pTitleBar = maPanels[nIndex]->GetTitleBar();
        if (pTitleBar == &rWindow)
            return FocusLocation(PC_PanelTitle, nIndex);
        if (pTitleBar!=NULL && &pTitleBar->GetToolBox()==&rWindow)
            return FocusLocation(PC_PanelToolBox, nIndex);
    }

    // Search the buttons.
    for (sal_Int32 nIndex=0,nCount(maButtons.size()); nIndex<nCount; ++nIndex)
        if (maButtons[nIndex] == &rWindow)
            return FocusLocation(PC_TabBar, nIndex);

    return FocusLocation(PC_None, -1);
}

bool FocusManager::IsAnyPanelFocused (void) const
{
    for (::std::vector<Panel*>::const_iterator iPanel(maPanels.begin()),iEnd(maPanels.end());
         iPanel!=iEnd;
         ++iPanel)
    {
        if ((*iPanel)->HasFocus())
            return true;
        else if ((*iPanel)->HasChildPathFocus())
            return true;
    }
    return false;
}

bool FocusManager::IsAnyButtonFocused (void) const
{
    for (::std::vector<Button*>::const_iterator iButton(maButtons.begin()),iEnd(maButtons.end());
         iButton!=iEnd;
         ++iButton)
    {
        if ((*iButton)->HasFocus())
            return true;
    }
    return false;
}

void FocusManager::FocusDeckTitle (void)
{
    if (IsDeckTitleVisible())
    {
        ToolBox& rToolBox = mpDeckTitleBar->GetToolBox();
        if (rToolBox.GetItemCount() > 0)
        {
            rToolBox.GrabFocus();
            rToolBox.Invalidate();
        }
    }
    else
        FocusPanel(0);
}

bool FocusManager::IsDeckTitleVisible (void) const
{
    return mpDeckTitleBar != NULL && mpDeckTitleBar->IsVisible();
}

void FocusManager::FocusPanel (const sal_Int32 nPanelIndex)
{
    if (nPanelIndex<0 || nPanelIndex>=static_cast<sal_Int32>(maPanels.size()))
        return;
    Panel& rPanel (*maPanels[nPanelIndex]);
    TitleBar* pTitleBar = rPanel.GetTitleBar();
    if (pTitleBar!=NULL && pTitleBar->IsVisible())
    {
        rPanel.SetExpanded(true);
        pTitleBar->GrabFocus();
    }
    else
        FocusPanelContent(nPanelIndex);
    if (maShowPanelFunctor)
        maShowPanelFunctor(rPanel);
}

void FocusManager::FocusPanelContent (const sal_Int32 nPanelIndex)
{
    Window* pWindow = VCLUnoHelper::GetWindow(maPanels[nPanelIndex]->GetElementWindow());
    if (pWindow != NULL)
        pWindow->GrabFocus();
}

void FocusManager::FocusButton (const sal_Int32 nButtonIndex)
{
    maButtons[nButtonIndex]->GrabFocus();
    maButtons[nButtonIndex]->Invalidate();
}

void FocusManager::ClickButton (const sal_Int32 nButtonIndex)
{
    maButtons[nButtonIndex]->Click();
    if (nButtonIndex > 0)
        if ( ! maPanels.empty())
            FocusPanel(0);
    maButtons[nButtonIndex]->GetParent()->Invalidate();
}

void FocusManager::RemoveWindow (Window& rWindow)
{
    ::std::vector<Panel*>::iterator iPanel (::std::find(maPanels.begin(), maPanels.end(), &rWindow));
    if (iPanel != maPanels.end())
    {
        UnregisterWindow(rWindow);
        if ((*iPanel)->GetTitleBar() != NULL)
        {
            UnregisterWindow(*(*iPanel)->GetTitleBar());
            UnregisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
        }
        maPanels.erase(iPanel);
        return;
    }

    ::std::vector<Button*>::iterator iButton (::std::find(maButtons.begin(), maButtons.end(), &rWindow));
    if (iButton != maButtons.end())
    {
        UnregisterWindow(rWindow);
        maButtons.erase(iButton);
        return;
    }
}

bool FocusManager::MoveFocusInsidePanel (
    const FocusLocation aFocusLocation,
    const sal_Int32 nDirection)
{
    const bool bHasToolBoxItem (
        maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GetToolBox().GetItemCount() > 0);
    switch (aFocusLocation.meComponent)
    {
        case  PC_PanelTitle:
            if (nDirection > 0 && bHasToolBoxItem)
                maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GetToolBox().GrabFocus();
            else
                FocusPanelContent(aFocusLocation.mnIndex);
            return true;

        case PC_PanelToolBox:
            if (nDirection < 0 && bHasToolBoxItem)
                maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GrabFocus();
            else
                FocusPanelContent(aFocusLocation.mnIndex);
            return true;

        default:
            return false;
    }
}

void FocusManager::HandleKeyEvent (
    const KeyCode& rKeyCode,
    const Window& rWindow)
{
    const FocusLocation aLocation (GetFocusLocation(rWindow));

    switch (rKeyCode.GetCode())
    {
        case KEY_SPACE:
            switch (aLocation.meComponent)
            {
                case PC_PanelTitle:
                    // Toggle panel between expanded and collapsed.
                    maPanels[aLocation.mnIndex]->SetExpanded( ! maPanels[aLocation.mnIndex]->IsExpanded());
                    break;

                case PC_TabBar:
                    // Activate the button.
                    ClickButton(aLocation.mnIndex);
                    break;

                default:
                    break;
            }
            return;

        case KEY_RETURN:
            switch (aLocation.meComponent)
            {
                case PC_DeckToolBox:
                    FocusButton(0);
                    break;

                case PC_PanelTitle:
                    // Enter the panel.
                    FocusPanelContent(aLocation.mnIndex);
                    break;

                case PC_TabBar:
                    // Activate the button.
                    ClickButton(aLocation.mnIndex);
                    break;

                default:
                    break;
            }
            return;

        case KEY_TAB:
            switch (aLocation.meComponent)
            {
                case PC_PanelTitle:
                case PC_PanelToolBox:
                case PC_PanelContent:
                    if (rKeyCode.IsShift())
                        MoveFocusInsidePanel(aLocation, -1);
                    else
                        MoveFocusInsidePanel(aLocation, +1);
                    break;

                default:
                    break;
            }
            break;

        case KEY_LEFT:
        case KEY_UP:
            switch (aLocation.meComponent)
            {
                case PC_PanelTitle:
                case PC_PanelToolBox:
                case PC_PanelContent:
                    // Go to previous panel or the deck title.
                    if (aLocation.mnIndex > 0)
                        FocusPanel(aLocation.mnIndex-1);
                    else if (IsDeckTitleVisible())
                        FocusDeckTitle();
                    else
                        FocusButton(maButtons.size()-1);
                    break;

                case PC_DeckTitle:
                case PC_DeckToolBox:
                    // Focus the last button.
                    FocusButton(maButtons.size()-1);
                    break;

                case PC_TabBar:
                    // Go to previous tab bar item.
                    if (aLocation.mnIndex == 0)
                        FocusPanel(maPanels.size()-1);
                    else
                        FocusButton((aLocation.mnIndex + maButtons.size() - 1) % maButtons.size());
                    break;

                default:
                    break;
            }
            break;

        case KEY_RIGHT:
        case KEY_DOWN:
            switch(aLocation.meComponent)
            {
                case PC_PanelTitle:
                case PC_PanelToolBox:
                case PC_PanelContent:
                    // Go to next panel.
                    if (aLocation.mnIndex < static_cast<sal_Int32>(maPanels.size())-1)
                        FocusPanel(aLocation.mnIndex+1);
                    else
                        FocusButton(0);
                    break;

                case PC_DeckTitle:
                case PC_DeckToolBox:
                    // Focus the first panel.
                    FocusPanel(0);
                    break;

                case PC_TabBar:
                    // Go to next tab bar item.
                    if (aLocation.mnIndex < static_cast<sal_Int32>(maButtons.size())-1)
                        FocusButton(aLocation.mnIndex + 1);
                    else if (IsDeckTitleVisible())
                        FocusDeckTitle();
                    else
                        FocusPanel(0);
                    break;

                default:
                    break;
            }
            break;
    }
}

IMPL_LINK(FocusManager, WindowEventListener, VclSimpleEvent*, pEvent)
{
    if (pEvent == NULL)
        return 0;

    if ( ! pEvent->ISA(VclWindowEvent))
        return 0;

    VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
    Window* pSource = pWindowEvent->GetWindow();
    if (pSource == NULL)
        return 0;

    switch (pWindowEvent->GetId())
    {
        case VCLEVENT_WINDOW_KEYINPUT:
        {
            KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());
            HandleKeyEvent(pKeyEvent->GetKeyCode(), *pSource);
            return 1;
        }

        case VCLEVENT_OBJECT_DYING:
            RemoveWindow(*pSource);
            return 1;

        case VCLEVENT_WINDOW_GETFOCUS:
        case VCLEVENT_WINDOW_LOSEFOCUS:
            pSource->Invalidate();
    }

    return 0;
}

IMPL_LINK(FocusManager, ChildEventListener, VclSimpleEvent*, pEvent)
{
    if (pEvent == NULL)
        return 0;

    if ( ! pEvent->ISA(VclWindowEvent))
        return 0;

    VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
    Window* pSource = pWindowEvent->GetWindow();
    if (pSource == NULL)
        return 0;

    switch (pWindowEvent->GetId())
    {
        case VCLEVENT_WINDOW_KEYINPUT:
        {
            KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());

            // Go up the window hierarchy to find the parent of the
            // event source which is known to us.
            Window* pWindow = pSource;
            FocusLocation aLocation (PC_None, -1);
            while (true)
            {
                if (pWindow == NULL)
                    break;
                aLocation = GetFocusLocation(*pWindow);
                if (aLocation.meComponent != PC_None)
                    break;
                pWindow = pWindow->GetParent();
            }

            if (aLocation.meComponent != PC_None)
            {
                switch (pKeyEvent->GetKeyCode().GetCode())
                {
                    case KEY_ESCAPE:
                        // Return focus back to the panel title.
                        FocusPanel(aLocation.mnIndex);
                        break;

                    default:
                        break;
                }
            }
            break;
        }

        default:
            break;
    }

    return 1;
}

} } // end of namespace sfx2::sidebar
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008-2016 the MRtrix3 contributors
 *
 * 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/
 *
 * MRtrix 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.
 *
 * For more details, see www.mrtrix.org
 *
 */

#include "command.h"
#include "image.h"
#include <Eigen/Dense>
#include <Eigen/SVD>

#define DEFAULT_SIZE 5

using namespace MR;
using namespace App;

void usage ()
{
  DESCRIPTION
  + "denoise DWI data and estimate the noise level based on the optimal threshold for PCA.";

  AUTHOR = "Daan Christiaens (daan.christiaens@kuleuven.be) & Jelle Veraart (jelle.veraart@nyumc.org) & J-Donald Tournier (jdtournier.gmail.com)";

  ARGUMENTS
  + Argument ("dwi", "the input diffusion-weighted image.").type_image_in ()

  + Argument ("out", "the output denoised DWI image.").type_image_out ();

  OPTIONS
  + Option ("size", "set the window size of the denoising filter. (default = " + str(DEFAULT_SIZE) + ")")
    + Argument ("window").type_integer (0, 50)

  + Option ("noise", "the output noise map.")
    + Argument ("level").type_image_out();

}

typedef float value_type;

template <class ImageType>
class DenoisingFunctor
{
public:
  DenoisingFunctor (ImageType& dwi, int size)
    : extent(size/2),
      m(dwi.size(3)),
      n(size*size*size),
      r((m<n) ? m : n),
      X(m,n), Xm(m),
      pos{{0, 0, 0}}
  { }

  void operator () (ImageType& dwi, ImageType& out)
  {
    // Load data in local window
    load_data(dwi);
    // Centre data
    Xm = X.rowwise().mean();
    X.colwise() -= Xm;
    // Compute SVD
    Eigen::JacobiSVD<Eigen::MatrixXf> svd (X, Eigen::ComputeThinU | Eigen::ComputeThinV);
    Eigen::VectorXf s = svd.singularValues();
    Eigen::VectorXf lam = s.array().square() / n;
    Eigen::VectorXf clam (r);
    float cs = 0.0;
    for (size_t i = r; i != 0; --i) {
      cs += lam[i-1];
      clam[i-1] = cs;
    }
    float sigsq1, sigsq2, gam;
    size_t p;
    for (p = 0; p < r; ++p) {
      gam = float(m-p) / float(n);
      sigsq1 = clam[p] / (r-p) / ((gam<1.0) ? 1.0 : gam);
      sigsq2 = (lam[p] - lam[r]) / 4 / std::sqrt(gam);
      // for signal components sigsq2 > sigsq1
      if (sigsq2 < sigsq1)
        break;
    }
    s.tail(r-p).setZero();
    sigma = (p==r) ? NaN : std::sqrt(sigsq1);
    // Restore DWI data
    X = svd.matrixU() * s.asDiagonal() * svd.matrixV().adjoint();
    X.colwise() += Xm;
    // Store output
    assign_pos_of(dwi).to(out);
    out.row(3) = X.col(n/2).template cast<value_type>();
  }

  void operator () (ImageType& dwi, ImageType& out, ImageType& noise)
  {
    operator ()(dwi, out);
    assign_pos_of(dwi).to(noise);
    noise.value() = sigma;
  }

  void load_data (ImageType& dwi)
  {
    pos[0] = dwi.index(0); pos[1] = dwi.index(1); pos[2] = dwi.index(2);
    X.setZero();
    ssize_t k = 0;
    for (dwi.index(2) = pos[2]-extent; dwi.index(2) <= pos[2]+extent; ++dwi.index(2))
      for (dwi.index(1) = pos[1]-extent; dwi.index(1) <= pos[1]+extent; ++dwi.index(1))
        for (dwi.index(0) = pos[0]-extent; dwi.index(0) <= pos[0]+extent; ++dwi.index(0), ++k)
          if (! is_out_of_bounds(dwi))
            X.col(k) = dwi.row(3).template cast<float>();
    // reset image position
    dwi.index(0) = pos[0];
    dwi.index(1) = pos[1];
    dwi.index(2) = pos[2];
  }

private:
  int extent;
  size_t m, n, r;
  Eigen::MatrixXf X;
  Eigen::VectorXf Xm;
  std::array<ssize_t, 3> pos;
  float sigma;

};

void run ()
{
  auto dwi_in = Image<value_type>::open (argument[0]).with_direct_io(3);

  auto header = Header (dwi_in);
  header.datatype() = DataType::Float32;
  auto dwi_out = Image<value_type>::create (argument[1], header);

  int extent = get_option_value("size", DEFAULT_SIZE);

  DenoisingFunctor< Image<value_type> > func (dwi_in, extent);

  auto opt = get_options("noise");
  if (opt.size())
  {
    header.set_ndim(3);
    auto noise = Image<value_type>::create (opt[0][0], header);
    ThreadedLoop ("running MP-PCA denoising", dwi_in, 0, 3)
      .run (func, dwi_in, dwi_out, noise);
  }
  else
  {
    ThreadedLoop ("running MP-PCA denoising", dwi_in, 0, 3)
      .run (func, dwi_in, dwi_out);
  }

}

<commit_msg>Correct vector index error.<commit_after>/*
 * Copyright (c) 2008-2016 the MRtrix3 contributors
 *
 * 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/
 *
 * MRtrix 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.
 *
 * For more details, see www.mrtrix.org
 *
 */

#include "command.h"
#include "image.h"
#include <Eigen/Dense>
#include <Eigen/SVD>

#define DEFAULT_SIZE 5

using namespace MR;
using namespace App;

void usage ()
{
  DESCRIPTION
  + "denoise DWI data and estimate the noise level based on the optimal threshold for PCA.";

  AUTHOR = "Daan Christiaens (daan.christiaens@kuleuven.be) & Jelle Veraart (jelle.veraart@nyumc.org) & J-Donald Tournier (jdtournier.gmail.com)";

  ARGUMENTS
  + Argument ("dwi", "the input diffusion-weighted image.").type_image_in ()

  + Argument ("out", "the output denoised DWI image.").type_image_out ();

  OPTIONS
  + Option ("size", "set the window size of the denoising filter. (default = " + str(DEFAULT_SIZE) + ")")
    + Argument ("window").type_integer (0, 50)

  + Option ("noise", "the output noise map.")
    + Argument ("level").type_image_out();

}

typedef float value_type;

template <class ImageType>
class DenoisingFunctor
{
public:
  DenoisingFunctor (ImageType& dwi, int size)
    : extent(size/2),
      m(dwi.size(3)),
      n(size*size*size),
      r((m<n) ? m : n),
      X(m,n), Xm(m),
      pos{{0, 0, 0}}
  { }

  void operator () (ImageType& dwi, ImageType& out)
  {
    // Load data in local window
    load_data(dwi);
    // Centre data
    Xm = X.rowwise().mean();
    X.colwise() -= Xm;
    // Compute SVD
    Eigen::JacobiSVD<Eigen::MatrixXf> svd (X, Eigen::ComputeThinU | Eigen::ComputeThinV);
    Eigen::VectorXf s = svd.singularValues();
    Eigen::VectorXf lam = s.array().square() / n;
    Eigen::VectorXf clam (r);
    float cs = 0.0;
    for (size_t i = r; i != 0; --i) {
      cs += lam[i-1];
      clam[i-1] = cs;
    }
    float sigsq1, sigsq2, gam;
    size_t p;
    for (p = 0; p < r; ++p) {
      gam = float(m-p) / float(n);
      sigsq1 = clam[p] / (r-p) / ((gam<1.0) ? 1.0 : gam);
      sigsq2 = (lam[p] - lam[r-1]) / 4 / std::sqrt(gam);
      // for signal components sigsq2 > sigsq1
      if (sigsq2 < sigsq1)
        break;
    }
    s.tail(r-p).setZero();
    sigma = (p==r) ? NaN : std::sqrt(sigsq1);
    // Restore DWI data
    X = svd.matrixU() * s.asDiagonal() * svd.matrixV().adjoint();
    X.colwise() += Xm;
    // Store output
    assign_pos_of(dwi).to(out);
    out.row(3) = X.col(n/2).template cast<value_type>();
  }

  void operator () (ImageType& dwi, ImageType& out, ImageType& noise)
  {
    operator ()(dwi, out);
    assign_pos_of(dwi).to(noise);
    noise.value() = sigma;
  }

  void load_data (ImageType& dwi)
  {
    pos[0] = dwi.index(0); pos[1] = dwi.index(1); pos[2] = dwi.index(2);
    X.setZero();
    ssize_t k = 0;
    for (dwi.index(2) = pos[2]-extent; dwi.index(2) <= pos[2]+extent; ++dwi.index(2))
      for (dwi.index(1) = pos[1]-extent; dwi.index(1) <= pos[1]+extent; ++dwi.index(1))
        for (dwi.index(0) = pos[0]-extent; dwi.index(0) <= pos[0]+extent; ++dwi.index(0), ++k)
          if (! is_out_of_bounds(dwi))
            X.col(k) = dwi.row(3).template cast<float>();
    // reset image position
    dwi.index(0) = pos[0];
    dwi.index(1) = pos[1];
    dwi.index(2) = pos[2];
  }

private:
  int extent;
  size_t m, n, r;
  Eigen::MatrixXf X;
  Eigen::VectorXf Xm;
  std::array<ssize_t, 3> pos;
  float sigma;

};

void run ()
{
  auto dwi_in = Image<value_type>::open (argument[0]).with_direct_io(3);

  auto header = Header (dwi_in);
  header.datatype() = DataType::Float32;
  auto dwi_out = Image<value_type>::create (argument[1], header);

  int extent = get_option_value("size", DEFAULT_SIZE);

  DenoisingFunctor< Image<value_type> > func (dwi_in, extent);

  auto opt = get_options("noise");
  if (opt.size())
  {
    header.set_ndim(3);
    auto noise = Image<value_type>::create (opt[0][0], header);
    ThreadedLoop ("running MP-PCA denoising", dwi_in, 0, 3)
      .run (func, dwi_in, dwi_out, noise);
  }
  else
  {
    ThreadedLoop ("running MP-PCA denoising", dwi_in, 0, 3)
      .run (func, dwi_in, dwi_out);
  }

}

<|endoftext|>


<commit_before>// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.

#include <stdio.h>
#include <string.h>

// libwebm parser includes
#include "mkvreader.hpp"
#include "mkvparser.hpp"

// libwebm muxer includes
#include "mkvmuxer.hpp"
#include "mkvwriter.hpp"
#include "mkvmuxerutil.hpp"

namespace {

void Usage() {
  printf("Usage: sample_muxer -i input -o output [options]\n");
  printf("\n");
  printf("Main options:\n");
  printf("  -h | -?                     show help\n");
  printf("  -video <int>                >0 outputs video\n");
  printf("  -audio <int>                >0 outputs audio\n");
  printf("  -live <int>                 >0 puts the muxer into live mode\n");
  printf("                              0 puts the muxer into file mode\n");
  printf("  -output_cues <int>          >0 outputs cues element\n");
  printf("  -cues_on_video_track <int>  >0 outputs cues on video track\n");
  printf("                              0 outputs cues on audio track\n");
  printf("  -max_cluster_duration <double> in seconds\n");
  printf("  -max_cluster_size <int>     in bytes\n");
  printf("  -switch_tracks <int>        >0 switches tracks in output\n");
  printf("\n");
  printf("Video options:\n");
  printf("  -display_width <int>        Display width in pixels\n");
  printf("  -display_height <int>       Display height in pixels\n");
  printf("  -stereo_mode <int>          3D video mode\n");
  printf("\n");
  printf("Cues options:\n");
  printf("  -output_cues_block_number <int> >0 outputs cue block number\n");
}

} //end namespace

int main(int argc, char* argv[]) {
  using mkvmuxer::uint64;

  char* input = NULL;
  char* output = NULL;

  // Segment variables
  bool output_video = true;
  bool output_audio = true;
  bool live_mode = false;
  bool output_cues = true;
  bool cues_on_video_track = true;
  uint64 max_cluster_duration = 0;
  uint64 max_cluster_size = 0;
  bool switch_tracks = false;

  bool output_cues_block_number = true;

  uint64 display_width = 0;
  uint64 display_height = 0;
  uint64 stereo_mode = 0;

  for (int i = 1; i < argc; ++i) {
    char* end;

    if (!strcmp("-h", argv[i]) || !strcmp("-?", argv[i])) {
      Usage();
      return 0;
    } else if (!strcmp("-i", argv[i])) {
      input = argv[++i];
    } else if (!strcmp("-o", argv[i])) {
      output = argv[++i];
    } else if (!strcmp("-video", argv[i])) {
      output_video = strtol(argv[++i], &end, 10) == 0 ? false : true;
    } else if (!strcmp("-audio", argv[i])) {
      output_audio = strtol(argv[++i], &end, 10) == 0 ? false : true;
    } else if (!strcmp("-live", argv[i])) {
      live_mode = strtol(argv[++i], &end, 10) == 0 ? false : true;
    } else if (!strcmp("-output_cues", argv[i])) {
      output_cues = strtol(argv[++i], &end, 10) == 0 ? false : true;
    } else if (!strcmp("-cues_on_video_track", argv[i])) {
      cues_on_video_track = strtol(argv[++i], &end, 10) == 0 ? false : true;
    } else if (!strcmp("-max_cluster_duration", argv[i])) {
      const double seconds = strtod(argv[++i], &end);
      max_cluster_duration =
          static_cast<uint64>(seconds * 1000000000.0);
    } else if (!strcmp("-max_cluster_size", argv[i])) {
      max_cluster_size = strtol(argv[++i], &end, 10);
    } else if (!strcmp("-switch_tracks", argv[i])) {
      switch_tracks = strtol(argv[++i], &end, 10) == 0 ? false : true;
    } else if (!strcmp("-display_width", argv[i])) {
      display_width = strtol(argv[++i], &end, 10);
    } else if (!strcmp("-display_height", argv[i])) {
      display_height = strtol(argv[++i], &end, 10);
    } else if (!strcmp("-stereo_mode", argv[i])) {
      stereo_mode = strtol(argv[++i], &end, 10);
    } else if (!strcmp("-output_cues_block_number", argv[i])) {
      output_cues_block_number =
          strtol(argv[++i], &end, 10) == 0 ? false : true;
    }
  }

  if (input == NULL || output == NULL) {
    Usage();
    return 0;
  }

  // Get parser header info
  mkvparser::MkvReader reader;

  if (reader.Open(input)) {
    printf("\n Filename is invalid or error while opening.\n");
    return -1;
  }

  long long pos = 0;
  mkvparser::EBMLHeader ebml_header;
  ebml_header.Parse(&reader, pos);

  mkvparser::Segment* parser_segment;
  long long ret = mkvparser::Segment::CreateInstance(&reader,
                                                     pos,
                                                     parser_segment);
  if (ret) {
    printf("\n Segment::CreateInstance() failed.");
    return -1;
  }

  ret = parser_segment->Load();
  if (ret < 0) {
    printf("\n Segment::Load() failed.");
    return -1;
  }

  const mkvparser::SegmentInfo* const segment_info = parser_segment->GetInfo();
  const long long timeCodeScale = segment_info->GetTimeCodeScale();

  // Set muxer header info
  mkvmuxer::MkvWriter writer;

  if (!writer.Open(output)) {
    printf("\n Filename is invalid or error while opening.\n");
    return -1;
  }

  // Set Segment element attributes
  mkvmuxer::Segment muxer_segment(&writer);
  if (live_mode)
    muxer_segment.set_mode(mkvmuxer::Segment::kLive);
  else
    muxer_segment.set_mode(mkvmuxer::Segment::kFile);

  if (max_cluster_duration > 0)
    muxer_segment.set_max_cluster_duration(max_cluster_duration);
  if (max_cluster_size > 0)
    muxer_segment.set_max_cluster_size(max_cluster_size);
  muxer_segment.OutputCues(output_cues);

  // Set SegmentInfo element attributes
  mkvmuxer::SegmentInfo* info = muxer_segment.GetSegmentInfo();
  info->set_timecode_scale(timeCodeScale);
  info->set_writing_app("sample_muxer");

  // Set Tracks element attributes
  enum { kVideoTrack = 1, kAudioTrack = 2 };
  const mkvparser::Tracks* parser_tracks = parser_segment->GetTracks();
  unsigned long i = 0;
  uint64 vid_track = 0; // no track added
  uint64 aud_track = 0; // no track added

  while (i != parser_tracks->GetTracksCount()) {
    int track_num = i++;
    if (switch_tracks)
      track_num = i % parser_tracks->GetTracksCount();

    const mkvparser::Track* const parser_track =
        parser_tracks->GetTrackByIndex(track_num);

    if (parser_track == NULL)
      continue;

    // TODO(fgalligan): Add support for language to parser.
    const char* track_name = parser_track->GetNameAsUTF8();

    const long long track_type = parser_track->GetType();

    if (track_type == kVideoTrack && output_video) {
      // Get the video track from the parser
      const mkvparser::VideoTrack* const pVideoTrack =
          static_cast<const mkvparser::VideoTrack*>(parser_track);
      const long long width =  pVideoTrack->GetWidth();
      const long long height = pVideoTrack->GetHeight();

      // Add the video track to the muxer
      vid_track = muxer_segment.AddVideoTrack(static_cast<int>(width),
                                              static_cast<int>(height));
      if (!vid_track) {
        printf("\n Could not add video track.\n");
        return -1;
      }

      mkvmuxer::VideoTrack* video =
          static_cast<mkvmuxer::VideoTrack*>(
            muxer_segment.GetTrackByNumber(vid_track));
      if (!video) {
        printf("\n Could not get video track.\n");
        return -1;
      }

      if (track_name)
        video->set_name(track_name);

      if (display_width > 0)
        video->set_display_width(display_width);
      if (display_height > 0)
        video->set_display_height(display_height);
      if (stereo_mode > 0)
        video->SetStereoMode(stereo_mode);

      const double rate = pVideoTrack->GetFrameRate();
      if (rate > 0.0) {
        video->set_frame_rate(rate);
      }
    } else if (track_type == kAudioTrack && output_audio) {
      // Get the audio track from the parser
      const mkvparser::AudioTrack* const pAudioTrack =
          static_cast<const mkvparser::AudioTrack*>(parser_track);
      const long long channels =  pAudioTrack->GetChannels();
      const double sample_rate = pAudioTrack->GetSamplingRate();

      // Add the audio track to the muxer
      aud_track = muxer_segment.AddAudioTrack(static_cast<int>(sample_rate),
                                              static_cast<int>(channels));
      if (!aud_track) {
        printf("\n Could not add audio track.\n");
        return -1;
      }

      mkvmuxer::AudioTrack* audio =
          static_cast<mkvmuxer::AudioTrack*>(
            muxer_segment.GetTrackByNumber(aud_track));
      if (!audio) {
        printf("\n Could not get audio track.\n");
        return -1;
      }

      if (track_name)
        audio->set_name(track_name);

      size_t private_size;
      const unsigned char* private_data =
          pAudioTrack->GetCodecPrivate(private_size);
      if (private_size > 0) {
        if (!audio->SetCodecPrivate(private_data, private_size)) {
          printf("\n Could not add audio private data.\n");
          return -1;
        }
      }

      const long long bit_depth = pAudioTrack->GetBitDepth();
      if (bit_depth > 0)
        audio->set_bit_depth(bit_depth);
    }
  }

  // Set Cues element attributes
  mkvmuxer::Cues* cues = muxer_segment.GetCues();
  cues->set_output_block_number(output_cues_block_number);
  if (cues_on_video_track) {
    if (vid_track)
      muxer_segment.CuesTrack(vid_track);
  } else {
    if (aud_track)
      muxer_segment.CuesTrack(aud_track);
  }

  // Write clusters
  unsigned char* data = NULL;
  int data_len = 0;

  const mkvparser::Cluster* cluster = parser_segment->GetFirst();

  while ((cluster != NULL) && !cluster->EOS()) {
    const mkvparser::BlockEntry* block_entry = cluster->GetFirst();

    while ((block_entry != NULL) && !block_entry->EOS()) {
      const mkvparser::Block* const block = block_entry->GetBlock();
      const long long trackNum = block->GetTrackNumber();
      const mkvparser::Track* const parser_track =
          parser_tracks->GetTrackByNumber(
            static_cast<unsigned long>(trackNum));
      const long long track_type = parser_track->GetType();

      if ((track_type == kAudioTrack && output_audio) ||
          (track_type == kVideoTrack && output_video)) {
        const int frame_count = block->GetFrameCount();
        const long long time_ns = block->GetTime(cluster);
        const bool is_key = block->IsKey();

        for (int i = 0; i < frame_count; ++i) {
          const mkvparser::Block::Frame& frame = block->GetFrame(i);

          if (frame.len > data_len) {
            delete [] data;
            data = new unsigned char[frame.len];
            if (!data)
              return -1;
            data_len = frame.len;
          }

          if (frame.Read(&reader, data))
            return -1;

          uint64 track_num = vid_track;
          if (track_type == kAudioTrack)
            track_num = aud_track;

          if (!muxer_segment.AddFrame(data,
                                      frame.len,
                                      track_num,
                                      time_ns,
                                      is_key)) {
            printf("\n Could not add frame.\n");
            return -1;
          }
        }
      }

      block_entry = cluster->GetNext(block_entry);
    }

    cluster = parser_segment->GetNext(cluster);
  }

  muxer_segment.Finalize();

  delete [] data;
  delete parser_segment;
  return 0;
}

<commit_msg>Added const to some pointers.<commit_after>// Copyright (c) 2011 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.

#include <stdio.h>
#include <string.h>

// libwebm parser includes
#include "mkvreader.hpp"
#include "mkvparser.hpp"

// libwebm muxer includes
#include "mkvmuxer.hpp"
#include "mkvwriter.hpp"
#include "mkvmuxerutil.hpp"

namespace {

void Usage() {
  printf("Usage: sample_muxer -i input -o output [options]\n");
  printf("\n");
  printf("Main options:\n");
  printf("  -h | -?                     show help\n");
  printf("  -video <int>                >0 outputs video\n");
  printf("  -audio <int>                >0 outputs audio\n");
  printf("  -live <int>                 >0 puts the muxer into live mode\n");
  printf("                              0 puts the muxer into file mode\n");
  printf("  -output_cues <int>          >0 outputs cues element\n");
  printf("  -cues_on_video_track <int>  >0 outputs cues on video track\n");
  printf("                              0 outputs cues on audio track\n");
  printf("  -max_cluster_duration <double> in seconds\n");
  printf("  -max_cluster_size <int>     in bytes\n");
  printf("  -switch_tracks <int>        >0 switches tracks in output\n");
  printf("\n");
  printf("Video options:\n");
  printf("  -display_width <int>        Display width in pixels\n");
  printf("  -display_height <int>       Display height in pixels\n");
  printf("  -stereo_mode <int>          3D video mode\n");
  printf("\n");
  printf("Cues options:\n");
  printf("  -output_cues_block_number <int> >0 outputs cue block number\n");
}

} //end namespace

int main(int argc, char* argv[]) {
  using mkvmuxer::uint64;

  char* input = NULL;
  char* output = NULL;

  // Segment variables
  bool output_video = true;
  bool output_audio = true;
  bool live_mode = false;
  bool output_cues = true;
  bool cues_on_video_track = true;
  uint64 max_cluster_duration = 0;
  uint64 max_cluster_size = 0;
  bool switch_tracks = false;

  bool output_cues_block_number = true;

  uint64 display_width = 0;
  uint64 display_height = 0;
  uint64 stereo_mode = 0;

  for (int i = 1; i < argc; ++i) {
    char* end;

    if (!strcmp("-h", argv[i]) || !strcmp("-?", argv[i])) {
      Usage();
      return 0;
    } else if (!strcmp("-i", argv[i])) {
      input = argv[++i];
    } else if (!strcmp("-o", argv[i])) {
      output = argv[++i];
    } else if (!strcmp("-video", argv[i])) {
      output_video = strtol(argv[++i], &end, 10) == 0 ? false : true;
    } else if (!strcmp("-audio", argv[i])) {
      output_audio = strtol(argv[++i], &end, 10) == 0 ? false : true;
    } else if (!strcmp("-live", argv[i])) {
      live_mode = strtol(argv[++i], &end, 10) == 0 ? false : true;
    } else if (!strcmp("-output_cues", argv[i])) {
      output_cues = strtol(argv[++i], &end, 10) == 0 ? false : true;
    } else if (!strcmp("-cues_on_video_track", argv[i])) {
      cues_on_video_track = strtol(argv[++i], &end, 10) == 0 ? false : true;
    } else if (!strcmp("-max_cluster_duration", argv[i])) {
      const double seconds = strtod(argv[++i], &end);
      max_cluster_duration =
          static_cast<uint64>(seconds * 1000000000.0);
    } else if (!strcmp("-max_cluster_size", argv[i])) {
      max_cluster_size = strtol(argv[++i], &end, 10);
    } else if (!strcmp("-switch_tracks", argv[i])) {
      switch_tracks = strtol(argv[++i], &end, 10) == 0 ? false : true;
    } else if (!strcmp("-display_width", argv[i])) {
      display_width = strtol(argv[++i], &end, 10);
    } else if (!strcmp("-display_height", argv[i])) {
      display_height = strtol(argv[++i], &end, 10);
    } else if (!strcmp("-stereo_mode", argv[i])) {
      stereo_mode = strtol(argv[++i], &end, 10);
    } else if (!strcmp("-output_cues_block_number", argv[i])) {
      output_cues_block_number =
          strtol(argv[++i], &end, 10) == 0 ? false : true;
    }
  }

  if (input == NULL || output == NULL) {
    Usage();
    return 0;
  }

  // Get parser header info
  mkvparser::MkvReader reader;

  if (reader.Open(input)) {
    printf("\n Filename is invalid or error while opening.\n");
    return -1;
  }

  long long pos = 0;
  mkvparser::EBMLHeader ebml_header;
  ebml_header.Parse(&reader, pos);

  mkvparser::Segment* parser_segment;
  long long ret = mkvparser::Segment::CreateInstance(&reader,
                                                     pos,
                                                     parser_segment);
  if (ret) {
    printf("\n Segment::CreateInstance() failed.");
    return -1;
  }

  ret = parser_segment->Load();
  if (ret < 0) {
    printf("\n Segment::Load() failed.");
    return -1;
  }

  const mkvparser::SegmentInfo* const segment_info = parser_segment->GetInfo();
  const long long timeCodeScale = segment_info->GetTimeCodeScale();

  // Set muxer header info
  mkvmuxer::MkvWriter writer;

  if (!writer.Open(output)) {
    printf("\n Filename is invalid or error while opening.\n");
    return -1;
  }

  // Set Segment element attributes
  mkvmuxer::Segment muxer_segment(&writer);
  if (live_mode)
    muxer_segment.set_mode(mkvmuxer::Segment::kLive);
  else
    muxer_segment.set_mode(mkvmuxer::Segment::kFile);

  if (max_cluster_duration > 0)
    muxer_segment.set_max_cluster_duration(max_cluster_duration);
  if (max_cluster_size > 0)
    muxer_segment.set_max_cluster_size(max_cluster_size);
  muxer_segment.OutputCues(output_cues);

  // Set SegmentInfo element attributes
  mkvmuxer::SegmentInfo* const info = muxer_segment.GetSegmentInfo();
  info->set_timecode_scale(timeCodeScale);
  info->set_writing_app("sample_muxer");

  // Set Tracks element attributes
  enum { kVideoTrack = 1, kAudioTrack = 2 };
  const mkvparser::Tracks* const parser_tracks = parser_segment->GetTracks();
  unsigned long i = 0;
  uint64 vid_track = 0; // no track added
  uint64 aud_track = 0; // no track added

  while (i != parser_tracks->GetTracksCount()) {
    int track_num = i++;
    if (switch_tracks)
      track_num = i % parser_tracks->GetTracksCount();

    const mkvparser::Track* const parser_track =
        parser_tracks->GetTrackByIndex(track_num);

    if (parser_track == NULL)
      continue;

    // TODO(fgalligan): Add support for language to parser.
    const char* const track_name = parser_track->GetNameAsUTF8();

    const long long track_type = parser_track->GetType();

    if (track_type == kVideoTrack && output_video) {
      // Get the video track from the parser
      const mkvparser::VideoTrack* const pVideoTrack =
          static_cast<const mkvparser::VideoTrack*>(parser_track);
      const long long width =  pVideoTrack->GetWidth();
      const long long height = pVideoTrack->GetHeight();

      // Add the video track to the muxer
      vid_track = muxer_segment.AddVideoTrack(static_cast<int>(width),
                                              static_cast<int>(height));
      if (!vid_track) {
        printf("\n Could not add video track.\n");
        return -1;
      }

      mkvmuxer::VideoTrack* const video =
          static_cast<mkvmuxer::VideoTrack*>(
              muxer_segment.GetTrackByNumber(vid_track));
      if (!video) {
        printf("\n Could not get video track.\n");
        return -1;
      }

      if (track_name)
        video->set_name(track_name);

      if (display_width > 0)
        video->set_display_width(display_width);
      if (display_height > 0)
        video->set_display_height(display_height);
      if (stereo_mode > 0)
        video->SetStereoMode(stereo_mode);

      const double rate = pVideoTrack->GetFrameRate();
      if (rate > 0.0) {
        video->set_frame_rate(rate);
      }
    } else if (track_type == kAudioTrack && output_audio) {
      // Get the audio track from the parser
      const mkvparser::AudioTrack* const pAudioTrack =
          static_cast<const mkvparser::AudioTrack*>(parser_track);
      const long long channels =  pAudioTrack->GetChannels();
      const double sample_rate = pAudioTrack->GetSamplingRate();

      // Add the audio track to the muxer
      aud_track = muxer_segment.AddAudioTrack(static_cast<int>(sample_rate),
                                              static_cast<int>(channels));
      if (!aud_track) {
        printf("\n Could not add audio track.\n");
        return -1;
      }

      mkvmuxer::AudioTrack* const audio =
          static_cast<mkvmuxer::AudioTrack*>(
              muxer_segment.GetTrackByNumber(aud_track));
      if (!audio) {
        printf("\n Could not get audio track.\n");
        return -1;
      }

      if (track_name)
        audio->set_name(track_name);

      size_t private_size;
      const unsigned char* const private_data =
          pAudioTrack->GetCodecPrivate(private_size);
      if (private_size > 0) {
        if (!audio->SetCodecPrivate(private_data, private_size)) {
          printf("\n Could not add audio private data.\n");
          return -1;
        }
      }

      const long long bit_depth = pAudioTrack->GetBitDepth();
      if (bit_depth > 0)
        audio->set_bit_depth(bit_depth);
    }
  }

  // Set Cues element attributes
  mkvmuxer::Cues* const cues = muxer_segment.GetCues();
  cues->set_output_block_number(output_cues_block_number);
  if (cues_on_video_track) {
    if (vid_track)
      muxer_segment.CuesTrack(vid_track);
  } else {
    if (aud_track)
      muxer_segment.CuesTrack(aud_track);
  }

  // Write clusters
  unsigned char* data = NULL;
  int data_len = 0;

  const mkvparser::Cluster* cluster = parser_segment->GetFirst();

  while ((cluster != NULL) && !cluster->EOS()) {
    const mkvparser::BlockEntry* block_entry = cluster->GetFirst();

    while ((block_entry != NULL) && !block_entry->EOS()) {
      const mkvparser::Block* const block = block_entry->GetBlock();
      const long long trackNum = block->GetTrackNumber();
      const mkvparser::Track* const parser_track =
          parser_tracks->GetTrackByNumber(
              static_cast<unsigned long>(trackNum));
      const long long track_type = parser_track->GetType();

      if ((track_type == kAudioTrack && output_audio) ||
          (track_type == kVideoTrack && output_video)) {
        const int frame_count = block->GetFrameCount();
        const long long time_ns = block->GetTime(cluster);
        const bool is_key = block->IsKey();

        for (int i = 0; i < frame_count; ++i) {
          const mkvparser::Block::Frame& frame = block->GetFrame(i);

          if (frame.len > data_len) {
            delete [] data;
            data = new unsigned char[frame.len];
            if (!data)
              return -1;
            data_len = frame.len;
          }

          if (frame.Read(&reader, data))
            return -1;

          uint64 track_num = vid_track;
          if (track_type == kAudioTrack)
            track_num = aud_track;

          if (!muxer_segment.AddFrame(data,
                                      frame.len,
                                      track_num,
                                      time_ns,
                                      is_key)) {
            printf("\n Could not add frame.\n");
            return -1;
          }
        }
      }

      block_entry = cluster->GetNext(block_entry);
    }

    cluster = parser_segment->GetNext(cluster);
  }

  muxer_segment.Finalize();

  delete [] data;
  delete parser_segment;

  writer.Close();
  reader.Close();

  return 0;
}

<|endoftext|>


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

#ifndef _SWTEXTSH_HXX
#define _SWTEXTSH_HXX

#ifndef _SWBASESH_HXX
#include <basesh.hxx>
#endif

//CHINA001 class Button;
class AbstractSvxPostItDialog;
class SwFldMgr;
class SvxHyperlinkItem;

class SwTextShell: public SwBaseShell
{
    SwFldMgr*   pPostItFldMgr;

    void InsertSymbol( SfxRequest& );
    void InsertHyperlink(const SvxHyperlinkItem& rHlnkItem);
    BOOL InsertGraphicDlg( SfxRequest& );
    bool InsertMediaDlg( SfxRequest& );
    void ChangeHeaderOrFooter(const String& rStyleName, BOOL bHeader, BOOL bOn, BOOL bShowWarning);

public:
    SFX_DECL_INTERFACE(SW_TEXTSHELL);
    TYPEINFO();

//CHINA001  DECL_LINK( PostItNextHdl, Button * );
//CHINA001  DECL_LINK( PostItPrevHdl, Button * );
//CHINA001  DECL_LINK( RedlineNextHdl, Button * );
//CHINA001  DECL_LINK( RedlinePrevHdl, Button * );
    DECL_LINK( PostItNextHdl, AbstractSvxPostItDialog * );
    DECL_LINK( PostItPrevHdl, AbstractSvxPostItDialog * );
    DECL_LINK( RedlineNextHdl, AbstractSvxPostItDialog * );
    DECL_LINK( RedlinePrevHdl, AbstractSvxPostItDialog * );

    void    Execute(SfxRequest &);
    void    GetState(SfxItemSet &);

    void    ExecInsert(SfxRequest &);
    void    StateInsert(SfxItemSet&);
    void    ExecDelete(SfxRequest &);
    void    ExecEnterNum(SfxRequest &);
    void    ExecBasicMove(SfxRequest &);
    void    ExecMove(SfxRequest &);
    void    ExecMovePage(SfxRequest &);
    void    ExecMoveCol(SfxRequest &);
    void    ExecMoveLingu(SfxRequest &);
    void    ExecMoveMisc(SfxRequest &);
    void    ExecField(SfxRequest &rReq);
    void    StateField(SfxItemSet &);
    void    ExecIdx(SfxRequest &);
    void    GetIdxState(SfxItemSet &);
    void    ExecGlossary(SfxRequest &);

    void    ExecCharAttr(SfxRequest &);
    void    ExecCharAttrArgs(SfxRequest &);
    void    ExecParaAttr(SfxRequest &);
    void    ExecParaAttrArgs(SfxRequest &);
    void    ExecAttr(SfxRequest &);
    void    ExecDB(SfxRequest &);
    void    ExecTransliteration(SfxRequest &);

    void    GetAttrState(SfxItemSet &);

             SwTextShell(SwView &rView);
    virtual ~SwTextShell();
};

#endif
<commit_msg>INTEGRATION: CWS swqbf51 (1.12.178); FILE MERGED 2006/01/30 11:24:17 tl 1.12.178.1: #125842# moving InsertGraphicDlg to SwView<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: textsh.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: rt $ $Date: 2006-02-06 17:23:53 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SWTEXTSH_HXX
#define _SWTEXTSH_HXX

#ifndef _SWBASESH_HXX
#include <basesh.hxx>
#endif

//CHINA001 class Button;
class AbstractSvxPostItDialog;
class SwFldMgr;
class SvxHyperlinkItem;

class SwTextShell: public SwBaseShell
{
    SwFldMgr*   pPostItFldMgr;

    void InsertSymbol( SfxRequest& );
    void InsertHyperlink(const SvxHyperlinkItem& rHlnkItem);
    bool InsertMediaDlg( SfxRequest& );
    void ChangeHeaderOrFooter(const String& rStyleName, BOOL bHeader, BOOL bOn, BOOL bShowWarning);

public:
    SFX_DECL_INTERFACE(SW_TEXTSHELL);
    TYPEINFO();

//CHINA001  DECL_LINK( PostItNextHdl, Button * );
//CHINA001  DECL_LINK( PostItPrevHdl, Button * );
//CHINA001  DECL_LINK( RedlineNextHdl, Button * );
//CHINA001  DECL_LINK( RedlinePrevHdl, Button * );
    DECL_LINK( PostItNextHdl, AbstractSvxPostItDialog * );
    DECL_LINK( PostItPrevHdl, AbstractSvxPostItDialog * );
    DECL_LINK( RedlineNextHdl, AbstractSvxPostItDialog * );
    DECL_LINK( RedlinePrevHdl, AbstractSvxPostItDialog * );

    void    Execute(SfxRequest &);
    void    GetState(SfxItemSet &);

    void    ExecInsert(SfxRequest &);
    void    StateInsert(SfxItemSet&);
    void    ExecDelete(SfxRequest &);
    void    ExecEnterNum(SfxRequest &);
    void    ExecBasicMove(SfxRequest &);
    void    ExecMove(SfxRequest &);
    void    ExecMovePage(SfxRequest &);
    void    ExecMoveCol(SfxRequest &);
    void    ExecMoveLingu(SfxRequest &);
    void    ExecMoveMisc(SfxRequest &);
    void    ExecField(SfxRequest &rReq);
    void    StateField(SfxItemSet &);
    void    ExecIdx(SfxRequest &);
    void    GetIdxState(SfxItemSet &);
    void    ExecGlossary(SfxRequest &);

    void    ExecCharAttr(SfxRequest &);
    void    ExecCharAttrArgs(SfxRequest &);
    void    ExecParaAttr(SfxRequest &);
    void    ExecParaAttrArgs(SfxRequest &);
    void    ExecAttr(SfxRequest &);
    void    ExecDB(SfxRequest &);
    void    ExecTransliteration(SfxRequest &);

    void    GetAttrState(SfxItemSet &);

             SwTextShell(SwView &rView);
    virtual ~SwTextShell();
};

#endif
<|endoftext|>


<commit_before>#include "../../base/SRC_FIRST.hpp"

#include "api.hpp"

#include "../feature_vec_model.hpp"

#include "../../indexer/data_factory.hpp"
#include "../../indexer/feature_visibility.hpp"

#include "../../platform/platform.hpp"

#include "../../base/timer.hpp"

#include "../../base/start_mem_debug.hpp"

namespace bench
{

namespace
{
  class Accumulator
  {
    my::Timer m_timer;
    size_t m_count;

    int m_scale;

  public:
    Result m_res;

    void Reset(int scale)
    {
      m_scale = scale;
      m_count = 0;
    }

    bool IsEmpty() const { return m_count == 0; }

    void operator() (FeatureType const & ft)
    {
      ++m_count;

      m_timer.Reset();

      vector<drule::Key> keys;
      string names;       // for debug use only, in release it's empty
      (void)feature::GetDrawRule(ft, m_scale, keys, names);

      if (!keys.empty())
      {
        // Call this function to load feature's inner data and geometry.
        (void)ft.IsEmptyGeometry(m_scale);
      }

      m_res.Add(m_timer.ElapsedSeconds());
    }
  };

  Result RunBenchmark(model::FeaturesFetcher const & src, m2::RectD const & rect,
                      pair<int, int> const & scaleR)
  {
    ASSERT_LESS_OR_EQUAL ( scaleR.first, scaleR.second, () );

    vector<m2::RectD> rects;
    rects.push_back(rect);

    Accumulator acc;

    while (!rects.empty())
    {
      m2::RectD const r = rects.back();
      rects.pop_back();

      bool doDivide = true;
      int const scale = scales::GetScaleLevel(r);
      if (scale >= scaleR.first)
      {
        acc.Reset(scale);
        src.ForEachFeature(r, acc, scale);
        doDivide = !acc.IsEmpty();
      }

      if (doDivide && scale < scaleR.second)
      {
        m2::RectD r1, r2;
        r.DivideByGreaterSize(r1, r2);
        rects.push_back(r1);
        rects.push_back(r2);
      }
    }

    return acc.m_res;
  }
}

AllResult RunFeaturesLoadingBenchmark(string const & file, size_t count, pair<int, int> scaleR)
{
  feature::DataHeader header;
  LoadMapHeader(GetPlatform().GetReader(file), header);

  pair<int, int> const r = header.GetScaleRange();
  if (r.first > scaleR.first)
    scaleR.first = r.first;
  if (r.second < scaleR.second)
    scaleR.second = r.second;

  if (scaleR.first > scaleR.second)
    return;

  model::FeaturesFetcher src;
  src.AddMap(file);

  m2::RectD const rect = header.GetBounds();

  my::Timer timer;
  AllResult res;

  for (size_t i = 0; i < count; ++i)
  {
    timer.Reset();

    res.m_reading.Add(RunBenchmark(src, rect, scaleR));

    res.m_all.Add(timer.ElapsedSeconds());
  }

  return res;
}

}
<commit_msg>Fix dummy erro (warning).<commit_after>#include "../../base/SRC_FIRST.hpp"

#include "api.hpp"

#include "../feature_vec_model.hpp"

#include "../../indexer/data_factory.hpp"
#include "../../indexer/feature_visibility.hpp"

#include "../../platform/platform.hpp"

#include "../../base/timer.hpp"

#include "../../base/start_mem_debug.hpp"

namespace bench
{

namespace
{
  class Accumulator
  {
    my::Timer m_timer;
    size_t m_count;

    int m_scale;

  public:
    Result m_res;

    void Reset(int scale)
    {
      m_scale = scale;
      m_count = 0;
    }

    bool IsEmpty() const { return m_count == 0; }

    void operator() (FeatureType const & ft)
    {
      ++m_count;

      m_timer.Reset();

      vector<drule::Key> keys;
      string names;       // for debug use only, in release it's empty
      (void)feature::GetDrawRule(ft, m_scale, keys, names);

      if (!keys.empty())
      {
        // Call this function to load feature's inner data and geometry.
        (void)ft.IsEmptyGeometry(m_scale);
      }

      m_res.Add(m_timer.ElapsedSeconds());
    }
  };

  Result RunBenchmark(model::FeaturesFetcher const & src, m2::RectD const & rect,
                      pair<int, int> const & scaleR)
  {
    ASSERT_LESS_OR_EQUAL ( scaleR.first, scaleR.second, () );

    vector<m2::RectD> rects;
    rects.push_back(rect);

    Accumulator acc;

    while (!rects.empty())
    {
      m2::RectD const r = rects.back();
      rects.pop_back();

      bool doDivide = true;
      int const scale = scales::GetScaleLevel(r);
      if (scale >= scaleR.first)
      {
        acc.Reset(scale);
        src.ForEachFeature(r, acc, scale);
        doDivide = !acc.IsEmpty();
      }

      if (doDivide && scale < scaleR.second)
      {
        m2::RectD r1, r2;
        r.DivideByGreaterSize(r1, r2);
        rects.push_back(r1);
        rects.push_back(r2);
      }
    }

    return acc.m_res;
  }
}

AllResult RunFeaturesLoadingBenchmark(string const & file, size_t count, pair<int, int> scaleR)
{
  feature::DataHeader header;
  LoadMapHeader(GetPlatform().GetReader(file), header);

  pair<int, int> const r = header.GetScaleRange();
  if (r.first > scaleR.first)
    scaleR.first = r.first;
  if (r.second < scaleR.second)
    scaleR.second = r.second;

  if (scaleR.first > scaleR.second)
    return AllResult();

  model::FeaturesFetcher src;
  src.AddMap(file);

  m2::RectD const rect = header.GetBounds();

  my::Timer timer;
  AllResult res;

  for (size_t i = 0; i < count; ++i)
  {
    timer.Reset();

    res.m_reading.Add(RunBenchmark(src, rect, scaleR));

    res.m_all.Add(timer.ElapsedSeconds());
  }

  return res;
}

}
<|endoftext|>


<commit_before>// @(#)root/base:$Name:  $:$Id: TDSet.cxx,v 1.12 2002/08/09 13:12:24 rdm Exp $
// Author: Fons Rademakers   11/01/02

/*************************************************************************
 * Copyright (C) 1995-2001, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TDSet                                                                //
//                                                                      //
// This class implements a data set to be used for PROOF processing.    //
// The TDSet defines the class of which objects will be processed,      //
// the directory in the file where the objects of that type can be      //
// found and the list of files to be processed. The files can be        //
// specified as logical file names (LFN's) or as physical file names    //
// (PFN's). In case of LFN's the resolution to PFN's will be done       //
// according to the currently active GRID interface.                    //
// Examples:                                                            //
//   TDSet treeset("TTree", "AOD");                                     //
//   treeset.Add("lfn:/alien.cern.ch/alice/prod2002/file1");            //
//   ...                                                                //
//   treeset.AddFriend(friendset);                                      //
//                                                                      //
// or                                                                   //
//                                                                      //
//   TDSet objset("MyEvent", "*", "/events");                           //
//   objset.Add("root://cms.cern.ch/user/prod2002/hprod_1.root");       //
//   ...                                                                //
//   objset.Add(set2003);                                               //
//                                                                      //
// Validity of file names will only be checked at processing time       //
// (typically on the PROOF master server), not at creation time.        //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TDSet.h"
#include "TList.h"
#include "TROOT.h"
#include "TClass.h"
#include "TClassTable.h"
#include "Riostream.h"
#include "TFile.h"
#include "TTree.h"
#include "TKey.h"
#include "TError.h"
#include "TVirtualProof.h"

ClassImp(TDSetElement)
ClassImp(TDSet)

//______________________________________________________________________________
TDSetElement::TDSetElement(const TDSet *set, const char *file,
                           const char *objname, const char *dir,
                           Long64_t first, Long64_t num)
{
   // Create a TDSet element.

   fSet      = set;
   fFileName = file;
   fFirst    = first;
   fNum      = num;

   if (objname)
      fObjName = objname;
   if (dir)
      fDirectory = dir;
}

//______________________________________________________________________________
const char *TDSetElement::GetObjName() const
{
   // Return object name.

   if (fSet && fObjName.IsNull())
      return fSet->GetObjName();
   return fObjName;
}

//______________________________________________________________________________
const char *TDSetElement::GetDirectory() const
{
   // Return directory where to look for object.

   if (fSet && fDirectory.IsNull())
      return fSet->GetDirectory();
   return fDirectory;
}

//______________________________________________________________________________
void TDSetElement::Print(Option_t *option) const
{
   // Print a TDSetElement.

   cout << IsA()->GetName()
      << " file '" << fFileName
      << "' dir '" << fDirectory
      << "' obj '" << fObjName
      << "' first=" << fFirst << " num=" << fNum << endl;
}

//______________________________________________________________________________
TDSet::TDSet()
{
   // Default ctor.

   fElements = new TList;
   fElements->IsOwner();
   fIsTree   = kFALSE;
   fIterator = 0;
   fCurrent  = 0;
}

//______________________________________________________________________________
TDSet::TDSet(const char *type, const char *objname, const char *dir)
{
   // Create a TDSet object. The "type" defines the class of which objects
   // will be processed. The optional "objname" argument specifies the
   // name of the objects of the specified class (the name is mandatory
   // if the type inherits from a TTree). If the "objname" is not given all
   // objects of the class found in the specified directory are processed.
   // The "dir" argument specifies in which directory the objects are
   // to be found, the top level directory ("/") is the default.
   // Directories can be specified using wildcards, e.g. "*" or "/*"
   // means to look in all top level directories, "/dir/*" in all
   // directories under "/dir", and "/*/*" to look in all directories
   // two levels deep.

   fElements = new TList;
   fElements->IsOwner();
   fIterator = 0;
   fCurrent  = 0;

   if (!type || !*type) {
      Error("TDSet", "type name must be specified");
      return;
   }

   TClass *c;
   if (!(c = gROOT->GetClass(type)))
      Warning("TDSet", "type %s not yet known", type);

   fName   = type;
   fIsTree = kFALSE;

   if (c && c->InheritsFrom("TTree"))
      fIsTree = kTRUE;

   if (objname)
      fObjName = objname;

   if (dir)
      fTitle = dir;
}

//______________________________________________________________________________
TDSet::~TDSet()
{
   // Cleanup.

   delete fElements;
   delete fIterator;
}

//______________________________________________________________________________
Int_t TDSet::Process(const char *selector, Long64_t nentries,
                     Long64_t first, TEventList *evl)
{
   // Process TDSet on currently active PROOF session.
   // Returns -1 in case of error, 0 otherwise.

   if (!IsValid() || !fElements->GetSize()) {
      Error("Process", "not a correctly initialized TDSet");
      return -1;
   }

   if (gProof)
      return gProof->Process(this, selector, nentries, first, evl);

   Error("Process", "no active PROOF session");
   return -1;
}

//______________________________________________________________________________
void TDSet::Print(const Option_t *option) const
{
   // Print TDSet basic or full data.

   cout <<"OBJ: " << IsA()->GetName() << "\ttype " << GetName() << "\t"
      << fObjName << "\tin " << GetTitle() << endl;

   if (option && *option) {
      TIter next(GetListOfElements());
      TObject *obj;
      while ((obj = next())) {
         obj->Print(option);
      }
   }
}

//______________________________________________________________________________
void TDSet::SetObjName(const char *objname)
{
   // Set/change object name.

   if (objname)
      fObjName = objname;
}

//______________________________________________________________________________
void TDSet::SetDirectory(const char *dir)
{
   // Set/change directory.

   if (dir)
      fTitle = dir;
}

//______________________________________________________________________________
void TDSet::Add(const char *file, const char *objname, const char *dir,
                Long64_t first, Long64_t num)
{
   // Add file to list of files to be analyzed. Optionally with the
   // objname and dir arguments the default, TDSet wide, objname and
   // dir can be overridden.

   if (!file || !*file) {
      Error("Add", "file name must be specified");
      return;
   }

   fElements->Add(new TDSetElement(this, file, objname, dir, first, num));
}

//______________________________________________________________________________
void TDSet::Add(TDSet *set)
{
   // Add specified data set to the this set.

   if (!set)
      return;

   if (set->fName != fName) {
      Error("Add", "cannot add a set with a different type");
      return;
   }

   TDSetElement *el;
   TIter next(set->fElements);
   while ((el = (TDSetElement*) next()))
      Add(el->GetFileName(), el->GetObjName(), el->GetDirectory());
}

//______________________________________________________________________________
void TDSet::AddFriend(TDSet *friendset)
{
   // Add friend dataset to this set. Only possible if the TDSet type is
   // a TTree or derived class.

   if (!friendset)
      return;

   if (!fIsTree) {
      Error("AddFriend", "a friend set can only be added to a TTree TDSet");
      return;
   }

   // to be implemented
}

//______________________________________________________________________________
void TDSet::Reset()
{
   // Reset or initialize access to the elements.

   if (!fIterator) {
      fIterator = new TIter(fElements);
   } else {
      fIterator->Reset();
   }
}

//______________________________________________________________________________
TDSetElement *TDSet::Next()
{
   // Returns next TDSetElement.

   if (!fIterator) {
      fIterator = new TIter(fElements);
   }

   fCurrent = (TDSetElement *) fIterator->Next();
   return fCurrent;
}

//______________________________________________________________________________
Int_t TDSet::GetEntries(Bool_t isTree, const char *filename, const char *path,
                        const char *objname, Long64_t &entries)
{
   TFile *file = TFile::Open(filename);

   if (file->IsZombie()) {
      ::SysError("GetEntries","cannot open file %s", filename);
      return -1;
   }

   TDirectory *dirsave = gDirectory;
   if ( ! file->cd(path) ) {
      ::Error("GetEntries","cannot cd to %s", path);
      delete file;
      return -1;
   }
   TDirectory *dir = gDirectory;
   dirsave->cd();

   if (isTree) {
      TKey *key = dir->GetKey(objname);
      if (key == 0) {
         ::Error("GetEntries","cannot find tree \"%s\" in %s",
                 objname, filename);
         delete file;
         return -1;
      }
      TTree *tree = (TTree *) key->ReadObj();
      if (tree == 0) {
         // Error always reported?
         delete file;
         return -1;
      }
      entries = (Long64_t) tree->GetEntries();
      delete tree;

   } else {
      TList *keys = dir->GetListOfKeys();
      entries = keys->GetSize();
   }

   delete file;

   return 0;
}
<commit_msg>update comments in several method and improve Print() output.<commit_after>// @(#)root/base:$Name:  $:$Id: TDSet.cxx,v 1.13 2002/09/16 10:57:57 rdm Exp $
// Author: Fons Rademakers   11/01/02

/*************************************************************************
 * Copyright (C) 1995-2001, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TDSet                                                                //
//                                                                      //
// This class implements a data set to be used for PROOF processing.    //
// The TDSet defines the class of which objects will be processed,      //
// the directory in the file where the objects of that type can be      //
// found and the list of files to be processed. The files can be        //
// specified as logical file names (LFN's) or as physical file names    //
// (PFN's). In case of LFN's the resolution to PFN's will be done       //
// according to the currently active GRID interface.                    //
// Examples:                                                            //
//   TDSet treeset("TTree", "AOD");                                     //
//   treeset.Add("lfn:/alien.cern.ch/alice/prod2002/file1");            //
//   ...                                                                //
//   treeset.AddFriend(friendset);                                      //
//                                                                      //
// or                                                                   //
//                                                                      //
//   TDSet objset("MyEvent", "*", "/events");                           //
//   objset.Add("root://cms.cern.ch/user/prod2002/hprod_1.root");       //
//   ...                                                                //
//   objset.Add(set2003);                                               //
//                                                                      //
// Validity of file names will only be checked at processing time       //
// (typically on the PROOF master server), not at creation time.        //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TDSet.h"
#include "TList.h"
#include "TROOT.h"
#include "TClass.h"
#include "TClassTable.h"
#include "Riostream.h"
#include "TFile.h"
#include "TTree.h"
#include "TKey.h"
#include "TError.h"
#include "TVirtualProof.h"

ClassImp(TDSetElement)
ClassImp(TDSet)

//______________________________________________________________________________
TDSetElement::TDSetElement(const TDSet *set, const char *file,
                           const char *objname, const char *dir,
                           Long64_t first, Long64_t num)
{
   // Create a TDSet element.

   fSet      = set;
   fFileName = file;
   fFirst    = first;
   fNum      = num;

   if (objname)
      fObjName = objname;
   if (dir)
      fDirectory = dir;
}

//______________________________________________________________________________
const char *TDSetElement::GetObjName() const
{
   // Return object name.

   if (fSet && fObjName.IsNull())
      return fSet->GetObjName();
   return fObjName;
}

//______________________________________________________________________________
const char *TDSetElement::GetDirectory() const
{
   // Return directory where to look for object.

   if (fSet && fDirectory.IsNull())
      return fSet->GetDirectory();
   return fDirectory;
}

//______________________________________________________________________________
void TDSetElement::Print(Option_t *option) const
{
   // Print a TDSetElement.

   cout << IsA()->GetName()
      << " file='" << fFileName
      << "' dir='" << fDirectory
      << "' obj='" << fObjName
      << "' first=" << fFirst << " num=" << fNum << endl;
}

//______________________________________________________________________________
TDSet::TDSet()
{
   // Default ctor.

   fElements = new TList;
   fElements->IsOwner();
   fIsTree   = kFALSE;
   fIterator = 0;
   fCurrent  = 0;
}

//______________________________________________________________________________
TDSet::TDSet(const char *type, const char *objname, const char *dir)
{
   // Create a TDSet object. The "type" defines the class of which objects
   // will be processed. The optional "objname" argument specifies the
   // name of the objects of the specified class (the name is mandatory
   // if the type inherits from a TTree). If the "objname" is not given all
   // objects of the class found in the specified directory are processed.
   // The "dir" argument specifies in which directory the objects are
   // to be found, the top level directory ("/") is the default.
   // Directories can be specified using wildcards, e.g. "*" or "/*"
   // means to look in all top level directories, "/dir/*" in all
   // directories under "/dir", and "/*/*" to look in all directories
   // two levels deep.

   fElements = new TList;
   fElements->IsOwner();
   fIterator = 0;
   fCurrent  = 0;

   if (!type || !*type) {
      Error("TDSet", "type name must be specified");
      return;
   }

   TClass *c;
   if (!(c = gROOT->GetClass(type)))
      Warning("TDSet", "type %s not yet known", type);

   fName   = type;
   fIsTree = kFALSE;

   if (c && c->InheritsFrom("TTree"))
      fIsTree = kTRUE;

   if (objname)
      fObjName = objname;

   if (dir)
      fTitle = dir;
}

//______________________________________________________________________________
TDSet::~TDSet()
{
   // Cleanup.

   delete fElements;
   delete fIterator;
}

//______________________________________________________________________________
Int_t TDSet::Process(const char *selector, Long64_t nentries,
                     Long64_t first, TEventList *evl)
{
   // Process TDSet on currently active PROOF session.
   // Returns -1 in case of error, 0 otherwise.

   if (!IsValid() || !fElements->GetSize()) {
      Error("Process", "not a correctly initialized TDSet");
      return -1;
   }

   if (gProof)
      return gProof->Process(this, selector, nentries, first, evl);

   Error("Process", "no active PROOF session");
   return -1;
}

//______________________________________________________________________________
void TDSet::Print(const Option_t *option) const
{
   // Print TDSet basic or full data. When option="a" print full data.

   cout <<"OBJ: " << IsA()->GetName() << "\ttype " << GetName() << "\t"
        << fObjName << "\tin " << GetTitle()
        << "\telements " << GetListOfElements()->GetSize() << endl;

   if (option && *option) {
      TIter next(GetListOfElements());
      TObject *obj;
      while ((obj = next())) {
         obj->Print(option);
      }
   }
}

//______________________________________________________________________________
void TDSet::SetObjName(const char *objname)
{
   // Set/change object name.

   if (objname)
      fObjName = objname;
}

//______________________________________________________________________________
void TDSet::SetDirectory(const char *dir)
{
   // Set/change directory.

   if (dir)
      fTitle = dir;
}

//______________________________________________________________________________
void TDSet::Add(const char *file, const char *objname, const char *dir,
                Long64_t first, Long64_t num)
{
   // Add file to list of files to be analyzed. Optionally with the
   // objname and dir arguments the default, TDSet wide, objname and
   // dir can be overridden.

   if (!file || !*file) {
      Error("Add", "file name must be specified");
      return;
   }

   fElements->Add(new TDSetElement(this, file, objname, dir, first, num));
}

//______________________________________________________________________________
void TDSet::Add(TDSet *set)
{
   // Add specified data set to the this set.

   if (!set)
      return;

   if (set->fName != fName) {
      Error("Add", "cannot add a set with a different type");
      return;
   }

   TDSetElement *el;
   TIter next(set->fElements);
   while ((el = (TDSetElement*) next()))
      Add(el->GetFileName(), el->GetObjName(), el->GetDirectory());
}

//______________________________________________________________________________
void TDSet::AddFriend(TDSet *friendset)
{
   // Add friend dataset to this set. Only possible if the TDSet type is
   // a TTree or derived class.

   if (!friendset)
      return;

   if (!fIsTree) {
      Error("AddFriend", "a friend set can only be added to a TTree TDSet");
      return;
   }

   // to be implemented
}

//______________________________________________________________________________
void TDSet::Reset()
{
   // Reset or initialize access to the elements.

   if (!fIterator) {
      fIterator = new TIter(fElements);
   } else {
      fIterator->Reset();
   }
}

//______________________________________________________________________________
TDSetElement *TDSet::Next()
{
   // Returns next TDSetElement.

   if (!fIterator) {
      fIterator = new TIter(fElements);
   }

   fCurrent = (TDSetElement *) fIterator->Next();
   return fCurrent;
}

//______________________________________________________________________________
Int_t TDSet::GetEntries(Bool_t isTree, const char *filename, const char *path,
                        const char *objname, Long64_t &entries)
{
   // Returns number of entries in tree or objects in file. Returns -1 in
   // case of error, 0 otherwise.

   TFile *file = TFile::Open(filename);

   if (file->IsZombie()) {
      ::SysError("GetEntries","cannot open file %s", filename);
      return -1;
   }

   TDirectory *dirsave = gDirectory;
   if ( ! file->cd(path) ) {
      ::Error("GetEntries","cannot cd to %s", path);
      delete file;
      return -1;
   }
   TDirectory *dir = gDirectory;
   dirsave->cd();

   if (isTree) {
      TKey *key = dir->GetKey(objname);
      if (key == 0) {
         ::Error("GetEntries","cannot find tree \"%s\" in %s",
                 objname, filename);
         delete file;
         return -1;
      }
      TTree *tree = (TTree *) key->ReadObj();
      if (tree == 0) {
         // Error always reported?
         delete file;
         return -1;
      }
      entries = (Long64_t) tree->GetEntries();
      delete tree;

   } else {
      TList *keys = dir->GetListOfKeys();
      entries = keys->GetSize();
   }

   delete file;

   return 0;
}
<|endoftext|>