summaryrefslogtreecommitdiff
path: root/sc/qa/extras/accessibility/basics.cxx
blob: e96323625549c19168ce0d94120720c00f4cae9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
 * 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/.
 */

#include <com/sun/star/accessibility/XAccessibleTable.hpp>
#include <com/sun/star/accessibility/XAccessibleText.hpp>
#include <com/sun/star/accessibility/XAccessibleValue.hpp>
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>

#include <com/sun/star/awt/Key.hpp>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>

#include <tools/date.hxx>
#include <tools/time.hxx>

#include <test/a11y/accessibletestbase.hxx>

using namespace css;

CPPUNIT_TEST_FIXTURE(test::AccessibleTestBase, TestCalcMenu)
{
    load(u"private:factory/scalc"_ustr);

    const Date beforeDate(Date::SYSTEM);
    const double beforeTime = tools::Time(tools::Time::SYSTEM).GetTimeInDays();

    // in cell A1, insert the date
    CPPUNIT_ASSERT(activateMenuItem(u"Insert", u"Date"));
    // move down to A2
    documentPostKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, css::awt::Key::DOWN);
    // in cell A2, insert the time
    CPPUNIT_ASSERT(activateMenuItem(u"Insert", u"Time"));

    uno::Reference<accessibility::XAccessibleTable> sheet(
        getDocumentAccessibleContext()->getAccessibleChild(0)->getAccessibleContext(), // sheet 1
        uno::UNO_QUERY_THROW);

    /* As it's very tricky to check the dates and times are correct in text format (imagine running
     * on 1970-12-31 23:59:59.99, it's gonna shift *everything* in a 100th of a second) because
     * clock can have changed between generating the two values to compare.  So instead we just
     * check the text is not empty, and the underlying value (representing the date or time) is
     * between the time it was before and after the call. */

    // cell A1 contains a date
    auto xCell = sheet->getAccessibleCellAt(0, 0)->getAccessibleContext();
    uno::Reference<accessibility::XAccessibleText> xText(xCell, uno::UNO_QUERY_THROW);
    std::cout << "A1 (text):  " << xText->getText() << std::endl;
    CPPUNIT_ASSERT(!xText->getText().isEmpty());
    uno::Reference<accessibility::XAccessibleValue> xValue(xCell, uno::UNO_QUERY_THROW);
    double value;
    CPPUNIT_ASSERT(xValue->getCurrentValue() >>= value);
    std::cout << "A1 (value): " << value << std::endl;
    uno::Reference<util::XNumberFormatsSupplier> xSupplier(mxDocument, uno::UNO_QUERY_THROW);
    util::Date nullDate;
    CPPUNIT_ASSERT(xSupplier->getNumberFormatSettings()->getPropertyValue(u"NullDate"_ustr)
                   >>= nullDate);
    const Date afterDate(Date::SYSTEM);
    CPPUNIT_ASSERT_GREATEREQUAL(double(beforeDate - Date(nullDate)), value);
    CPPUNIT_ASSERT_LESSEQUAL(double(afterDate - Date(nullDate)), value);

    // cell A2 contains time, no date, so we have to be careful passing midnight
    xCell = sheet->getAccessibleCellAt(1, 0)->getAccessibleContext();
    xText.set(xCell, uno::UNO_QUERY_THROW);
    std::cout << "A2 (text):  " << xText->getText() << std::endl;
    CPPUNIT_ASSERT(!xText->getText().isEmpty());
    xValue.set(xCell, uno::UNO_QUERY_THROW);
    CPPUNIT_ASSERT(xValue->getCurrentValue() >>= value);
    std::cout << "A2 (value): " << value << std::endl;
    double afterTime = tools::Time(tools::Time::SYSTEM).GetTimeInDays();
    // in case day changed -- assuming no more than 24 hours passed
    if (afterTime < beforeTime)
    {
        afterTime += 1;
        if (value < beforeTime)
            value += 1;
    }
    CPPUNIT_ASSERT_GREATEREQUAL(beforeTime, value);
    CPPUNIT_ASSERT_LESSEQUAL(afterTime, value);
}

// test that converting cell row/col number <-> child index works
// for the case where 32-bit a11y child indices don't suffice (tdf#150683)
CPPUNIT_TEST_FIXTURE(test::AccessibleTestBase, Test64BitChildIndices)
{
    load(u"private:factory/scalc"_ustr);

    const sal_Int32 nRow = 1048575;
    const sal_Int32 nCol = 16383;

    uno::Reference<accessibility::XAccessibleTable> xTable(
        getDocumentAccessibleContext()->getAccessibleChild(0)->getAccessibleContext(), // sheet 1
        uno::UNO_QUERY_THROW);

    uno::Reference<accessibility::XAccessible> xCell = xTable->getAccessibleCellAt(nRow, nCol);
    const sal_Int64 nChildIndex = xCell->getAccessibleContext()->getAccessibleIndexInParent();
    // child index should be positive for all cells except the first one (A1)
    CPPUNIT_ASSERT_GREATER(sal_Int64(0), nChildIndex);

    // test that retrieving the row and column number via the child index again works
    CPPUNIT_ASSERT_EQUAL(nRow, xTable->getAccessibleRow(nChildIndex));
    CPPUNIT_ASSERT_EQUAL(nCol, xTable->getAccessibleColumn(nChildIndex));
}

CPPUNIT_TEST_FIXTURE(test::AccessibleTestBase, tdf157568)
{
    load(u"private:factory/scalc"_ustr);

    uno::Reference<accessibility::XAccessibleTable> sheet(
        getDocumentAccessibleContext()->getAccessibleChild(0)->getAccessibleContext(), // sheet 1
        uno::UNO_QUERY_THROW);

    uno::Reference<accessibility::XAccessible> xCell = sheet->getAccessibleCellAt(1, 1);
    CPPUNIT_ASSERT(xCell);
    uno::WeakReference<accessibility::XAccessible> xCellWeak(xCell);
    xCell.clear();
    // Verify that there are no reference cycles and that the ScAccessibleCell object dies after we
    // are done with it.
    uno::Reference<accessibility::XAccessible> xCell2(xCellWeak);
    CPPUNIT_ASSERT(!xCell2.is());
}

CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */