bump product version to 5.0.4.1
[LibreOffice.git] / starmath / source / ElementsDockingWindow.cxx
blobf5f2c17d7be939397c6822ec704266a8721b6e5f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <ElementsDockingWindow.hxx>
22 #include <starmath.hrc>
23 #include <smmod.hxx>
24 #include <config.hxx>
25 #include <view.hxx>
26 #include <visitors.hxx>
28 #include <svl/stritem.hxx>
29 #include <sfx2/dispatch.hxx>
30 #include <sfx2/sfxmodelfactory.hxx>
31 #include <vcl/settings.hxx>
33 typedef tools::SvRef<SmDocShell> SmDocShellRef;
35 SmElement::SmElement(SmNodePointer pNode, const OUString& aText, const OUString& aHelpText) :
36 mpNode(pNode),
37 maText(aText),
38 maHelpText(aHelpText)
41 SmElement::~SmElement()
44 SmNodePointer SmElement::getNode()
46 return mpNode;
49 SmElementSeparator::SmElementSeparator() :
50 SmElement(SmNodePointer(), OUString(), OUString())
53 const sal_uInt16 SmElementsControl::aUnaryBinaryOperatorsList[][2] =
55 {RID_PLUSX, RID_PLUSX_HELP}, {RID_MINUSX, RID_MINUSX_HELP},
56 {RID_PLUSMINUSX, RID_PLUSMINUSX_HELP}, {RID_MINUSPLUSX, RID_MINUSPLUSX_HELP},
57 {0xFFFF, 0},
58 {RID_XPLUSY, RID_XPLUSY_HELP}, {RID_XMINUSY, RID_XMINUSY_HELP},
59 {RID_XCDOTY, RID_XCDOTY_HELP}, {RID_XTIMESY, RID_XTIMESY_HELP},
60 {RID_XSYMTIMESY, RID_XSYMTIMESY_HELP}, {RID_XOTIMESY, RID_XOTIMESY_HELP},
61 {RID_XOVERY, RID_XOVERY_HELP},
62 {RID_XDIVY, RID_XDIVY_HELP}, {RID_XSYMDIVIDEY, RID_XSYMDIVIDEY_HELP},
63 {RID_XCIRCY, RID_XCIRCY_HELP}, {RID_XWIDESLASHY, RID_XWIDESLASHY_HELP},
64 {RID_XWIDEBSLASHY, RID_XWIDEBSLASHY_HELP},
65 {0xFFFF, 0},
66 {RID_NEGX, RID_NEGX_HELP}, {RID_XANDY, RID_XANDY_HELP}, {RID_XORY, RID_XORY_HELP},
69 const sal_uInt16 SmElementsControl::aRelationsList[][2] =
71 {RID_XEQY, RID_XEQY_HELP}, {RID_XNEQY, RID_XNEQY_HELP}, {RID_XLTY, RID_XLTY_HELP},
72 {RID_XLEY, RID_XLEY_HELP}, {RID_XLESLANTY, RID_XLESLANTY_HELP}, {RID_XGTY, RID_XGTY_HELP},
73 {RID_XGEY, RID_XGEY_HELP}, {RID_XGESLANTY, RID_XGESLANTY_HELP},
74 {RID_XLLY, RID_XLLY_HELP}, {RID_XGGY, RID_XGGY_HELP},
75 {0xFFFF, 0},
76 {RID_XAPPROXY, RID_XAPPROXY_HELP}, {RID_XSIMY, RID_XSIMY_HELP}, {RID_XSIMEQY, RID_XSIMEQY_HELP},
77 {RID_XEQUIVY, RID_XEQUIVY_HELP}, {RID_XPROPY, RID_XPROPY_HELP}, {RID_XPARALLELY, RID_XPARALLELY_HELP},
78 {RID_XORTHOY, RID_XORTHOY_HELP}, {RID_XDIVIDESY, RID_XDIVIDESY_HELP}, {RID_XNDIVIDESY, RID_XNDIVIDESY_HELP},
79 {RID_XTOWARDY, RID_XTOWARDY_HELP},
80 {0xFFFF, 0},
81 {RID_DLARROW, RID_DLARROW_HELP}, {RID_DLRARROW, RID_DLRARROW_HELP}, {RID_DRARROW, RID_DRARROW_HELP},
82 {0xFFFF, 0},
83 {RID_XPRECEDESY, RID_XPRECEDESY_HELP}, {RID_XSUCCEEDSY, RID_XSUCCEEDSY_HELP},
84 {RID_XPRECEDESEQUALY, RID_XPRECEDESEQUALY_HELP}, {RID_XSUCCEEDSEQUALY, RID_XSUCCEEDSEQUALY_HELP},
85 {RID_XPRECEDESEQUIVY, RID_XPRECEDESEQUIVY_HELP}, {RID_XSUCCEEDSEQUIVY, RID_XSUCCEEDSEQUIVY_HELP},
86 {RID_XNOTPRECEDESY, RID_XNOTPRECEDESY_HELP}, {RID_XNOTSUCCEEDSY, RID_XNOTSUCCEEDSY_HELP},
89 const sal_uInt16 SmElementsControl::aSetOperations[][2] =
91 {RID_XINY, RID_XINY_HELP}, {RID_XNOTINY, RID_XNOTINY_HELP}, {RID_XOWNSY, RID_XOWNSY_HELP},
92 {0xFFFF, 0},
93 {RID_XINTERSECTIONY, RID_XINTERSECTIONY_HELP}, {RID_XUNIONY, RID_XUNIONY_HELP},
94 {RID_XSETMINUSY, RID_XSETMINUSY_HELP}, {RID_XSLASHY, RID_XSLASHY_HELP},
95 {RID_XSUBSETY, RID_XSUBSETY_HELP}, {RID_XSUBSETEQY, RID_XSUBSETEQY_HELP},
96 {RID_XSUPSETY, RID_XSUPSETY_HELP}, {RID_XSUPSETEQY, RID_XSUPSETEQY_HELP},
97 {RID_XNSUBSETY, RID_XNSUBSETY_HELP}, {RID_XNSUBSETEQY, RID_XNSUBSETEQY_HELP},
98 {RID_XNSUPSETY, RID_XNSUPSETY_HELP}, {RID_XNSUPSETEQY, RID_XNSUPSETEQY_HELP},
99 {0xFFFF, 0},
100 {RID_EMPTYSET, RID_EMPTYSET_HELP}, {RID_ALEPH, RID_ALEPH_HELP}, {RID_SETN, RID_SETN_HELP},
101 {RID_SETZ, RID_SETZ_HELP}, {RID_SETQ, RID_SETQ_HELP}, {RID_SETR, RID_SETR_HELP}, {RID_SETC, RID_SETC_HELP}
104 const sal_uInt16 SmElementsControl::aFunctions[][2] =
106 {RID_ABSX, RID_ABSX_HELP}, {RID_FACTX, RID_FACTX_HELP}, {RID_SQRTX, RID_SQRTX_HELP},
107 {RID_NROOTXY, RID_NROOTXY_HELP}, {RID_RSUPX, RID_RSUPX_HELP}, {RID_EX, RID_EX_HELP},
108 {RID_LNX, RID_LNX_HELP}, {RID_EXPX, RID_EXPX_HELP}, {RID_LOGX, RID_LOGX_HELP},
109 {0xFFFF, 0},
110 {RID_SINX, RID_SINX_HELP}, {RID_COSX, RID_COSX_HELP}, {RID_TANX, RID_TANX_HELP}, {RID_COTX, RID_COTX_HELP},
111 {RID_SINHX, RID_SINHX_HELP}, {RID_COSHX, RID_COSHX_HELP}, {RID_TANHX, RID_TANHX_HELP},
112 {RID_COTHX, RID_COTHX_HELP},
113 {0xFFFF, 0},
114 {RID_ARCSINX, RID_ARCSINX_HELP}, {RID_ARCCOSX, RID_ARCCOSX_HELP}, {RID_ARCTANX, RID_ARCTANX_HELP},
115 {RID_ARCCOTX, RID_ARCCOTX_HELP}, {RID_ARSINHX, RID_ARSINHX_HELP}, {RID_ARCOSHX, RID_ARCOSHX_HELP},
116 {RID_ARTANHX, RID_ARTANHX_HELP}, {RID_ARCOTHX, RID_ARCOTHX_HELP}
119 const sal_uInt16 SmElementsControl::aOperators[][2] =
121 {RID_LIMX, RID_LIMX_HELP}, {RID_LIM_FROMX, RID_LIM_FROMX_HELP},
122 {RID_LIM_TOX, RID_LIM_TOX_HELP}, {RID_LIM_FROMTOX, RID_LIM_FROMTOX_HELP},
123 {0xFFFF, 0},
124 {RID_SUMX, RID_SUMX_HELP}, {RID_SUM_FROMX, RID_SUM_FROMX_HELP},
125 {RID_SUM_TOX, RID_SUM_TOX_HELP}, {RID_SUM_FROMTOX, RID_SUM_FROMTOX_HELP},
126 {0xFFFF, 0},
127 {RID_PRODX, RID_PRODX_HELP}, {RID_PROD_FROMX, RID_PROD_FROMX_HELP},
128 {RID_PROD_TOX, RID_PROD_TOX_HELP}, {RID_PROD_FROMTOX, RID_PROD_FROMTOX_HELP},
129 {0xFFFF, 0},
130 {RID_COPRODX, RID_COPRODX_HELP}, {RID_COPROD_FROMX, RID_COPROD_FROMX_HELP},
131 {RID_COPROD_TOX, RID_COPROD_TOX_HELP}, {RID_COPROD_FROMTOX, RID_COPROD_FROMTOX_HELP},
132 {0xFFFF, 0},
133 {RID_INTX, RID_INTX_HELP}, {RID_INT_FROMX, RID_INT_FROMX_HELP},
134 {RID_INT_TOX, RID_INT_TOX_HELP}, {RID_INT_FROMTOX, RID_INT_FROMTOX_HELP},
135 {0xFFFF, 0},
136 {RID_IINTX, RID_IINTX_HELP}, {RID_IINT_FROMX, RID_IINT_FROMX_HELP},
137 {RID_IINT_TOX, RID_IINT_TOX_HELP}, {RID_IINT_FROMTOX, RID_IINT_FROMTOX_HELP},
138 {0xFFFF, 0},
139 {RID_IIINTX, RID_IIINTX_HELP}, {RID_IIINT_FROMX, RID_IIINT_FROMX_HELP},
140 {RID_IIINT_TOX, RID_IIINT_TOX_HELP}, {RID_IIINT_FROMTOX, RID_IIINT_FROMTOX_HELP},
141 {0xFFFF, 0},
142 {RID_LINTX, RID_LINTX_HELP}, {RID_LINT_FROMX, RID_LINT_FROMX_HELP},
143 {RID_LINT_TOX, RID_LINT_TOX_HELP}, {RID_LINT_FROMTOX, RID_LINT_FROMTOX_HELP},
144 {0xFFFF, 0},
145 {RID_LLINTX, RID_LINTX_HELP}, {RID_LLINT_FROMX, RID_LLINT_FROMX_HELP},
146 {RID_LLINT_TOX, RID_LINT_TOX_HELP}, {RID_LLINT_FROMTOX, RID_LLINT_FROMTOX_HELP},
147 {0xFFFF, 0},
148 {RID_LLLINTX, RID_LINTX_HELP}, {RID_LLLINT_FROMX, RID_LLLINT_FROMX_HELP},
149 {RID_LLLINT_TOX, RID_LINT_TOX_HELP}, {RID_LLLINT_FROMTOX, RID_LLLINT_FROMTOX_HELP},
152 const sal_uInt16 SmElementsControl::aAttributes[][2] =
154 {RID_ACUTEX, RID_ACUTEX_HELP}, {RID_GRAVEX, RID_GRAVEX_HELP}, {RID_BREVEX, RID_BREVEX_HELP},
155 {RID_CIRCLEX, RID_CIRCLEX_HELP}, {RID_DOTX, RID_DOTX_HELP}, {RID_DDOTX, RID_DDOTX_HELP},
156 {RID_DDDOTX, RID_DDDOTX_HELP}, {RID_BARX, RID_BARX_HELP}, {RID_VECX, RID_VECX_HELP},
157 {RID_TILDEX, RID_TILDEX_HELP}, {RID_HATX, RID_HATX_HELP}, {RID_CHECKX, RID_CHECKX_HELP},
158 {0xFFFF, 0},
159 {RID_WIDEVECX, RID_WIDEVECX_HELP}, {RID_WIDETILDEX, RID_WIDETILDEX_HELP}, {RID_WIDEHATX, RID_WIDEHATX_HELP},
160 {RID_OVERLINEX, RID_OVERLINEX_HELP}, {RID_UNDERLINEX, RID_UNDERLINEX_HELP}, {RID_OVERSTRIKEX, RID_OVERSTRIKEX_HELP},
161 {0xFFFF, 0},
162 {RID_PHANTOMX, RID_PHANTOMX_HELP}, {RID_BOLDX, RID_BOLDX_HELP}, {RID_ITALX, RID_ITALX_HELP},
163 {RID_SIZEXY, RID_SIZEXY_HELP}, {RID_FONTXY, RID_FONTXY_HELP},
164 {0xFFFF, 0},
165 {RID_COLORX_BLACK, RID_COLORX_BLACK_HELP}, {RID_COLORX_BLUE, RID_COLORX_BLUE_HELP},
166 {RID_COLORX_GREEN, RID_COLORX_GREEN_HELP}, {RID_COLORX_RED, RID_COLORX_RED_HELP},
167 {RID_COLORX_CYAN, RID_COLORX_CYAN_HELP}, {RID_COLORX_MAGENTA, RID_COLORX_MAGENTA_HELP},
168 {RID_COLORX_YELLOW, RID_COLORX_YELLOW_HELP}, {RID_COLORX_GRAY, RID_COLORX_GRAY_HELP},
169 {RID_COLORX_LIME, RID_COLORX_LIME_HELP}, {RID_COLORX_MAROON, RID_COLORX_MAROON_HELP},
170 {RID_COLORX_NAVY, RID_COLORX_NAVY_HELP}, {RID_COLORX_OLIVE, RID_COLORX_OLIVE_HELP},
171 {RID_COLORX_PURPLE, RID_COLORX_PURPLE_HELP}, {RID_COLORX_SILVER, RID_COLORX_SILVER_HELP},
172 {RID_COLORX_TEAL, RID_COLORX_TEAL_HELP}
175 const sal_uInt16 SmElementsControl::aBrackets[][2] =
177 {RID_LRGROUPX, RID_LRGROUPX_HELP},
178 {0xFFFF, 0},
179 {RID_LRPARENTX, RID_LRPARENTX_HELP}, {RID_LRBRACKETX, RID_LRBRACKETX_HELP},
180 {RID_LRDBRACKETX, RID_LRDBRACKETX_HELP}, {RID_LRBRACEX, RID_LRBRACEX_HELP},
181 {RID_LRANGLEX, RID_LRANGLEX_HELP}, {RID_LMRANGLEXY, RID_LMRANGLEXY_HELP},
182 {RID_LRCEILX, RID_LRCEILX_HELP}, {RID_LRFLOORX, RID_LRFLOORX_HELP},
183 {RID_LRLINEX, RID_LRLINEX_HELP}, {RID_LRDLINEX, RID_LRDLINEX_HELP},
184 {0xFFFF, 0},
185 {RID_SLRPARENTX, RID_SLRPARENTX_HELP}, {RID_SLRBRACKETX, RID_SLRBRACKETX_HELP},
186 {RID_SLRDBRACKETX, RID_SLRDBRACKETX_HELP}, {RID_SLRBRACEX, RID_SLRBRACEX_HELP},
187 {RID_SLRANGLEX, RID_SLRANGLEX_HELP}, {RID_SLMRANGLEXY, RID_SLMRANGLEXY_HELP},
188 {RID_SLRCEILX, RID_SLRCEILX_HELP}, {RID_SLRFLOORX, RID_SLRFLOORX_HELP},
189 {RID_SLRLINEX, RID_SLRLINEX_HELP}, {RID_SLRDLINEX, RID_SLRDLINEX_HELP},
190 {0XFFFF, 0},
191 {RID_XOVERBRACEY, RID_XOVERBRACEY_HELP}, {RID_XUNDERBRACEY, RID_XUNDERBRACEY_HELP},
194 const sal_uInt16 SmElementsControl::aFormats[][2] =
196 {RID_RSUPX, RID_RSUPX_HELP}, {RID_RSUBX, RID_RSUBX_HELP}, {RID_LSUPX, RID_LSUPX_HELP},
197 {RID_LSUBX, RID_LSUBX_HELP}, {RID_CSUPX, RID_CSUPX_HELP}, {RID_CSUBX, RID_CSUBX_HELP},
198 {0xFFFF, 0},
199 {RID_NEWLINE, RID_NEWLINE_HELP}, {RID_SBLANK, RID_SBLANK_HELP}, {RID_BLANK, RID_BLANK_HELP},
200 {RID_NOSPACE, RID_NOSPACE_HELP},
201 {RID_ALIGNLX, RID_ALIGNLX_HELP}, {RID_ALIGNCX, RID_ALIGNCX_HELP}, {RID_ALIGNRX, RID_ALIGNRX_HELP},
202 {0xFFFF, 0},
203 {RID_BINOMXY, RID_BINOMXY_HELP}, {RID_STACK, RID_STACK_HELP},
204 {RID_MATRIX, RID_MATRIX_HELP},
207 const sal_uInt16 SmElementsControl::aOthers[][2] =
209 {RID_INFINITY, RID_INFINITY_HELP}, {RID_PARTIAL, RID_PARTIAL_HELP}, {RID_NABLA, RID_NABLA_HELP},
210 {RID_EXISTS, RID_EXISTS_HELP}, {RID_NOTEXISTS, RID_NOTEXISTS_HELP}, {RID_FORALL, RID_FORALL_HELP},
211 {RID_HBAR, RID_HBAR_HELP}, {RID_LAMBDABAR, RID_LAMBDABAR_HELP}, {RID_RE, RID_RE_HELP},
212 {RID_IM, RID_IM_HELP}, {RID_WP, RID_WP_HELP},
213 {0xFFFF, 0},
214 {RID_LEFTARROW, RID_LEFTARROW_HELP}, {RID_RIGHTARROW, RID_RIGHTARROW_HELP}, {RID_UPARROW, RID_UPARROW_HELP},
215 {RID_DOWNARROW, RID_DOWNARROW_HELP},
216 {0xFFFF, 0},
217 {RID_DOTSLOW, RID_DOTSLOW_HELP}, {RID_DOTSAXIS, RID_DOTSAXIS_HELP}, {RID_DOTSVERT, RID_DOTSVERT_HELP},
218 {RID_DOTSUP, RID_DOTSUP_HELP}, {RID_DOTSDOWN, RID_DOTSDOWN_HELP}
221 SmElementsControl::SmElementsControl(vcl::Window *pParent)
222 : Control(pParent, WB_TABSTOP)
223 , mpDocShell(new SmDocShell(SfxModelFlags::EMBEDDED_OBJECT))
224 , maCurrentSetId(0)
225 , mpCurrentElement(NULL)
226 , mbVerticalMode(true)
227 , mxScroll(VclPtr<ScrollBar>::Create(this, WB_VERT))
229 SetMapMode( MapMode(MAP_100TH_MM) );
230 SetDrawMode( DrawModeFlags::Default );
231 SetLayoutMode( TEXT_LAYOUT_DEFAULT );
232 SetDigitLanguage( LANGUAGE_ENGLISH );
234 maFormat.SetBaseSize(PixelToLogic(Size(0, SmPtsTo100th_mm(12))));
236 mxScroll->SetScrollHdl( LINK(this, SmElementsControl, ScrollHdl) );
237 mxScroll->Show();
240 SmElementsControl::~SmElementsControl()
242 disposeOnce();
245 void SmElementsControl::dispose()
247 mpDocShell->DoClose();
248 mxScroll.disposeAndClear();
249 Control::dispose();
252 void SmElementsControl::setVerticalMode(bool bVerticalMode)
254 mbVerticalMode = bVerticalMode;
257 void SmElementsControl::LayoutOrPaintContents(vcl::RenderContext *pContext)
259 bool bOldVisibleState = mxScroll->IsVisible();
261 sal_Int32 nScrollbarWidth = bOldVisibleState ? GetSettings().GetStyleSettings().GetScrollBarSize() : 0;
263 sal_Int32 nControlWidth = GetOutputSizePixel().Width() - nScrollbarWidth;
264 sal_Int32 nControlHeight = GetOutputSizePixel().Height();
266 sal_Int32 boxX = maMaxElementDimensions.Width() + 10;
267 sal_Int32 boxY = maMaxElementDimensions.Height() + 10;
269 sal_Int32 x = 0;
270 sal_Int32 y = -mxScroll->GetThumbPos();
272 sal_Int32 perLine = 0;
274 if (mbVerticalMode)
275 perLine = nControlHeight / boxY;
276 else
277 perLine = nControlWidth / boxX;
279 if (perLine <= 0)
281 perLine = 1;
284 if (mbVerticalMode)
285 boxY = nControlHeight / perLine;
286 else
287 boxX = nControlWidth / perLine;
289 for (sal_uInt16 i = 0; i < maElementList.size() ; i++)
291 SmElement* element = maElementList[i].get();
292 if (element->isSeparator())
294 if (mbVerticalMode)
296 x += boxX;
297 y = 0;
299 Rectangle aSelectionRectangle(x + 5 - 1, y + 5,
300 x + 5 + 1, nControlHeight - 5);
302 if (pContext)
303 pContext->DrawRect(PixelToLogic(aSelectionRectangle));
304 x += 10;
306 else
308 x = 0;
309 y += boxY;
311 Rectangle aSelectionRectangle(x + 5, y + 5 - 1,
312 nControlWidth - 5, y + 5 + 1);
314 if (pContext)
315 pContext->DrawRect(PixelToLogic(aSelectionRectangle));
316 y += 10;
319 else
321 Size aSizePixel = LogicToPixel(Size(element->getNode()->GetWidth(),
322 element->getNode()->GetHeight()));
323 if (mbVerticalMode)
325 if (y + boxY > nControlHeight)
327 x += boxX;
328 y = 0;
331 else
333 if ( x + boxX > nControlWidth)
335 x = 0;
336 y += boxY;
340 if (mpCurrentElement == element && pContext)
342 pContext->Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
343 pContext->SetFillColor(Color(230, 230, 230));
344 pContext->SetLineColor(Color(230, 230, 230));
346 pContext->DrawRect(PixelToLogic(Rectangle(x + 2, y + 2, x + boxX - 2, y + boxY - 2)));
347 pContext->Pop();
350 Point location(x + ((boxX - aSizePixel.Width()) / 2),
351 y + ((boxY - aSizePixel.Height()) / 2));
353 if (pContext)
354 SmDrawingVisitor(*pContext, PixelToLogic(location), element->getNode().get());
356 element->mBoxLocation = Point(x,y);
357 element->mBoxSize = Size(boxX, boxY);
359 if (mbVerticalMode)
360 y += boxY;
361 else
362 x += boxX;
366 if (!pContext)
368 sal_Int32 nTotalControlHeight = y + boxY + mxScroll->GetThumbPos();
370 if (nTotalControlHeight > GetOutputSizePixel().Height())
372 mxScroll->SetRangeMax(nTotalControlHeight);
373 mxScroll->SetPosSizePixel(Point(nControlWidth, 0), Size(nScrollbarWidth, nControlHeight));
374 mxScroll->SetVisibleSize(nControlHeight);
375 mxScroll->Show();
377 else
379 mxScroll->SetThumbPos(0);
380 mxScroll->Hide();
385 void SmElementsControl::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
387 rRenderContext.Push();
388 LayoutOrPaintContents(&rRenderContext);
389 rRenderContext.Pop();
392 void SmElementsControl::MouseMove( const MouseEvent& rMouseEvent )
394 mpCurrentElement = NULL;
395 OUString tooltip;
396 if (Rectangle(Point(0, 0), GetOutputSizePixel()).IsInside(rMouseEvent.GetPosPixel()))
398 for (sal_uInt16 i = 0; i < maElementList.size() ; i++)
400 SmElement* element = maElementList[i].get();
401 Rectangle rect(element->mBoxLocation, element->mBoxSize);
402 if (rect.IsInside(rMouseEvent.GetPosPixel()))
404 if (mpCurrentElement != element)
406 mpCurrentElement = element;
407 LayoutOrPaintContents();
408 Invalidate();
409 tooltip = element->getHelpText();
414 else
416 Control::MouseMove (rMouseEvent);
419 SetQuickHelpText(tooltip);
422 void SmElementsControl::MouseButtonDown(const MouseEvent& rMouseEvent)
424 GrabFocus();
426 if (rMouseEvent.IsLeft() && Rectangle(Point(0, 0), GetOutputSizePixel()).IsInside(rMouseEvent.GetPosPixel()))
428 for (sal_uInt16 i = 0; i < maElementList.size() ; i++)
430 SmElement* element = maElementList[i].get();
431 Rectangle rect(element->mBoxLocation, element->mBoxSize);
432 if (rect.IsInside(rMouseEvent.GetPosPixel()))
434 selectedSignal(element);
435 return;
439 else
441 Control::MouseButtonDown (rMouseEvent);
445 IMPL_LINK_NOARG( SmElementsControl, ScrollHdl )
447 DoScroll(mxScroll->GetDelta());
448 return 0;
451 void SmElementsControl::DoScroll(long nDelta)
453 Point aNewPoint = mxScroll->GetPosPixel();
454 Rectangle aRect(Point(), GetOutputSize());
455 aRect.Right() -= mxScroll->GetSizePixel().Width();
456 Scroll( 0, -nDelta, aRect );
457 mxScroll->SetPosPixel(aNewPoint);
458 LayoutOrPaintContents();
459 Invalidate();
462 void SmElementsControl::addSeparator()
464 SmElementPointer pElement(new SmElementSeparator());
465 maElementList.push_back(pElement);
468 void SmElementsControl::addElement(const OUString& aElementVisual, const OUString& aElementSource, const OUString& aHelpText)
470 SmNodePointer pNode(SmParser().ParseExpression(aElementVisual));
472 pNode->Prepare(maFormat, *mpDocShell);
473 pNode->SetSize(Fraction(10,8));
474 pNode->Arrange(*this, maFormat);
476 Size aSizePixel = LogicToPixel(Size(pNode->GetWidth(), pNode->GetHeight()), MAP_100TH_MM);
477 if (aSizePixel.Width() > maMaxElementDimensions.Width()) {
478 maMaxElementDimensions.Width() = aSizePixel.Width();
481 if (aSizePixel.Height() > maMaxElementDimensions.Height()) {
482 maMaxElementDimensions.Height() = aSizePixel.Height();
485 SmElementPointer pElement(new SmElement(pNode, aElementSource, aHelpText));
486 maElementList.push_back(pElement);
489 void SmElementsControl::setElementSetId(sal_uInt16 aSetId)
491 maCurrentSetId = aSetId;
492 maMaxElementDimensions = Size();
493 build();
496 void SmElementsControl::addElements(const sal_uInt16 aElementsArray[][2], sal_uInt16 aElementsArraySize)
498 for (sal_uInt16 i = 0; i < aElementsArraySize ; i++)
500 sal_uInt16 aElementId = aElementsArray[i][0];
501 sal_uInt16 aElementIdHelp = aElementsArray[i][1];
502 if (aElementId == 0xFFFF) {
503 addSeparator();
504 } else {
505 if (aElementId == RID_NEWLINE)
506 addElement(OUString( "\xe2\x86\xb5", 3, RTL_TEXTENCODING_UTF8 ), SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
507 else if (aElementId == RID_SBLANK)
508 addElement("\"`\"", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
509 else if (aElementId == RID_BLANK)
510 addElement("\"~\"", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
511 else if (aElementId == RID_PHANTOMX)
512 addElement("\"" + SM_RESSTR(STR_HIDE) +"\"", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
513 else if (aElementId == RID_BOLDX)
514 addElement("bold B", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
515 else if (aElementId == RID_ITALX)
516 addElement("ital I", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
517 else if (aElementId == RID_SIZEXY)
518 addElement("\"" + SM_RESSTR(STR_SIZE) + "\"", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
519 else if (aElementId == RID_FONTXY)
520 addElement("\"" + SM_RESSTR(STR_FONT) + "\"", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
521 else if (aElementId == RID_COLORX_BLACK)
522 addElement("color black { \"" + SM_RESSTR(STR_BLACK) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
523 else if (aElementId == RID_COLORX_BLUE)
524 addElement("color blue { \"" + SM_RESSTR(STR_BLUE) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
525 else if (aElementId == RID_COLORX_GREEN)
526 addElement("color green { \"" + SM_RESSTR(STR_GREEN) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
527 else if (aElementId == RID_COLORX_RED)
528 addElement("color red { \"" + SM_RESSTR(STR_RED) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
529 else if (aElementId == RID_COLORX_CYAN)
530 addElement("color cyan { \"" + SM_RESSTR(STR_CYAN) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
531 else if (aElementId == RID_COLORX_MAGENTA)
532 addElement("color magenta { \"" + SM_RESSTR(STR_MAGENTA) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
533 else if (aElementId == RID_COLORX_YELLOW)
534 addElement("color yellow { \"" + SM_RESSTR(STR_YELLOW) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
535 else if (aElementId == RID_COLORX_GRAY)
536 addElement("color gray { \"" + SM_RESSTR(STR_GRAY) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
537 else if (aElementId == RID_COLORX_LIME)
538 addElement("color lime { \"" + SM_RESSTR(STR_LIME) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
539 else if (aElementId == RID_COLORX_MAROON)
540 addElement("color maroon { \"" + SM_RESSTR(STR_MAROON) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
541 else if (aElementId == RID_COLORX_NAVY)
542 addElement("color navy { \"" + SM_RESSTR(STR_NAVY) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
543 else if (aElementId == RID_COLORX_OLIVE)
544 addElement("color olive { \"" + SM_RESSTR(STR_OLIVE) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
545 else if (aElementId == RID_COLORX_PURPLE)
546 addElement("color purple { \"" + SM_RESSTR(STR_PURPLE) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
547 else if (aElementId == RID_COLORX_SILVER)
548 addElement("color silver { \"" + SM_RESSTR(STR_SILVER) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
549 else if (aElementId == RID_COLORX_TEAL)
550 addElement("color teal { \"" + SM_RESSTR(STR_TEAL) + "\" }", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
551 else if (aElementId == RID_ALIGNLX)
552 addElement("\"" + SM_RESSTR(STR_ALIGN_LEFT) + "\"", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
553 else if (aElementId == RID_ALIGNCX)
554 addElement("\"" + SM_RESSTR(STR_ALIGN_CENTER) + "\"", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
555 else if (aElementId == RID_ALIGNRX)
556 addElement("\"" + SM_RESSTR(STR_ALIGN_RIGHT) + "\"", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
558 else if (aElementId == RID_SLRPARENTX)
559 addElement("left ( binom{<?>}{<?>} right ) ", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
560 else if (aElementId == RID_SLRBRACKETX)
561 addElement("left [ binom{<?>}{<?>} right ] ", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
562 else if (aElementId == RID_SLRDBRACKETX)
563 addElement("left ldbracket binom{<?>}{<?>} right rdbracket ", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
564 else if (aElementId == RID_SLRBRACEX)
565 addElement("left lbrace binom{<?>}{<?>} right rbrace ", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
566 else if (aElementId == RID_SLRANGLEX)
567 addElement("left langle binom{<?>}{<?>} right rangle ", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
568 else if (aElementId == RID_SLRCEILX)
569 addElement("left lceil binom{<?>}{<?>} right rceil ", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
570 else if (aElementId == RID_SLRFLOORX)
571 addElement("left lfloor binom{<?>}{<?>} right rfloor ", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
573 else if (aElementId == RID_SLRLINEX)
574 addElement("left lline binom{<?>}{<?>} right rline ", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
575 else if (aElementId == RID_SLRDLINEX)
576 addElement("left ldline binom{<?>}{<?>} right rdline ", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
577 else if (aElementId == RID_SLMRANGLEXY)
578 addElement("left langle binom{<?>}{<?>} mline binom{<?>}{<?>} right rangle ", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
580 else if (aElementId == RID_XOVERBRACEY)
581 addElement("{<?><?><?>} overbrace {<?>} ", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
582 else if (aElementId == RID_XUNDERBRACEY)
583 addElement("{<?><?><?>} underbrace {<?>} ", SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
584 else
585 addElement(SM_RESSTR(aElementId), SM_RESSTR(aElementId), SM_RESSTR(aElementIdHelp));
590 void SmElementsControl::build()
592 maElementList.clear();
594 switch(maCurrentSetId)
596 // we need to divide by 2 because of the matrix of two dimensions
597 case RID_CATEGORY_UNARY_BINARY_OPERATORS:
598 addElements(aUnaryBinaryOperatorsList, SAL_N_ELEMENTS(aUnaryBinaryOperatorsList));
599 break;
600 case RID_CATEGORY_RELATIONS:
601 addElements(aRelationsList, SAL_N_ELEMENTS(aRelationsList));
602 break;
603 case RID_CATEGORY_SET_OPERATIONS:
604 addElements(aSetOperations, SAL_N_ELEMENTS(aSetOperations));
605 break;
606 case RID_CATEGORY_FUNCTIONS:
607 addElements(aFunctions, SAL_N_ELEMENTS(aFunctions));
608 break;
609 case RID_CATEGORY_OPERATORS:
610 addElements(aOperators, SAL_N_ELEMENTS(aOperators));
611 break;
612 case RID_CATEGORY_ATTRIBUTES:
613 addElements(aAttributes, SAL_N_ELEMENTS(aAttributes));
614 break;
615 case RID_CATEGORY_BRACKETS:
616 addElements(aBrackets, SAL_N_ELEMENTS(aBrackets));
617 break;
618 case RID_CATEGORY_FORMATS:
619 addElements(aFormats, SAL_N_ELEMENTS(aFormats));
620 break;
621 case RID_CATEGORY_OTHERS:
622 addElements(aOthers, SAL_N_ELEMENTS(aOthers));
623 break;
624 case RID_CATEGORY_EXAMPLES:
626 OUString aEquation = "C=%pi cdot d = 2 cdot %pi cdot r";
627 addElement(aEquation, aEquation, "");
628 aEquation = "E=mc^2";
629 addElement(aEquation, aEquation, "");
630 aEquation = "a^2 + b^2 = c^2";
631 addElement(aEquation, aEquation, "");
632 aEquation = "f ( x ) = sum from { { i = 0 } } to { infinity } { {f^{(i)}(0)} over {i!} x^i}";
633 addElement(aEquation, aEquation, "");
634 aEquation = "f ( x ) = {1} over {%sigma sqrt{2%pi} }e^-{{(x-%mu)^2} over {2%sigma^2}}";
635 addElement(aEquation, aEquation, "");
637 break;
639 LayoutOrPaintContents();
640 Invalidate();
643 Size SmElementsControl::GetOptimalSize() const
645 return LogicToPixel(Size(100, 100), MapMode(MAP_APPFONT));
648 const sal_uInt16 SmElementsDockingWindow::aCategories[] = {
649 RID_CATEGORY_UNARY_BINARY_OPERATORS,
650 RID_CATEGORY_RELATIONS,
651 RID_CATEGORY_SET_OPERATIONS,
652 RID_CATEGORY_FUNCTIONS,
653 RID_CATEGORY_OPERATORS,
654 RID_CATEGORY_ATTRIBUTES,
655 RID_CATEGORY_BRACKETS,
656 RID_CATEGORY_FORMATS,
657 RID_CATEGORY_OTHERS,
658 RID_CATEGORY_EXAMPLES
661 SmElementsDockingWindow::SmElementsDockingWindow(SfxBindings* pInputBindings, SfxChildWindow* pChildWindow, vcl::Window* pParent) :
662 SfxDockingWindow(pInputBindings, pChildWindow, pParent, "DockingElements",
663 "modules/smath/ui/dockingelements.ui")
665 mpElementsControl = VclPtr<SmElementsControl>::Create(get<vcl::Window>("box"));
666 mpElementsControl->set_hexpand(true);
667 mpElementsControl->set_vexpand(true);
668 mpElementsControl->Show();
669 get(mpElementListBox, "listbox");
671 mpElementsControl->SetBorderStyle( WindowBorderStyle::MONO );
673 mpElementListBox->SetDropDownLineCount( SAL_N_ELEMENTS(aCategories) );
675 for (sal_uInt16 i = 0; i < SAL_N_ELEMENTS(aCategories) ; i++)
677 mpElementListBox->InsertEntry(SM_RESSTR(aCategories[i]));
680 mpElementListBox->SetSelectHdl(LINK(this, SmElementsDockingWindow, ElementSelectedHandle));
681 mpElementListBox->SelectEntry(SM_RESSTR(RID_CATEGORY_UNARY_BINARY_OPERATORS));
683 mpElementsControl->SetBackground( Color( COL_WHITE ) );
684 mpElementsControl->SetTextColor( Color( COL_BLACK ) );
685 mpElementsControl->setElementSetId(RID_CATEGORY_UNARY_BINARY_OPERATORS);
686 mpElementsControl->selectedSignal.connect( boost::bind( &SmElementsDockingWindow::SelectClickHandler, this, _1 ) );
689 SmElementsDockingWindow::~SmElementsDockingWindow ()
691 disposeOnce();
694 void SmElementsDockingWindow::dispose()
696 mpElementsControl.disposeAndClear();
697 mpElementListBox.clear();
698 SfxDockingWindow::dispose();
701 void SmElementsDockingWindow::ToggleFloatingMode()
703 SfxDockingWindow::ToggleFloatingMode();
705 if (GetFloatingWindow())
706 GetFloatingWindow()->SetMinOutputSizePixel( Size(100, 100) );
708 Invalidate();
711 void SmElementsDockingWindow::EndDocking( const Rectangle& rReactangle, bool bFloatMode)
713 SfxDockingWindow::EndDocking(rReactangle, bFloatMode);
714 bool bVertical = ( GetAlignment() == SfxChildAlignment::TOP || GetAlignment() == SfxChildAlignment::BOTTOM );
715 mpElementsControl->setVerticalMode(bVertical);
718 void SmElementsDockingWindow::SelectClickHandler( SmElement* pElement )
720 SmViewShell* pViewSh = GetView();
722 if (pViewSh)
724 pViewSh->GetViewFrame()->GetDispatcher()->Execute(
725 SID_INSERTCOMMANDTEXT, SfxCallMode::RECORD,
726 new SfxStringItem(SID_INSERTCOMMANDTEXT, pElement->getText()), 0L);
730 IMPL_LINK( SmElementsDockingWindow, ElementSelectedHandle, ListBox*, pList)
732 for (sal_uInt16 i = 0; i < SAL_N_ELEMENTS(aCategories) ; i++)
734 sal_uInt16 aCurrentCategory = aCategories[i];
735 OUString aCurrentCategoryString = SM_RESSTR(aCurrentCategory);
736 if (aCurrentCategoryString == pList->GetSelectEntry())
738 mpElementsControl->setElementSetId(aCurrentCategory);
739 return 0;
742 return 0;
745 SmViewShell* SmElementsDockingWindow::GetView()
747 SfxViewShell* pView = GetBindings().GetDispatcher()->GetFrame()->GetViewShell();
748 return PTR_CAST(SmViewShell, pView);
751 void SmElementsDockingWindow::Resize()
753 bool bVertical = ( GetAlignment() == SfxChildAlignment::TOP || GetAlignment() == SfxChildAlignment::BOTTOM );
754 mpElementsControl->setVerticalMode(bVertical);
756 SfxDockingWindow::Resize();
757 Invalidate();
760 SFX_IMPL_DOCKINGWINDOW_WITHID(SmElementsDockingWindowWrapper, SID_ELEMENTSDOCKINGWINDOW);
762 SmElementsDockingWindowWrapper::SmElementsDockingWindowWrapper(
763 vcl::Window *pParentWindow, sal_uInt16 nId,
764 SfxBindings *pBindings, SfxChildWinInfo *pInfo) :
765 SfxChildWindow(pParentWindow, nId)
767 VclPtrInstance<SmElementsDockingWindow> pDialog(pBindings, this, pParentWindow);
768 pWindow.reset(pDialog);
769 pDialog->setDeferredProperties();
770 pDialog->SetPosSizePixel(Point(0, 0), Size(300, 0));
771 pDialog->Show();
773 eChildAlignment = SfxChildAlignment::LEFT;
775 pDialog->Initialize( pInfo );
778 SmElementsDockingWindowWrapper::~SmElementsDockingWindowWrapper()
782 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */