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 .
20 #include <ElementsDockingWindow.hxx>
22 #include <starmath.hrc>
26 #include <visitors.hxx>
28 #include <svl/stritem.hxx>
29 #include <sfx2/dispatch.hxx>
31 SV_DECL_REF(SmDocShell
)
32 SV_IMPL_REF(SmDocShell
)
34 SmElement::SmElement(SmNodePointer pNode
, OUString aText
) :
39 SmElement::~SmElement()
42 SmNodePointer
SmElement::getNode()
47 SmElementSeparator::SmElementSeparator() :
48 SmElement(SmNodePointer(), OUString())
51 //////////////////////////////////
53 const sal_uInt16
SmElementsControl::aUnaryBinaryOperatorsList
[] =
55 RID_PLUSX
, RID_MINUSX
, RID_PLUSMINUSX
, RID_MINUSPLUSX
,
57 RID_XPLUSY
, RID_XMINUSY
, RID_XCDOTY
, RID_XTIMESY
,
58 RID_XSYMTIMESY
, RID_XOVERY
, RID_XDIVY
, RID_XSYMDIVIDEY
,
59 RID_XCIRCY
, RID_XWIDESLASHY
, RID_XWIDEBSLASHY
,
61 RID_NEGX
, RID_XANDY
, RID_XORY
,
64 const sal_uInt16
SmElementsControl::aRelationsList
[] =
66 RID_XEQY
, RID_XNEQY
, RID_XLTY
, RID_XLEY
,
67 RID_XLESLANTY
, RID_XGTY
, RID_XGEY
, RID_XGESLANTY
,
69 RID_XAPPROXY
, RID_XSIMY
, RID_XSIMEQY
, RID_XEQUIVY
,
70 RID_XPROPY
, RID_XPARALLELY
, RID_XORTHOY
, RID_XDIVIDESY
,
71 RID_XNDIVIDESY
, RID_XTOWARDY
,
73 RID_DLARROW
, RID_DLRARROW
, RID_DRARROW
,
75 RID_XPRECEDESY
, RID_XSUCCEEDSY
, RID_XPRECEDESEQUALY
, RID_XSUCCEEDSEQUALY
,
76 RID_XPRECEDESEQUIVY
, RID_XSUCCEEDSEQUIVY
, RID_XNOTPRECEDESY
, RID_XNOTSUCCEEDSY
79 const sal_uInt16
SmElementsControl::aSetOperations
[] =
81 RID_XINY
, RID_XNOTINY
, RID_XOWNSY
,
83 RID_XINTERSECTIONY
, RID_XUNIONY
, RID_XSETMINUSY
, RID_XSLASHY
,
84 RID_XSUBSETY
, RID_XSUBSETEQY
, RID_XSUPSETY
, RID_XSUPSETEQY
, RID_XNSUBSETY
,
85 RID_XNSUBSETEQY
, RID_XNSUPSETY
, RID_XNSUPSETEQY
,
87 RID_EMPTYSET
, RID_ALEPH
, RID_SETN
, RID_SETZ
,
88 RID_SETQ
, RID_SETR
, RID_SETC
91 const sal_uInt16
SmElementsControl::aFunctions
[] =
93 RID_ABSX
, RID_FACTX
, RID_SQRTX
, RID_NROOTXY
,
94 RID_RSUPX
, RID_EX
, RID_LNX
, RID_EXPX
,
97 RID_SINX
, RID_COSX
, RID_TANX
, RID_COTX
,
98 RID_SINHX
, RID_COSHX
, RID_TANHX
, RID_COTHX
,
100 RID_ARCSINX
, RID_ARCCOSX
, RID_ARCTANX
, RID_ARCCOTX
,
101 RID_ARSINHX
, RID_ARCOSHX
, RID_ARTANHX
, RID_ARCOTHX
104 const sal_uInt16
SmElementsControl::aOperators
[] =
106 RID_LIMX
, RID_SUMX
, RID_PRODX
, RID_COPRODX
,
107 RID_INTX
, RID_IINTX
, RID_IIINTX
, RID_LINTX
,
108 RID_LLINTX
, RID_LLLINTX
,
110 RID_LIM_FROMX
, RID_SUM_FROMX
, RID_PROD_FROMX
, RID_COPROD_FROMX
,
111 RID_INT_FROMX
, RID_IINT_FROMX
, RID_IIINT_FROMX
, RID_LINT_FROMX
,
112 RID_LLINT_FROMX
, RID_LLLINT_FROMX
,
114 RID_LIM_TOX
, RID_SUM_TOX
, RID_PROD_TOX
, RID_COPROD_TOX
,
115 RID_INT_TOX
, RID_IINT_TOX
, RID_IIINT_TOX
, RID_LINT_TOX
,
116 RID_LLINT_TOX
, RID_LLLINT_TOX
,
118 RID_LIM_FROMTOX
, RID_SUM_FROMTOX
, RID_PROD_FROMTOX
, RID_COPROD_FROMTOX
,
119 RID_INT_FROMTOX
, RID_IINT_FROMTOX
, RID_IIINT_FROMTOX
, RID_LINT_FROMTOX
,
120 RID_LLINT_FROMTOX
, RID_LLLINT_FROMTOX
,
124 const sal_uInt16
SmElementsControl::aAttributes
[] =
126 RID_ACUTEX
, RID_GRAVEX
, RID_BREVEX
, RID_CIRCLEX
,
127 RID_DOTX
, RID_DDOTX
, RID_DDDOTX
, RID_BARX
,
128 RID_VECX
, RID_TILDEX
, RID_HATX
,
130 RID_WIDEVECX
, RID_WIDETILDEX
, RID_WIDEHATX
, RID_OVERLINEX
,
131 RID_UNDERLINEX
, RID_OVERSTRIKEX
,
133 RID_PHANTOMX
, RID_BOLDX
, RID_ITALX
, RID_SIZEXY
, RID_FONTXY
136 const sal_uInt16
SmElementsControl::aBrackets
[] =
140 RID_LRPARENTX
, RID_LRBRACKETX
, RID_LRDBRACKETX
, RID_LRBRACEX
,
141 RID_LRANGLEX
, RID_LMRANGLEXY
, RID_LRCEILX
, RID_LRFLOORX
,
142 RID_LRLINEX
, RID_LRDLINEX
,
144 RID_SLRPARENTX
, RID_SLRBRACKETX
, RID_SLRDBRACKETX
, RID_SLRANGLEX
,
145 RID_SLMRANGLEXY
, RID_SLRCEILX
, RID_SLRFLOORX
, RID_SLRLINEX
,
148 RID_XOVERBRACEY
, RID_XUNDERBRACEY
151 const sal_uInt16
SmElementsControl::aFormats
[] =
153 RID_RSUPX
, RID_RSUBX
, RID_LSUPX
, RID_LSUBX
,
154 RID_CSUPX
, RID_CSUBX
,
156 RID_NEWLINE
, RID_SBLANK
, RID_BLANK
, RID_NOSPACE
,
157 RID_BINOMXY
, RID_STACK
, RID_MATRIX
,
160 const sal_uInt16
SmElementsControl::aOthers
[] =
162 RID_INFINITY
, RID_PARTIAL
, RID_NABLA
, RID_EXISTS
,
163 RID_NOTEXISTS
, RID_FORALL
, RID_HBAR
, RID_LAMBDABAR
,
164 RID_RE
, RID_IM
, RID_WP
,
166 RID_LEFTARROW
, RID_RIGHTARROW
, RID_UPARROW
, RID_DOWNARROW
,
168 RID_DOTSLOW
, RID_DOTSAXIS
, RID_DOTSVERT
, RID_DOTSUP
,
172 SmElementsControl::SmElementsControl(Window
*pParent
, const ResId
& rResId
) :
173 Control(pParent
, rResId
),
174 mpDocShell(new SmDocShell(SFXOBJECTSHELL_STD_NORMAL
)),
175 mpCurrentElement(NULL
)
177 maFormat
.SetBaseSize(PixelToLogic(Size(0, 24)));
180 void SmElementsControl::Paint(const Rectangle
&)
184 SetMapMode( MapMode(MAP_100TH_MM
) );
185 SetDrawMode( DRAWMODE_DEFAULT
);
186 SetLayoutMode( TEXT_LAYOUT_BIDI_LTR
);
187 SetDigitLanguage( LANGUAGE_ENGLISH
);
189 sal_Int32 boxX
= maMaxElementDimensions
.Width() + 10;
190 sal_Int32 boxY
= maMaxElementDimensions
.Height() + 10;
195 sal_Int32 perLine
= GetOutputSizePixel().Width() / boxX
;
201 boxX
= GetOutputSizePixel().Width() / perLine
;
203 for (sal_uInt16 i
= 0; i
< maElementList
.size() ; i
++)
205 SmElement
* element
= maElementList
[i
].get();
206 if (element
->isSeparator())
210 Rectangle
aSelectionRectangle(
212 GetOutputSizePixel().Width() - 5, y
+5+1);
214 DrawRect(PixelToLogic(aSelectionRectangle
));
219 Size aSizePixel
= LogicToPixel(Size(element
->getNode()->GetWidth(), element
->getNode()->GetHeight()));
220 if ( x
+ boxX
> GetOutputSizePixel().Width())
226 if (mpCurrentElement
== element
)
229 SetFillColor( Color(230,230,230) );
230 SetLineColor( Color(230,230,230) );
232 DrawRect(PixelToLogic(Rectangle(x
+2, y
+2, x
+boxX
-2, y
+boxY
-2)));
236 Point
location(x
+ ((boxX
-aSizePixel
.Width())/2), y
+ ((boxY
-aSizePixel
.Height())/2));
237 SmDrawingVisitor(*this, PixelToLogic(location
), element
->getNode().get());
239 element
->mBoxLocation
= Point(x
,y
);
240 element
->mBoxSize
= Size(boxX
, boxY
);
249 void SmElementsControl::MouseMove( const MouseEvent
& rMouseEvent
)
251 mpCurrentElement
= NULL
;
252 if (Rectangle(Point(0, 0), GetOutputSizePixel()).IsInside(rMouseEvent
.GetPosPixel()))
254 for (sal_uInt16 i
= 0; i
< maElementList
.size() ; i
++)
256 SmElement
* element
= maElementList
[i
].get();
257 Rectangle
rect(element
->mBoxLocation
, element
->mBoxSize
);
258 if (rect
.IsInside(rMouseEvent
.GetPosPixel()))
260 if (mpCurrentElement
!= element
)
262 mpCurrentElement
= element
;
270 Control::MouseMove (rMouseEvent
);
274 void SmElementsControl::MouseButtonDown(const MouseEvent
& rMouseEvent
)
278 if (rMouseEvent
.IsLeft() && Rectangle(Point(0, 0), GetOutputSizePixel()).IsInside(rMouseEvent
.GetPosPixel()))
280 for (sal_uInt16 i
= 0; i
< maElementList
.size() ; i
++)
282 SmElement
* element
= maElementList
[i
].get();
283 Rectangle
rect(element
->mBoxLocation
, element
->mBoxSize
);
284 if (rect
.IsInside(rMouseEvent
.GetPosPixel()))
286 aSelectHdlLink
.Call(element
);
293 Control::MouseButtonDown (rMouseEvent
);
297 void SmElementsControl::addSeparator()
299 SmElementPointer
pElement(new SmElementSeparator());
300 maElementList
.push_back(pElement
);
303 void SmElementsControl::addElement(OUString aElementVisual
, OUString aElementSource
)
305 SmNodePointer
pNode(SmParser().ParseExpression(aElementVisual
));
307 pNode
->Prepare(maFormat
, *mpDocShell
);
308 pNode
->SetSize(Fraction(10,8));
309 pNode
->Arrange(*this, maFormat
);
311 Size aSizePixel
= LogicToPixel(Size(pNode
->GetWidth(), pNode
->GetHeight()), MAP_100TH_MM
);
312 if (aSizePixel
.Width() > maMaxElementDimensions
.Width()) {
313 maMaxElementDimensions
.Width() = aSizePixel
.Width();
316 if (aSizePixel
.Height() > maMaxElementDimensions
.Height()) {
317 maMaxElementDimensions
.Height() = aSizePixel
.Height();
320 SmElementPointer
pElement(new SmElement(pNode
, aElementSource
));
321 maElementList
.push_back(pElement
);
324 void SmElementsControl::setElementSetId(sal_uInt16 aSetId
)
326 maCurrentSetId
= aSetId
;
327 maMaxElementDimensions
= Size();
331 void SmElementsControl::addElements(const sal_uInt16 aElementsArray
[], sal_uInt16 aElementsArraySize
)
333 for (sal_uInt16 i
= 0; i
< aElementsArraySize
; i
++)
335 sal_uInt16 aElementId
= aElementsArray
[i
];
336 if (aElementId
== 0xFFFF) {
339 if (aElementId
== RID_NEWLINE
)
340 addElement(OStringToOUString( "\xe2\x86\xb5", RTL_TEXTENCODING_UTF8
), SmResId(aElementId
));
341 else if (aElementId
== RID_SBLANK
)
342 addElement(OUString("\"`\""), SmResId(aElementId
));
343 else if (aElementId
== RID_BLANK
)
344 addElement(OUString("\"~\""), SmResId(aElementId
));
345 else if (aElementId
== RID_PHANTOMX
)
346 addElement(OUString("\"hide\""), SmResId(aElementId
));
347 else if (aElementId
== RID_BOLDX
)
348 addElement(OUString("bold B"), SmResId(aElementId
));
349 else if (aElementId
== RID_ITALX
)
350 addElement(OUString("ital I"), SmResId(aElementId
));
351 else if (aElementId
== RID_SIZEXY
)
352 addElement(OUString("\"size\""), SmResId(aElementId
));
353 else if (aElementId
== RID_FONTXY
)
354 addElement(OUString("\"font\""), SmResId(aElementId
));
356 addElement(SmResId(aElementId
), SmResId(aElementId
));
361 void SmElementsControl::build()
363 maElementList
.clear();
365 switch(maCurrentSetId
)
367 case RID_CATEGORY_UNARY_BINARY_OPERATORS
:
368 addElements(aUnaryBinaryOperatorsList
, sizeof(aUnaryBinaryOperatorsList
) / sizeof(sal_uInt16
));
370 case RID_CATEGORY_RELATIONS
:
371 addElements(aRelationsList
, sizeof(aRelationsList
) / sizeof(sal_uInt16
));
373 case RID_CATEGORY_SET_OPERATIONS
:
374 addElements(aSetOperations
, sizeof(aSetOperations
) / sizeof(sal_uInt16
));
376 case RID_CATEGORY_FUNCTIONS
:
377 addElements(aFunctions
, sizeof(aFunctions
) / sizeof(sal_uInt16
));
379 case RID_CATEGORY_OPERATORS
:
380 addElements(aOperators
, sizeof(aOperators
) / sizeof(sal_uInt16
));
382 case RID_CATEGORY_ATTRIBUTES
:
383 addElements(aAttributes
, sizeof(aAttributes
) / sizeof(sal_uInt16
));
385 case RID_CATEGORY_BRACKETS
:
386 addElements(aBrackets
, sizeof(aBrackets
) / sizeof(sal_uInt16
));
388 case RID_CATEGORY_FORMATS
:
389 addElements(aFormats
, sizeof(aFormats
) / sizeof(sal_uInt16
));
391 case RID_CATEGORY_OTHERS
:
392 addElements(aOthers
, sizeof(aOthers
) / sizeof(sal_uInt16
));
394 case RID_CATEGORY_EXAMPLES
:
396 OUString aEquation
= OUString("C=%pi cdot d = 2 cdot %pi cdot r");
397 addElement(aEquation
, aEquation
);
398 aEquation
= OUString("E=mc^2");
399 addElement(aEquation
, aEquation
);
400 aEquation
= OUString("a^2 + b^2 = c^2");
401 addElement(aEquation
, aEquation
);
402 aEquation
= OUString("f ( x ) = sum from { { i = 0 } } to { infinity } { {f^{(i)}(0)} over {i!} x^i}");
403 addElement(aEquation
, aEquation
);
404 aEquation
= OUString("f ( x ) = {1} over {%sigma sqrt{2%pi} }e^-{{(x-%mu)^2} over {2%sigma^2}}");
405 addElement(aEquation
, aEquation
);
412 //*******************
414 const sal_uInt16
SmElementsDockingWindow::aCategories
[] = {
415 RID_CATEGORY_UNARY_BINARY_OPERATORS
,
416 RID_CATEGORY_RELATIONS
,
417 RID_CATEGORY_SET_OPERATIONS
,
418 RID_CATEGORY_FUNCTIONS
,
419 RID_CATEGORY_OPERATORS
,
420 RID_CATEGORY_ATTRIBUTES
,
421 RID_CATEGORY_BRACKETS
,
422 RID_CATEGORY_FORMATS
,
424 RID_CATEGORY_EXAMPLES
427 SmElementsDockingWindow::SmElementsDockingWindow(SfxBindings
* pInputBindings
, SfxChildWindow
* pChildWindow
, Window
* pParent
) :
428 SfxDockingWindow(pInputBindings
, pChildWindow
, pParent
, SmResId(RID_ELEMENTSDOCKINGWINDOW
)),
429 maElementsControl (this, SmResId(1)),
430 maElementListBox (this, SmResId(1))
432 maElementsControl
.SetBorderStyle( WINDOW_BORDER_MONO
);
434 maElementListBox
.SetDropDownLineCount( 10 );
436 for (sal_uInt16 i
= 0; i
< sizeof(aCategories
) / sizeof(sal_uInt16
) ; i
++)
438 maElementListBox
.InsertEntry(OUString(SmResId(aCategories
[i
])));
441 maElementListBox
.SetSelectHdl(LINK(this, SmElementsDockingWindow
, ElementSelectedHandle
));
443 Wallpaper
aWallpaper( Color( COL_WHITE
) );
445 maElementsControl
.SetBackground( aWallpaper
);
446 maElementsControl
.SetTextColor( Color( COL_BLACK
) );
447 maElementsControl
.SetSelectHdl(LINK(this, SmElementsDockingWindow
, SelectClickHdl
));
449 maElementListBox
.SelectEntry(OUString(SmResId(RID_CATEGORY_UNARY_BINARY_OPERATORS
)));
450 maElementsControl
.setElementSetId(RID_CATEGORY_UNARY_BINARY_OPERATORS
);
455 SmElementsDockingWindow::~SmElementsDockingWindow ()
459 IMPL_LINK( SmElementsDockingWindow
, SelectClickHdl
, SmElement
*, pElement
)
461 SmViewShell
* pViewSh
= GetView();
465 pViewSh
->GetViewFrame()->GetDispatcher()->Execute(
466 SID_INSERTCOMMANDTEXT
, SFX_CALLMODE_STANDARD
,
467 new SfxStringItem(SID_INSERTCOMMANDTEXT
, pElement
->getText()), 0L);
472 IMPL_LINK( SmElementsDockingWindow
, ElementSelectedHandle
, ListBox
*, pList
)
474 for (sal_uInt16 i
= 0; i
< sizeof(aCategories
) / sizeof(sal_uInt16
) ; i
++)
476 sal_uInt16 aCurrentCategory
= aCategories
[i
];
477 OUString aCurrentCategoryString
= OUString(SmResId(aCurrentCategory
));
478 if (aCurrentCategoryString
== pList
->GetSelectEntry())
480 maElementsControl
.setElementSetId(aCurrentCategory
);
487 SmViewShell
* SmElementsDockingWindow::GetView()
489 SfxViewShell
*pView
= GetBindings().GetDispatcher()->GetFrame()->GetViewShell();
490 return PTR_CAST(SmViewShell
, pView
);
493 void SmElementsDockingWindow::Resize()
495 sal_uInt32 aWidth
= GetOutputSizePixel().Width();
496 sal_uInt32 aHeight
= GetOutputSizePixel().Height();
498 sal_uInt32 aElementsSetsHeight
= 23;
499 sal_uInt32 aPadding
= 5;
501 Rectangle aRect1
= Rectangle(aPadding
, aPadding
, aWidth
- aPadding
, aElementsSetsHeight
+ aPadding
);
503 maElementListBox
.SetPosSizePixel(aRect1
.TopLeft(), aRect1
.GetSize());
505 Rectangle aRect
= Rectangle(aPadding
, aElementsSetsHeight
+ aPadding
+ aPadding
, aWidth
- aPadding
, aHeight
- aPadding
);
507 maElementsControl
.SetPosSizePixel(aRect
.TopLeft(), aRect
.GetSize());
509 SfxDockingWindow::Resize();
513 SFX_IMPL_DOCKINGWINDOW_WITHID(SmElementsDockingWindowWrapper
, SID_ELEMENTSDOCKINGWINDOW
);
515 SmElementsDockingWindowWrapper::SmElementsDockingWindowWrapper(
516 Window
*pParentWindow
, sal_uInt16 nId
,
517 SfxBindings
*pBindings
, SfxChildWinInfo
*pInfo
) :
518 SfxChildWindow(pParentWindow
, nId
)
520 pWindow
= new SmElementsDockingWindow(pBindings
, this, pParentWindow
);
521 SmElementsDockingWindow
* pDialog
= (SmElementsDockingWindow
*) pWindow
;
522 pDialog
->SetPosSizePixel(Point(0, 0), Size(300, 0));
525 eChildAlignment
= SFX_ALIGN_LEFT
;
527 pDialog
->Initialize( pInfo
);
530 SmElementsDockingWindowWrapper::~SmElementsDockingWindowWrapper()
535 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */