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