<commit_before>#include "kwm.h"

extern std::vector<spaces_info> SpacesLst;
extern std::vector<screen_info> DisplayLst;
extern std::vector<window_info> WindowLst;
extern std::vector<screen_layout> ScreenLayoutLst;
extern std::vector<window_layout> LayoutLst;

extern uint32_t MaxDisplayCount;
extern ProcessSerialNumber FocusedPSN;
extern AXUIElementRef FocusedWindowRef;
extern window_info FocusedWindow;

void ApplyLayoutForDisplay(int ScreenIndex)
{
    RefreshActiveSpacesInfo();
    DetectWindowBelowCursor();

    std::vector<window_info*> ScreenWindowLst = GetAllWindowsOnDisplay(ScreenIndex);
    screen_layout *LayoutMaster = &ScreenLayoutLst[ScreenIndex];

    int SpaceIndex = GetSpaceOfWindow(&FocusedWindow);
    if(SpaceIndex == -1)
        return;

    int ActiveLayoutIndex = SpacesLst[SpaceIndex].NextLayoutIndex;
    SpacesLst[SpaceIndex].ActiveLayoutIndex = ActiveLayoutIndex;

    if(ActiveLayoutIndex + 1 < LayoutMaster->NumberOfLayouts)
        SpacesLst[SpaceIndex].NextLayoutIndex = ActiveLayoutIndex + 1;
    else
        SpacesLst[SpaceIndex].NextLayoutIndex = 0;

    for(int WindowIndex = 0; WindowIndex < ScreenWindowLst.size(); ++WindowIndex)
    {
        window_info *Window = ScreenWindowLst[WindowIndex];
        AXUIElementRef WindowRef;
        if(GetWindowRef(Window, &WindowRef))
        {
            if(WindowIndex < LayoutMaster->Layouts[ActiveLayoutIndex].Layouts.size())
            {
                window_layout *Layout = &LayoutMaster->Layouts[ActiveLayoutIndex].Layouts[WindowIndex];
                LayoutMaster->Layouts[ActiveLayoutIndex].TileWID[WindowIndex] = Window->WID;
                SetWindowDimensions(WindowRef, Window, Layout->X, Layout->Y, Layout->Width, Layout->Height);
            }

            if(!WindowsAreEqual(&FocusedWindow, Window))
                CFRelease(WindowRef);
        }
    }

    DetectWindowBelowCursor();
}

void ApplyLayoutForWindow(AXUIElementRef WindowRef, window_info *Window, window_layout *Layout)
{
    SetWindowDimensions(WindowRef, Window, Layout->X, Layout->Y, Layout->Width, Layout->Height);
}

void ToggleFocusedWindowFullscreen()
{
    int SpaceIndex = GetSpaceOfWindow(&FocusedWindow);
    int ScreenIndex = GetDisplayOfWindow(&FocusedWindow)->ID;

    int FocusedWindowIndex = GetLayoutIndexOfWindow(&FocusedWindow);
    int ActiveLayoutIndex = SpacesLst[SpaceIndex].ActiveLayoutIndex;

    screen_layout *LayoutMaster = &ScreenLayoutLst[ScreenIndex];
    window_layout *FocusedWindowLayout = &LayoutMaster->Layouts[ActiveLayoutIndex].Layouts[FocusedWindowIndex];

    if(FocusedWindow.X == FocusedWindowLayout->X && FocusedWindow.Y == FocusedWindowLayout->Y
            && FocusedWindow.Width == FocusedWindowLayout->Width
            && FocusedWindow.Height == FocusedWindowLayout->Height)
    {
        window_layout Layout = GetWindowLayoutForScreen(ScreenIndex, "fullscreen");
        ApplyLayoutForWindow(FocusedWindowRef, &FocusedWindow, &Layout);
    }
    else
    {
        ApplyLayoutForWindow(FocusedWindowRef, &FocusedWindow, FocusedWindowLayout);
    }
}

void CycleFocusedWindowLayout(int ScreenIndex, int Shift)
{
    std::vector<window_info*> ScreenWindowLst = GetAllWindowsOnDisplay(ScreenIndex);
    screen_layout *LayoutMaster = &ScreenLayoutLst[ScreenIndex];

    int SpaceIndex = GetSpaceOfWindow(&FocusedWindow);
    if(SpaceIndex == -1)
        return;

    int ActiveLayoutIndex = SpacesLst[SpaceIndex].ActiveLayoutIndex;
    int MaxLayoutTiles = LayoutMaster->Layouts[ActiveLayoutIndex].Layouts.size();

    int FocusedWindowIndex = GetLayoutIndexOfWindow(&FocusedWindow);
    int SwapWithWindowIndex = FocusedWindowIndex + Shift;
    if(SwapWithWindowIndex < 0 || SwapWithWindowIndex >= MaxLayoutTiles)
        return;

    window_info *Window = NULL;
    for(int WindowIndex = 0; WindowIndex < ScreenWindowLst.size(); ++WindowIndex)
    {
        Window = ScreenWindowLst[WindowIndex];
        if(GetLayoutIndexOfWindow(Window) == SwapWithWindowIndex)
            break;
    }
    if (Window == NULL)
        return;

    AXUIElementRef WindowRef;
    if(GetWindowRef(Window, &WindowRef))
    {
        window_layout *FocusedWindowLayout = &LayoutMaster->Layouts[ActiveLayoutIndex].Layouts[FocusedWindowIndex];
        window_layout *SwapWithWindowLayout = &LayoutMaster->Layouts[ActiveLayoutIndex].Layouts[SwapWithWindowIndex];
        LayoutMaster->Layouts[ActiveLayoutIndex].TileWID[SwapWithWindowIndex] = FocusedWindow.WID;
        LayoutMaster->Layouts[ActiveLayoutIndex].TileWID[FocusedWindowIndex] = Window->WID;
        ApplyLayoutForWindow(WindowRef, Window, FocusedWindowLayout);
        ApplyLayoutForWindow(FocusedWindowRef, &FocusedWindow, SwapWithWindowLayout);
        CFRelease(WindowRef);
    }
}

void CycleWindowInsideLayout(int ScreenIndex)
{
    DetectWindowBelowCursor();
    std::vector<window_info*> ScreenWindowLst = GetAllWindowsOnDisplay(ScreenIndex);
    screen_layout *LayoutMaster = &ScreenLayoutLst[ScreenIndex];

    int SpaceIndex = GetSpaceOfWindow(&FocusedWindow);
    if(SpaceIndex == -1)
        return;

    int ActiveLayoutIndex = SpacesLst[SpaceIndex].ActiveLayoutIndex;
    int MaxLayoutTiles = LayoutMaster->Layouts[ActiveLayoutIndex].Layouts.size();
    if(ScreenWindowLst.size() <= MaxLayoutTiles)
        return;

    int FocusedWindowIndex = GetLayoutIndexOfWindow(&FocusedWindow);
    if(FocusedWindowIndex == -1)
        return;

    bool Found = false;
    window_info *Window = NULL;
    for(int WindowIndex = ScreenWindowLst.size()-1; WindowIndex >= 0; --WindowIndex)
    {
        Window = ScreenWindowLst[WindowIndex];
        if(GetLayoutIndexOfWindow(Window) == -1)
        {
            Found = true;
            break;
        }
    }
    if(!Found)
        return;

    AXUIElementRef WindowRef;
    if(GetWindowRef(Window, &WindowRef))
    {
        window_layout *FocusedWindowLayout = &LayoutMaster->Layouts[ActiveLayoutIndex].Layouts[FocusedWindowIndex];
        LayoutMaster->Layouts[ActiveLayoutIndex].TileWID[FocusedWindowIndex] = Window->WID;
        ApplyLayoutForWindow(WindowRef, Window, FocusedWindowLayout);

        ProcessSerialNumber NewPSN;
        GetProcessForPID(Window->PID, &NewPSN);

        AXUIElementSetAttributeValue(WindowRef, kAXMainAttribute, kCFBooleanTrue);
        AXUIElementSetAttributeValue(WindowRef, kAXFocusedAttribute, kCFBooleanTrue);
        AXUIElementPerformAction (WindowRef, kAXRaiseAction);

        SetFrontProcessWithOptions(&NewPSN, kSetFrontProcessFrontWindowOnly);

        if(FocusedWindowRef != NULL)
            CFRelease(FocusedWindowRef);

        FocusedWindowRef = WindowRef;
        FocusedWindow = *Window;
        FocusedPSN = NewPSN;
    }
}

int GetLayoutIndexOfWindow(window_info *Window)
{
    int ScreenID = GetDisplayOfWindow(Window)->ID;
    int SpaceIndex = GetSpaceOfWindow(&FocusedWindow);
    if(SpaceIndex == -1)
        return -1;

    int ActiveLayoutIndex = SpacesLst[SpaceIndex].ActiveLayoutIndex;
    int MaxLayoutSize = ScreenLayoutLst[ScreenID].Layouts[ActiveLayoutIndex].Layouts.size();

    for(int LayoutIndex = 0; LayoutIndex < MaxLayoutSize; ++LayoutIndex)
    {
        if(Window->WID == ScreenLayoutLst[ScreenID].Layouts[ActiveLayoutIndex].TileWID[LayoutIndex])
            return LayoutIndex;
    }

    return -1;
}

void SetWindowLayoutValues(window_layout *Layout, int X, int Y, int Width, int Height)
{
    Layout->X = X;
    Layout->Y = Y;
    Layout->Width = Width;
    Layout->Height = Height;
}

window_layout GetWindowLayoutForScreen(int ScreenIndex, const std::string &Name)
{
    window_layout Layout;
    Layout.Name = "invalid";

    screen_info *Screen = &DisplayLst[ScreenIndex];
    if(Screen)
    {
        for(int LayoutIndex = 0; LayoutIndex < LayoutLst.size(); ++LayoutIndex)
        {
            if(LayoutLst[LayoutIndex].Name == Name)
            {
                Layout = LayoutLst[LayoutIndex];
                break;
            }
        }

        if(Name == "fullscreen")
            SetWindowLayoutValues(&Layout,
                    Screen->X + Layout.GapX,
                    Screen->Y + Layout.GapY,
                    (Screen->Width - (Layout.GapVertical * 2)),
                    (Screen->Height - (Layout.GapY * 1.5f)));
        else if(Name == "left vertical split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + Layout.GapX,
                    Screen->Y + Layout.GapY,
                    ((Screen->Width / 2) - (Layout.GapVertical * 1.5f)),
                    (Screen->Height - (Layout.GapY * 1.5f)));
        else if(Name == "right vertical split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + ((Screen->Width / 2) + (Layout.GapVertical * 0.5f)),
                    Screen->Y + Layout.GapY,
                    ((Screen->Width / 2) - (Layout.GapVertical * 1.5f)),
                    (Screen->Height - (Layout.GapY * 1.5f)));
        else if(Name == "upper horizontal split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + Layout.GapX,
                    Screen->Y + Layout.GapY,
                    (Screen->Width - (Layout.GapVertical * 2)),
                    ((Screen->Height / 2) - (Layout.GapHorizontal * 1.0f)));
        else if(Name == "lower horizontal split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + Layout.GapX,
                    Screen->Y + ((Screen->Height / 2) + (Layout.GapHorizontal * 0.5f) + (Layout.GapY / 8)),
                    (Screen->Width - (Layout.GapVertical * 2)),
                    ((Screen->Height / 2) - (Layout.GapHorizontal * 1.0f)));
        else if(Name == "upper left split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + Layout.GapX,
                    Screen->Y + Layout.GapY,
                    ((Screen->Width / 2) - (Layout.GapVertical * 1.5f)),
                    ((Screen->Height / 2) - (Layout.GapHorizontal * 1.0f)));
        else if(Name == "lower left split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + Layout.GapX,
                    Screen->Y + ((Screen->Height / 2) + (Layout.GapHorizontal * 0.5f) + (Layout.GapY / 8)),
                    ((Screen->Width / 2) - (Layout.GapVertical * 1.5f)),
                    ((Screen->Height / 2) - (Layout.GapHorizontal * 1.0f)));
        else if(Name == "upper right split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + ((Screen->Width / 2) + (Layout.GapVertical * 0.5f)),
                    Screen->Y + Layout.GapY,
                    ((Screen->Width / 2) - (Layout.GapVertical * 1.5f)),
                    ((Screen->Height / 2) - (Layout.GapHorizontal * 1.0f)));
        else if(Name == "lower right split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + ((Screen->Width / 2) + (Layout.GapVertical * 0.5f)),
                    Screen->Y + ((Screen->Height / 2) + (Layout.GapHorizontal * 0.5f) + (Layout.GapY / 8)),
                    ((Screen->Width / 2) - (Layout.GapVertical * 1.5f)),
                    ((Screen->Height / 2) - (Layout.GapHorizontal * 1.0f)));
    }

    return Layout;
}

void InitWindowLayouts()
{
    window_layout ScreenVerticalSplit;
    ScreenVerticalSplit.GapX = 30;
    ScreenVerticalSplit.GapY = 40;
    ScreenVerticalSplit.GapVertical = 30;
    ScreenVerticalSplit.GapHorizontal = 30;

    ScreenVerticalSplit.Name = "fullscreen";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "left vertical split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "right vertical split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "upper horizontal split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "lower horizontal split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "upper left split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "lower left split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "upper right split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "lower right split";
    LayoutLst.push_back(ScreenVerticalSplit);

    // Screen Layouts
    for(int ScreenIndex = 0; ScreenIndex < MaxDisplayCount; ++ScreenIndex)
    {
        screen_layout LayoutMaster;

        window_group_layout LayoutTallLeft;
        LayoutTallLeft.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "left vertical split"));
        LayoutTallLeft.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "upper right split"));
        LayoutTallLeft.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "lower right split"));
        LayoutTallLeft.TileWID = std::vector<int>(3, 0);
        LayoutMaster.Layouts.push_back(LayoutTallLeft);

        window_group_layout LayoutTallRight;
        LayoutTallRight.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "upper left split"));
        LayoutTallRight.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "lower left split"));
        LayoutTallRight.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "right vertical split"));
        LayoutTallRight.TileWID = std::vector<int>(3, 0);
        LayoutMaster.Layouts.push_back(LayoutTallRight);

        window_group_layout LayoutVerticalSplit;
        LayoutVerticalSplit.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "left vertical split"));
        LayoutVerticalSplit.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "right vertical split"));
        LayoutVerticalSplit.TileWID = std::vector<int>(2, 0);;
        LayoutMaster.Layouts.push_back(LayoutVerticalSplit);

        window_group_layout LayoutQuarters;
        LayoutQuarters.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "upper left split"));
        LayoutQuarters.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "lower left split"));
        LayoutQuarters.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "upper right split"));
        LayoutQuarters.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "lower right split"));
        LayoutQuarters.TileWID = std::vector<int>(4, 0);
        LayoutMaster.Layouts.push_back(LayoutQuarters);

        window_group_layout LayoutFullscreen;
        LayoutFullscreen.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "fullscreen"));
        LayoutFullscreen.TileWID = std::vector<int>(1, 0);
        LayoutMaster.Layouts.push_back(LayoutFullscreen);

        LayoutMaster.NumberOfLayouts = LayoutMaster.Layouts.size();;
        ScreenLayoutLst.push_back(LayoutMaster);
    }
}
<commit_msg>only try and toggle fullscreen if a valid window is focused<commit_after>#include "kwm.h"

extern std::vector<spaces_info> SpacesLst;
extern std::vector<screen_info> DisplayLst;
extern std::vector<window_info> WindowLst;
extern std::vector<screen_layout> ScreenLayoutLst;
extern std::vector<window_layout> LayoutLst;

extern uint32_t MaxDisplayCount;
extern ProcessSerialNumber FocusedPSN;
extern AXUIElementRef FocusedWindowRef;
extern window_info FocusedWindow;

void ApplyLayoutForDisplay(int ScreenIndex)
{
    RefreshActiveSpacesInfo();
    DetectWindowBelowCursor();

    std::vector<window_info*> ScreenWindowLst = GetAllWindowsOnDisplay(ScreenIndex);
    screen_layout *LayoutMaster = &ScreenLayoutLst[ScreenIndex];

    int SpaceIndex = GetSpaceOfWindow(&FocusedWindow);
    if(SpaceIndex == -1)
        return;

    int ActiveLayoutIndex = SpacesLst[SpaceIndex].NextLayoutIndex;
    SpacesLst[SpaceIndex].ActiveLayoutIndex = ActiveLayoutIndex;

    if(ActiveLayoutIndex + 1 < LayoutMaster->NumberOfLayouts)
        SpacesLst[SpaceIndex].NextLayoutIndex = ActiveLayoutIndex + 1;
    else
        SpacesLst[SpaceIndex].NextLayoutIndex = 0;

    for(int WindowIndex = 0; WindowIndex < ScreenWindowLst.size(); ++WindowIndex)
    {
        window_info *Window = ScreenWindowLst[WindowIndex];
        AXUIElementRef WindowRef;
        if(GetWindowRef(Window, &WindowRef))
        {
            if(WindowIndex < LayoutMaster->Layouts[ActiveLayoutIndex].Layouts.size())
            {
                window_layout *Layout = &LayoutMaster->Layouts[ActiveLayoutIndex].Layouts[WindowIndex];
                LayoutMaster->Layouts[ActiveLayoutIndex].TileWID[WindowIndex] = Window->WID;
                SetWindowDimensions(WindowRef, Window, Layout->X, Layout->Y, Layout->Width, Layout->Height);
            }

            if(!WindowsAreEqual(&FocusedWindow, Window))
                CFRelease(WindowRef);
        }
    }

    DetectWindowBelowCursor();
}

void ApplyLayoutForWindow(AXUIElementRef WindowRef, window_info *Window, window_layout *Layout)
{
    SetWindowDimensions(WindowRef, Window, Layout->X, Layout->Y, Layout->Width, Layout->Height);
}

void ToggleFocusedWindowFullscreen()
{
    int ScreenIndex = GetDisplayOfWindow(&FocusedWindow)->ID;
    int SpaceIndex = GetSpaceOfWindow(&FocusedWindow);
    if(SpaceIndex == -1)
        return;

    int ActiveLayoutIndex = SpacesLst[SpaceIndex].ActiveLayoutIndex;
    int FocusedWindowIndex = GetLayoutIndexOfWindow(&FocusedWindow);
    if(FocusedWindowIndex == -1)
        return;

    screen_layout *LayoutMaster = &ScreenLayoutLst[ScreenIndex];
    window_layout *FocusedWindowLayout = &LayoutMaster->Layouts[ActiveLayoutIndex].Layouts[FocusedWindowIndex];

    if(FocusedWindow.X == FocusedWindowLayout->X && FocusedWindow.Y == FocusedWindowLayout->Y
            && FocusedWindow.Width == FocusedWindowLayout->Width
            && FocusedWindow.Height == FocusedWindowLayout->Height)
    {
        window_layout Layout = GetWindowLayoutForScreen(ScreenIndex, "fullscreen");
        ApplyLayoutForWindow(FocusedWindowRef, &FocusedWindow, &Layout);
    }
    else
    {
        ApplyLayoutForWindow(FocusedWindowRef, &FocusedWindow, FocusedWindowLayout);
    }
}

void CycleFocusedWindowLayout(int ScreenIndex, int Shift)
{
    std::vector<window_info*> ScreenWindowLst = GetAllWindowsOnDisplay(ScreenIndex);
    screen_layout *LayoutMaster = &ScreenLayoutLst[ScreenIndex];

    int SpaceIndex = GetSpaceOfWindow(&FocusedWindow);
    if(SpaceIndex == -1)
        return;

    int ActiveLayoutIndex = SpacesLst[SpaceIndex].ActiveLayoutIndex;
    int MaxLayoutTiles = LayoutMaster->Layouts[ActiveLayoutIndex].Layouts.size();

    int FocusedWindowIndex = GetLayoutIndexOfWindow(&FocusedWindow);
    int SwapWithWindowIndex = FocusedWindowIndex + Shift;
    if(SwapWithWindowIndex < 0 || SwapWithWindowIndex >= MaxLayoutTiles)
        return;

    window_info *Window = NULL;
    for(int WindowIndex = 0; WindowIndex < ScreenWindowLst.size(); ++WindowIndex)
    {
        Window = ScreenWindowLst[WindowIndex];
        if(GetLayoutIndexOfWindow(Window) == SwapWithWindowIndex)
            break;
    }
    if (Window == NULL)
        return;

    AXUIElementRef WindowRef;
    if(GetWindowRef(Window, &WindowRef))
    {
        window_layout *FocusedWindowLayout = &LayoutMaster->Layouts[ActiveLayoutIndex].Layouts[FocusedWindowIndex];
        window_layout *SwapWithWindowLayout = &LayoutMaster->Layouts[ActiveLayoutIndex].Layouts[SwapWithWindowIndex];
        LayoutMaster->Layouts[ActiveLayoutIndex].TileWID[SwapWithWindowIndex] = FocusedWindow.WID;
        LayoutMaster->Layouts[ActiveLayoutIndex].TileWID[FocusedWindowIndex] = Window->WID;
        ApplyLayoutForWindow(WindowRef, Window, FocusedWindowLayout);
        ApplyLayoutForWindow(FocusedWindowRef, &FocusedWindow, SwapWithWindowLayout);
        CFRelease(WindowRef);
    }
}

void CycleWindowInsideLayout(int ScreenIndex)
{
    DetectWindowBelowCursor();
    std::vector<window_info*> ScreenWindowLst = GetAllWindowsOnDisplay(ScreenIndex);
    screen_layout *LayoutMaster = &ScreenLayoutLst[ScreenIndex];

    int SpaceIndex = GetSpaceOfWindow(&FocusedWindow);
    if(SpaceIndex == -1)
        return;

    int ActiveLayoutIndex = SpacesLst[SpaceIndex].ActiveLayoutIndex;
    int MaxLayoutTiles = LayoutMaster->Layouts[ActiveLayoutIndex].Layouts.size();
    if(ScreenWindowLst.size() <= MaxLayoutTiles)
        return;

    int FocusedWindowIndex = GetLayoutIndexOfWindow(&FocusedWindow);
    if(FocusedWindowIndex == -1)
        return;

    bool Found = false;
    window_info *Window = NULL;
    for(int WindowIndex = ScreenWindowLst.size()-1; WindowIndex >= 0; --WindowIndex)
    {
        Window = ScreenWindowLst[WindowIndex];
        if(GetLayoutIndexOfWindow(Window) == -1)
        {
            Found = true;
            break;
        }
    }
    if(!Found)
        return;

    AXUIElementRef WindowRef;
    if(GetWindowRef(Window, &WindowRef))
    {
        window_layout *FocusedWindowLayout = &LayoutMaster->Layouts[ActiveLayoutIndex].Layouts[FocusedWindowIndex];
        LayoutMaster->Layouts[ActiveLayoutIndex].TileWID[FocusedWindowIndex] = Window->WID;
        ApplyLayoutForWindow(WindowRef, Window, FocusedWindowLayout);

        ProcessSerialNumber NewPSN;
        GetProcessForPID(Window->PID, &NewPSN);

        AXUIElementSetAttributeValue(WindowRef, kAXMainAttribute, kCFBooleanTrue);
        AXUIElementSetAttributeValue(WindowRef, kAXFocusedAttribute, kCFBooleanTrue);
        AXUIElementPerformAction (WindowRef, kAXRaiseAction);

        SetFrontProcessWithOptions(&NewPSN, kSetFrontProcessFrontWindowOnly);

        if(FocusedWindowRef != NULL)
            CFRelease(FocusedWindowRef);

        FocusedWindowRef = WindowRef;
        FocusedWindow = *Window;
        FocusedPSN = NewPSN;
    }
}

int GetLayoutIndexOfWindow(window_info *Window)
{
    int ScreenID = GetDisplayOfWindow(Window)->ID;
    int SpaceIndex = GetSpaceOfWindow(&FocusedWindow);
    if(SpaceIndex == -1)
        return -1;

    int ActiveLayoutIndex = SpacesLst[SpaceIndex].ActiveLayoutIndex;
    int MaxLayoutSize = ScreenLayoutLst[ScreenID].Layouts[ActiveLayoutIndex].Layouts.size();

    for(int LayoutIndex = 0; LayoutIndex < MaxLayoutSize; ++LayoutIndex)
    {
        if(Window->WID == ScreenLayoutLst[ScreenID].Layouts[ActiveLayoutIndex].TileWID[LayoutIndex])
            return LayoutIndex;
    }

    return -1;
}

void SetWindowLayoutValues(window_layout *Layout, int X, int Y, int Width, int Height)
{
    Layout->X = X;
    Layout->Y = Y;
    Layout->Width = Width;
    Layout->Height = Height;
}

window_layout GetWindowLayoutForScreen(int ScreenIndex, const std::string &Name)
{
    window_layout Layout;
    Layout.Name = "invalid";

    screen_info *Screen = &DisplayLst[ScreenIndex];
    if(Screen)
    {
        for(int LayoutIndex = 0; LayoutIndex < LayoutLst.size(); ++LayoutIndex)
        {
            if(LayoutLst[LayoutIndex].Name == Name)
            {
                Layout = LayoutLst[LayoutIndex];
                break;
            }
        }

        if(Name == "fullscreen")
            SetWindowLayoutValues(&Layout,
                    Screen->X + Layout.GapX,
                    Screen->Y + Layout.GapY,
                    (Screen->Width - (Layout.GapVertical * 2)),
                    (Screen->Height - (Layout.GapY * 1.5f)));
        else if(Name == "left vertical split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + Layout.GapX,
                    Screen->Y + Layout.GapY,
                    ((Screen->Width / 2) - (Layout.GapVertical * 1.5f)),
                    (Screen->Height - (Layout.GapY * 1.5f)));
        else if(Name == "right vertical split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + ((Screen->Width / 2) + (Layout.GapVertical * 0.5f)),
                    Screen->Y + Layout.GapY,
                    ((Screen->Width / 2) - (Layout.GapVertical * 1.5f)),
                    (Screen->Height - (Layout.GapY * 1.5f)));
        else if(Name == "upper horizontal split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + Layout.GapX,
                    Screen->Y + Layout.GapY,
                    (Screen->Width - (Layout.GapVertical * 2)),
                    ((Screen->Height / 2) - (Layout.GapHorizontal * 1.0f)));
        else if(Name == "lower horizontal split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + Layout.GapX,
                    Screen->Y + ((Screen->Height / 2) + (Layout.GapHorizontal * 0.5f) + (Layout.GapY / 8)),
                    (Screen->Width - (Layout.GapVertical * 2)),
                    ((Screen->Height / 2) - (Layout.GapHorizontal * 1.0f)));
        else if(Name == "upper left split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + Layout.GapX,
                    Screen->Y + Layout.GapY,
                    ((Screen->Width / 2) - (Layout.GapVertical * 1.5f)),
                    ((Screen->Height / 2) - (Layout.GapHorizontal * 1.0f)));
        else if(Name == "lower left split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + Layout.GapX,
                    Screen->Y + ((Screen->Height / 2) + (Layout.GapHorizontal * 0.5f) + (Layout.GapY / 8)),
                    ((Screen->Width / 2) - (Layout.GapVertical * 1.5f)),
                    ((Screen->Height / 2) - (Layout.GapHorizontal * 1.0f)));
        else if(Name == "upper right split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + ((Screen->Width / 2) + (Layout.GapVertical * 0.5f)),
                    Screen->Y + Layout.GapY,
                    ((Screen->Width / 2) - (Layout.GapVertical * 1.5f)),
                    ((Screen->Height / 2) - (Layout.GapHorizontal * 1.0f)));
        else if(Name == "lower right split")
            SetWindowLayoutValues(&Layout,
                    Screen->X + ((Screen->Width / 2) + (Layout.GapVertical * 0.5f)),
                    Screen->Y + ((Screen->Height / 2) + (Layout.GapHorizontal * 0.5f) + (Layout.GapY / 8)),
                    ((Screen->Width / 2) - (Layout.GapVertical * 1.5f)),
                    ((Screen->Height / 2) - (Layout.GapHorizontal * 1.0f)));
    }

    return Layout;
}

void InitWindowLayouts()
{
    window_layout ScreenVerticalSplit;
    ScreenVerticalSplit.GapX = 30;
    ScreenVerticalSplit.GapY = 40;
    ScreenVerticalSplit.GapVertical = 30;
    ScreenVerticalSplit.GapHorizontal = 30;

    ScreenVerticalSplit.Name = "fullscreen";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "left vertical split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "right vertical split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "upper horizontal split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "lower horizontal split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "upper left split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "lower left split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "upper right split";
    LayoutLst.push_back(ScreenVerticalSplit);

    ScreenVerticalSplit.Name = "lower right split";
    LayoutLst.push_back(ScreenVerticalSplit);

    // Screen Layouts
    for(int ScreenIndex = 0; ScreenIndex < MaxDisplayCount; ++ScreenIndex)
    {
        screen_layout LayoutMaster;

        window_group_layout LayoutTallLeft;
        LayoutTallLeft.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "left vertical split"));
        LayoutTallLeft.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "upper right split"));
        LayoutTallLeft.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "lower right split"));
        LayoutTallLeft.TileWID = std::vector<int>(3, 0);
        LayoutMaster.Layouts.push_back(LayoutTallLeft);

        window_group_layout LayoutTallRight;
        LayoutTallRight.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "upper left split"));
        LayoutTallRight.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "lower left split"));
        LayoutTallRight.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "right vertical split"));
        LayoutTallRight.TileWID = std::vector<int>(3, 0);
        LayoutMaster.Layouts.push_back(LayoutTallRight);

        window_group_layout LayoutVerticalSplit;
        LayoutVerticalSplit.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "left vertical split"));
        LayoutVerticalSplit.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "right vertical split"));
        LayoutVerticalSplit.TileWID = std::vector<int>(2, 0);;
        LayoutMaster.Layouts.push_back(LayoutVerticalSplit);

        window_group_layout LayoutQuarters;
        LayoutQuarters.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "upper left split"));
        LayoutQuarters.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "lower left split"));
        LayoutQuarters.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "upper right split"));
        LayoutQuarters.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "lower right split"));
        LayoutQuarters.TileWID = std::vector<int>(4, 0);
        LayoutMaster.Layouts.push_back(LayoutQuarters);

        window_group_layout LayoutFullscreen;
        LayoutFullscreen.Layouts.push_back(GetWindowLayoutForScreen(ScreenIndex, "fullscreen"));
        LayoutFullscreen.TileWID = std::vector<int>(1, 0);
        LayoutMaster.Layouts.push_back(LayoutFullscreen);

        LayoutMaster.NumberOfLayouts = LayoutMaster.Layouts.size();;
        ScreenLayoutLst.push_back(LayoutMaster);
    }
}
<|endoftext|>


<commit_before>#include "geom2D.hpp"

namespace boom {
	namespace geo2d {
		Line::Line(const Vec2& p, const Vec2& d): pos(p), dir(d) {}
		Vec2x2 Line::nearest(const Line& st) const {
			auto fn = [](float f) { return f; };
			return NearestPoint(*this, st, fn, fn);
		}
		Vec2 Line::nearest(const Vec2& p) const {
			return pos + (p-pos).dot(dir);
		}
		float Line::distance(const Vec2& p) const {
			return std::fabs(dir.ccw(p - pos));
		}
		Vec2 Line::placeOnLine(const Vec2& p) const {
			return pos + dir*posDot(p);
		}
		float Line::posDot(const Vec2& p) const {
			Vec2 tv(p-pos);
			return dir.dot(tv);
		}
		Line Line::operator * (const AMat32& m) const {
			return Line{pos.asVec3(1)*m, dir.asVec3(0)*m};
		}
		std::ostream& operator << (std::ostream& os, const Line& l) {
			return os << "Line [ pos: " << l.pos << std::endl
						<< "dir: " << l.dir << ']';
		}
		bool Line::hit(const Vec2& p, float t) const {
			Vec2 v = p - pos;
			float d = std::abs(v.dot(dir));
			return (pos + dir*d).dist_sq(p) <= spn::Square(t);
		}
	}
}
<commit_msg>Line2D: nearest(vec2)を修正<commit_after>#include "geom2D.hpp"

namespace boom {
	namespace geo2d {
		Line::Line(const Vec2& p, const Vec2& d): pos(p), dir(d) {}
		Vec2x2 Line::nearest(const Line& st) const {
			auto fn = [](float f) { return f; };
			return NearestPoint(*this, st, fn, fn);
		}
		Vec2 Line::nearest(const Vec2& p) const {
			return pos + dir * (p-pos).dot(dir);
		}
		float Line::distance(const Vec2& p) const {
			return std::fabs(dir.ccw(p - pos));
		}
		Vec2 Line::placeOnLine(const Vec2& p) const {
			return pos + dir*posDot(p);
		}
		float Line::posDot(const Vec2& p) const {
			Vec2 tv(p-pos);
			return dir.dot(tv);
		}
		Line Line::operator * (const AMat32& m) const {
			return Line{pos.asVec3(1)*m, dir.asVec3(0)*m};
		}
		std::ostream& operator << (std::ostream& os, const Line& l) {
			return os << "Line [ pos: " << l.pos << std::endl
						<< "dir: " << l.dir << ']';
		}
		bool Line::hit(const Vec2& p, float t) const {
			Vec2 v = p - pos;
			float d = std::abs(v.dot(dir));
			return (pos + dir*d).dist_sq(p) <= spn::Square(t);
		}
	}
}
<|endoftext|>


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

#include "scenariobuffer.hxx"

#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/sheet/XScenario.hpp>
#include <com/sun/star/sheet/XScenarios.hpp>
#include <com/sun/star/sheet/XScenariosSupplier.hpp>
#include <com/sun/star/sheet/XSpreadsheet.hpp>
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include "oox/helper/attributelist.hxx"
#include "oox/helper/containerhelper.hxx"
#include "oox/helper/propertyset.hxx"
#include "oox/token/properties.hxx"
#include "addressconverter.hxx"
#include "biffinputstream.hxx"

namespace oox {
namespace xls {

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

using namespace ::com::sun::star::container;
using namespace ::com::sun::star::sheet;
using namespace ::com::sun::star::table;
using namespace ::com::sun::star::uno;

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

namespace {

const sal_Int32 BIFF_SCENARIO_DELETED       = 0x4000;

} // namespace

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

ScenarioCellModel::ScenarioCellModel() :
    mnNumFmtId( 0 ),
    mbDeleted( false )
{
}

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

ScenarioModel::ScenarioModel() :
    mbLocked( false ),
    mbHidden( false )
{
}

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

Scenario::Scenario( const WorkbookHelper& rHelper, sal_Int16 nSheet ) :
    WorkbookHelper( rHelper ),
    mnSheet( nSheet )
{
}

void Scenario::importScenario( const AttributeList& rAttribs )
{
    maModel.maName    = rAttribs.getXString( XML_name, OUString() );
    maModel.maComment = rAttribs.getXString( XML_comment, OUString() );
    maModel.maUser    = rAttribs.getXString( XML_user, OUString() );
    maModel.mbLocked  = rAttribs.getBool( XML_locked, false );
    maModel.mbHidden  = rAttribs.getBool( XML_hidden, false );
}

void Scenario::importInputCells( const AttributeList& rAttribs )
{
    ScenarioCellModel aModel;
    getAddressConverter().convertToCellAddressUnchecked( aModel.maPos, rAttribs.getString( XML_r, OUString() ), mnSheet );
    aModel.maValue    = rAttribs.getXString( XML_val, OUString() );
    aModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
    aModel.mbDeleted  = rAttribs.getBool( XML_deleted, false );
    maCells.push_back( aModel );
}

void Scenario::importScenario( SequenceInputStream& rStrm )
{
    rStrm.skip( 2 );    // cell count
    // two longs instead of flag field
    maModel.mbLocked = rStrm.readInt32() != 0;
    maModel.mbHidden = rStrm.readInt32() != 0;
    rStrm >> maModel.maName >> maModel.maComment >> maModel.maUser;
}

void Scenario::importInputCells( SequenceInputStream& rStrm )
{
    // TODO: where is the deleted flag?
    ScenarioCellModel aModel;
    BinAddress aPos;
    rStrm >> aPos;
    rStrm.skip( 8 );
    aModel.mnNumFmtId = rStrm.readuInt16();
    rStrm >> aModel.maValue;
    getAddressConverter().convertToCellAddressUnchecked( aModel.maPos, aPos, mnSheet );
    maCells.push_back( aModel );
}

void Scenario::finalizeImport()
{
    AddressConverter& rAddrConv = getAddressConverter();
    ::std::vector< CellRangeAddress > aRanges;
    for( ScenarioCellVector::iterator aIt = maCells.begin(), aEnd = maCells.end(); aIt != aEnd; ++aIt )
        if( !aIt->mbDeleted && rAddrConv.checkCellAddress( aIt->maPos, true ) )
            aRanges.push_back( CellRangeAddress( aIt->maPos.Sheet, aIt->maPos.Column, aIt->maPos.Row, aIt->maPos.Column, aIt->maPos.Row ) );

    if( !aRanges.empty() && !maModel.maName.isEmpty() ) try
    {
        /*  Find an unused name for the scenario (Calc stores scenario data in
            hidden sheets named after the scenario following the base sheet). */
        Reference< XNameAccess > xSheetsNA( getDocument()->getSheets(), UNO_QUERY_THROW );
        OUString aScenName = ContainerHelper::getUnusedName( xSheetsNA, maModel.maName, '_' );

        // create the new scenario sheet
        Reference< XScenariosSupplier > xScenariosSupp( getSheetFromDoc( mnSheet ), UNO_QUERY_THROW );
        Reference< XScenarios > xScenarios( xScenariosSupp->getScenarios(), UNO_SET_THROW );
        xScenarios->addNewByName( aScenName, ContainerHelper::vectorToSequence( aRanges ), maModel.maComment );

        // write scenario cell values
        Reference< XSpreadsheet > xSheet( getSheetFromDoc( aScenName ), UNO_SET_THROW );
        for( ScenarioCellVector::iterator aIt = maCells.begin(), aEnd = maCells.end(); aIt != aEnd; ++aIt )
        {
            if( !aIt->mbDeleted ) try
            {
                // use XCell::setFormula to auto-detect values and strings
                Reference< XCell > xCell( xSheet->getCellByPosition( aIt->maPos.Column, aIt->maPos.Row ), UNO_SET_THROW );
                xCell->setFormula( aIt->maValue );
            }
            catch( Exception& )
            {
            }
        }

        // scenario properties
        PropertySet aPropSet( xScenarios->getByName( aScenName ) );
        aPropSet.setProperty( PROP_IsActive, false );
        aPropSet.setProperty( PROP_CopyBack, false );
        aPropSet.setProperty( PROP_CopyStyles, false );
        aPropSet.setProperty( PROP_CopyFormulas, false );
        aPropSet.setProperty( PROP_Protected, maModel.mbLocked );
        // #112621# do not show/print scenario border
        aPropSet.setProperty( PROP_ShowBorder, false );
        aPropSet.setProperty( PROP_PrintBorder, false );
    }
    catch( Exception& )
    {
    }
}

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

SheetScenariosModel::SheetScenariosModel() :
    mnCurrent( 0 ),
    mnShown( 0 )
{
}

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

SheetScenarios::SheetScenarios( const WorkbookHelper& rHelper, sal_Int16 nSheet ) :
    WorkbookHelper( rHelper ),
    mnSheet( nSheet )
{
}

void SheetScenarios::importScenarios( const AttributeList& rAttribs )
{
    maModel.mnCurrent = rAttribs.getInteger( XML_current, 0 );
    maModel.mnShown   = rAttribs.getInteger( XML_show, 0 );
}

void SheetScenarios::importScenarios( SequenceInputStream& rStrm )
{
    maModel.mnCurrent = rStrm.readuInt16();
    maModel.mnShown   = rStrm.readuInt16();
}

Scenario& SheetScenarios::createScenario()
{
    ScenarioVector::value_type xScenario( new Scenario( *this, mnSheet ) );
    maScenarios.push_back( xScenario );
    return *xScenario;
}

void SheetScenarios::finalizeImport()
{
    maScenarios.forEachMem( &Scenario::finalizeImport );

    // activate a scenario
    try
    {
        Reference< XScenariosSupplier > xScenariosSupp( getSheetFromDoc( mnSheet ), UNO_QUERY_THROW );
        Reference< XIndexAccess > xScenariosIA( xScenariosSupp->getScenarios(), UNO_QUERY_THROW );
        Reference< XScenario > xScenario( xScenariosIA->getByIndex( maModel.mnShown ), UNO_QUERY_THROW );
        xScenario->apply();
    }
    catch( Exception& )
    {
    }
}

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

ScenarioBuffer::ScenarioBuffer( const WorkbookHelper& rHelper ) :
    WorkbookHelper( rHelper )
{
}

SheetScenarios& ScenarioBuffer::createSheetScenarios( sal_Int16 nSheet )
{
    SheetScenariosMap::mapped_type& rxSheetScens = maSheetScenarios[ nSheet ];
    if( !rxSheetScens )
        rxSheetScens.reset( new SheetScenarios( *this, nSheet ) );
    return *rxSheetScens;
}

void ScenarioBuffer::finalizeImport()
{
    maSheetScenarios.forEachMem( &SheetScenarios::finalizeImport );
}

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

} // namespace xls
} // namespace oox

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>-Werror,-Wunused-const-variable<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "scenariobuffer.hxx"

#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/sheet/XScenario.hpp>
#include <com/sun/star/sheet/XScenarios.hpp>
#include <com/sun/star/sheet/XScenariosSupplier.hpp>
#include <com/sun/star/sheet/XSpreadsheet.hpp>
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include "oox/helper/attributelist.hxx"
#include "oox/helper/containerhelper.hxx"
#include "oox/helper/propertyset.hxx"
#include "oox/token/properties.hxx"
#include "addressconverter.hxx"
#include "biffinputstream.hxx"

namespace oox {
namespace xls {

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

using namespace ::com::sun::star::container;
using namespace ::com::sun::star::sheet;
using namespace ::com::sun::star::table;
using namespace ::com::sun::star::uno;

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

ScenarioCellModel::ScenarioCellModel() :
    mnNumFmtId( 0 ),
    mbDeleted( false )
{
}

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

ScenarioModel::ScenarioModel() :
    mbLocked( false ),
    mbHidden( false )
{
}

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

Scenario::Scenario( const WorkbookHelper& rHelper, sal_Int16 nSheet ) :
    WorkbookHelper( rHelper ),
    mnSheet( nSheet )
{
}

void Scenario::importScenario( const AttributeList& rAttribs )
{
    maModel.maName    = rAttribs.getXString( XML_name, OUString() );
    maModel.maComment = rAttribs.getXString( XML_comment, OUString() );
    maModel.maUser    = rAttribs.getXString( XML_user, OUString() );
    maModel.mbLocked  = rAttribs.getBool( XML_locked, false );
    maModel.mbHidden  = rAttribs.getBool( XML_hidden, false );
}

void Scenario::importInputCells( const AttributeList& rAttribs )
{
    ScenarioCellModel aModel;
    getAddressConverter().convertToCellAddressUnchecked( aModel.maPos, rAttribs.getString( XML_r, OUString() ), mnSheet );
    aModel.maValue    = rAttribs.getXString( XML_val, OUString() );
    aModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, 0 );
    aModel.mbDeleted  = rAttribs.getBool( XML_deleted, false );
    maCells.push_back( aModel );
}

void Scenario::importScenario( SequenceInputStream& rStrm )
{
    rStrm.skip( 2 );    // cell count
    // two longs instead of flag field
    maModel.mbLocked = rStrm.readInt32() != 0;
    maModel.mbHidden = rStrm.readInt32() != 0;
    rStrm >> maModel.maName >> maModel.maComment >> maModel.maUser;
}

void Scenario::importInputCells( SequenceInputStream& rStrm )
{
    // TODO: where is the deleted flag?
    ScenarioCellModel aModel;
    BinAddress aPos;
    rStrm >> aPos;
    rStrm.skip( 8 );
    aModel.mnNumFmtId = rStrm.readuInt16();
    rStrm >> aModel.maValue;
    getAddressConverter().convertToCellAddressUnchecked( aModel.maPos, aPos, mnSheet );
    maCells.push_back( aModel );
}

void Scenario::finalizeImport()
{
    AddressConverter& rAddrConv = getAddressConverter();
    ::std::vector< CellRangeAddress > aRanges;
    for( ScenarioCellVector::iterator aIt = maCells.begin(), aEnd = maCells.end(); aIt != aEnd; ++aIt )
        if( !aIt->mbDeleted && rAddrConv.checkCellAddress( aIt->maPos, true ) )
            aRanges.push_back( CellRangeAddress( aIt->maPos.Sheet, aIt->maPos.Column, aIt->maPos.Row, aIt->maPos.Column, aIt->maPos.Row ) );

    if( !aRanges.empty() && !maModel.maName.isEmpty() ) try
    {
        /*  Find an unused name for the scenario (Calc stores scenario data in
            hidden sheets named after the scenario following the base sheet). */
        Reference< XNameAccess > xSheetsNA( getDocument()->getSheets(), UNO_QUERY_THROW );
        OUString aScenName = ContainerHelper::getUnusedName( xSheetsNA, maModel.maName, '_' );

        // create the new scenario sheet
        Reference< XScenariosSupplier > xScenariosSupp( getSheetFromDoc( mnSheet ), UNO_QUERY_THROW );
        Reference< XScenarios > xScenarios( xScenariosSupp->getScenarios(), UNO_SET_THROW );
        xScenarios->addNewByName( aScenName, ContainerHelper::vectorToSequence( aRanges ), maModel.maComment );

        // write scenario cell values
        Reference< XSpreadsheet > xSheet( getSheetFromDoc( aScenName ), UNO_SET_THROW );
        for( ScenarioCellVector::iterator aIt = maCells.begin(), aEnd = maCells.end(); aIt != aEnd; ++aIt )
        {
            if( !aIt->mbDeleted ) try
            {
                // use XCell::setFormula to auto-detect values and strings
                Reference< XCell > xCell( xSheet->getCellByPosition( aIt->maPos.Column, aIt->maPos.Row ), UNO_SET_THROW );
                xCell->setFormula( aIt->maValue );
            }
            catch( Exception& )
            {
            }
        }

        // scenario properties
        PropertySet aPropSet( xScenarios->getByName( aScenName ) );
        aPropSet.setProperty( PROP_IsActive, false );
        aPropSet.setProperty( PROP_CopyBack, false );
        aPropSet.setProperty( PROP_CopyStyles, false );
        aPropSet.setProperty( PROP_CopyFormulas, false );
        aPropSet.setProperty( PROP_Protected, maModel.mbLocked );
        // #112621# do not show/print scenario border
        aPropSet.setProperty( PROP_ShowBorder, false );
        aPropSet.setProperty( PROP_PrintBorder, false );
    }
    catch( Exception& )
    {
    }
}

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

SheetScenariosModel::SheetScenariosModel() :
    mnCurrent( 0 ),
    mnShown( 0 )
{
}

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

SheetScenarios::SheetScenarios( const WorkbookHelper& rHelper, sal_Int16 nSheet ) :
    WorkbookHelper( rHelper ),
    mnSheet( nSheet )
{
}

void SheetScenarios::importScenarios( const AttributeList& rAttribs )
{
    maModel.mnCurrent = rAttribs.getInteger( XML_current, 0 );
    maModel.mnShown   = rAttribs.getInteger( XML_show, 0 );
}

void SheetScenarios::importScenarios( SequenceInputStream& rStrm )
{
    maModel.mnCurrent = rStrm.readuInt16();
    maModel.mnShown   = rStrm.readuInt16();
}

Scenario& SheetScenarios::createScenario()
{
    ScenarioVector::value_type xScenario( new Scenario( *this, mnSheet ) );
    maScenarios.push_back( xScenario );
    return *xScenario;
}

void SheetScenarios::finalizeImport()
{
    maScenarios.forEachMem( &Scenario::finalizeImport );

    // activate a scenario
    try
    {
        Reference< XScenariosSupplier > xScenariosSupp( getSheetFromDoc( mnSheet ), UNO_QUERY_THROW );
        Reference< XIndexAccess > xScenariosIA( xScenariosSupp->getScenarios(), UNO_QUERY_THROW );
        Reference< XScenario > xScenario( xScenariosIA->getByIndex( maModel.mnShown ), UNO_QUERY_THROW );
        xScenario->apply();
    }
    catch( Exception& )
    {
    }
}

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

ScenarioBuffer::ScenarioBuffer( const WorkbookHelper& rHelper ) :
    WorkbookHelper( rHelper )
{
}

SheetScenarios& ScenarioBuffer::createSheetScenarios( sal_Int16 nSheet )
{
    SheetScenariosMap::mapped_type& rxSheetScens = maSheetScenarios[ nSheet ];
    if( !rxSheetScens )
        rxSheetScens.reset( new SheetScenarios( *this, nSheet ) );
    return *rxSheetScens;
}

void ScenarioBuffer::finalizeImport()
{
    maSheetScenarios.forEachMem( &SheetScenarios::finalizeImport );
}

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

} // namespace xls
} // namespace oox

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


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

#ifndef _SC_ACCESSIBLEDOCUMENT_HXX
#define _SC_ACCESSIBLEDOCUMENT_HXX

#ifndef _SC_ACCESSIBLEDOCUMENTBASE_HXX
#include "AccessibleDocumentBase.hxx"
#endif
#ifndef SC_VIEWDATA_HXX
#include "viewdata.hxx"
#endif

#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESELECTION_HPP_
#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
#endif
#ifndef _COM_SUN_STAR_VIEW_XSELECTIONCHANGELISTENER_HPP_
#include <com/sun/star/view/XSelectionChangeListener.hpp>
#endif

#ifndef _CPPUHELPER_IMPLBASE2_HXX_
#include <cppuhelper/implbase2.hxx>
#endif

#ifndef _SVX_ACCESSIBILITY_IACCESSIBLE_VIEW_FORWARDER_HXX
#include <svx/IAccessibleViewForwarder.hxx>
#endif

class ScTabViewShell;
class ScAccessibleSpreadsheet;
class ScChildrenShapes;
class ScAccessibleEditObject;

namespace accessibility
{
    class AccessibleShape;
}
namespace utl
{
    class AccessibleRelationSetHelper;
}

/** @descr
        This base class provides an implementation of the
        AccessibleContext service.
*/

typedef cppu::ImplHelper2< ::com::sun::star::accessibility::XAccessibleSelection,
                            ::com::sun::star::view::XSelectionChangeListener >
                    ScAccessibleDocumentImpl;

