update credits
[LibreOffice.git] / starmath / source / ElementsDockingWindow.cxx
blob2c3f33e1470535d187a22238539f00f69884d3bd
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>
31 SV_DECL_REF(SmDocShell)
32 SV_IMPL_REF(SmDocShell)
34 SmElement::SmElement(SmNodePointer pNode, OUString aText) :
35 mpNode(pNode),
36 maText(aText)
39 SmElement::~SmElement()
42 SmNodePointer SmElement::getNode()
44 return mpNode;
47 SmElementSeparator::SmElementSeparator() :
48 SmElement(SmNodePointer(), OUString())
51 //////////////////////////////////
53 const sal_uInt16 SmElementsControl::aUnaryBinaryOperatorsList[] =
55 RID_PLUSX, RID_MINUSX, RID_PLUSMINUSX, RID_MINUSPLUSX,
56 0xFFFF,
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,
60 0xFFFF,
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,
68 0xFFFF,
69 RID_XAPPROXY, RID_XSIMY, RID_XSIMEQY, RID_XEQUIVY,
70 RID_XPROPY, RID_XPARALLELY, RID_XORTHOY, RID_XDIVIDESY,
71 RID_XNDIVIDESY, RID_XTOWARDY,
72 0xFFFF,
73 RID_DLARROW, RID_DLRARROW, RID_DRARROW,
74 0xFFFF,
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,
82 0xFFFF,
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,
86 0xFFFF,
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,
95 RID_LOGX,
96 0xFFFF,
97 RID_SINX, RID_COSX, RID_TANX, RID_COTX,
98 RID_SINHX, RID_COSHX, RID_TANHX, RID_COTHX,
99 0xFFFF,
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,
109 0xFFFF,
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,
113 0xFFFF,
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,
117 0xFFFF,
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,
129 0xFFFF,
130 RID_WIDEVECX, RID_WIDETILDEX, RID_WIDEHATX, RID_OVERLINEX,
131 RID_UNDERLINEX, RID_OVERSTRIKEX,
132 0xFFFF,
133 RID_PHANTOMX, RID_BOLDX, RID_ITALX, RID_SIZEXY, RID_FONTXY
136 const sal_uInt16 SmElementsControl::aBrackets[] =
138 RID_LRGROUPX,
139 0xFFFF,
140 RID_LRPARENTX, RID_LRBRACKETX, RID_LRDBRACKETX, RID_LRBRACEX,
141 RID_LRANGLEX, RID_LMRANGLEXY, RID_LRCEILX, RID_LRFLOORX,
142 RID_LRLINEX, RID_LRDLINEX,
143 0xFFFF,
144 RID_SLRPARENTX, RID_SLRBRACKETX, RID_SLRDBRACKETX, RID_SLRANGLEX,
145 RID_SLMRANGLEXY, RID_SLRCEILX, RID_SLRFLOORX, RID_SLRLINEX,
146 RID_SLRDLINEX,
147 0XFFFF,
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,
155 0xFFFF,
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,
165 0xFFFF,
166 RID_LEFTARROW, RID_RIGHTARROW, RID_UPARROW, RID_DOWNARROW,
167 0xFFFF,
168 RID_DOTSLOW, RID_DOTSAXIS, RID_DOTSVERT, RID_DOTSUP,
169 RID_DOTSDOWN
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&)
182 Push();
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;
192 sal_Int32 x = 0;
193 sal_Int32 y = 0;
195 sal_Int32 perLine = GetOutputSizePixel().Width() / boxX;
197 if(perLine <= 0) {
198 perLine = 1;
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())
208 x = 0;
209 y += boxY;
210 Rectangle aSelectionRectangle(
211 x+5, y+5-1,
212 GetOutputSizePixel().Width() - 5, y+5+1);
214 DrawRect(PixelToLogic(aSelectionRectangle));
215 y += 10;
217 else
219 Size aSizePixel = LogicToPixel(Size(element->getNode()->GetWidth(), element->getNode()->GetHeight()));
220 if ( x + boxX > GetOutputSizePixel().Width())
222 x = 0;
223 y += boxY;
226 if (mpCurrentElement == element)
228 Push();
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)));
233 Pop();
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);
242 x += boxX;
246 Pop();
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;
263 Invalidate();
268 else
270 Control::MouseMove (rMouseEvent);
274 void SmElementsControl::MouseButtonDown(const MouseEvent& rMouseEvent)
276 GrabFocus();
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);
287 return;
291 else
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();
328 build();
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) {
337 addSeparator();
338 } else {
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));
355 else
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));
369 break;
370 case RID_CATEGORY_RELATIONS:
371 addElements(aRelationsList, sizeof(aRelationsList) / sizeof(sal_uInt16));
372 break;
373 case RID_CATEGORY_SET_OPERATIONS:
374 addElements(aSetOperations, sizeof(aSetOperations) / sizeof(sal_uInt16));
375 break;
376 case RID_CATEGORY_FUNCTIONS:
377 addElements(aFunctions, sizeof(aFunctions) / sizeof(sal_uInt16));
378 break;
379 case RID_CATEGORY_OPERATORS:
380 addElements(aOperators, sizeof(aOperators) / sizeof(sal_uInt16));
381 break;
382 case RID_CATEGORY_ATTRIBUTES:
383 addElements(aAttributes, sizeof(aAttributes) / sizeof(sal_uInt16));
384 break;
385 case RID_CATEGORY_BRACKETS:
386 addElements(aBrackets, sizeof(aBrackets) / sizeof(sal_uInt16));
387 break;
388 case RID_CATEGORY_FORMATS:
389 addElements(aFormats, sizeof(aFormats) / sizeof(sal_uInt16));
390 break;
391 case RID_CATEGORY_OTHERS:
392 addElements(aOthers, sizeof(aOthers) / sizeof(sal_uInt16));
393 break;
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);
407 break;
409 Invalidate();
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,
423 RID_CATEGORY_OTHERS,
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);
452 FreeResource();
455 SmElementsDockingWindow::~SmElementsDockingWindow ()
459 IMPL_LINK( SmElementsDockingWindow, SelectClickHdl, SmElement*, pElement)
461 SmViewShell* pViewSh = GetView();
463 if (pViewSh)
465 pViewSh->GetViewFrame()->GetDispatcher()->Execute(
466 SID_INSERTCOMMANDTEXT, SFX_CALLMODE_STANDARD,
467 new SfxStringItem(SID_INSERTCOMMANDTEXT, pElement->getText()), 0L);
469 return 0;
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);
481 return 0;
484 return 0;
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();
510 Invalidate();
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));
523 pDialog->Show();
525 eChildAlignment = SFX_ALIGN_LEFT;
527 pDialog->Initialize( pInfo );
530 SmElementsDockingWindowWrapper::~SmElementsDockingWindowWrapper()
535 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */