xref: /trunk/main/sw/source/ui/misc/glosbib.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_sw.hxx"
30 #ifdef SW_DLLIMPLEMENTATION
31 #undef SW_DLLIMPLEMENTATION
32 #endif
33 
34 
35 
36 #define _SVSTDARR_STRINGS
37 #include <tools/urlobj.hxx>
38 #include <tools/stream.hxx>
39 #ifndef _MSGBOX_HXX //autogen
40 #include <vcl/msgbox.hxx>
41 #endif
42 #include <vcl/help.hxx>
43 #include <unotools/transliterationwrapper.hxx>
44 #include <unotools/tempfile.hxx>
45 
46 #include <svl/svstdarr.hxx>
47 #include <unotools/pathoptions.hxx>
48 #include <swtypes.hxx>
49 #include <glosbib.hxx>
50 #include <gloshdl.hxx>
51 #include <actctrl.hxx>
52 #include <glossary.hxx>
53 #include <glosdoc.hxx>
54 #include <swunohelper.hxx>
55 
56 #ifndef _GLOSBIB_HRC
57 #include <glosbib.hrc>
58 #endif
59 #ifndef _MISC_HRC
60 #include <misc.hrc>
61 #endif
62 #ifndef _HELPID_H
63 #include <helpid.h>
64 #endif
65 
66 
67 #define PATH_CASE_SENSITIVE 0x01
68 #define PATH_READONLY 		0x02
69 
70 #define RENAME_TOKEN_DELIM		(sal_Unicode)1
71 
72 /*-----------------09.06.97 13:05-------------------
73 
74 --------------------------------------------------*/
75 SwGlossaryGroupDlg::SwGlossaryGroupDlg(Window * pParent,
76 						const SvStrings* pPathArr,
77 						SwGlossaryHdl *pHdl) :
78 	SvxStandardDialog(pParent, SW_RES(DLG_BIB_BASE)),
79     aBibFT(     this, SW_RES(FT_BIB)),
80 	aNameED( 	this, SW_RES(ED_NAME)),
81     aPathFT(     this, SW_RES(FT_PATH)),
82     aPathLB(	this, SW_RES(LB_PATH)),
83     aSelectFT(   this, SW_RES(FT_SELECT)),
84     aGroupTLB(  this, SW_RES(TLB_GROUPS)),
85 
86     aOkPB(      this, SW_RES(BT_OK)),
87     aCancelPB(  this, SW_RES(BT_CANCEL)),
88     aHelpPB(    this, SW_RES(BT_HELP)),
89     aNewPB(     this, SW_RES(PB_NEW)),
90     aDelPB(     this, SW_RES(PB_DELETE)),
91     aRenamePB(  this, SW_RES(PB_RENAME)),
92 
93     pRemovedArr(0),
94 	pInsertedArr(0),
95 	pRenamedArr(0),
96 	pGlosHdl(pHdl)
97 {
98 	sal_uInt16 i;
99 
100 	FreeResource();
101 
102 	long nTabs[] =
103 	{	2, // Number of Tabs
104 		0, 160
105 	};
106 
107 	aGroupTLB.SetHelpId(HID_GLOS_GROUP_TREE);
108 	aGroupTLB.SetTabs( &nTabs[0], MAP_APPFONT );
109 	aGroupTLB.SetStyle(aGroupTLB.GetStyle()|WB_HSCROLL|WB_CLIPCHILDREN|WB_SORT);
110 	aGroupTLB.SetSelectHdl(LINK(this, SwGlossaryGroupDlg, SelectHdl));
111 	aGroupTLB.GetModel()->SetSortMode(SortAscending);
112 	aNewPB.SetClickHdl(LINK(this, SwGlossaryGroupDlg, NewHdl));
113 	aDelPB.SetClickHdl(LINK(this, SwGlossaryGroupDlg, DeleteHdl));
114 	aNameED.SetModifyHdl(LINK(this, SwGlossaryGroupDlg, ModifyHdl));
115 	aPathLB.SetSelectHdl(LINK(this, SwGlossaryGroupDlg, ModifyHdl));
116 	aRenamePB.SetClickHdl(LINK(this, SwGlossaryGroupDlg, RenameHdl));
117 	for( i = 0; i < pPathArr->Count(); i++)
118 	{
119 		String sPath(*(*pPathArr)[i]);
120         INetURLObject aTempURL(sPath);
121         sPath = aTempURL.GetMainURL(INetURLObject::DECODE_WITH_CHARSET );
122 		aPathLB.InsertEntry(sPath);
123 		sal_uLong nCaseReadonly = 0;
124 		utl::TempFile aTempFile(&sPath);
125 		aTempFile.EnableKillingFile();
126 		if(!aTempFile.IsValid())
127 			nCaseReadonly |= PATH_READONLY;
128 		else if( SWUnoHelper::UCB_IsCaseSensitiveFileName( aTempFile.GetURL()))
129 			nCaseReadonly |= PATH_CASE_SENSITIVE;
130 		aPathLB.SetEntryData(i, (void*)nCaseReadonly);
131 	}
132 	aPathLB.SelectEntryPos(0);
133 	aPathLB.Enable(sal_True);
134 
135 	const sal_uInt16 nCount = pHdl->GetGroupCnt();
136 	for(i = 0; i < nCount; ++i)
137 	{
138 		String sTitle;
139 		String sGroup = pHdl->GetGroupName(i, &sTitle);
140 		if(!sGroup.Len())
141 			continue;
142 		GlosBibUserData* pData = new GlosBibUserData;
143 		pData->sGroupName = sGroup;
144 		pData->sGroupTitle = sTitle;
145 		String sTemp(sTitle);
146 		//sGroup.GetToken(0, GLOS_DELIM)
147 		sTemp += '\t';
148         pData->sPath = aPathLB.GetEntry((sal_uInt16)sGroup.GetToken(1, GLOS_DELIM).ToInt32());
149 		sTemp += pData->sPath;
150 		SvLBoxEntry* pEntry = aGroupTLB.InsertEntry(sTemp);
151 		pEntry->SetUserData(pData);
152 
153 	}
154 	aGroupTLB.GetModel()->Resort();
155 }
156 
157 /*-----------------09.06.97 13:05-------------------
158 
159 --------------------------------------------------*/
160 SwGlossaryGroupDlg::~SwGlossaryGroupDlg()
161 {
162 
163 	if(pInsertedArr)
164 	{
165 		pInsertedArr->DeleteAndDestroy(0, pInsertedArr->Count());
166 		delete pInsertedArr;
167 	}
168 	if(pRemovedArr)
169 	{
170 		pRemovedArr->DeleteAndDestroy(0, pRemovedArr->Count());
171 		delete pRemovedArr;
172 	}
173 	if(pRenamedArr)
174 	{
175 		pRenamedArr->DeleteAndDestroy(0, pRenamedArr->Count());
176 		delete pRenamedArr;
177 	}
178 
179 }
180 
181 /*-----------------09.06.97 13:11-------------------
182 
183 --------------------------------------------------*/
184 
185 void __EXPORT SwGlossaryGroupDlg::Apply()
186 {
187 	if(aNewPB.IsEnabled())
188 		NewHdl(&aNewPB);
189 
190 	String aActGroup = SwGlossaryDlg::GetCurrGroup();
191 
192 	if(pRemovedArr && pRemovedArr->Count())
193 	{
194 		sal_uInt16 nCount = pRemovedArr->Count();
195 		for(sal_uInt16 i = 0; i < nCount; ++i)
196 		{
197 			const String* pDelEntry = (*pRemovedArr)[i];
198 			const String sDelGroup = pDelEntry->GetToken(0, '\t');
199 			if( sDelGroup == aActGroup )
200 			{
201 				//soll die aktuelle Gruppe geloescht werden, muss die akt. Gruppe
202 				//umgesetzt werden
203 				if(aGroupTLB.GetEntryCount())
204 				{
205 					SvLBoxEntry* pFirst = aGroupTLB.First();
206 					GlosBibUserData* pUserData = (GlosBibUserData*)pFirst->GetUserData();
207 					pGlosHdl->SetCurGroup(pUserData->sGroupName);
208 				}
209 			}
210 			String sMsg(SW_RES(STR_QUERY_DELETE_GROUP1));
211 			String sTitle(pDelEntry->GetToken(1, '\t'));
212 			if(sTitle.Len())
213 				sMsg += sTitle;
214 			else
215 				sDelGroup.GetToken(1, GLOS_DELIM);
216 			sMsg += SW_RESSTR(STR_QUERY_DELETE_GROUP2);
217 			QueryBox aQuery(this->GetParent(), WB_YES_NO|WB_DEF_NO, sMsg );
218 			if(RET_YES == aQuery.Execute())
219 				pGlosHdl->DelGroup( sDelGroup );
220 		}
221 
222 	}
223 	//erst umbenennen, falls es schon eins gab
224 	if(pRenamedArr && pRenamedArr->Count())
225 	{
226 		sal_uInt16 nCount = pRenamedArr->Count();
227 		for(sal_uInt16 i = 0; i < nCount; ++i)
228 		{
229 			String * pEntry = (*pRenamedArr)[i];
230 			xub_StrLen nStrSttPos = 0;
231 			String sOld( pEntry->GetToken(0, RENAME_TOKEN_DELIM, nStrSttPos ) );
232 			String sNew( pEntry->GetToken(0, RENAME_TOKEN_DELIM, nStrSttPos) );
233 			String sTitle( pEntry->GetToken(0, RENAME_TOKEN_DELIM, nStrSttPos) );
234 			pGlosHdl->RenameGroup(sOld, sNew, sTitle);
235 			if(!i)
236 				sCreatedGroup = sNew;
237 		}
238 	}
239 	if(pInsertedArr && pInsertedArr->Count())
240 	{
241 		sal_uInt16 nCount = pInsertedArr->Count();
242 		for(sal_uInt16 i = 0; i < nCount; ++i)
243 		{
244 			String sNewGroup = *(*pInsertedArr)[i];
245 			String sNewTitle = sNewGroup.GetToken(0, GLOS_DELIM);
246 			if( *(*pInsertedArr)[i] != aActGroup )
247 			{
248 				pGlosHdl->NewGroup(sNewGroup, sNewTitle);
249 				if(!sCreatedGroup.Len())
250 					sCreatedGroup = sNewGroup;
251 			}
252 		}
253 	}
254 }
255 /*-----------------09.06.97 13:12-------------------
256 
257 --------------------------------------------------*/
258 IMPL_LINK( SwGlossaryGroupDlg, SelectHdl, SvTabListBox*, EMPTYARG  )
259 {
260 	aNewPB.Enable(sal_False);
261     SvLBoxEntry* pFirstEntry = aGroupTLB.FirstSelected();
262     if(pFirstEntry)
263 	{
264         GlosBibUserData* pUserData = (GlosBibUserData*)pFirstEntry->GetUserData();
265 		String sEntry(pUserData->sGroupName);
266 		String sName(aNameED.GetText());
267 		sal_Bool bExists = sal_False;
268 		sal_uLong nPos = aGroupTLB.GetEntryPos(sName, 0);
269 		if( 0xffffffff > nPos)
270 		{
271 			SvLBoxEntry* pEntry = aGroupTLB.GetEntry(nPos);
272 			GlosBibUserData* pFoundData = (GlosBibUserData*)pEntry->GetUserData();
273 			String sGroup = pFoundData->sGroupName;
274 			bExists = sGroup == sEntry;
275 		}
276 
277 		aRenamePB.Enable(!bExists && sName.Len());
278 		aDelPB.Enable(IsDeleteAllowed(sEntry));
279 	}
280 	return 0;
281 }
282 
283 /*-----------------09.06.97 13:22-------------------
284 
285 --------------------------------------------------*/
286 IMPL_LINK( SwGlossaryGroupDlg, NewHdl, Button*, EMPTYARG )
287 {
288 	String sGroup(aNameED.GetText());
289 //	sGroup.ToLower();
290 	sGroup += GLOS_DELIM;
291 	sGroup += String::CreateFromInt32(aPathLB.GetSelectEntryPos());
292 	DBG_ASSERT(!pGlosHdl->FindGroupName(sGroup), "Gruppe bereits vorhanden!");
293 	if(!pInsertedArr)
294 		pInsertedArr = new SvStrings;
295 	pInsertedArr->Insert(new String(sGroup), pInsertedArr->Count());
296 	String sTemp(aNameED.GetText());
297 //	sTemp.ToLower();
298 	sTemp += '\t';
299 	sTemp += aPathLB.GetSelectEntry();
300 	SvLBoxEntry* pEntry = aGroupTLB.InsertEntry(sTemp);
301 	GlosBibUserData* pData = new GlosBibUserData;
302 	pData->sPath = aPathLB.GetSelectEntry();
303 	pData->sGroupName = sGroup;
304 	pData->sGroupTitle = aNameED.GetText();
305 	pEntry->SetUserData(pData);
306 	aGroupTLB.Select(pEntry);
307 	aGroupTLB.MakeVisible(pEntry);
308 	aGroupTLB.GetModel()->Resort();
309 
310 	return 0;
311 }
312 /*-----------------09.06.97 13:22-------------------
313 
314 --------------------------------------------------*/
315 IMPL_LINK( SwGlossaryGroupDlg, DeleteHdl, Button*, pButton  )
316 {
317 	SvLBoxEntry* pEntry = aGroupTLB.FirstSelected();
318 	if(!pEntry)
319 	{
320 		pButton->Enable(sal_False);
321 		return 0;
322 	}
323 	GlosBibUserData* pUserData = (GlosBibUserData*)pEntry->GetUserData();
324 	String sEntry(pUserData->sGroupName);
325 	// befindet sich der zu loeschende Name schon unter den
326 	// den neuen - dann weg damit
327 	sal_Bool bDelete = sal_True;
328 	if(pInsertedArr && pInsertedArr->Count())
329 	{
330 		sal_uInt16 nCount = pInsertedArr->Count();
331 		for(sal_uInt16 i = 0; i < nCount; ++i)
332 		{
333 			const String* pTemp = (*pInsertedArr)[i];
334 			if(*pTemp == sEntry)
335 			{
336 				pInsertedArr->Remove(i);
337 				bDelete = sal_False;
338 				break;
339 			}
340 
341 		}
342 	}
343 	// moeglicherweise sollte es schon umbenannt werden?
344 	if(bDelete)
345 	{
346 		if(pRenamedArr && pRenamedArr->Count())
347 		{
348 			sal_uInt16 nCount = pRenamedArr->Count();
349 			for(sal_uInt16 i = 0; i < nCount; ++i)
350 			{
351 				const String* pTemp = (*pRenamedArr)[i];
352 				String sTemp( pTemp->GetToken(0, RENAME_TOKEN_DELIM ));
353 				if(sTemp == sEntry)
354 				{
355 					pRenamedArr->Remove(i);
356 					bDelete = sal_False;
357 					break;
358 				}
359 			}
360 		}
361 	}
362 	if(bDelete)
363 	{
364 		if(!pRemovedArr)
365 			pRemovedArr = new SvStrings;
366         String sGroupEntry(pUserData->sGroupName);
367         sGroupEntry += '\t';
368         sGroupEntry += pUserData->sGroupTitle;
369         pRemovedArr->Insert(new String(sGroupEntry), pRemovedArr->Count());
370 	}
371 	delete pUserData;
372 	aGroupTLB.GetModel()->Remove(pEntry);
373 	if(!aGroupTLB.First())
374 		pButton->Enable(sal_False);
375 	//the content must be deleted - otherwise the new handler would be called in Apply()
376 	aNameED.SetText(aEmptyStr);
377 	return 0;
378 }
379 
380 /* -----------------23.11.98 12:26-------------------
381  *
382  * --------------------------------------------------*/
383 IMPL_LINK( SwGlossaryGroupDlg, RenameHdl, Button *, EMPTYARG )
384 {
385 	SvLBoxEntry* pEntry = aGroupTLB.FirstSelected();
386 	GlosBibUserData* pUserData = (GlosBibUserData*)pEntry->GetUserData();
387 	String sEntryText(aGroupTLB.GetEntryText(pEntry));
388 	String sEntry(pUserData->sGroupName);
389 
390 	String sNewName(aNameED.GetText());
391 	String sNewTitle(sNewName);
392 
393 	sNewName += GLOS_DELIM;
394 	sNewName += String::CreateFromInt32(aPathLB.GetSelectEntryPos());
395 	DBG_ASSERT(!pGlosHdl->FindGroupName(sNewName), "Gruppe bereits vorhanden!");
396 
397 	// befindet sich der umzubenennende Name unter den
398 	// den neuen - dann austauschen
399 	sal_Bool bDone = sal_False;
400 	if(pInsertedArr && pInsertedArr->Count())
401 	{
402 		sal_uInt16 nCount = pInsertedArr->Count();
403 		for(sal_uInt16 i = 0; i < nCount; ++i)
404 		{
405 			const String* pTemp = (*pInsertedArr)[i];
406 			if(*pTemp == sEntry)
407 			{
408 				pInsertedArr->Remove(i);
409 				pInsertedArr->Insert(new String(sNewName), pInsertedArr->Count());
410 				bDone = sal_True;
411 				break;
412 			}
413 		}
414 	}
415 	if(!bDone)
416 	{
417 		if(!pRenamedArr)
418 			pRenamedArr = new SvStrings;
419 		sEntry += RENAME_TOKEN_DELIM;
420 		sEntry += sNewName;
421 		sEntry += RENAME_TOKEN_DELIM;
422 		sEntry += sNewTitle;
423 		pRenamedArr->Insert(new String(sEntry), pRenamedArr->Count());
424 	}
425 	delete (GlosBibUserData*)pEntry->GetUserData();
426 	aGroupTLB.GetModel()->Remove(pEntry);
427 	String sTemp(aNameED.GetText());
428 //	sTemp.ToLower();
429 	sTemp += '\t';
430 	sTemp += aPathLB.GetSelectEntry();
431 	pEntry = aGroupTLB.InsertEntry(sTemp);
432 	GlosBibUserData* pData = new GlosBibUserData;
433 	pData->sPath = aPathLB.GetSelectEntry();
434 	pData->sGroupName = sNewName;
435 	pData->sGroupTitle = sNewTitle;
436 	pEntry->SetUserData(pData);
437 	aGroupTLB.Select(pEntry);
438 	aGroupTLB.MakeVisible(pEntry);
439 	aGroupTLB.GetModel()->Resort();
440 	return 0;
441 }
442 /*-----------------09.06.97 13:42-------------------
443 
444 --------------------------------------------------*/
445 IMPL_LINK( SwGlossaryGroupDlg, ModifyHdl, Edit*, EMPTYARG )
446 {
447 	String sEntry(aNameED.GetText());
448 //	sEntry.ToLower();
449 	sal_Bool bEnableNew = sal_True;
450 	sal_Bool bEnableDel = sal_False;
451 	sal_uLong nCaseReadonly =
452 			(sal_uLong)aPathLB.GetEntryData(aPathLB.GetSelectEntryPos());
453 	sal_Bool bDirReadonly = 0 != (nCaseReadonly&PATH_READONLY);
454 
455 	if(!sEntry.Len() || bDirReadonly)
456 		bEnableNew = sal_False;
457 	else if(sEntry.Len())
458 	{
459 		sal_uLong nPos = 0xffffffff;
460 
461 
462 		nPos = aGroupTLB.GetEntryPos(sEntry, 0);
463 		//ist es nicht case sensitive muss man selbst suchen
464 		if( 0xffffffff == nPos)
465 		{
466 			const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
467 			for(sal_uInt16 i = 0; i < aGroupTLB.GetEntryCount(); i++)
468 			{
469 				String sTemp = aGroupTLB.GetEntryText( i, 0 );
470                 nCaseReadonly = (sal_uLong)aPathLB.GetEntryData(
471 					aPathLB.GetEntryPos(aGroupTLB.GetEntryText(i,1)));
472 				sal_Bool bCase = 0 != (nCaseReadonly & PATH_CASE_SENSITIVE);
473 
474 				if( !bCase && rSCmp.isEqual( sTemp, sEntry ))
475 				{
476 					nPos = i;
477 					break;
478 				}
479 			}
480 		}
481 		if( 0xffffffff > nPos)
482 		{
483 			bEnableNew = sal_False;
484 			aGroupTLB.Select(aGroupTLB.GetEntry( nPos ));
485 			aGroupTLB.MakeVisible(aGroupTLB.GetEntry( nPos ));
486 		}
487 	}
488 	SvLBoxEntry* pEntry = aGroupTLB.FirstSelected();
489 	if(pEntry)
490 	{
491 		GlosBibUserData* pUserData = (GlosBibUserData*)pEntry->GetUserData();
492 		bEnableDel = IsDeleteAllowed(pUserData->sGroupName);
493 
494 //		String sGroup = aGroupTLB.GetEntryText(pEntry, 0);
495 //		sGroup += GLOS_DELIM;
496 //		sGroup += String::CreateFromInt32(aPathLB.GetEntryPos(aGroupTLB.GetEntryText(pEntry, 1)));
497 //		bEnableDel = IsDeleteAllowed(sGroup);
498 	}
499 
500 	aDelPB.Enable(bEnableDel);
501 	aNewPB.Enable(bEnableNew);
502 	aRenamePB.Enable(bEnableNew && pEntry);
503 	return 0;
504 }
505 
506 /*------------------------------------------------------------------------
507  Beschreibung:
508 ------------------------------------------------------------------------*/
509 
510 sal_Bool SwGlossaryGroupDlg::IsDeleteAllowed(const String &rGroup)
511 {
512 	sal_Bool bDel = (!pGlosHdl->IsReadOnly(&rGroup));
513 
514 	// OM: befindet sich der Name unter den den neuen Bereichsnamen,
515 	// dann ist er auch loeschbar! Bei noch nicht existenten Bereichsnamen
516 	// liefert ReadOnly naemlich sal_True.
517 
518 	if(pInsertedArr && pInsertedArr->Count())
519 	{
520 		sal_uInt16 nCount = pInsertedArr->Count();
521 		for(sal_uInt16 i = 0; i < nCount; ++i)
522 		{
523 			const String* pTemp = (*pInsertedArr)[i];
524 			if(*pTemp == rGroup)
525 			{
526 				bDel = sal_True;
527 				break;
528 			}
529 		}
530 	}
531 
532 	return bDel;
533 }
534 
535 /*-----------------18.07.97 19:06-------------------
536 
537 --------------------------------------------------*/
538 void FEdit::KeyInput( const KeyEvent& rKEvent )
539 {
540 	KeyCode aCode = rKEvent.GetKeyCode();
541 	if( KEYGROUP_CURSOR == aCode.GetGroup() ||
542 		( KEYGROUP_MISC == aCode.GetGroup() &&
543 		  KEY_DELETE >= aCode.GetCode() ) ||
544 		SVT_SEARCHPATH_DELIMITER != rKEvent.GetCharCode() )
545 		Edit::KeyInput( rKEvent );
546 }
547 /* -----------------------------08.02.00 15:07--------------------------------
548 
549  ---------------------------------------------------------------------------*/
550 void 	SwGlossaryGroupTLB::RequestHelp( const HelpEvent& rHEvt )
551 {
552 	Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ));
553 	SvLBoxEntry* pEntry = GetEntry( aPos );
554 	if(pEntry)
555 	{
556 		SvLBoxTab* pTab;
557 		SvLBoxItem* pItem = GetItem( pEntry, aPos.X(), &pTab );
558 		if(pItem)
559 		{
560 			aPos = GetEntryPosition( pEntry );
561 			Size aSize(pItem->GetSize( this, pEntry ));
562 			aPos.X() = GetTabPos( pEntry, pTab );
563 
564 			if((aPos.X() + aSize.Width()) > GetSizePixel().Width())
565 				aSize.Width() = GetSizePixel().Width() - aPos.X();
566 			aPos = OutputToScreenPixel(aPos);
567 			Rectangle aItemRect( aPos, aSize );
568 			String sMsg;
569 			GlosBibUserData* pData = (GlosBibUserData*)pEntry->GetUserData();
570 			sMsg = pData->sPath;
571 			sMsg += INET_PATH_TOKEN;
572 			sMsg += pData->sGroupName.GetToken(0, GLOS_DELIM);
573 			sMsg += SwGlossaries::GetExtension();
574 
575 			Help::ShowQuickHelp( this, aItemRect, sMsg,
576 						QUICKHELP_LEFT|QUICKHELP_VCENTER );
577 		}
578 	}
579 }
580