class ScAccessibleDocument
    :   public ScAccessibleDocumentBase,
        public ScAccessibleDocumentImpl,
        public accessibility::IAccessibleViewForwarder
{
public:
    //=====  internal  ========================================================
    ScAccessibleDocument(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible>& rxParent,
        ScTabViewShell* pViewShell,
        ScSplitPos eSplitPos);

    virtual void Init();

    DECL_LINK( WindowChildEventListener, VclSimpleEvent* );
protected:
    virtual ~ScAccessibleDocument(void);
public:

     virtual void SAL_CALL disposing();

   ///=====  SfxListener  =====================================================

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

    ///=====  XInterface  =====================================================

    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
        ::com::sun::star::uno::Type const & rType )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL acquire() throw ();

    virtual void SAL_CALL release() throw ();

    ///=====  XAccessibleComponent  ============================================

    virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
        SAL_CALL getAccessibleAtPoint(
        const ::com::sun::star::awt::Point& rPoint )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL grabFocus(  )
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XAccessibleContext  ==============================================

    /// Return the number of currently visible children.
    virtual long SAL_CALL
        getAccessibleChildCount(void)
        throw (::com::sun::star::uno::RuntimeException);

    /// Return the specified child or NULL if index is invalid.
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
        getAccessibleChild(long nIndex)
        throw (::com::sun::star::uno::RuntimeException,
                ::com::sun::star::lang::IndexOutOfBoundsException);

    /// Return the set of current states.
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
        getAccessibleStateSet(void)
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XAccessibleSelection  ===========================================

    virtual void SAL_CALL
        selectAccessibleChild( sal_Int32 nChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    virtual sal_Bool SAL_CALL
        isAccessibleChildSelected( sal_Int32 nChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
        clearAccessibleSelection(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
        selectAllAccessibleChildren(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual sal_Int32 SAL_CALL
        getSelectedAccessibleChildCount(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible > SAL_CALL
        getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
        deselectAccessibleChild( sal_Int32 nChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    ///=====  XSelectionListener  =============================================

    virtual void SAL_CALL selectionChanged( const ::com::sun::star::lang::EventObject& aEvent )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XServiceInfo  ===================================================

    /** Returns an identifier for the implementation of this object.
    */
    virtual ::rtl::OUString SAL_CALL
        getImplementationName(void)
        throw (::com::sun::star::uno::RuntimeException);

    /** Returns a list of all supported services.
    */
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
        getSupportedServiceNames(void)
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XTypeProvider  ===================================================

    /// returns the possible types
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
        getTypes()
        throw (::com::sun::star::uno::RuntimeException);

    /** Returns a implementation id.
    */
    virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
        getImplementationId(void)
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  IAccessibleViewForwarder  ========================================

    /** This method informs you about the state of the forwarder.  Do not
        use it when the returned value is <false/>.

        @return
            Return <true/> if the view forwarder is valid and <false/> else.
     */
    virtual sal_Bool IsValid (void) const;

    /** Returns the area of the underlying document that is visible in the
    * corresponding window.

        @return
            The rectangle of the visible part of the document. The values
            are, contrary to the base class, in internal coordinates.
     */
    virtual Rectangle GetVisibleArea() const;

    /** Transform the specified point from internal coordinates to an
        absolute screen position.

        @param rPoint
            Point in internal coordinates.

        @return
            The same point but in screen coordinates relative to the upper
            left corner of the (current) screen.
     */
    virtual Point LogicToPixel (const Point& rPoint) const;

    /** Transform the specified size from internal coordinates to a screen
    * oriented pixel size.

        @param rSize
            Size in internal coordinates.

        @return
            The same size but in screen coordinates.
     */
    virtual Size LogicToPixel (const Size& rSize) const;

    /** Transform the specified point from absolute screen coordinates to
        internal coordinates.

        @param rPoint
            Point in screen coordinates relative to the upper left corner of
            the (current) screen.

        @return
            The same point but in internal coordinates.
     */
    virtual Point PixelToLogic (const Point& rPoint) const;

    /** Transform the specified size from screen coordinates to internal
        coordinates.

        @param rSize
            Size in screen coordinates.

        @return
            The same size but in internal coordinates.
     */
    virtual Size PixelToLogic (const Size& rSize) const;

    ///======== internal =====================================================

    utl::AccessibleRelationSetHelper* GetRelationSet(const ScAddress* pAddress) const;

    ::com::sun::star::uno::Reference
        < ::com::sun::star::accessibility::XAccessible >
        GetAccessibleSpreadsheet();

protected:
    /// Return this object's description.
    virtual ::rtl::OUString SAL_CALL
        createAccessibleDescription(void)
        throw (::com::sun::star::uno::RuntimeException);

    /// Return the object's current name.
    virtual ::rtl::OUString SAL_CALL
        createAccessibleName(void)
        throw (::com::sun::star::uno::RuntimeException);

    /// Return the object's current bounding box relative to the desktop.
    virtual Rectangle GetBoundingBoxOnScreen(void) const
        throw (::com::sun::star::uno::RuntimeException);

    /// Return the object's current bounding box relative to the parent object.
    virtual Rectangle GetBoundingBox(void) const
        throw (::com::sun::star::uno::RuntimeException);

private:
    ScTabViewShell* mpViewShell;
    ScSplitPos      meSplitPos;
    ScAccessibleSpreadsheet* mpAccessibleSpreadsheet;
    ScChildrenShapes* mpChildrenShapes;
    ScAccessibleEditObject* mpTempAccEdit;
    com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible> mxTempAcc;
    Rectangle maVisArea;
    sal_Bool mbCompleteSheetSelected;

public:
    SCTAB getVisibleTable() const; // use it in ScChildrenShapes

private:
    void FreeAccessibleSpreadsheet();

    sal_Bool IsTableSelected() const;

    sal_Bool IsDefunc(
        const com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
    sal_Bool IsEditable(
        const com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);

    void AddChild(const com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible>& xAcc, sal_Bool bFireEvent);
    void RemoveChild(const com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible>& xAcc, sal_Bool bFireEvent);

    rtl::OUString GetCurrentCellName() const;
    rtl::OUString GetCurrentCellDescription() const;

    Rectangle GetVisibleArea_Impl() const;
};

#endif
<commit_msg>INTEGRATION: CWS long2int (1.25.46); FILE MERGED 2005/10/26 18:07:18 kendy 1.25.46.1: #i56715# Trivial long/ULONG -> sal_Int32/sal_uInt32 patches extracted from ooo64bit02 CWS.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: AccessibleDocument.hxx,v $
 *
 *  $Revision: 1.26 $
 *
 *  last change: $Author: vg $ $Date: 2006-03-31 09:31:42 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SC_ACCESSIBLEDOCUMENT_HXX
#define _SC_ACCESSIBLEDOCUMENT_HXX

#ifndef _SC_ACCESSIBLEDOCUMENTBASE_HXX
#include "AccessibleDocumentBase.hxx"
#endif
#ifndef SC_VIEWDATA_HXX
#include "viewdata.hxx"
#endif

#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESELECTION_HPP_
#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
#endif
#ifndef _COM_SUN_STAR_VIEW_XSELECTIONCHANGELISTENER_HPP_
#include <com/sun/star/view/XSelectionChangeListener.hpp>
#endif

#ifndef _CPPUHELPER_IMPLBASE2_HXX_
#include <cppuhelper/implbase2.hxx>
#endif

#ifndef _SVX_ACCESSIBILITY_IACCESSIBLE_VIEW_FORWARDER_HXX
#include <svx/IAccessibleViewForwarder.hxx>
#endif

class ScTabViewShell;
class ScAccessibleSpreadsheet;
class ScChildrenShapes;
class ScAccessibleEditObject;

namespace accessibility
{
    class AccessibleShape;
}
namespace utl
{
    class AccessibleRelationSetHelper;
}

/** @descr
        This base class provides an implementation of the
        AccessibleContext service.
*/

typedef cppu::ImplHelper2< ::com::sun::star::accessibility::XAccessibleSelection,
                            ::com::sun::star::view::XSelectionChangeListener >
                    ScAccessibleDocumentImpl;

class ScAccessibleDocument
    :   public ScAccessibleDocumentBase,
        public ScAccessibleDocumentImpl,
        public accessibility::IAccessibleViewForwarder
{
public:
    //=====  internal  ========================================================
    ScAccessibleDocument(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible>& rxParent,
        ScTabViewShell* pViewShell,
        ScSplitPos eSplitPos);

    virtual void Init();

    DECL_LINK( WindowChildEventListener, VclSimpleEvent* );
protected:
    virtual ~ScAccessibleDocument(void);
public:

     virtual void SAL_CALL disposing();

   ///=====  SfxListener  =====================================================

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

    ///=====  XInterface  =====================================================

    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
        ::com::sun::star::uno::Type const & rType )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL acquire() throw ();

    virtual void SAL_CALL release() throw ();

    ///=====  XAccessibleComponent  ============================================

    virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
        SAL_CALL getAccessibleAtPoint(
        const ::com::sun::star::awt::Point& rPoint )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL grabFocus(  )
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XAccessibleContext  ==============================================

    /// Return the number of currently visible children.
    virtual sal_Int32 SAL_CALL
        getAccessibleChildCount(void)
        throw (::com::sun::star::uno::RuntimeException);

    /// Return the specified child or NULL if index is invalid.
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
        getAccessibleChild(sal_Int32 nIndex)
        throw (::com::sun::star::uno::RuntimeException,
                ::com::sun::star::lang::IndexOutOfBoundsException);

    /// Return the set of current states.
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
        getAccessibleStateSet(void)
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XAccessibleSelection  ===========================================

    virtual void SAL_CALL
        selectAccessibleChild( sal_Int32 nChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    virtual sal_Bool SAL_CALL
        isAccessibleChildSelected( sal_Int32 nChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
        clearAccessibleSelection(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
        selectAllAccessibleChildren(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual sal_Int32 SAL_CALL
        getSelectedAccessibleChildCount(  )
        throw (::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible > SAL_CALL
        getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL
        deselectAccessibleChild( sal_Int32 nChildIndex )
        throw (::com::sun::star::lang::IndexOutOfBoundsException,
        ::com::sun::star::uno::RuntimeException);

    ///=====  XSelectionListener  =============================================

    virtual void SAL_CALL selectionChanged( const ::com::sun::star::lang::EventObject& aEvent )
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XServiceInfo  ===================================================

    /** Returns an identifier for the implementation of this object.
    */
    virtual ::rtl::OUString SAL_CALL
        getImplementationName(void)
        throw (::com::sun::star::uno::RuntimeException);

    /** Returns a list of all supported services.
    */
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
        getSupportedServiceNames(void)
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  XTypeProvider  ===================================================

    /// returns the possible types
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL
        getTypes()
        throw (::com::sun::star::uno::RuntimeException);

    /** Returns a implementation id.
    */
    virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
        getImplementationId(void)
        throw (::com::sun::star::uno::RuntimeException);

    ///=====  IAccessibleViewForwarder  ========================================

    /** This method informs you about the state of the forwarder.  Do not
        use it when the returned value is <false/>.

        @return
            Return <true/> if the view forwarder is valid and <false/> else.
     */
    virtual sal_Bool IsValid (void) const;

    /** Returns the area of the underlying document that is visible in the
    * corresponding window.

        @return
            The rectangle of the visible part of the document. The values
            are, contrary to the base class, in internal coordinates.
     */
    virtual Rectangle GetVisibleArea() const;

    /** Transform the specified point from internal coordinates to an
        absolute screen position.

        @param rPoint
            Point in internal coordinates.

        @return
            The same point but in screen coordinates relative to the upper
            left corner of the (current) screen.
     */
    virtual Point LogicToPixel (const Point& rPoint) const;

    /** Transform the specified size from internal coordinates to a screen
    * oriented pixel size.

        @param rSize
            Size in internal coordinates.

        @return
            The same size but in screen coordinates.
     */
    virtual Size LogicToPixel (const Size& rSize) const;

    /** Transform the specified point from absolute screen coordinates to
        internal coordinates.

        @param rPoint
            Point in screen coordinates relative to the upper left corner of
            the (current) screen.

        @return
            The same point but in internal coordinates.
     */
    virtual Point PixelToLogic (const Point& rPoint) const;

    /** Transform the specified size from screen coordinates to internal
        coordinates.

        @param rSize
            Size in screen coordinates.

        @return
            The same size but in internal coordinates.
     */
    virtual Size PixelToLogic (const Size& rSize) const;

    ///======== internal =====================================================

    utl::AccessibleRelationSetHelper* GetRelationSet(const ScAddress* pAddress) const;

    ::com::sun::star::uno::Reference
        < ::com::sun::star::accessibility::XAccessible >
        GetAccessibleSpreadsheet();

protected:
    /// Return this object's description.
    virtual ::rtl::OUString SAL_CALL
        createAccessibleDescription(void)
        throw (::com::sun::star::uno::RuntimeException);

    /// Return the object's current name.
    virtual ::rtl::OUString SAL_CALL
        createAccessibleName(void)
        throw (::com::sun::star::uno::RuntimeException);

    /// Return the object's current bounding box relative to the desktop.
    virtual Rectangle GetBoundingBoxOnScreen(void) const
        throw (::com::sun::star::uno::RuntimeException);

    /// Return the object's current bounding box relative to the parent object.
    virtual Rectangle GetBoundingBox(void) const
        throw (::com::sun::star::uno::RuntimeException);

private:
    ScTabViewShell* mpViewShell;
    ScSplitPos      meSplitPos;
    ScAccessibleSpreadsheet* mpAccessibleSpreadsheet;
    ScChildrenShapes* mpChildrenShapes;
    ScAccessibleEditObject* mpTempAccEdit;
    com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible> mxTempAcc;
    Rectangle maVisArea;
    sal_Bool mbCompleteSheetSelected;

public:
    SCTAB getVisibleTable() const; // use it in ScChildrenShapes

private:
    void FreeAccessibleSpreadsheet();

    sal_Bool IsTableSelected() const;

    sal_Bool IsDefunc(
        const com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);
    sal_Bool IsEditable(
        const com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessibleStateSet>& rxParentStates);

    void AddChild(const com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible>& xAcc, sal_Bool bFireEvent);
    void RemoveChild(const com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible>& xAcc, sal_Bool bFireEvent);

    rtl::OUString GetCurrentCellName() const;
    rtl::OUString GetCurrentCellDescription() const;

    Rectangle GetVisibleArea_Impl() const;
};

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008 James Molloy, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "RoutingTable.h"
#include <config/Config.h>
#include <machine/DeviceHashTree.h>
#include <LockGuard.h>

RoutingTable RoutingTable::m_Instance;

RoutingTable::RoutingTable() : m_bHasRoutes(false), m_TableLock(false)
{
}

RoutingTable::~RoutingTable()
{
}

void RoutingTable::Add(Type type, IpAddress dest, IpAddress subIp, String meta, Network *card)
{
    LockGuard<Mutex> guard(m_TableLock);

    // Add to the hash tree, if not already done. This ensures the loopback
    // device is definitely available as an interface.
    DeviceHashTree::instance().add(card);

    // Add the route to the database directly
    String str;
    size_t hash = DeviceHashTree::instance().getHash(card);
    str.sprintf("INSERT INTO routes (ipaddr, subip, name, type, iface) VALUES (%d, %d, '%s', %d, %d)", dest.getIp(), subIp.getIp(), static_cast<const char*>(meta), static_cast<int>(type), hash);
    Config::Result *pResult = Config::instance().query(str);
    if(!pResult->succeeded())
    {
        ERROR("Routing table query failed: " << pResult->errorMessage());
    }

    NOTICE("RoutingTable: Adding IP match route for " << dest.toString() << ", sub " << subIp.toString() << ".");

    m_bHasRoutes = true;

    delete pResult;
}

void RoutingTable::Add(Type type, IpAddress dest, IpAddress subnet, IpAddress subIp, String meta, Network *card)
{
    LockGuard<Mutex> guard(m_TableLock);

    // Add to the hash tree, if not already done. This ensures the loopback
    // device is definitely available as an interface.
    DeviceHashTree::instance().add(card);

    // Invert the subnet to get an IP range
    IpAddress invSubnet(subnet.getIp() ^ 0xFFFFFFFF);
    IpAddress bottomOfRange = dest & subnet;
    IpAddress topOfRange = (dest & subnet) + invSubnet;

    NOTICE("RoutingTable: Adding " << (type == DestSubnetComplement ? "complement of " : "") << "subnet match for range " << bottomOfRange.toString() << "-" << topOfRange.toString());

    // Add to the database
    String str;
    size_t hash = DeviceHashTree::instance().getHash(card);
    str.sprintf("INSERT INTO routes (ipstart, ipend, subip, name, type, iface) VALUES (%d, %d, %d, '%s', %d, %d)",
                bottomOfRange.getIp(),
                topOfRange.getIp(),
                subIp.getIp(),
                static_cast<const char*>(meta),
                static_cast<int>(type),
                hash);
    Config::Result *pResult = Config::instance().query(str);
    if(!pResult->succeeded())
    {
        ERROR("Routing table query failed: " << pResult->errorMessage());
    }

    m_bHasRoutes = true;

    delete pResult;
}

Network *RoutingTable::route(IpAddress *ip, Config::Result *pResult)
{
    // Grab the interface
    Network *pCard = dynamic_cast<Network*>(DeviceHashTree::instance().getDevice(pResult->getNum(0, "iface")));

    // If we are to perform substitution, do so
    Type t = static_cast<Type>(pResult->getNum(0, "type"));
    if(t == DestIpSub || t == DestSubnetComplement)
        ip->setIp(pResult->getNum(0, "subip"));

    // Return the interface to use
    delete pResult;
    return pCard;
}

Network *RoutingTable::DetermineRoute(IpAddress *ip, bool bGiveDefault)
{
    LockGuard<Mutex> guard(m_TableLock);

    // Build a query to search for a direct match
    String str;
    str.sprintf("SELECT * FROM routes WHERE ipaddr=%d", ip->getIp());
    Config::Result *pResult = Config::instance().query(str);
    if(!pResult->succeeded())
        ERROR("Routing table query failed: " << pResult->errorMessage());
    else if(pResult->rows())
    {
        return route(ip, pResult);
    }
    delete pResult;

    // No rows! Try a subnet lookup first, without a complement.
    str.sprintf("SELECT * FROM routes WHERE (ipstart <= %d AND ipend >= %d)", ip->getIp(), ip->getIp());
    pResult = Config::instance().query(str);
    if(!pResult->succeeded())
        ERROR("Routing table query failed: " << pResult->errorMessage());
    else if(pResult->rows())
    {
        return route(ip, pResult);
    }
    delete pResult;

    // Still nothing, try a complement subnet search
    str.sprintf("SELECT * FROM routes WHERE NOT (ipstart <= %d AND ipend >= %d)", ip->getIp(), ip->getIp());
    pResult = Config::instance().query(str);
    if(!pResult->succeeded())
        ERROR("Routing table query failed: " << pResult->errorMessage());
    else if(pResult->rows())
    {
        return route(ip, pResult);
    }
    delete pResult;

    // Nothing even still, try the default route if we're allowed
    if(bGiveDefault)
        return DefaultRoute();

    // Not even the default route worked!
    return 0;
}

Network *RoutingTable::DefaultRoute()
{
    // If already locked, will return false, so we don't unlock (DetermineRoute calls this function)
    bool bLocked = m_TableLock.tryAcquire();

    String str;
    str.sprintf("SELECT * FROM routes WHERE name='default'");
    Config::Result *pResult = Config::instance().query(str);
    if(!pResult->succeeded())
        ERROR("Routing table query failed: " << pResult->errorMessage());
    else if(pResult->rows())
    {
        if(bLocked)
            m_TableLock.release();
        return route(0, pResult);
    }

    delete pResult;

    if(bLocked)
        m_TableLock.release();

    return 0;
}
<commit_msg>Fix a signed/unsigned comparison bug in the routing table, and enforce specific searches to avoid ambiguity between complement of subnet and subnet matches.<commit_after>/*
 * Copyright (c) 2008 James Molloy, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "RoutingTable.h"
#include <config/Config.h>
#include <machine/DeviceHashTree.h>
#include <LockGuard.h>

RoutingTable RoutingTable::m_Instance;

RoutingTable::RoutingTable() : m_bHasRoutes(false), m_TableLock(false)
{
}

RoutingTable::~RoutingTable()
{
}

void RoutingTable::Add(Type type, IpAddress dest, IpAddress subIp, String meta, Network *card)
{
    LockGuard<Mutex> guard(m_TableLock);

    // Add to the hash tree, if not already done. This ensures the loopback
    // device is definitely available as an interface.
    DeviceHashTree::instance().add(card);

    // Add the route to the database directly
    String str;
    size_t hash = DeviceHashTree::instance().getHash(card);
    str.sprintf("INSERT INTO routes (ipaddr, subip, name, type, iface) VALUES (%u, %u, '%s', %d, %u)", dest.getIp(), subIp.getIp(), static_cast<const char*>(meta), static_cast<int>(type), hash);
    Config::Result *pResult = Config::instance().query(str);
    if(!pResult->succeeded())
    {
        ERROR("Routing table query failed: " << pResult->errorMessage());
    }

    NOTICE("RoutingTable: Adding IP match route for " << dest.toString() << ", sub " << subIp.toString() << ".");

    m_bHasRoutes = true;

    delete pResult;
}

void RoutingTable::Add(Type type, IpAddress dest, IpAddress subnet, IpAddress subIp, String meta, Network *card)
{
    LockGuard<Mutex> guard(m_TableLock);

    // Add to the hash tree, if not already done. This ensures the loopback
    // device is definitely available as an interface.
    DeviceHashTree::instance().add(card);

    // Invert the subnet to get an IP range
    IpAddress invSubnet(subnet.getIp() ^ 0xFFFFFFFF);
    IpAddress bottomOfRange = dest & subnet;
    IpAddress topOfRange = (dest & subnet) + invSubnet;

    NOTICE("RoutingTable: Adding " << (type == DestSubnetComplement ? "complement of " : "") << "subnet match for range " << bottomOfRange.toString() << " [" << bottomOfRange.getIp() << "] -" << topOfRange.toString() << " [" << topOfRange.getIp() << "]");

    // Add to the database
    String str;
    size_t hash = DeviceHashTree::instance().getHash(card);
    str.sprintf("INSERT INTO routes (ipstart, ipend, subip, name, type, iface) VALUES (%u, %u, %u, '%s', %d, %u)",
                bottomOfRange.getIp(),
                topOfRange.getIp(),
                subIp.getIp(),
                static_cast<const char*>(meta),
                static_cast<int>(type),
                hash);
    Config::Result *pResult = Config::instance().query(str);
    if(!pResult->succeeded())
    {
        ERROR("Routing table query failed: " << pResult->errorMessage());
    }

    m_bHasRoutes = true;

    delete pResult;
}

Network *RoutingTable::route(IpAddress *ip, Config::Result *pResult)
{
    // Grab the interface
    Network *pCard = dynamic_cast<Network*>(DeviceHashTree::instance().getDevice(pResult->getNum(0, "iface")));

    // If we are to perform substitution, do so
    Type t = static_cast<Type>(pResult->getNum(0, "type"));
    if(t == DestIpSub || t == DestSubnetComplement)
        ip->setIp(pResult->getNum(0, "subip"));

    // Return the interface to use
    delete pResult;
    return pCard;
}

Network *RoutingTable::DetermineRoute(IpAddress *ip, bool bGiveDefault)
{
    LockGuard<Mutex> guard(m_TableLock);

    // Build a query to search for a direct match
    String str;
    str.sprintf("SELECT * FROM routes WHERE ipaddr=%u", ip->getIp());
    Config::Result *pResult = Config::instance().query(str);
    if(!pResult->succeeded())
        ERROR("Routing table query failed: " << pResult->errorMessage());
    else if(pResult->rows())
    {
        return route(ip, pResult);
    }
    delete pResult;

    // No rows! Try a subnet lookup first, without a complement.
    str.sprintf("SELECT * FROM routes WHERE ((ipstart <= %u) AND (ipend >= %u) AND (type == %u))", ip->getIp(), ip->getIp(), static_cast<int>(DestSubnet));
    pResult = Config::instance().query(str);
    if(!pResult->succeeded())
        ERROR("Routing table query failed: " << pResult->errorMessage());
    else if(pResult->rows())
    {
        return route(ip, pResult);
    }
    delete pResult;

    // Still nothing, try a complement subnet search
    str.sprintf("SELECT * FROM routes WHERE (NOT ((ipstart <= %u) AND (ipend >= %u))) AND (type == %u)", ip->getIp(), ip->getIp(), static_cast<int>(DestSubnetComplement));
    pResult = Config::instance().query(str);
    if(!pResult->succeeded())
        ERROR("Routing table query failed: " << pResult->errorMessage());
    else if(pResult->rows())
    {
        return route(ip, pResult);
    }
    delete pResult;

    // Nothing even still, try the default route if we're allowed
    if(bGiveDefault)
        return DefaultRoute();

    // Not even the default route worked!
    return 0;
}

Network *RoutingTable::DefaultRoute()
{
    // If already locked, will return false, so we don't unlock (DetermineRoute calls this function)
    bool bLocked = m_TableLock.tryAcquire();

    String str;
    str.sprintf("SELECT * FROM routes WHERE name='default'");
    Config::Result *pResult = Config::instance().query(str);
    if(!pResult->succeeded())
        ERROR("Routing table query failed: " << pResult->errorMessage());
    else if(pResult->rows())
    {
        if(bLocked)
            m_TableLock.release();
        return route(0, pResult);
    }

    delete pResult;

    if(bLocked)
        m_TableLock.release();

    return 0;
}
<|endoftext|>