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 <sfx2/app.hxx> 33 #include <vcl/virdev.hxx> 34 #include <tools/string.hxx> 35 #include <tools/tenccvt.hxx> 36 #include <osl/thread.h> 37 38 #include <tools/stream.hxx> 39 40 #include "starmath.hrc" 41 42 #include "utility.hxx" 43 #include "dialog.hxx" 44 #include "view.hxx" 45 #include "smdll.hxx" 46 47 48 //////////////////////////////////////////////////////////// 49 50 // return pointer to active SmViewShell, if this is not possible 51 // return 0 instead. 52 //!! Since this method is based on the current focus it is somewhat 53 //!! unreliable and may return unexpected 0 pointers! 54 SmViewShell * SmGetActiveView() 55 { 56 SfxViewShell *pView = SfxViewShell::Current(); 57 return PTR_CAST(SmViewShell, pView); 58 } 59 60 61 //////////////////////////////////////////////////////////// 62 63 64 /**************************************************************************/ 65 66 SmPickList::SmPickList(sal_uInt16 nInitSize, sal_uInt16 nMaxSize) : 67 SfxPtrArr((sal_uInt8) nInitSize, 1) 68 { 69 nSize = nMaxSize; 70 } 71 72 73 SmPickList::~SmPickList() 74 { 75 Clear(); 76 } 77 78 79 SmPickList& SmPickList::operator=(const SmPickList& rList) 80 { 81 sal_uInt16 nPos; 82 83 Clear(); 84 nSize = rList.nSize; 85 for (nPos = 0; nPos < rList.Count(); nPos++) 86 InsertPtr(nPos, CreateItem(rList.Get(nPos))); 87 88 return *this; 89 } 90 91 92 void SmPickList::Insert(const void *pItem) 93 { 94 Remove(pItem); 95 InsertPtr(0, CreateItem(pItem)); 96 97 if (Count() > nSize) 98 { 99 DestroyItem(GetPtr(nSize)); 100 RemovePtr(nSize, 1); 101 } 102 } 103 104 105 void SmPickList::Update(const void *pItem, const void *pNewItem) 106 { 107 sal_uInt16 nPos; 108 109 for (nPos = 0; nPos < Count(); nPos++) 110 if (CompareItem(GetPtr(nPos), pItem)) 111 { 112 DestroyItem(GetPtr(nPos)); 113 GetPtr(nPos) = CreateItem(pNewItem); 114 break; 115 } 116 } 117 118 void SmPickList::Remove(const void *pItem) 119 { 120 sal_uInt16 nPos; 121 122 for (nPos = 0; nPos < Count(); nPos++) 123 if (CompareItem(GetPtr(nPos), pItem)) 124 { 125 DestroyItem(GetPtr(nPos)); 126 RemovePtr(nPos, 1); 127 break; 128 } 129 } 130 131 void SmPickList::Clear() 132 { 133 sal_uInt16 nPos; 134 135 for (nPos = 0; nPos < Count(); nPos++) 136 DestroyItem(GetPtr(nPos)); 137 138 RemovePtr(0, Count()); 139 } 140 141 142 /**************************************************************************/ 143 /**************************************************************************/ 144 145 void * SmFontPickList::CreateItem(const String& /*rString*/) 146 { 147 return new Font(); 148 } 149 150 void * SmFontPickList::CreateItem(const void *pItem) 151 { 152 return new Font(*((Font *) pItem)); 153 } 154 155 void SmFontPickList::DestroyItem(void *pItem) 156 { 157 delete (Font *)pItem; 158 } 159 160 sal_Bool SmFontPickList::CompareItem(const void *pFirstItem, const void *pSecondItem) const 161 { 162 Font *pFirstFont, *pSecondFont; 163 164 pFirstFont = (Font *)pFirstItem; 165 pSecondFont = (Font *)pSecondItem; 166 167 if (pFirstFont->GetName() == pSecondFont->GetName()) 168 if ((pFirstFont->GetFamily() == pSecondFont->GetFamily()) && 169 (pFirstFont->GetCharSet() == pSecondFont->GetCharSet()) && 170 (pFirstFont->GetWeight() == pSecondFont->GetWeight()) && 171 (pFirstFont->GetItalic() == pSecondFont->GetItalic())) 172 return (sal_True); 173 174 return sal_False; 175 } 176 177 String SmFontPickList::GetStringItem(void *pItem) 178 { 179 Font *pFont; 180 String aString; 181 const sal_Char *pDelim = ", "; 182 183 pFont = (Font *)pItem; 184 185 aString = pFont->GetName(); 186 187 if (IsItalic( *pFont )) 188 { 189 aString.AppendAscii( pDelim ); 190 aString += String(SmResId(RID_FONTITALIC)); 191 } 192 if (IsBold( *pFont )) // bold? 193 { 194 aString.AppendAscii( pDelim ); 195 aString += String(SmResId(RID_FONTBOLD)); 196 } 197 198 return (aString); 199 } 200 201 void SmFontPickList::Insert(const Font &rFont) 202 { 203 SmPickList::Insert((void *)&rFont); 204 } 205 206 void SmFontPickList::Update(const Font &rFont, const Font &rNewFont) 207 { 208 SmPickList::Update((void *)&rFont, (void *)&rNewFont); 209 } 210 211 void SmFontPickList::Remove(const Font &rFont) 212 { 213 SmPickList::Remove((void *)&rFont); 214 } 215 216 217 void SmFontPickList::ReadFrom(const SmFontDialog& rDialog) 218 { 219 Insert(rDialog.GetFont()); 220 } 221 222 void SmFontPickList::WriteTo(SmFontDialog& rDialog) const 223 { 224 rDialog.SetFont(Get()); 225 } 226 227 228 /**************************************************************************/ 229 230 231 /**************************************************************************/ 232 233 IMPL_LINK( SmFontPickListBox, SelectHdl, ListBox *, /*pListBox*/ ) 234 { 235 sal_uInt16 nPos; 236 String aString; 237 238 nPos = GetSelectEntryPos(); 239 240 if (nPos != 0) 241 { 242 SmFontPickList::Insert(Get(nPos)); 243 aString = GetEntry(nPos); 244 RemoveEntry(nPos); 245 InsertEntry(aString, 0); 246 } 247 248 SelectEntryPos(0); 249 250 return 0; 251 } 252 253 254 SmFontPickListBox::SmFontPickListBox(Window* pParent, const ResId& rResId, sal_uInt16 nMax) : 255 SmFontPickList(nMax, nMax), 256 ListBox(pParent, rResId) 257 { 258 SetSelectHdl(LINK(this, SmFontPickListBox, SelectHdl)); 259 } 260 261 262 SmFontPickListBox& SmFontPickListBox::operator=(const SmFontPickList& rList) 263 { 264 sal_uInt16 nPos; 265 266 *(SmFontPickList *)this = rList; 267 268 for (nPos = 0; nPos < Count(); nPos++) 269 InsertEntry(GetStringItem(GetPtr(nPos)), nPos); 270 271 if (Count() > 0) 272 SelectEntry(GetStringItem(GetPtr(0))); 273 274 return *this; 275 } 276 277 void SmFontPickListBox::Insert(const Font &rFont) 278 { 279 SmFontPickList::Insert(rFont); 280 281 RemoveEntry(GetStringItem(GetPtr(0))); 282 InsertEntry(GetStringItem(GetPtr(0)), 0); 283 SelectEntry(GetStringItem(GetPtr(0))); 284 285 while (GetEntryCount() > nSize) 286 RemoveEntry(GetEntryCount() - 1); 287 288 return; 289 } 290 291 292 void SmFontPickListBox::Update(const Font &rFont, const Font &rNewFont) 293 { 294 SmFontPickList::Update(rFont, rNewFont); 295 296 // ********************** hier fehlt noch was 297 298 return; 299 } 300 301 302 void SmFontPickListBox::Remove(const Font &rFont) 303 { 304 SmFontPickList::Remove(rFont); 305 306 // ********************** hier fehlt noch was 307 308 return; 309 } 310 311 //////////////////////////////////////// 312 313 sal_Bool IsItalic( const Font &rFont ) 314 { 315 FontItalic eItalic = rFont.GetItalic(); 316 // the code below leaves only _NONE and _DONTKNOW as not italic 317 return eItalic == ITALIC_OBLIQUE || eItalic == ITALIC_NORMAL; 318 } 319 320 321 sal_Bool IsBold( const Font &rFont ) 322 { 323 FontWeight eWeight = rFont.GetWeight(); 324 return eWeight != WEIGHT_DONTKNOW && eWeight > WEIGHT_NORMAL; 325 } 326 327 328 void SmFace::Impl_Init() 329 { 330 SetSize( GetSize() ); 331 SetTransparent( sal_True ); 332 SetAlign( ALIGN_BASELINE ); 333 SetColor( COL_AUTO ); 334 } 335 336 void SmFace::SetSize(const Size& rSize) 337 { 338 Size aSize (rSize); 339 340 // check the requested size against minimum value 341 static int __READONLY_DATA nMinVal = SmPtsTo100th_mm(2); 342 343 if (aSize.Height() < nMinVal) 344 aSize.Height() = nMinVal; 345 346 //! we don't force a maximum value here because this may prevent eg the 347 //! parentheses in "left ( ... right )" from matching up with large 348 //! bodies (eg stack{...} with many entries). 349 //! Of course this is holds only if characters are used and not polygons. 350 351 Font::SetSize(aSize); 352 } 353 354 355 long SmFace::GetBorderWidth() const 356 { 357 if (nBorderWidth < 0) 358 return GetDefaultBorderWidth(); 359 else 360 return nBorderWidth; 361 } 362 363 SmFace & SmFace::operator = (const SmFace &rFace) 364 { 365 Font::operator = (rFace); 366 nBorderWidth = -1; 367 return *this; 368 } 369 370 371 SmFace & operator *= (SmFace &rFace, const Fraction &rFrac) 372 // scales the width and height of 'rFace' by 'rFrac' and returns a 373 // reference to 'rFace'. 374 // It's main use is to make scaling fonts look easier. 375 { const Size &rFaceSize = rFace.GetSize(); 376 377 rFace.SetSize(Size(Fraction(rFaceSize.Width()) *= rFrac, 378 Fraction(rFaceSize.Height()) *= rFrac)); 379 return rFace; 380 } 381 382 383 384