/src/libreoffice/sc/source/ui/StatisticsDialogs/DescriptiveStatisticsDialog.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | */ |
10 | | |
11 | | #include <memory> |
12 | | |
13 | | #include <reffact.hxx> |
14 | | #include <TableFillingAndNavigationTools.hxx> |
15 | | #include <DescriptiveStatisticsDialog.hxx> |
16 | | #include <scresid.hxx> |
17 | | #include <strings.hrc> |
18 | | |
19 | | namespace |
20 | | { |
21 | | |
22 | | struct StatisticCalculation { |
23 | | TranslateId aCalculationNameId; |
24 | | const char* aFormula; |
25 | | }; |
26 | | |
27 | | const StatisticCalculation lclCalcDefinitions[] = |
28 | | { |
29 | | { STRID_CALC_MEAN, "=AVERAGE(%RANGE%)" }, |
30 | | { STRID_CALC_STD_ERROR, "=SQRT(VAR(%RANGE%)/COUNT(%RANGE%))"}, |
31 | | { STRID_CALC_MODE, "=MODE(%RANGE%)"}, |
32 | | { STRID_CALC_MEDIAN, "=MEDIAN(%RANGE%)"}, |
33 | | { STRID_CALC_FIRST_QUARTILE, "=QUARTILE(%RANGE%; 1)" }, |
34 | | { STRID_CALC_THIRD_QUARTILE, "=QUARTILE(%RANGE%; 3)" }, |
35 | | { STRID_CALC_VARIANCE, "=VAR(%RANGE%)"}, |
36 | | { STRID_CALC_STD_DEVIATION, "=STDEV(%RANGE%)"}, |
37 | | { STRID_CALC_KURTOSIS, "=KURT(%RANGE%)"}, |
38 | | { STRID_CALC_SKEWNESS, "=SKEW(%RANGE%)"}, |
39 | | { STRID_CALC_RANGE, "=MAX(%RANGE%)-MIN(%RANGE%)"}, |
40 | | { STRID_CALC_MIN, "=MIN(%RANGE%)"}, |
41 | | { STRID_CALC_MAX, "=MAX(%RANGE%)"}, |
42 | | { STRID_CALC_SUM, "=SUM(%RANGE%)"}, |
43 | | { STRID_CALC_COUNT, "=COUNT(%RANGE%)" }, |
44 | | { {}, nullptr } |
45 | | }; |
46 | | |
47 | | } |
48 | | |
49 | | ScDescriptiveStatisticsDialog::ScDescriptiveStatisticsDialog( |
50 | | SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow, |
51 | | weld::Window* pParent, ScViewData& rViewData ) : |
52 | 0 | ScStatisticsInputOutputDialog( |
53 | 0 | pSfxBindings, pChildWindow, pParent, rViewData, |
54 | 0 | u"modules/scalc/ui/descriptivestatisticsdialog.ui"_ustr, |
55 | 0 | u"DescriptiveStatisticsDialog"_ustr) |
56 | 0 | {} |
57 | | |
58 | | ScDescriptiveStatisticsDialog::~ScDescriptiveStatisticsDialog() |
59 | 0 | {} |
60 | | |
61 | | void ScDescriptiveStatisticsDialog::Close() |
62 | 0 | { |
63 | 0 | DoClose( ScDescriptiveStatisticsDialogWrapper::GetChildWindowId() ); |
64 | 0 | } |
65 | | |
66 | | TranslateId ScDescriptiveStatisticsDialog::GetUndoNameId() |
67 | 0 | { |
68 | 0 | return STR_DESCRIPTIVE_STATISTICS_UNDO_NAME; |
69 | 0 | } |
70 | | |
71 | | ScRange ScDescriptiveStatisticsDialog::ApplyOutput(ScDocShell* pDocShell) |
72 | 0 | { |
73 | 0 | AddressWalkerWriter aOutput(mOutputAddress, pDocShell, mDocument, |
74 | 0 | formula::FormulaGrammar::mergeToGrammar( formula::FormulaGrammar::GRAM_ENGLISH, mAddressDetails.eConv)); |
75 | 0 | FormulaTemplate aTemplate(&mDocument); |
76 | |
|
77 | 0 | std::unique_ptr<DataRangeIterator> pIterator; |
78 | 0 | if (mGroupedBy == BY_COLUMN) |
79 | 0 | pIterator.reset(new DataRangeByColumnIterator(mInputRange)); |
80 | 0 | else |
81 | 0 | pIterator.reset(new DataRangeByRowIterator(mInputRange)); |
82 | |
|
83 | 0 | aOutput.nextColumn(); |
84 | | |
85 | | // Use explicit sheet name in case the input and output are on different sheets. |
86 | 0 | bool b3DAddress = mInputRange.aStart.Tab() != mOutputAddress.Tab(); |
87 | | |
88 | | // Write column/row labels |
89 | 0 | for( ; pIterator->hasNext(); pIterator->next() ) |
90 | 0 | { |
91 | | // tdf#128018 - add column/row labels to the output |
92 | 0 | OUString aColRowLabel = mDocument.GetString(pIterator->get().aStart); |
93 | 0 | if (aColRowLabel.isEmpty()) |
94 | 0 | { |
95 | 0 | if (mGroupedBy == BY_COLUMN) |
96 | 0 | aTemplate.setTemplate(ScResId(STR_COLUMN_LABEL_TEMPLATE)); |
97 | 0 | else |
98 | 0 | aTemplate.setTemplate(ScResId(STR_ROW_LABEL_TEMPLATE)); |
99 | |
|
100 | 0 | aTemplate.applyNumber(u"%NUMBER%", pIterator->index() + 1); |
101 | 0 | aOutput.writeBoldString(aTemplate.getTemplate()); |
102 | 0 | } |
103 | 0 | else |
104 | 0 | { |
105 | 0 | aOutput.writeBoldString(aColRowLabel); |
106 | 0 | } |
107 | 0 | aOutput.nextColumn(); |
108 | 0 | } |
109 | 0 | aOutput.nextRow(); |
110 | 0 | aOutput.resetColumn(); |
111 | 0 | aOutput.push(); |
112 | | |
113 | | // Write calculation labels |
114 | 0 | for(sal_Int32 i = 0; lclCalcDefinitions[i].aFormula != nullptr; i++) |
115 | 0 | { |
116 | 0 | OUString aLabel(ScResId(lclCalcDefinitions[i].aCalculationNameId)); |
117 | 0 | aOutput.writeString(aLabel); |
118 | 0 | aOutput.nextRow(); |
119 | 0 | } |
120 | 0 | aOutput.nextColumn(); |
121 | |
|
122 | 0 | pIterator->reset(); |
123 | |
|
124 | 0 | for( ; pIterator->hasNext(); pIterator->next() ) |
125 | 0 | { |
126 | 0 | aOutput.resetRow(); |
127 | |
|
128 | 0 | for(sal_Int32 i = 0; lclCalcDefinitions[i].aFormula != nullptr; i++) |
129 | 0 | { |
130 | 0 | aTemplate.setTemplate(lclCalcDefinitions[i].aFormula); |
131 | 0 | aTemplate.applyRange(u"%RANGE%", pIterator->get(), b3DAddress); |
132 | 0 | aOutput.writeFormula(aTemplate.getTemplate()); |
133 | 0 | aOutput.nextRow(); |
134 | 0 | } |
135 | 0 | aOutput.nextColumn(); |
136 | 0 | } |
137 | |
|
138 | 0 | return ScRange(aOutput.mMinimumAddress, aOutput.mMaximumAddress); |
139 | 0 | } |
140 | | |
141 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |