1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <ElementsDockingWindow.hxx>
23 #include <starmath.hrc>
24 #include <strings.hrc>
27 #include <visitors.hxx>
28 #include <document.hxx>
30 #include "uiobject.hxx"
31 #include <strings.hxx>
33 #include <o3tl/make_unique.hxx>
34 #include <svl/stritem.hxx>
35 #include <sfx2/dispatch.hxx>
36 #include <sfx2/sfxmodelfactory.hxx>
37 #include <vcl/help.hxx>
38 #include <vcl/settings.hxx>
40 SmElement::SmElement(std::unique_ptr
<SmNode
>&& pNode
, const OUString
& aText
, const OUString
& aHelpText
) :
41 mpNode(std::move(pNode
)),
46 SmElement::~SmElement()
49 const std::unique_ptr
<SmNode
>& SmElement::getNode()
54 SmElementSeparator::SmElementSeparator() :
55 SmElement(std::unique_ptr
<SmNode
>(), OUString(), OUString())
58 const std::pair
<const char*, const char*> SmElementsControl::aUnaryBinaryOperatorsList
[] =
60 {RID_PLUSX
, RID_PLUSX_HELP
}, {RID_MINUSX
, RID_MINUSX_HELP
},
61 {RID_PLUSMINUSX
, RID_PLUSMINUSX_HELP
}, {RID_MINUSPLUSX
, RID_MINUSPLUSX_HELP
},
63 {RID_XPLUSY
, RID_XPLUSY_HELP
}, {RID_XMINUSY
, RID_XMINUSY_HELP
},
64 {RID_XCDOTY
, RID_XCDOTY_HELP
}, {RID_XTIMESY
, RID_XTIMESY_HELP
},
65 {RID_XSYMTIMESY
, RID_XSYMTIMESY_HELP
}, {RID_XOVERY
, RID_XOVERY_HELP
},
66 {RID_XDIVY
, RID_XDIVY_HELP
}, {RID_XSYMDIVIDEY
, RID_XSYMDIVIDEY_HELP
},
67 {RID_XOPLUSY
, RID_XOPLUSY_HELP
}, {RID_XOMINUSY
, RID_XOMINUSY_HELP
},
68 {RID_XODOTY
, RID_XODOTY_HELP
}, {RID_XOTIMESY
, RID_XOTIMESY_HELP
},
69 {RID_XODIVIDEY
, RID_XODIVIDEY_HELP
}, {RID_XCIRCY
, RID_XCIRCY_HELP
},
70 {RID_XWIDESLASHY
, RID_XWIDESLASHY_HELP
}, {RID_XWIDEBSLASHY
, RID_XWIDEBSLASHY_HELP
},
72 {RID_NEGX
, RID_NEGX_HELP
}, {RID_XANDY
, RID_XANDY_HELP
}, {RID_XORY
, RID_XORY_HELP
},
75 const std::pair
<const char*, const char*> SmElementsControl::aRelationsList
[] =
77 {RID_XEQY
, RID_XEQY_HELP
}, {RID_XNEQY
, RID_XNEQY_HELP
}, {RID_XLTY
, RID_XLTY_HELP
},
78 {RID_XLEY
, RID_XLEY_HELP
}, {RID_XLESLANTY
, RID_XLESLANTY_HELP
}, {RID_XGTY
, RID_XGTY_HELP
},
79 {RID_XGEY
, RID_XGEY_HELP
}, {RID_XGESLANTY
, RID_XGESLANTY_HELP
},
80 {RID_XLLY
, RID_XLLY_HELP
}, {RID_XGGY
, RID_XGGY_HELP
},
82 {RID_XAPPROXY
, RID_XAPPROXY_HELP
}, {RID_XSIMY
, RID_XSIMY_HELP
}, {RID_XSIMEQY
, RID_XSIMEQY_HELP
},
83 {RID_XEQUIVY
, RID_XEQUIVY_HELP
}, {RID_XPROPY
, RID_XPROPY_HELP
}, {RID_XPARALLELY
, RID_XPARALLELY_HELP
},
84 {RID_XORTHOY
, RID_XORTHOY_HELP
}, {RID_XDIVIDESY
, RID_XDIVIDESY_HELP
}, {RID_XNDIVIDESY
, RID_XNDIVIDESY_HELP
},
85 {RID_XTOWARDY
, RID_XTOWARDY_HELP
}, {RID_XTRANSLY
, RID_XTRANSLY_HELP
}, {RID_XTRANSRY
, RID_XTRANSRY_HELP
},
86 {RID_XDEFY
, RID_XDEFY_HELP
},
88 {RID_DLARROW
, RID_DLARROW_HELP
}, {RID_DLRARROW
, RID_DLRARROW_HELP
}, {RID_DRARROW
, RID_DRARROW_HELP
},
90 {RID_XPRECEDESY
, RID_XPRECEDESY_HELP
}, {RID_XSUCCEEDSY
, RID_XSUCCEEDSY_HELP
},
91 {RID_XPRECEDESEQUALY
, RID_XPRECEDESEQUALY_HELP
}, {RID_XSUCCEEDSEQUALY
, RID_XSUCCEEDSEQUALY_HELP
},
92 {RID_XPRECEDESEQUIVY
, RID_XPRECEDESEQUIVY_HELP
}, {RID_XSUCCEEDSEQUIVY
, RID_XSUCCEEDSEQUIVY_HELP
},
93 {RID_XNOTPRECEDESY
, RID_XNOTPRECEDESY_HELP
}, {RID_XNOTSUCCEEDSY
, RID_XNOTSUCCEEDSY_HELP
},
96 const std::pair
<const char*, const char*> SmElementsControl::aSetOperations
[] =
98 {RID_XINY
, RID_XINY_HELP
}, {RID_XNOTINY
, RID_XNOTINY_HELP
}, {RID_XOWNSY
, RID_XOWNSY_HELP
},
100 {RID_XINTERSECTIONY
, RID_XINTERSECTIONY_HELP
}, {RID_XUNIONY
, RID_XUNIONY_HELP
},
101 {RID_XSETMINUSY
, RID_XSETMINUSY_HELP
}, {RID_XSLASHY
, RID_XSLASHY_HELP
},
102 {RID_XSUBSETY
, RID_XSUBSETY_HELP
}, {RID_XSUBSETEQY
, RID_XSUBSETEQY_HELP
},
103 {RID_XSUPSETY
, RID_XSUPSETY_HELP
}, {RID_XSUPSETEQY
, RID_XSUPSETEQY_HELP
},
104 {RID_XNSUBSETY
, RID_XNSUBSETY_HELP
}, {RID_XNSUBSETEQY
, RID_XNSUBSETEQY_HELP
},
105 {RID_XNSUPSETY
, RID_XNSUPSETY_HELP
}, {RID_XNSUPSETEQY
, RID_XNSUPSETEQY_HELP
},
107 {RID_EMPTYSET
, RID_EMPTYSET_HELP
}, {RID_ALEPH
, RID_ALEPH_HELP
}, {RID_SETN
, RID_SETN_HELP
},
108 {RID_SETZ
, RID_SETZ_HELP
}, {RID_SETQ
, RID_SETQ_HELP
}, {RID_SETR
, RID_SETR_HELP
}, {RID_SETC
, RID_SETC_HELP
}
111 const std::pair
<const char*, const char*> SmElementsControl::aFunctions
[] =
113 {RID_ABSX
, RID_ABSX_HELP
}, {RID_FACTX
, RID_FACTX_HELP
}, {RID_SQRTX
, RID_SQRTX_HELP
},
114 {RID_NROOTXY
, RID_NROOTXY_HELP
}, {RID_RSUPX
, RID_RSUPX_HELP
}, {RID_EX
, RID_EX_HELP
},
115 {RID_LNX
, RID_LNX_HELP
}, {RID_EXPX
, RID_EXPX_HELP
}, {RID_LOGX
, RID_LOGX_HELP
},
117 {RID_SINX
, RID_SINX_HELP
}, {RID_COSX
, RID_COSX_HELP
}, {RID_TANX
, RID_TANX_HELP
}, {RID_COTX
, RID_COTX_HELP
},
118 {RID_SINHX
, RID_SINHX_HELP
}, {RID_COSHX
, RID_COSHX_HELP
}, {RID_TANHX
, RID_TANHX_HELP
},
119 {RID_COTHX
, RID_COTHX_HELP
},
121 {RID_ARCSINX
, RID_ARCSINX_HELP
}, {RID_ARCCOSX
, RID_ARCCOSX_HELP
}, {RID_ARCTANX
, RID_ARCTANX_HELP
},
122 {RID_ARCCOTX
, RID_ARCCOTX_HELP
}, {RID_ARSINHX
, RID_ARSINHX_HELP
}, {RID_ARCOSHX
, RID_ARCOSHX_HELP
},
123 {RID_ARTANHX
, RID_ARTANHX_HELP
}, {RID_ARCOTHX
, RID_ARCOTHX_HELP
}
126 const std::pair
<const char*, const char*> SmElementsControl::aOperators
[] =
128 {RID_LIMX
, RID_LIMX_HELP
}, {RID_LIM_FROMX
, RID_LIM_FROMX_HELP
},
129 {RID_LIM_TOX
, RID_LIM_TOX_HELP
}, {RID_LIM_FROMTOX
, RID_LIM_FROMTOX_HELP
},
131 {RID_LIMINFX
, RID_LIMINFX_HELP
}, {RID_LIMINF_FROMX
, RID_LIMINF_FROMX_HELP
},
132 {RID_LIMINF_TOX
, RID_LIMINF_TOX_HELP
}, {RID_LIMINF_FROMTOX
, RID_LIMINF_FROMTOX_HELP
},
134 {RID_LIMSUPX
, RID_LIMSUPX_HELP
}, {RID_LIMSUP_FROMX
, RID_LIMSUP_FROMX_HELP
},
135 {RID_LIMSUP_TOX
, RID_LIMSUP_TOX_HELP
}, {RID_LIMSUP_FROMTOX
, RID_LIMSUP_FROMTOX_HELP
},
137 {RID_SUMX
, RID_SUMX_HELP
}, {RID_SUM_FROMX
, RID_SUM_FROMX_HELP
},
138 {RID_SUM_TOX
, RID_SUM_TOX_HELP
}, {RID_SUM_FROMTOX
, RID_SUM_FROMTOX_HELP
},
140 {RID_PRODX
, RID_PRODX_HELP
}, {RID_PROD_FROMX
, RID_PROD_FROMX_HELP
},
141 {RID_PROD_TOX
, RID_PROD_TOX_HELP
}, {RID_PROD_FROMTOX
, RID_PROD_FROMTOX_HELP
},
143 {RID_COPRODX
, RID_COPRODX_HELP
}, {RID_COPROD_FROMX
, RID_COPROD_FROMX_HELP
},
144 {RID_COPROD_TOX
, RID_COPROD_TOX_HELP
}, {RID_COPROD_FROMTOX
, RID_COPROD_FROMTOX_HELP
},
146 {RID_INTX
, RID_INTX_HELP
}, {RID_INT_FROMX
, RID_INT_FROMX_HELP
},
147 {RID_INT_TOX
, RID_INT_TOX_HELP
}, {RID_INT_FROMTOX
, RID_INT_FROMTOX_HELP
},
149 {RID_IINTX
, RID_IINTX_HELP
}, {RID_IINT_FROMX
, RID_IINT_FROMX_HELP
},
150 {RID_IINT_TOX
, RID_IINT_TOX_HELP
}, {RID_IINT_FROMTOX
, RID_IINT_FROMTOX_HELP
},
152 {RID_IIINTX
, RID_IIINTX_HELP
}, {RID_IIINT_FROMX
, RID_IIINT_FROMX_HELP
},
153 {RID_IIINT_TOX
, RID_IIINT_TOX_HELP
}, {RID_IIINT_FROMTOX
, RID_IIINT_FROMTOX_HELP
},
155 {RID_LINTX
, RID_LINTX_HELP
}, {RID_LINT_FROMX
, RID_LINT_FROMX_HELP
},
156 {RID_LINT_TOX
, RID_LINT_TOX_HELP
}, {RID_LINT_FROMTOX
, RID_LINT_FROMTOX_HELP
},
158 {RID_LLINTX
, RID_LLINTX_HELP
}, {RID_LLINT_FROMX
, RID_LLINT_FROMX_HELP
},
159 {RID_LLINT_TOX
, RID_LLINT_TOX_HELP
}, {RID_LLINT_FROMTOX
, RID_LLINT_FROMTOX_HELP
},
161 {RID_LLLINTX
, RID_LLLINTX_HELP
}, {RID_LLLINT_FROMX
, RID_LLLINT_FROMX_HELP
},
162 {RID_LLLINT_TOX
, RID_LLLINT_TOX_HELP
}, {RID_LLLINT_FROMTOX
, RID_LLLINT_FROMTOX_HELP
},
165 const std::pair
<const char*, const char*> SmElementsControl::aAttributes
[] =
167 {RID_ACUTEX
, RID_ACUTEX_HELP
}, {RID_GRAVEX
, RID_GRAVEX_HELP
}, {RID_BREVEX
, RID_BREVEX_HELP
},
168 {RID_CIRCLEX
, RID_CIRCLEX_HELP
}, {RID_DOTX
, RID_DOTX_HELP
}, {RID_DDOTX
, RID_DDOTX_HELP
},
169 {RID_DDDOTX
, RID_DDDOTX_HELP
}, {RID_BARX
, RID_BARX_HELP
}, {RID_VECX
, RID_VECX_HELP
},
170 {RID_TILDEX
, RID_TILDEX_HELP
}, {RID_HATX
, RID_HATX_HELP
}, {RID_CHECKX
, RID_CHECKX_HELP
},
172 {RID_WIDEVECX
, RID_WIDEVECX_HELP
}, {RID_WIDETILDEX
, RID_WIDETILDEX_HELP
}, {RID_WIDEHATX
, RID_WIDEHATX_HELP
},
173 {RID_OVERLINEX
, RID_OVERLINEX_HELP
}, {RID_UNDERLINEX
, RID_UNDERLINEX_HELP
}, {RID_OVERSTRIKEX
, RID_OVERSTRIKEX_HELP
},
175 {RID_PHANTOMX
, RID_PHANTOMX_HELP
}, {RID_BOLDX
, RID_BOLDX_HELP
}, {RID_ITALX
, RID_ITALX_HELP
},
176 {RID_SIZEXY
, RID_SIZEXY_HELP
}, {RID_FONTXY
, RID_FONTXY_HELP
},
178 {RID_COLORX_BLACK
, RID_COLORX_BLACK_HELP
}, {RID_COLORX_BLUE
, RID_COLORX_BLUE_HELP
},
179 {RID_COLORX_GREEN
, RID_COLORX_GREEN_HELP
}, {RID_COLORX_RED
, RID_COLORX_RED_HELP
},
180 {RID_COLORX_CYAN
, RID_COLORX_CYAN_HELP
}, {RID_COLORX_MAGENTA
, RID_COLORX_MAGENTA_HELP
},
181 {RID_COLORX_YELLOW
, RID_COLORX_YELLOW_HELP
}, {RID_COLORX_GRAY
, RID_COLORX_GRAY_HELP
},
182 {RID_COLORX_LIME
, RID_COLORX_LIME_HELP
}, {RID_COLORX_MAROON
, RID_COLORX_MAROON_HELP
},
183 {RID_COLORX_NAVY
, RID_COLORX_NAVY_HELP
}, {RID_COLORX_OLIVE
, RID_COLORX_OLIVE_HELP
},
184 {RID_COLORX_PURPLE
, RID_COLORX_PURPLE_HELP
}, {RID_COLORX_SILVER
, RID_COLORX_SILVER_HELP
},
185 {RID_COLORX_TEAL
, RID_COLORX_TEAL_HELP
}
188 const std::pair
<const char*, const char*> SmElementsControl::aBrackets
[] =
190 {RID_LRGROUPX
, RID_LRGROUPX_HELP
},
192 {RID_LRPARENTX
, RID_LRPARENTX_HELP
}, {RID_LRBRACKETX
, RID_LRBRACKETX_HELP
},
193 {RID_LRDBRACKETX
, RID_LRDBRACKETX_HELP
}, {RID_LRBRACEX
, RID_LRBRACEX_HELP
},
194 {RID_LRANGLEX
, RID_LRANGLEX_HELP
}, {RID_LMRANGLEXY
, RID_LMRANGLEXY_HELP
},
195 {RID_LRCEILX
, RID_LRCEILX_HELP
}, {RID_LRFLOORX
, RID_LRFLOORX_HELP
},
196 {RID_LRLINEX
, RID_LRLINEX_HELP
}, {RID_LRDLINEX
, RID_LRDLINEX_HELP
},
198 {RID_SLRPARENTX
, RID_SLRPARENTX_HELP
}, {RID_SLRBRACKETX
, RID_SLRBRACKETX_HELP
},
199 {RID_SLRDBRACKETX
, RID_SLRDBRACKETX_HELP
}, {RID_SLRBRACEX
, RID_SLRBRACEX_HELP
},
200 {RID_SLRANGLEX
, RID_SLRANGLEX_HELP
}, {RID_SLMRANGLEXY
, RID_SLMRANGLEXY_HELP
},
201 {RID_SLRCEILX
, RID_SLRCEILX_HELP
}, {RID_SLRFLOORX
, RID_SLRFLOORX_HELP
},
202 {RID_SLRLINEX
, RID_SLRLINEX_HELP
}, {RID_SLRDLINEX
, RID_SLRDLINEX_HELP
},
203 {RID_XEVALUATEDATY
, RID_XEVALUATEDATY_HELP
},
205 {RID_XOVERBRACEY
, RID_XOVERBRACEY_HELP
}, {RID_XUNDERBRACEY
, RID_XUNDERBRACEY_HELP
},
208 const std::pair
<const char*, const char*> SmElementsControl::aFormats
[] =
210 {RID_RSUPX
, RID_RSUPX_HELP
}, {RID_RSUBX
, RID_RSUBX_HELP
}, {RID_LSUPX
, RID_LSUPX_HELP
},
211 {RID_LSUBX
, RID_LSUBX_HELP
}, {RID_CSUPX
, RID_CSUPX_HELP
}, {RID_CSUBX
, RID_CSUBX_HELP
},
213 {RID_NEWLINE
, RID_NEWLINE_HELP
}, {RID_SBLANK
, RID_SBLANK_HELP
}, {RID_BLANK
, RID_BLANK_HELP
},
214 {RID_NOSPACE
, RID_NOSPACE_HELP
},
215 {RID_ALIGNLX
, RID_ALIGNLX_HELP
}, {RID_ALIGNCX
, RID_ALIGNCX_HELP
}, {RID_ALIGNRX
, RID_ALIGNRX_HELP
},
217 {RID_BINOMXY
, RID_BINOMXY_HELP
}, {RID_STACK
, RID_STACK_HELP
},
218 {RID_MATRIX
, RID_MATRIX_HELP
},
221 const std::pair
<const char*, const char*> SmElementsControl::aOthers
[] =
223 {RID_INFINITY
, RID_INFINITY_HELP
}, {RID_PARTIAL
, RID_PARTIAL_HELP
}, {RID_NABLA
, RID_NABLA_HELP
},
224 {RID_EXISTS
, RID_EXISTS_HELP
}, {RID_NOTEXISTS
, RID_NOTEXISTS_HELP
}, {RID_FORALL
, RID_FORALL_HELP
},
225 {RID_HBAR
, RID_HBAR_HELP
}, {RID_LAMBDABAR
, RID_LAMBDABAR_HELP
}, {RID_RE
, RID_RE_HELP
},
226 {RID_IM
, RID_IM_HELP
}, {RID_WP
, RID_WP_HELP
},
228 {RID_LEFTARROW
, RID_LEFTARROW_HELP
}, {RID_RIGHTARROW
, RID_RIGHTARROW_HELP
}, {RID_UPARROW
, RID_UPARROW_HELP
},
229 {RID_DOWNARROW
, RID_DOWNARROW_HELP
},
231 {RID_DOTSLOW
, RID_DOTSLOW_HELP
}, {RID_DOTSAXIS
, RID_DOTSAXIS_HELP
}, {RID_DOTSVERT
, RID_DOTSVERT_HELP
},
232 {RID_DOTSUP
, RID_DOTSUP_HELP
}, {RID_DOTSDOWN
, RID_DOTSDOWN_HELP
}
235 SmElementsControl::SmElementsControl(vcl::Window
*pParent
)
236 : Control(pParent
, WB_TABSTOP
)
237 , mpDocShell(new SmDocShell(SfxModelFlags::EMBEDDED_OBJECT
))
238 , mpCurrentElement(nullptr)
239 , mbVerticalMode(true)
240 , mxScroll(VclPtr
<ScrollBar
>::Create(this, WB_VERT
))
242 set_id("element_selector");
243 SetMapMode( MapMode(MapUnit::Map100thMM
) );
244 SetDrawMode( DrawModeFlags::Default
);
245 SetLayoutMode( ComplexTextLayoutFlags::Default
);
246 SetDigitLanguage( LANGUAGE_ENGLISH
);
248 maFormat
.SetBaseSize(PixelToLogic(Size(0, SmPtsTo100th_mm(12))));
250 mxScroll
->SetScrollHdl( LINK(this, SmElementsControl
, ScrollHdl
) );
254 SmElementsControl::~SmElementsControl()
259 void SmElementsControl::dispose()
261 mpDocShell
->DoClose();
262 mxScroll
.disposeAndClear();
266 void SmElementsControl::setVerticalMode(bool bVerticalMode
)
268 mbVerticalMode
= bVerticalMode
;
271 void SmElementsControl::LayoutOrPaintContents(vcl::RenderContext
*pContext
)
273 bool bOldVisibleState
= mxScroll
->IsVisible();
275 sal_Int32 nScrollbarWidth
= bOldVisibleState
? GetSettings().GetStyleSettings().GetScrollBarSize() : 0;
277 sal_Int32 nControlWidth
= GetOutputSizePixel().Width() - nScrollbarWidth
;
278 sal_Int32 nControlHeight
= GetOutputSizePixel().Height();
280 sal_Int32 boxX
= maMaxElementDimensions
.Width() + 10;
281 sal_Int32 boxY
= maMaxElementDimensions
.Height() + 10;
284 sal_Int32 y
= -mxScroll
->GetThumbPos();
286 sal_Int32 perLine
= 0;
289 perLine
= nControlHeight
/ boxY
;
291 perLine
= nControlWidth
/ boxX
;
299 boxY
= nControlHeight
/ perLine
;
301 boxX
= nControlWidth
/ perLine
;
303 for (std::unique_ptr
<SmElement
> & i
: maElementList
)
305 SmElement
* element
= i
.get();
306 if (element
->isSeparator())
313 tools::Rectangle
aSelectionRectangle(x
+ 5 - 1, y
+ 5,
314 x
+ 5 + 1, nControlHeight
- 5);
317 pContext
->DrawRect(PixelToLogic(aSelectionRectangle
));
325 tools::Rectangle
aSelectionRectangle(x
+ 5, y
+ 5 - 1,
326 nControlWidth
- 5, y
+ 5 + 1);
329 pContext
->DrawRect(PixelToLogic(aSelectionRectangle
));
335 Size aSizePixel
= LogicToPixel(Size(element
->getNode()->GetWidth(),
336 element
->getNode()->GetHeight()));
339 if (y
+ boxY
> nControlHeight
)
347 if ( x
+ boxX
> nControlWidth
)
354 if (mpCurrentElement
== element
&& pContext
)
356 pContext
->Push(PushFlags::FILLCOLOR
| PushFlags::LINECOLOR
);
357 pContext
->SetFillColor(Color(230, 230, 230));
358 pContext
->SetLineColor(Color(230, 230, 230));
360 pContext
->DrawRect(PixelToLogic(tools::Rectangle(x
+ 2, y
+ 2, x
+ boxX
- 2, y
+ boxY
- 2)));
364 Point
location(x
+ ((boxX
- aSizePixel
.Width()) / 2),
365 y
+ ((boxY
- aSizePixel
.Height()) / 2));
368 SmDrawingVisitor(*pContext
, PixelToLogic(location
), element
->getNode().get());
370 element
->mBoxLocation
= Point(x
,y
);
371 element
->mBoxSize
= Size(boxX
, boxY
);
382 sal_Int32 nTotalControlHeight
= y
+ boxY
+ mxScroll
->GetThumbPos();
384 if (nTotalControlHeight
> GetOutputSizePixel().Height())
386 mxScroll
->SetRangeMax(nTotalControlHeight
);
387 mxScroll
->SetPosSizePixel(Point(nControlWidth
, 0), Size(nScrollbarWidth
, nControlHeight
));
388 mxScroll
->SetVisibleSize(nControlHeight
);
393 mxScroll
->SetThumbPos(0);
399 void SmElementsControl::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
401 rRenderContext
.Push();
402 LayoutOrPaintContents(&rRenderContext
);
403 rRenderContext
.Pop();
406 void SmElementsControl::RequestHelp(const HelpEvent
& rHEvt
)
408 if (rHEvt
.GetMode() & (HelpEventMode::BALLOON
| HelpEventMode::QUICK
))
410 SmElement
* pHelpElement
= mpCurrentElement
;
412 if (!rHEvt
.KeyboardActivated())
414 Point
aHelpEventPos(ScreenToOutputPixel(rHEvt
.GetMousePosPixel()));
415 for (std::unique_ptr
<SmElement
> & i
: maElementList
)
417 SmElement
* pElement
= i
.get();
418 tools::Rectangle
aRect(pElement
->mBoxLocation
, pElement
->mBoxSize
);
419 if (aRect
.IsInside(aHelpEventPos
))
421 pHelpElement
= pElement
;
430 tools::Rectangle
aHelpRect(pHelpElement
->mBoxLocation
, pHelpElement
->mBoxSize
);
431 Point aPt
= OutputToScreenPixel( aHelpRect
.TopLeft() );
432 aHelpRect
.SetLeft( aPt
.X() );
433 aHelpRect
.SetTop( aPt
.Y() );
434 aPt
= OutputToScreenPixel( aHelpRect
.BottomRight() );
435 aHelpRect
.SetRight( aPt
.X() );
436 aHelpRect
.SetBottom( aPt
.Y() );
438 // get text and display it
439 OUString aStr
= pHelpElement
->getHelpText();
440 if (rHEvt
.GetMode() & HelpEventMode::BALLOON
)
442 Help::ShowBalloon(this, aHelpRect
.Center(), aHelpRect
, aStr
);
445 Help::ShowQuickHelp(this, aHelpRect
, aStr
, aStr
, QuickHelpFlags::CtrlText
);
449 Control::RequestHelp(rHEvt
);
452 void SmElementsControl::MouseMove( const MouseEvent
& rMouseEvent
)
454 SmElement
* pPrevElement
= mpCurrentElement
;
455 mpCurrentElement
= nullptr;
456 if (rMouseEvent
.IsLeaveWindow())
458 LayoutOrPaintContents();
462 if (tools::Rectangle(Point(0, 0), GetOutputSizePixel()).IsInside(rMouseEvent
.GetPosPixel()))
464 for (std::unique_ptr
<SmElement
> & i
: maElementList
)
466 SmElement
* element
= i
.get();
467 tools::Rectangle
rect(element
->mBoxLocation
, element
->mBoxSize
);
468 if (rect
.IsInside(rMouseEvent
.GetPosPixel()))
470 if (pPrevElement
!= element
)
472 mpCurrentElement
= element
;
473 LayoutOrPaintContents();
482 Control::MouseMove(rMouseEvent
);
485 void SmElementsControl::MouseButtonDown(const MouseEvent
& rMouseEvent
)
489 if (rMouseEvent
.IsLeft() && tools::Rectangle(Point(0, 0), GetOutputSizePixel()).IsInside(rMouseEvent
.GetPosPixel()) && maSelectHdlLink
.IsSet())
491 for (std::unique_ptr
<SmElement
> & i
: maElementList
)
493 SmElement
* element
= i
.get();
494 tools::Rectangle
rect(element
->mBoxLocation
, element
->mBoxSize
);
495 if (rect
.IsInside(rMouseEvent
.GetPosPixel()))
497 maSelectHdlLink
.Call(*element
);
504 Control::MouseButtonDown (rMouseEvent
);
508 IMPL_LINK_NOARG( SmElementsControl
, ScrollHdl
, ScrollBar
*, void )
510 DoScroll(mxScroll
->GetDelta());
513 void SmElementsControl::DoScroll(long nDelta
)
515 Point aNewPoint
= mxScroll
->GetPosPixel();
516 tools::Rectangle
aRect(Point(), GetOutputSize());
517 aRect
.AdjustRight( -(mxScroll
->GetSizePixel().Width()) );
518 Scroll( 0, -nDelta
, aRect
);
519 mxScroll
->SetPosPixel(aNewPoint
);
520 LayoutOrPaintContents();
524 void SmElementsControl::addElement(const OUString
& aElementVisual
, const OUString
& aElementSource
, const OUString
& aHelpText
)
526 auto pNode
= SmParser().ParseExpression(aElementVisual
);
528 pNode
->Prepare(maFormat
, *mpDocShell
, 0);
529 pNode
->SetSize(Fraction(10,8));
530 pNode
->Arrange(*this, maFormat
);
532 Size aSizePixel
= LogicToPixel(Size(pNode
->GetWidth(), pNode
->GetHeight()), MapMode(MapUnit::Map100thMM
));
533 if (aSizePixel
.Width() > maMaxElementDimensions
.Width()) {
534 maMaxElementDimensions
.setWidth( aSizePixel
.Width() );
537 if (aSizePixel
.Height() > maMaxElementDimensions
.Height()) {
538 maMaxElementDimensions
.setHeight( aSizePixel
.Height() );
541 maElementList
.push_back(o3tl::make_unique
<SmElement
>(std::move(pNode
), aElementSource
, aHelpText
));
544 void SmElementsControl::setElementSetId(const char* pSetId
)
546 msCurrentSetId
= pSetId
;
547 maMaxElementDimensions
= Size();
551 void SmElementsControl::addElements(const std::pair
<const char*, const char*> aElementsArray
[], sal_uInt16 aElementsArraySize
)
553 for (sal_uInt16 i
= 0; i
< aElementsArraySize
; i
++)
555 const char* pElement
= aElementsArray
[i
].first
;
556 const char* pElementHelp
= aElementsArray
[i
].second
;
558 maElementList
.push_back(o3tl::make_unique
<SmElementSeparator
>());
560 OUString
aElement(OUString::createFromAscii(pElement
));
561 if (aElement
== RID_NEWLINE
)
562 addElement(OUString(u
"\u21B5"), aElement
, SmResId(pElementHelp
));
563 else if (aElement
== RID_SBLANK
)
564 addElement("\"`\"", aElement
, SmResId(pElementHelp
));
565 else if (aElement
== RID_BLANK
)
566 addElement("\"~\"", aElement
, SmResId(pElementHelp
));
567 else if (aElement
== RID_PHANTOMX
)
568 addElement("\"" + SmResId(STR_HIDE
) +"\"", aElement
, SmResId(pElementHelp
));
569 else if (aElement
== RID_BOLDX
)
570 addElement("bold B", aElement
, SmResId(pElementHelp
));
571 else if (aElement
== RID_ITALX
)
572 addElement("ital I", aElement
, SmResId(pElementHelp
));
573 else if (aElement
== RID_SIZEXY
)
574 addElement("\"" + SmResId(STR_SIZE
) + "\"", aElement
, SmResId(pElementHelp
));
575 else if (aElement
== RID_FONTXY
)
576 addElement("\"" + SmResId(STR_FONT
) + "\"", aElement
, SmResId(pElementHelp
));
577 else if (aElement
== RID_COLORX_BLACK
)
578 addElement("color black { \"" + SmResId(STR_BLACK
) + "\" }", aElement
, SmResId(pElementHelp
));
579 else if (aElement
== RID_COLORX_BLUE
)
580 addElement("color blue { \"" + SmResId(STR_BLUE
) + "\" }", aElement
, SmResId(pElementHelp
));
581 else if (aElement
== RID_COLORX_GREEN
)
582 addElement("color green { \"" + SmResId(STR_GREEN
) + "\" }", aElement
, SmResId(pElementHelp
));
583 else if (aElement
== RID_COLORX_RED
)
584 addElement("color red { \"" + SmResId(STR_RED
) + "\" }", aElement
, SmResId(pElementHelp
));
585 else if (aElement
== RID_COLORX_CYAN
)
586 addElement("color cyan { \"" + SmResId(STR_CYAN
) + "\" }", aElement
, SmResId(pElementHelp
));
587 else if (aElement
== RID_COLORX_MAGENTA
)
588 addElement("color magenta { \"" + SmResId(STR_MAGENTA
) + "\" }", aElement
, SmResId(pElementHelp
));
589 else if (aElement
== RID_COLORX_YELLOW
)
590 addElement("color yellow { \"" + SmResId(STR_YELLOW
) + "\" }", aElement
, SmResId(pElementHelp
));
591 else if (aElement
== RID_COLORX_GRAY
)
592 addElement("color gray { \"" + SmResId(STR_GRAY
) + "\" }", aElement
, SmResId(pElementHelp
));
593 else if (aElement
== RID_COLORX_LIME
)
594 addElement("color lime { \"" + SmResId(STR_LIME
) + "\" }", aElement
, SmResId(pElementHelp
));
595 else if (aElement
== RID_COLORX_MAROON
)
596 addElement("color maroon { \"" + SmResId(STR_MAROON
) + "\" }", aElement
, SmResId(pElementHelp
));
597 else if (aElement
== RID_COLORX_NAVY
)
598 addElement("color navy { \"" + SmResId(STR_NAVY
) + "\" }", aElement
, SmResId(pElementHelp
));
599 else if (aElement
== RID_COLORX_OLIVE
)
600 addElement("color olive { \"" + SmResId(STR_OLIVE
) + "\" }", aElement
, SmResId(pElementHelp
));
601 else if (aElement
== RID_COLORX_PURPLE
)
602 addElement("color purple { \"" + SmResId(STR_PURPLE
) + "\" }", aElement
, SmResId(pElementHelp
));
603 else if (aElement
== RID_COLORX_SILVER
)
604 addElement("color silver { \"" + SmResId(STR_SILVER
) + "\" }", aElement
, SmResId(pElementHelp
));
605 else if (aElement
== RID_COLORX_TEAL
)
606 addElement("color teal { \"" + SmResId(STR_TEAL
) + "\" }", aElement
, SmResId(pElementHelp
));
607 else if (aElement
== RID_ALIGNLX
)
608 addElement("\"" + SmResId(STR_ALIGN_LEFT
) + "\"", aElement
, SmResId(pElementHelp
));
609 else if (aElement
== RID_ALIGNCX
)
610 addElement("\"" + SmResId(STR_ALIGN_CENTER
) + "\"", aElement
, SmResId(pElementHelp
));
611 else if (aElement
== RID_ALIGNRX
)
612 addElement("\"" + SmResId(STR_ALIGN_RIGHT
) + "\"", aElement
, SmResId(pElementHelp
));
614 else if (aElement
== RID_SLRPARENTX
)
615 addElement("left ( binom{<?>}{<?>} right ) ", aElement
, SmResId(pElementHelp
));
616 else if (aElement
== RID_SLRBRACKETX
)
617 addElement("left [ binom{<?>}{<?>} right ] ", aElement
, SmResId(pElementHelp
));
618 else if (aElement
== RID_SLRDBRACKETX
)
619 addElement("left ldbracket binom{<?>}{<?>} right rdbracket ", aElement
, SmResId(pElementHelp
));
620 else if (aElement
== RID_SLRBRACEX
)
621 addElement("left lbrace binom{<?>}{<?>} right rbrace ", aElement
, SmResId(pElementHelp
));
622 else if (aElement
== RID_SLRANGLEX
)
623 addElement("left langle binom{<?>}{<?>} right rangle ", aElement
, SmResId(pElementHelp
));
624 else if (aElement
== RID_SLRCEILX
)
625 addElement("left lceil binom{<?>}{<?>} right rceil ", aElement
, SmResId(pElementHelp
));
626 else if (aElement
== RID_SLRFLOORX
)
627 addElement("left lfloor binom{<?>}{<?>} right rfloor ", aElement
, SmResId(pElementHelp
));
629 else if (aElement
== RID_SLRLINEX
)
630 addElement("left lline binom{<?>}{<?>} right rline ", aElement
, SmResId(pElementHelp
));
631 else if (aElement
== RID_SLRDLINEX
)
632 addElement("left ldline binom{<?>}{<?>} right rdline ", aElement
, SmResId(pElementHelp
));
633 else if (aElement
== RID_SLMRANGLEXY
)
634 addElement("left langle binom{<?>}{<?>} mline binom{<?>}{<?>} right rangle ", aElement
, SmResId(pElementHelp
));
636 else if (aElement
== RID_XOVERBRACEY
)
637 addElement("{<?><?><?>} overbrace {<?>} ", aElement
, SmResId(pElementHelp
));
638 else if (aElement
== RID_XUNDERBRACEY
)
639 addElement("{<?><?><?>} underbrace {<?>} ", aElement
, SmResId(pElementHelp
));
641 addElement(aElement
, aElement
, SmResId(pElementHelp
));
646 void SmElementsControl::build()
648 maElementList
.clear();
650 if (msCurrentSetId
== RID_CATEGORY_UNARY_BINARY_OPERATORS
)
651 addElements(aUnaryBinaryOperatorsList
, SAL_N_ELEMENTS(aUnaryBinaryOperatorsList
));
652 else if (msCurrentSetId
== RID_CATEGORY_RELATIONS
)
653 addElements(aRelationsList
, SAL_N_ELEMENTS(aRelationsList
));
654 else if (msCurrentSetId
== RID_CATEGORY_SET_OPERATIONS
)
655 addElements(aSetOperations
, SAL_N_ELEMENTS(aSetOperations
));
656 else if (msCurrentSetId
== RID_CATEGORY_FUNCTIONS
)
657 addElements(aFunctions
, SAL_N_ELEMENTS(aFunctions
));
658 else if (msCurrentSetId
== RID_CATEGORY_OPERATORS
)
659 addElements(aOperators
, SAL_N_ELEMENTS(aOperators
));
660 else if (msCurrentSetId
== RID_CATEGORY_ATTRIBUTES
)
661 addElements(aAttributes
, SAL_N_ELEMENTS(aAttributes
));
662 else if (msCurrentSetId
== RID_CATEGORY_BRACKETS
)
663 addElements(aBrackets
, SAL_N_ELEMENTS(aBrackets
));
664 else if (msCurrentSetId
== RID_CATEGORY_FORMATS
)
665 addElements(aFormats
, SAL_N_ELEMENTS(aFormats
));
666 else if (msCurrentSetId
== RID_CATEGORY_OTHERS
)
667 addElements(aOthers
, SAL_N_ELEMENTS(aOthers
));
668 else if (msCurrentSetId
== RID_CATEGORY_EXAMPLES
)
670 OUString aEquation
= "C=%pi cdot d = 2 cdot %pi cdot r";
671 addElement(aEquation
, aEquation
, "");
672 aEquation
= "E=mc^2";
673 addElement(aEquation
, aEquation
, "");
674 aEquation
= "a^2 + b^2 = c^2";
675 addElement(aEquation
, aEquation
, "");
676 aEquation
= "f ( x ) = sum from { { i = 0 } } to { infinity } { {f^{(i)}(0)} over {i!} x^i}";
677 addElement(aEquation
, aEquation
, "");
678 aEquation
= "f ( x ) = {1} over {%sigma sqrt{2%pi} }func e^-{{(x-%mu)^2} over {2%sigma^2}}";
679 addElement(aEquation
, aEquation
, "");
681 LayoutOrPaintContents();
685 Size
SmElementsControl::GetOptimalSize() const
687 return LogicToPixel(Size(100, 100), MapMode(MapUnit::MapAppFont
));
690 FactoryFunction
SmElementsControl::GetUITestFactory() const
692 return ElementSelectorUIObject::create
;
695 const char* SmElementsDockingWindow::aCategories
[] = {
696 RID_CATEGORY_UNARY_BINARY_OPERATORS
,
697 RID_CATEGORY_RELATIONS
,
698 RID_CATEGORY_SET_OPERATIONS
,
699 RID_CATEGORY_FUNCTIONS
,
700 RID_CATEGORY_OPERATORS
,
701 RID_CATEGORY_ATTRIBUTES
,
702 RID_CATEGORY_BRACKETS
,
703 RID_CATEGORY_FORMATS
,
705 RID_CATEGORY_EXAMPLES
708 SmElementsDockingWindow::SmElementsDockingWindow(SfxBindings
* pInputBindings
, SfxChildWindow
* pChildWindow
, vcl::Window
* pParent
) :
709 SfxDockingWindow(pInputBindings
, pChildWindow
, pParent
, "DockingElements",
710 "modules/smath/ui/dockingelements.ui")
712 mpElementsControl
= VclPtr
<SmElementsControl
>::Create(get
<vcl::Window
>("box"));
713 mpElementsControl
->set_hexpand(true);
714 mpElementsControl
->set_vexpand(true);
715 mpElementsControl
->Show();
716 get(mpElementListBox
, "listbox");
718 mpElementsControl
->SetBorderStyle( WindowBorderStyle::MONO
);
720 mpElementListBox
->SetDropDownLineCount( SAL_N_ELEMENTS(aCategories
) );
722 for (const char* pCategory
: aCategories
)
724 mpElementListBox
->InsertEntry(SmResId(pCategory
));
727 mpElementListBox
->SetSelectHdl(LINK(this, SmElementsDockingWindow
, ElementSelectedHandle
));
728 mpElementListBox
->SelectEntry(SmResId(RID_CATEGORY_UNARY_BINARY_OPERATORS
));
730 mpElementsControl
->SetBackground( COL_WHITE
);
731 mpElementsControl
->SetTextColor( COL_BLACK
);
732 mpElementsControl
->setElementSetId(RID_CATEGORY_UNARY_BINARY_OPERATORS
);
733 mpElementsControl
->SetSelectHdl(LINK(this, SmElementsDockingWindow
, SelectClickHandler
));
736 SmElementsDockingWindow::~SmElementsDockingWindow ()
741 void SmElementsDockingWindow::dispose()
743 mpElementsControl
.disposeAndClear();
744 mpElementListBox
.clear();
745 SfxDockingWindow::dispose();
748 void SmElementsDockingWindow::ToggleFloatingMode()
750 SfxDockingWindow::ToggleFloatingMode();
752 if (GetFloatingWindow())
753 GetFloatingWindow()->SetMinOutputSizePixel( Size(100, 100) );
758 void SmElementsDockingWindow::EndDocking( const tools::Rectangle
& rReactangle
, bool bFloatMode
)
760 SfxDockingWindow::EndDocking(rReactangle
, bFloatMode
);
761 bool bVertical
= ( GetAlignment() == SfxChildAlignment::TOP
|| GetAlignment() == SfxChildAlignment::BOTTOM
);
762 mpElementsControl
->setVerticalMode(bVertical
);
765 IMPL_LINK(SmElementsDockingWindow
, SelectClickHandler
, SmElement
&, rElement
, void)
767 SmViewShell
* pViewSh
= GetView();
771 std::unique_ptr
<SfxStringItem
> pInsertCommand
= o3tl::make_unique
<SfxStringItem
>(SID_INSERTCOMMANDTEXT
, rElement
.getText());
772 pViewSh
->GetViewFrame()->GetDispatcher()->ExecuteList(
773 SID_INSERTCOMMANDTEXT
, SfxCallMode::RECORD
,
774 { pInsertCommand
.get() });
778 IMPL_LINK( SmElementsDockingWindow
, ElementSelectedHandle
, ListBox
&, rList
, void)
780 for (const char* pCurrentCategory
: aCategories
)
782 OUString aCurrentCategoryString
= SmResId(pCurrentCategory
);
783 if (aCurrentCategoryString
== rList
.GetSelectedEntry())
785 mpElementsControl
->setElementSetId(pCurrentCategory
);
791 SmViewShell
* SmElementsDockingWindow::GetView()
793 SfxViewShell
* pView
= GetBindings().GetDispatcher()->GetFrame()->GetViewShell();
794 return dynamic_cast<SmViewShell
*>( pView
);
797 void SmElementsDockingWindow::Resize()
799 bool bVertical
= ( GetAlignment() == SfxChildAlignment::TOP
|| GetAlignment() == SfxChildAlignment::BOTTOM
);
800 mpElementsControl
->setVerticalMode(bVertical
);
802 SfxDockingWindow::Resize();
806 SFX_IMPL_DOCKINGWINDOW_WITHID(SmElementsDockingWindowWrapper
, SID_ELEMENTSDOCKINGWINDOW
);
808 SmElementsDockingWindowWrapper::SmElementsDockingWindowWrapper(
809 vcl::Window
*pParentWindow
, sal_uInt16 nId
,
810 SfxBindings
*pBindings
, SfxChildWinInfo
*pInfo
) :
811 SfxChildWindow(pParentWindow
, nId
)
813 VclPtrInstance
<SmElementsDockingWindow
> pDialog(pBindings
, this, pParentWindow
);
815 pDialog
->setDeferredProperties();
816 pDialog
->SetPosSizePixel(Point(0, 0), Size(300, 0));
819 SetAlignment(SfxChildAlignment::LEFT
);
821 pDialog
->Initialize( pInfo
);
824 SmElementsDockingWindowWrapper::~SmElementsDockingWindowWrapper()
828 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */