xref: /trunk/main/starmath/source/toolbox.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_starmath.hxx"
30 
31 
32 #include <rtl/logfile.hxx>
33 #include <svl/eitem.hxx>
34 #include <sfx2/app.hxx>
35 #include <svl/intitem.hxx>
36 #include <svtools/imgdef.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <sfx2/imgmgr.hxx>
39 #include <vcl/wrkwin.hxx>
40 #include "toolbox.hxx"
41 #ifndef _STARMATH_HRC
42 #include "starmath.hrc"
43 #endif
44 #ifndef _TOOLBOX_HRC_
45 #include "toolbox.hrc"
46 #endif
47 #include "view.hxx"
48 
49 
50 ////////////////////////////////////////////////////////////
51 
52 static sal_uInt16  GetImageListRID( sal_uInt16 nCategoryRID, sal_Bool bHighContrast )
53 {
54     sal_uInt16 nRes = 0xFFFF;
55     switch (nCategoryRID)
56     {
57         case RID_UNBINOPS_CAT       : nRes = RID_IL_UNBINOPS; break;
58         case RID_RELATIONS_CAT      : nRes = RID_IL_RELATIONS; break;
59         case RID_SETOPERATIONS_CAT  : nRes = RID_IL_SETOPERATIONS; break;
60         case RID_FUNCTIONS_CAT      : nRes = RID_IL_FUNCTIONS; break;
61         case RID_OPERATORS_CAT      : nRes = RID_IL_OPERATORS; break;
62         case RID_ATTRIBUTES_CAT     : nRes = RID_IL_ATTRIBUTES; break;
63         case RID_BRACKETS_CAT       : nRes = RID_IL_BRACKETS; break;
64         case RID_FORMAT_CAT         : nRes = RID_IL_FORMAT; break;
65         case RID_MISC_CAT           : nRes = RID_IL_MISC; break;
66         default :
67             DBG_ERROR( "unkown category" );
68     }
69     if (nRes != 0xFFFF && bHighContrast)
70         ++nRes;     //! the resource ID for the high contrast image list is just +1 compared to the regular ones
71     return nRes;
72 }
73 
74 
75 static sal_Int16  GetToolBoxCategoriesIndex( sal_uInt16 nCategoryRID )
76 {
77     sal_Int16 nIdx = -1;
78     switch (nCategoryRID)
79     {
80         case RID_UNBINOPS_CAT       : nIdx = 0; break;
81         case RID_RELATIONS_CAT      : nIdx = 1; break;
82         case RID_SETOPERATIONS_CAT  : nIdx = 2; break;
83         case RID_FUNCTIONS_CAT      : nIdx = 3; break;
84         case RID_OPERATORS_CAT      : nIdx = 4; break;
85         case RID_ATTRIBUTES_CAT     : nIdx = 5; break;
86         case RID_BRACKETS_CAT       : nIdx = 6; break;
87         case RID_FORMAT_CAT         : nIdx = 7; break;
88         case RID_MISC_CAT           : nIdx = 8; break;
89         default:
90 			;
91     }
92     return nIdx;
93 }
94 
95 
96 static sal_uInt16  GetCategoryRID( sal_uInt16 nResId )
97 {
98     sal_uInt16 nRes = 0xFFFF;
99     switch (nResId)
100     {
101         case RID_IL_UNBINOPS        :
102         case RID_ILH_UNBINOPS       : nRes = RID_UNBINOPS_CAT; break;
103         case RID_IL_RELATIONS       :
104         case RID_ILH_RELATIONS      : nRes = RID_RELATIONS_CAT; break;
105         case RID_IL_SETOPERATIONS   :
106         case RID_ILH_SETOPERATIONS  : nRes = RID_SETOPERATIONS_CAT; break;
107         case RID_IL_FUNCTIONS       :
108         case RID_ILH_FUNCTIONS      : nRes = RID_FUNCTIONS_CAT; break;
109         case RID_IL_OPERATORS       :
110         case RID_ILH_OPERATORS      : nRes = RID_OPERATORS_CAT; break;
111         case RID_IL_ATTRIBUTES      :
112         case RID_ILH_ATTRIBUTES     : nRes = RID_ATTRIBUTES_CAT; break;
113         case RID_IL_BRACKETS        :
114         case RID_ILH_BRACKETS       : nRes = RID_BRACKETS_CAT; break;
115         case RID_IL_FORMAT          :
116         case RID_ILH_FORMAT         : nRes = RID_FORMAT_CAT; break;
117         case RID_IL_MISC            :
118         case RID_ILH_MISC           : nRes = RID_MISC_CAT; break;
119         default :
120             if (nResId != RID_IL_CATALOG  &&  nResId != RID_ILH_CATALOG)
121             {
122 #if OSL_DEBUG_LEVEL > 1
123                 DBG_ERROR( "unkown category" );
124 #endif
125             }
126     }
127     return nRes;
128 }
129 
130 
131 ////////////////////////////////////////////////////////////
132 
133 
134 SmToolBoxWindow::SmToolBoxWindow(SfxBindings *pTmpBindings,
135 								 SfxChildWindow *pChildWindow,
136 								 Window *pParent) :
137     SfxFloatingWindow(pTmpBindings, pChildWindow, pParent, SmResId(RID_TOOLBOXWINDOW)),
138     aToolBoxCat(this, SmResId(TOOLBOX_CATALOG)),
139     aToolBoxCat_Delim(this, SmResId( FL_TOOLBOX_CAT_DELIM ))
140 {
141     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmToolBoxWindow::SmToolBoxWindow" );
142 
143     // allow for cursor travelling between toolbox and sub-categories
144     SetStyle( GetStyle() | WB_DIALOGCONTROL );
145 
146     nActiveCategoryRID = USHRT_MAX;
147 
148     aToolBoxCat.SetClickHdl(LINK(this, SmToolBoxWindow, CategoryClickHdl));
149 
150     sal_uInt16 i;
151     for (i = 0;  i < NUM_TBX_CATEGORIES;  ++i)
152 	{
153 		ToolBox *pBox = new ToolBox(this, SmResId( TOOLBOX_CAT_A + i ));
154 		vToolBoxCategories[i] = pBox;
155 		pBox->SetSelectHdl(LINK(this, SmToolBoxWindow, CmdSelectHdl));
156 	}
157     pToolBoxCmd = vToolBoxCategories[0];
158 
159     for (i = 0;  i <= NUM_TBX_CATEGORIES; ++i)
160     {
161         aImageLists [i] = 0;
162         aImageListsH[i] = 0;
163     }
164 
165 	FreeResource();
166 }
167 
168 SmToolBoxWindow::~SmToolBoxWindow()
169 {
170     int i;
171     for (i = 0;  i < NUM_TBX_CATEGORIES;  ++i)
172 	{
173 		ToolBox *pBox = vToolBoxCategories[i];
174 		delete pBox;
175 	}
176     for (i = 0;  i < NUM_TBX_CATEGORIES + 1;  ++i)
177 	{
178         delete aImageLists[i];
179         delete aImageListsH[i];
180 	}
181 }
182 
183 
184 SmViewShell * SmToolBoxWindow::GetView()
185 {
186     SfxViewShell *pView = GetBindings().GetDispatcher()->GetFrame()->GetViewShell();
187     return PTR_CAST(SmViewShell, pView);
188 }
189 
190 
191 const ImageList * SmToolBoxWindow::GetImageList( sal_uInt16 nResId, sal_Bool bHighContrast )
192 {
193     // creates the image list via its resource id and stores that
194     // list for later use in the respective array.
195 
196     const ImageList *pIL = 0;
197 
198     // get index to use
199     sal_uInt16 nCategoryRID = GetCategoryRID( nResId );
200     sal_Int16 nIndex = GetToolBoxCategoriesIndex( nCategoryRID );
201     if (nIndex == -1 && (nResId == RID_IL_CATALOG || nResId == RID_ILH_CATALOG))
202         nIndex = NUM_TBX_CATEGORIES;
203 
204     if (nIndex >= 0)
205     {
206         ImageList **pImgList = bHighContrast ? aImageListsH : aImageLists;
207         if (!pImgList[ nIndex ])
208             pImgList[ nIndex ] = new ImageList( SmResId(nResId) );
209         pIL = pImgList[ nIndex ];
210     }
211 
212     DBG_ASSERT( pIL, "image list not found!" );
213     return pIL;
214 }
215 
216 
217 void SmToolBoxWindow::ApplyImageLists( sal_uInt16 nCategoryRID )
218 {
219     sal_Bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
220 
221     // set image list for toolbox 'catalog'
222 	const ImageList *pImageList = GetImageList( bHighContrast ? RID_ILH_CATALOG : RID_IL_CATALOG, bHighContrast );
223     DBG_ASSERT( pImageList, "image list missing" );
224     if (pImageList)
225         aToolBoxCat.SetImageList( *pImageList );
226 
227     // set image list for active (visible) category of 'catalog'
228     sal_Int16 nIdx = GetToolBoxCategoriesIndex( nCategoryRID );
229     sal_uInt16 nResId = GetImageListRID( nCategoryRID, bHighContrast );
230     pImageList = GetImageList( nResId, bHighContrast );
231     DBG_ASSERT( pImageList && nIdx >= 0, "image list or index missing" );
232     if (pImageList && nIdx >= 0)
233         vToolBoxCategories[ nIdx ]->SetImageList( *pImageList );
234 }
235 
236 void SmToolBoxWindow::DataChanged( const DataChangedEvent &rEvt )
237 {
238     if ( (rEvt.GetType() == DATACHANGED_SETTINGS) && (rEvt.GetFlags() & SETTINGS_STYLE) )
239         ApplyImageLists( nActiveCategoryRID );
240 
241     SfxFloatingWindow::DataChanged( rEvt );
242 }
243 
244 void SmToolBoxWindow::StateChanged( StateChangedType nStateChange )
245 {
246     static sal_Bool bSetPosition = sal_True;
247     if (STATE_CHANGE_INITSHOW == nStateChange)
248     {
249         SetCategory( nActiveCategoryRID == USHRT_MAX ? RID_UNBINOPS_CAT : nActiveCategoryRID );
250 
251         // calculate initial position to be used after creation of the window...
252         AdjustPosSize( bSetPosition );
253         bSetPosition = sal_False;
254     }
255     //... otherwise the base class will remember the last position of the window
256     SfxFloatingWindow::StateChanged( nStateChange );
257 }
258 
259 
260 void SmToolBoxWindow::AdjustPosSize( sal_Bool bSetPos )
261 {
262     Size aCatSize( aToolBoxCat.CalcWindowSizePixel( 2 ) );
263     Size aCmdSize( pToolBoxCmd->CalcWindowSizePixel( 4 /* see nLines in SetCategory*/ ) );
264     DBG_ASSERT( aCatSize.Width() == aCmdSize.Width(), "width mismatch" );
265 
266     // catalog settings
267     aToolBoxCat.SetPosPixel( Point(0, 3) );
268     aToolBoxCat.SetSizePixel( aCatSize );
269     // settings for catalog / category delimiter
270     Point aP( aToolBoxCat_Delim.GetPosPixel() );
271     aP.X() = 0;
272     aToolBoxCat_Delim.SetPosPixel( aP );
273     aToolBoxCat_Delim.SetSizePixel( Size( aCatSize.Width(), aToolBoxCat_Delim.GetSizePixel().Height() ) );
274     // category settings
275     aP.Y() += aToolBoxCat_Delim.GetSizePixel().Height();
276 	for (int i = 0;  i < NUM_TBX_CATEGORIES;  ++i)
277     {
278         vToolBoxCategories[i]->SetPosPixel( aP );
279         vToolBoxCategories[i]->SetSizePixel( aCmdSize );
280     }
281     // main window settings
282     Size    aWndSize ( aCatSize.Width(), pToolBoxCmd->GetPosPixel().Y() + pToolBoxCmd->GetSizePixel().Height() + 3);
283     SetOutputSizePixel( aWndSize );
284 
285     if (bSetPos)
286 	{
287         SmViewShell *pView = GetView();
288         DBG_ASSERT( pView, "view shell missing" );
289         Point aPos( 50, 75 );
290         if (pView)
291         {
292             SmGraphicWindow &rWin = pView->GetGraphicWindow();
293             aPos = Point( rWin.OutputToScreenPixel(
294                             Point( rWin.GetSizePixel().Width() - aWndSize.Width(), 0) ) );
295         }
296 		if (aPos.X() < 0)
297 			aPos.X() = 0;
298 		if (aPos.Y() < 0)
299 			aPos.Y() = 0;
300         SetPosPixel( aPos );
301 	}
302 }
303 
304 
305 sal_Bool SmToolBoxWindow::Close()
306 {
307     SmViewShell *pViewSh = GetView();
308 	if (pViewSh)
309 		pViewSh->GetViewFrame()->GetDispatcher()->Execute(
310 				SID_TOOLBOX, SFX_CALLMODE_STANDARD,
311 				new SfxBoolItem(SID_TOOLBOX, sal_False), 0L);
312 	return sal_True;
313 }
314 
315 void SmToolBoxWindow::GetFocus()
316 {
317     // give focus to category toolbox
318     // (allow for cursor travelling when a category is selected with the mouse)
319     aToolBoxCat.GrabFocus();
320 }
321 
322 void SmToolBoxWindow::SetCategory(sal_uInt16 nCategoryRID)
323 {
324     if (nCategoryRID != nActiveCategoryRID)
325         ApplyImageLists( nCategoryRID );
326 
327     sal_uInt16 nLines;
328 	// check for valid resource id
329     switch (nCategoryRID)
330 	{
331         case RID_UNBINOPS_CAT :     nLines = 4; break;
332         case RID_RELATIONS_CAT:     nLines = 4; break;
333         case RID_SETOPERATIONS_CAT: nLines = 4; break;
334         case RID_FUNCTIONS_CAT:     nLines = 4; break;
335         case RID_OPERATORS_CAT:     nLines = 3; break;
336         case RID_ATTRIBUTES_CAT:    nLines = 4; break;
337         case RID_MISC_CAT:          nLines = 4; break;
338         case RID_BRACKETS_CAT:      nLines = 4; break;
339         case RID_FORMAT_CAT:        nLines = 3; break;
340 		default:
341 			// nothing to be done
342 			return;
343 	}
344 
345     pToolBoxCmd->Hide();
346 
347     sal_Int16 nIdx = GetToolBoxCategoriesIndex( nCategoryRID );
348     DBG_ASSERT( nIdx >= 0, "unkown category" );
349     if (nIdx >= 0)
350         pToolBoxCmd = vToolBoxCategories[nIdx];
351 
352     // calculate actual size of window to use
353     Size aCatSize( aToolBoxCat.CalcWindowSizePixel( 2 ) );
354     Size aCmdSize( pToolBoxCmd->CalcWindowSizePixel( nLines ) );
355     DBG_ASSERT( aCatSize.Width() == aCmdSize.Width(), "width mismatch" );
356     // main window settings
357     Size  aWndSize ( aCatSize.Width(), pToolBoxCmd->GetPosPixel().Y() + aCmdSize.Height() + 3);
358     SetOutputSizePixel( aWndSize );
359 
360     if (nActiveCategoryRID)
361         aToolBoxCat.CheckItem(nActiveCategoryRID, sal_False);
362     nActiveCategoryRID = nCategoryRID;
363     aToolBoxCat.CheckItem(nActiveCategoryRID, sal_True);
364 
365 	pToolBoxCmd->Show();
366 }
367 
368 
369 IMPL_LINK( SmToolBoxWindow, CategoryClickHdl, ToolBox*, pToolBox)
370 {
371 	int nItemId = pToolBox->GetCurItemId();
372 	if (nItemId != 0)
373         SetCategory( sal::static_int_cast< sal_uInt16 >(nItemId) );
374 	return 0;
375 }
376 
377 
378 IMPL_LINK( SmToolBoxWindow, CmdSelectHdl, ToolBox*, pToolBox)
379 {
380     SmViewShell *pViewSh = GetView();
381 	if (pViewSh)
382 		pViewSh->GetViewFrame()->GetDispatcher()->Execute(
383 				SID_INSERTCOMMAND, SFX_CALLMODE_STANDARD,
384 				new SfxInt16Item(SID_INSERTCOMMAND, pToolBox->GetCurItemId()), 0L);
385 	return 0;
386 }
387 
388 
389 /**************************************************************************/
390 
391 SFX_IMPL_FLOATINGWINDOW(SmToolBoxWrapper, SID_TOOLBOXWINDOW);
392 
393 SmToolBoxWrapper::SmToolBoxWrapper(Window *pParentWindow,
394 								   sal_uInt16 nId, SfxBindings* pBindings,
395 								   SfxChildWinInfo *pInfo) :
396 	SfxChildWindow(pParentWindow, nId)
397 {
398     eChildAlignment = SFX_ALIGN_NOALIGNMENT;
399 
400 	pWindow = new SmToolBoxWindow(pBindings, this, pParentWindow);
401     ((SfxFloatingWindow *)pWindow)->Initialize(pInfo);
402 }
403 
404 
405