xref: /trunk/main/sw/source/ui/dochdl/gloshdl.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 
31 
32 #include <hintids.hxx>
33 #include <editeng/wghtitem.hxx>
34 #include <editeng/adjitem.hxx>
35 #ifndef __RSC //autogen
36 #include <tools/errinf.hxx>
37 #endif
38 #ifndef _MSGBOX_HXX //autogen
39 #include <vcl/msgbox.hxx>
40 #endif
41 #ifndef _MSGBOX_HXX //autogen
42 #include <vcl/msgbox.hxx>
43 #endif
44 #include <svl/macitem.hxx>
45 #include <sfx2/fcontnr.hxx>
46 #include <sfx2/docfile.hxx>
47 #define _SVSTDARR_STRINGS
48 #include <svl/svstdarr.hxx>
49 #include <svl/urihelper.hxx>
50 #include <unotools/transliterationwrapper.hxx>
51 #include <poolfmt.hxx>
52 #include <fmtcol.hxx>
53 #include <docary.hxx>
54 #include <wrtsh.hxx>
55 #include <uitool.hxx>                   // Fehlermeldungen
56 #include <view.hxx>
57 #include <swevent.hxx>
58 #include <gloshdl.hxx>
59 #include <glosdoc.hxx>
60 #include <shellio.hxx>
61 #include <swundo.hxx>                   // fuer Undo-Ids
62 #include <expfld.hxx>
63 #include <initui.hxx>                   // fuer ::GetGlossaries()
64 #include <gloslst.hxx>
65 #include <swdtflvr.hxx>
66 #ifndef _DOCSH_HXX
67 #include <docsh.hxx>
68 #endif
69 #include <crsskip.hxx>
70 
71 #ifndef _DOCHDL_HRC
72 #include <dochdl.hrc>
73 #endif
74 #ifndef _SWERROR_H
75 #include <swerror.h>
76 #endif
77 #include <frmmgr.hxx>
78 #ifndef _LSTBOX_HXX //autogen
79 #include <vcl/lstbox.hxx>
80 #endif
81 
82 #include <editeng/acorrcfg.hxx>
83 #include "swabstdlg.hxx"
84 #include <misc.hrc>
85 
86 #include <IDocumentFieldsAccess.hxx>
87 
88 using namespace ::com::sun::star;
89 
90 
91 const short RET_EDIT = 100;
92 
93 // PUBLIC METHODES -------------------------------------------------------
94 struct TextBlockInfo_Impl
95 {
96     String sTitle;
97     String sLongName;
98     String sGroupName;
99 };
100 typedef TextBlockInfo_Impl* TextBlockInfo_ImplPtr;
101 SV_DECL_PTRARR_DEL( TextBlockInfoArr, TextBlockInfo_ImplPtr, 0, 4 )
102 SV_IMPL_PTRARR( TextBlockInfoArr, TextBlockInfo_ImplPtr )
103 SV_IMPL_REF( SwDocShell )
104 /*------------------------------------------------------------------------
105     Beschreibung:   Dialog fuer Bearbeiten Vorlagen
106 ------------------------------------------------------------------------*/
107 
108 
109 void SwGlossaryHdl::GlossaryDlg()
110 {
111     SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
112     DBG_ASSERT(pFact, "Dialogdiet fail!");
113     AbstractGlossaryDlg* pDlg = pFact->CreateGlossaryDlg( DLG_RENAME_GLOS,
114                                                         pViewFrame, this, pWrtShell);
115     DBG_ASSERT(pDlg, "Dialogdiet fail!");
116     String sName, sShortName;
117 
118     if( RET_EDIT == pDlg->Execute() )
119     {
120         sName = pDlg->GetCurrGrpName();
121         sShortName = pDlg->GetCurrShortName();
122     }
123 
124     delete pDlg;
125     DELETEZ(pCurGrp);
126     if(HasGlossaryList())
127     {
128         GetGlossaryList()->ClearGroups();
129     }
130 
131     if( sName.Len() || sShortName.Len() )
132         rStatGlossaries.EditGroupDoc( sName, sShortName );
133 }
134 
135 /*------------------------------------------------------------------------
136     Beschreibung:   Setzen der aktuellen Gruppe; falls aus dem Dialog
137                     gerufen, wird die Gruppe temp. erzeugt fuer einen
138                     schnelleren Zugriff
139 ------------------------------------------------------------------------*/
140 
141 
142 void SwGlossaryHdl::SetCurGroup(const String &rGrp, sal_Bool bApi, sal_Bool bAlwaysCreateNew )
143 {
144     String sGroup(rGrp);
145     if(STRING_NOTFOUND == sGroup.Search(GLOS_DELIM) && !FindGroupName(sGroup))
146     {
147         sGroup += GLOS_DELIM;
148         sGroup += '0';
149     }
150     if(pCurGrp)
151     {
152         sal_Bool bPathEqual = sal_False;
153         if(!bAlwaysCreateNew)
154         {
155             INetURLObject aTemp( pCurGrp->GetFileName() );
156             String sCurBase = aTemp.getBase();
157             aTemp.removeSegment();
158             const String sCurEntryPath = aTemp.GetMainURL(INetURLObject::NO_DECODE);
159             const SvStrings* pPathArr = rStatGlossaries.GetPathArray();
160             sal_uInt16 nCurrentPath = USHRT_MAX;
161             for(sal_uInt16 nPath = 0; nPath < pPathArr->Count(); nPath++)
162             {
163                 if(sCurEntryPath == *(*pPathArr)[nPath])
164                 {
165                     nCurrentPath = nPath;
166                     break;
167                 }
168             }
169             String sPath = sGroup.GetToken(1, GLOS_DELIM);
170             sal_uInt16 nComparePath = (sal_uInt16)sPath.ToInt32();
171             if(nCurrentPath == nComparePath &&
172                 sGroup.GetToken(0, GLOS_DELIM) == sCurBase)
173                 bPathEqual = sal_True;
174         }
175 //      const String aMac_Tmp(pCurGrp->GetName());
176         // Beim Pfadwechsel kann man sich auf den Namen nicht verlassen
177         if(!bAlwaysCreateNew &&
178                 bPathEqual
179 //      aMac_Tmp == sGroup
180         )
181             return;
182     }
183     aCurGrp = sGroup;
184     if(!bApi)
185     {
186         if(pCurGrp)
187         {
188             rStatGlossaries.PutGroupDoc(pCurGrp);
189             pCurGrp = 0;
190         }
191         pCurGrp = rStatGlossaries.GetGroupDoc(aCurGrp, sal_True);
192     }
193 }
194 
195 /*------------------------------------------------------------------------
196     Beschreibung:
197 ------------------------------------------------------------------------*/
198 
199 
200 sal_uInt16 SwGlossaryHdl::GetGroupCnt() const
201 {
202     return rStatGlossaries.GetGroupCnt();
203 }
204 
205 /*------------------------------------------------------------------------
206     Beschreibung:
207 ------------------------------------------------------------------------*/
208 
209 
210 String SwGlossaryHdl::GetGroupName( sal_uInt16 nId, String* pTitle )
211 {
212     String sRet = rStatGlossaries.GetGroupName(nId);
213     if(pTitle)
214     {
215         SwTextBlocks* pGroup = rStatGlossaries.GetGroupDoc(sRet, sal_False);
216         if(pGroup && !pGroup->GetError())
217         {
218             *pTitle = pGroup->GetName();
219             if(!pTitle->Len())
220             {
221                 *pTitle = sRet.GetToken(0, GLOS_DELIM);
222                 pGroup->SetName(*pTitle);
223             }
224             rStatGlossaries.PutGroupDoc( pGroup );
225         }
226         else
227             sRet.Erase();
228     }
229     return sRet;
230 }
231 /*------------------------------------------------------------------------
232     Beschreibung:
233 ------------------------------------------------------------------------*/
234 
235 
236 sal_Bool SwGlossaryHdl::NewGroup(String &rGrpName, const String& rTitle)
237 {
238     if(STRING_NOTFOUND == rGrpName.Search(GLOS_DELIM))
239         FindGroupName(rGrpName);
240     return rStatGlossaries.NewGroupDoc(rGrpName, rTitle);
241 }
242 /* -----------------23.11.98 13:10-------------------
243  * Umbenennen eines Textbausteins
244  * --------------------------------------------------*/
245 sal_Bool SwGlossaryHdl::RenameGroup(const String & rOld, String& rNew, const String& rNewTitle)
246 {
247     sal_Bool bRet = sal_False;
248     String sOldGroup(rOld);
249     if(STRING_NOTFOUND == rOld.Search(GLOS_DELIM))
250         FindGroupName(sOldGroup);
251     if(rOld == rNew)
252     {
253         SwTextBlocks* pGroup = rStatGlossaries.GetGroupDoc(sOldGroup, sal_False);
254         if(pGroup)
255         {
256             pGroup->SetName(rNewTitle);
257             rStatGlossaries.PutGroupDoc( pGroup );
258             bRet = sal_True;
259         }
260     }
261     else
262     {
263         String sNewGroup(rNew);
264         if(STRING_NOTFOUND == sNewGroup.Search(GLOS_DELIM))
265         {
266             sNewGroup += GLOS_DELIM;
267             sNewGroup += '0';
268         }
269         bRet = rStatGlossaries.RenameGroupDoc(sOldGroup, sNewGroup, rNewTitle);
270         rNew = sNewGroup;
271     }
272     return bRet;
273 }
274 /* -----------------27.11.98 13:49-------------------
275  *
276  * --------------------------------------------------*/
277 sal_Bool SwGlossaryHdl::CopyOrMove( const String& rSourceGroupName,  String& rSourceShortName,
278                         const String& rDestGroupName, const String& rLongName, sal_Bool bMove )
279 {
280     SwTextBlocks* pSourceGroup = rStatGlossaries.GetGroupDoc(rSourceGroupName, sal_False);
281 
282     SwTextBlocks* pDestGroup = rStatGlossaries.GetGroupDoc(rDestGroupName, sal_False);
283     if(pDestGroup->IsReadOnly() || (bMove && pSourceGroup->IsReadOnly()) )
284         return sal_False;
285     /*if(pDestGroup->IsOld()&& 0!= pDestGroup->ConvertToNew())
286         return sal_False;
287     if(bMove && pSourceGroup->IsOld() && 0 != pSourceGroup->ConvertToNew())
288         return sal_False;*/
289 
290     //Der Index muss hier ermittelt werden, weil rSourceShortName in CopyBlock evtl veraendert wird
291     sal_uInt16 nDeleteIdx = pSourceGroup->GetIndex( rSourceShortName );
292     DBG_ASSERT(USHRT_MAX != nDeleteIdx, "Eintrag nicht gefunden");
293     sal_uLong nRet = pSourceGroup->CopyBlock( *pDestGroup, rSourceShortName, rLongName );
294     if(!nRet && bMove)
295     {
296         // der Index muss existieren
297         nRet = pSourceGroup->Delete( nDeleteIdx ) ? 0 : 1;
298     }
299     rStatGlossaries.PutGroupDoc( pSourceGroup );
300     rStatGlossaries.PutGroupDoc( pDestGroup );
301     return !nRet;
302 }
303 
304 /*------------------------------------------------------------------------
305     Beschreibung: Loeschen einer Textbausteindatei-Gruppe
306 ------------------------------------------------------------------------*/
307 
308 
309 sal_Bool SwGlossaryHdl::DelGroup(const String &rGrpName)
310 {
311     String sGroup(rGrpName);
312     if(STRING_NOTFOUND == sGroup.Search(GLOS_DELIM))
313         FindGroupName(sGroup);
314     if( rStatGlossaries.DelGroupDoc(sGroup) )
315     {
316         if(pCurGrp)
317         {
318             const String aMac_Tmp(pCurGrp->GetName());
319             if(aMac_Tmp == sGroup)
320                 DELETEZ(pCurGrp);
321         }
322         return sal_True;
323     }
324     return sal_False;
325 }
326 
327 /*------------------------------------------------------------------------
328     Beschreibung:   Anzahl Textbausteine erfragen
329 ------------------------------------------------------------------------*/
330 
331 
332 sal_uInt16 SwGlossaryHdl::GetGlossaryCnt()
333 {
334     return pCurGrp ? pCurGrp->GetCount() : 0;
335 }
336 
337 /*------------------------------------------------------------------------
338     Beschreibung:
339 ------------------------------------------------------------------------*/
340 
341 
342 String SwGlossaryHdl::GetGlossaryName( sal_uInt16 nId )
343 {
344     ASSERT(nId < GetGlossaryCnt(), Textbausteinarray ueberindiziert.);
345     return pCurGrp->GetLongName( nId );
346 }
347 /* -----------------30.11.98 13:18-------------------
348  *
349  * --------------------------------------------------*/
350 String  SwGlossaryHdl::GetGlossaryShortName(sal_uInt16 nId)
351 {
352     ASSERT(nId < GetGlossaryCnt(), Textbausteinarray ueberindiziert.);
353     return pCurGrp->GetShortName( nId );
354 }
355 
356 
357 /*------------------------------------------------------------------------
358     Beschreibung:   Kurzname erfragen
359 ------------------------------------------------------------------------*/
360 
361 
362 String SwGlossaryHdl::GetGlossaryShortName(const String &rName)
363 {
364     String sReturn;
365     SwTextBlocks *pTmp =
366         pCurGrp ? pCurGrp: rStatGlossaries.GetGroupDoc( aCurGrp, sal_False );
367     if(pTmp)
368     {
369         sal_uInt16 nIdx = pTmp->GetLongIndex( rName );
370         if( nIdx != (sal_uInt16) -1 )
371             sReturn = pTmp->GetShortName( nIdx );
372         if( !pCurGrp )
373             rStatGlossaries.PutGroupDoc( pTmp );
374     }
375     return sReturn;
376 }
377 
378 /*------------------------------------------------------------------------
379  Beschreibung:  Kuerzel fuer Textbaustein bereits verwendet?
380 ------------------------------------------------------------------------*/
381 
382 
383 sal_Bool SwGlossaryHdl::HasShortName(const String& rShortName) const
384 {
385     SwTextBlocks *pBlock = pCurGrp ? pCurGrp
386                                    : rStatGlossaries.GetGroupDoc( aCurGrp );
387     sal_Bool bRet = pBlock->GetIndex( rShortName ) != (sal_uInt16) -1;
388     if( !pCurGrp )
389         rStatGlossaries.PutGroupDoc( pBlock );
390     return bRet;
391 }
392 
393 /* -----------------------------20.03.01 10:52--------------------------------
394 
395  ---------------------------------------------------------------------------*/
396 sal_Bool    SwGlossaryHdl::ConvertToNew(SwTextBlocks& /*rOld*/)
397 {
398     /*if( rOld.IsOld() )
399     {
400         QueryBox aAsk( pWrtShell->GetView().GetWindow(), SW_RES( MSG_UPDATE_NEW_GLOS_FMT ) );
401         if( aAsk.Execute() == RET_YES )
402         {
403             if( rOld.ConvertToNew() )
404             {
405                 InfoBox(pWrtShell->GetView().GetWindow(), SW_RES(MSG_ERR_INSERT_GLOS)).Execute();
406                 return sal_False;
407             }
408         }
409         else
410             return sal_False;
411     }*/
412     return sal_True;
413 }
414 
415 /*------------------------------------------------------------------------
416     Beschreibung:   Erzeugen eines Textbausteines
417 ------------------------------------------------------------------------*/
418 
419 sal_Bool SwGlossaryHdl::NewGlossary(const String& rName, const String& rShortName,
420                                 sal_Bool bCreateGroup, sal_Bool bNoAttr)
421 {
422     SwTextBlocks *pTmp =
423         pCurGrp ? pCurGrp: rStatGlossaries.GetGroupDoc( aCurGrp, bCreateGroup );
424     //pTmp == 0 if the AutoText path setting is wrong
425     if(!pTmp)
426         return sal_False;
427     if(!ConvertToNew(*pTmp))
428         return sal_False;
429 
430     String sOnlyTxt;
431     String* pOnlyTxt = 0;
432     if( bNoAttr )
433     {
434         if( !pWrtShell->GetSelectedText( sOnlyTxt, GETSELTXT_PARABRK_TO_ONLYCR ))
435             return sal_False;
436         pOnlyTxt = &sOnlyTxt;
437     }
438 
439     const SvxAutoCorrCfg* pCfg = SvxAutoCorrCfg::Get();
440 
441     const sal_uInt16 nSuccess = pWrtShell->MakeGlossary( *pTmp, rName, rShortName,
442                             pCfg->IsSaveRelFile(), pOnlyTxt );
443     if(nSuccess == (sal_uInt16) -1 )
444     {
445         InfoBox(pWrtShell->GetView().GetWindow(), SW_RES(MSG_ERR_INSERT_GLOS)).Execute();
446     }
447     if( !pCurGrp )
448         rStatGlossaries.PutGroupDoc( pTmp );
449     return sal_Bool( nSuccess != (sal_uInt16) -1 );
450 }
451 /*------------------------------------------------------------------------
452     Beschreibung:   Loeschen eines Textbausteines
453 ------------------------------------------------------------------------*/
454 
455 
456 sal_Bool SwGlossaryHdl::DelGlossary(const String &rShortName)
457 {
458     SwTextBlocks *pGlossary = pCurGrp ? pCurGrp
459                                     : rStatGlossaries.GetGroupDoc(aCurGrp);
460     //pTmp == 0 if the AutoText path setting is wrong
461     if(!pGlossary || !ConvertToNew(*pGlossary))
462         return sal_False;
463 
464     sal_uInt16 nIdx = pGlossary->GetIndex( rShortName );
465     if( nIdx != (sal_uInt16) -1 )
466         pGlossary->Delete( nIdx );
467     if( !pCurGrp )
468         rStatGlossaries.PutGroupDoc( pGlossary );
469     return sal_True;
470 }
471 
472 /*------------------------------------------------------------------------
473     Beschreibung: Kurzform expandieren
474 ------------------------------------------------------------------------*/
475 
476 
477 sal_Bool SwGlossaryHdl::ExpandGlossary()
478 {
479     ASSERT(pWrtShell->CanInsert(), illegal);
480     SwTextBlocks *pGlossary;
481     SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
482     DBG_ASSERT(pFact, "Dialogdiet fail!");
483     ::GlossaryGetCurrGroup fnGetCurrGroup = pFact->GetGlossaryCurrGroupFunc( DLG_RENAME_GLOS );
484     DBG_ASSERT(fnGetCurrGroup, "Dialogdiet fail!");
485     String sGroupName( (*fnGetCurrGroup)() );
486     if(STRING_NOTFOUND == sGroupName.Search(GLOS_DELIM))
487         FindGroupName(sGroupName);
488     pGlossary = rStatGlossaries.GetGroupDoc(sGroupName);
489 
490     String aShortName;
491 
492         // bei Textselektion diese verwenden
493     if(pWrtShell->SwCrsrShell::HasSelection() && !pWrtShell->IsBlockMode())
494     {
495         aShortName = pWrtShell->GetSelTxt();
496     }
497     else
498     {
499         if(pWrtShell->IsAddMode())
500             pWrtShell->LeaveAddMode();
501         else if(pWrtShell->IsBlockMode())
502             pWrtShell->LeaveBlockMode();
503         else if(pWrtShell->IsExtMode())
504             pWrtShell->LeaveExtMode();
505             // Wort selektieren
506         pWrtShell->SelNearestWrd();
507             // Wort erfragen
508         if(pWrtShell->IsSelection())
509             aShortName = pWrtShell->GetSelTxt();
510     }
511     return pGlossary ? Expand( aShortName, &rStatGlossaries, pGlossary ) : sal_False;
512 }
513 
514 sal_Bool SwGlossaryHdl::Expand( const String& rShortName,
515                             SwGlossaries *pGlossaries,
516                             SwTextBlocks *pGlossary  )
517 {
518     TextBlockInfoArr aFoundArr;
519     String aShortName( rShortName );
520     sal_Bool bCancel = sal_False;
521     // search for text block
522     //#b6633427# - don't prefer current group depending on configuration setting
523     const SvxAutoCorrCfg* pCfg = SvxAutoCorrCfg::Get();
524     sal_uInt16 nFound = !pCfg->IsSearchInAllCategories() ? pGlossary->GetIndex( aShortName ) : -1;
525     // if not found then search in all groups
526     if( nFound == (sal_uInt16) -1 )
527     {
528         const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
529         SwGlossaryList* pGlossaryList = ::GetGlossaryList();
530         sal_uInt16 nGroupCount = pGlossaryList->GetGroupCount();
531         for(sal_uInt16 i = 1; i <= nGroupCount; i++)
532         {
533             // Gruppenname mit Pfad-Extension besorgen
534             String sTitle;
535             String sGroupName = pGlossaryList->GetGroupName(i - 1, sal_False, &sTitle);
536             if(sGroupName == pGlossary->GetName())
537                 continue;
538             sal_uInt16 nBlockCount = pGlossaryList->GetBlockCount(i -1);
539             if(nBlockCount)
540             {
541                 for(sal_uInt16 j = 0; j < nBlockCount; j++)
542                 {
543                     String sEntry;
544                     String sLongName(pGlossaryList->GetBlockName(i - 1, j, sEntry));
545                     if( rSCmp.isEqual( rShortName, sEntry ))
546                     {
547                         TextBlockInfo_Impl* pData = new TextBlockInfo_Impl;
548                         pData->sTitle = sTitle;
549                         pData->sLongName = sLongName;
550                         pData->sGroupName = sGroupName;
551                         aFoundArr.Insert(pData, aFoundArr.Count());
552                     }
553                 }
554             }
555         }
556         if( aFoundArr.Count() )  // einer wurde gefunden
557         {
558             pGlossaries->PutGroupDoc(pGlossary);
559             if(1 == aFoundArr.Count())
560             {
561                 TextBlockInfo_Impl* pData = aFoundArr.GetObject(0);
562                 pGlossary = (SwTextBlocks *)pGlossaries->GetGroupDoc(pData->sGroupName);
563                 nFound = pGlossary->GetIndex( aShortName );
564             }
565             else
566             {
567                 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
568                 DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");
569 
570                 AbstarctSwSelGlossaryDlg* pDlg = pFact->CreateSwSelGlossaryDlg( 0, aShortName, DLG_SEL_GLOS );
571                 DBG_ASSERT(pDlg, "Dialogdiet fail!");
572                 for(sal_uInt16 i = 0; i < aFoundArr.Count(); ++i)
573                 {
574                     TextBlockInfo_Impl* pData = aFoundArr.GetObject(i);
575                     pDlg->InsertGlos(pData->sTitle, pData->sLongName);
576                 }
577                 pDlg->SelectEntryPos(0);
578                 const sal_uInt16 nRet = RET_OK == pDlg->Execute()?
579                                         pDlg->GetSelectedIdx():
580                                         LISTBOX_ENTRY_NOTFOUND;
581                 delete pDlg;
582                 if(LISTBOX_ENTRY_NOTFOUND != nRet)
583                 {
584                     TextBlockInfo_Impl* pData = aFoundArr.GetObject(nRet);
585                     pGlossary = (SwTextBlocks *)pGlossaries->GetGroupDoc(pData->sGroupName);
586                     nFound = pGlossary->GetIndex( aShortName );
587                 }
588                 else
589                 {
590                     nFound = (sal_uInt16) -1;
591                     bCancel = sal_True;
592                 }
593             }
594         }
595     }
596 
597         // nicht gefunden
598     if( nFound == (sal_uInt16) -1 )
599     {
600         if( !bCancel )
601         {
602             pGlossaries->PutGroupDoc(pGlossary);
603 
604             const sal_uInt16 nMaxLen = 50;
605             if(pWrtShell->IsSelection() && aShortName.Len() > nMaxLen)
606             {
607                 aShortName.Erase(nMaxLen);
608                 aShortName.AppendAscii(" ...");
609             }
610             String aTmp( SW_RES(STR_NOGLOS));
611             aTmp.SearchAndReplaceAscii("%1", aShortName);
612             InfoBox( pWrtShell->GetView().GetWindow(), aTmp ).Execute();
613         }
614 
615         return sal_False;
616     }
617     else
618     {
619         String aLongName = pGlossary->GetLongName( nFound );
620         SvxMacro aStartMacro(aEmptyStr, aEmptyStr, STARBASIC);
621         SvxMacro aEndMacro(aEmptyStr, aEmptyStr, STARBASIC);
622         GetMacros( aShortName, aStartMacro, aEndMacro, pGlossary );
623 
624     // StartAction darf nich vor HasSelection und DelRight stehen,
625     // sonst wird der moeglich Shellwechsel verzoegert und
626     // API-Programme wuerden dann haengenbleiben
627     // ausserdem darf das Ereignismacro ebenfalls nicht in einer Action gerufen werden
628         pWrtShell->StartUndo(UNDO_INSGLOSSARY);
629         if( aStartMacro.GetMacName().Len() )
630             pWrtShell->ExecMacro( aStartMacro );
631         if(pWrtShell->HasSelection())
632             pWrtShell->DelLeft();
633         pWrtShell->StartAllAction();
634 
635         // alle InputFelder zwischenspeichern
636         SwInputFieldList aFldLst( pWrtShell, sal_True );
637 
638         pWrtShell->InsertGlossary(*pGlossary, aShortName);
639         pWrtShell->EndAllAction();
640         if( aEndMacro.GetMacName().Len() )
641         {
642             pWrtShell->ExecMacro( aEndMacro );
643         }
644         pWrtShell->EndUndo(UNDO_INSGLOSSARY);
645 
646         // fuer alle neuen InputFelder die Eingaben abfordern
647         if( aFldLst.BuildSortLst() )
648             pWrtShell->UpdateInputFlds( &aFldLst );
649     }
650     pGlossaries->PutGroupDoc(pGlossary);
651     return sal_True;
652 }
653 
654 /*------------------------------------------------------------------------
655     Beschreibung: Textbaustein einfuegen
656 ------------------------------------------------------------------------*/
657 
658 
659 sal_Bool SwGlossaryHdl::InsertGlossary(const String &rName)
660 {
661     ASSERT(pWrtShell->CanInsert(), illegal);
662 
663     SwTextBlocks *pGlos =
664         pCurGrp? pCurGrp: rStatGlossaries.GetGroupDoc(aCurGrp);
665 
666     if (!pGlos)
667         return sal_False;
668 
669     SvxMacro aStartMacro(aEmptyStr, aEmptyStr, STARBASIC);
670     SvxMacro aEndMacro(aEmptyStr, aEmptyStr, STARBASIC);
671     GetMacros( rName, aStartMacro, aEndMacro, pGlos );
672 
673     // StartAction darf nich vor HasSelection und DelRight stehen,
674     // sonst wird der moeglich Shellwechsel verzoegert und
675     // API-Programme wuerden dann haengenbleiben
676     // ausserdem darf das Ereignismacro ebenfalls nicht in einer Action gerufen werden
677     if( aStartMacro.GetMacName().Len() )
678         pWrtShell->ExecMacro( aStartMacro );
679     if( pWrtShell->HasSelection() )
680         pWrtShell->DelRight();
681     pWrtShell->StartAllAction();
682 
683     // alle InputFelder zwischenspeichern
684     SwInputFieldList aFldLst( pWrtShell, sal_True );
685 
686     pWrtShell->InsertGlossary(*pGlos, rName);
687     pWrtShell->EndAllAction();
688     if( aEndMacro.GetMacName().Len() )
689     {
690         pWrtShell->ExecMacro( aEndMacro );
691     }
692 
693     // fuer alle neuen InputFelder die Eingaben abfordern
694     if( aFldLst.BuildSortLst() )
695         pWrtShell->UpdateInputFlds( &aFldLst );
696 
697     if(!pCurGrp)
698         rStatGlossaries.PutGroupDoc(pGlos);
699     return sal_True;
700 }
701 
702 /*------------------------------------------------------------------------
703  Beschreibung:  Macro setzen / erfragen
704 ------------------------------------------------------------------------*/
705 
706 
707 void SwGlossaryHdl::SetMacros(const String& rShortName,
708                               const SvxMacro* pStart,
709                               const SvxMacro* pEnd,
710                               SwTextBlocks *pGlossary )
711 {
712     SwTextBlocks *pGlos = pGlossary ? pGlossary :
713                                 pCurGrp ? pCurGrp
714                                   : rStatGlossaries.GetGroupDoc( aCurGrp );
715     SvxMacroTableDtor aMacroTbl;
716     if( pStart )
717         aMacroTbl.Insert( SW_EVENT_START_INS_GLOSSARY, new SvxMacro(*pStart));
718     if( pEnd )
719         aMacroTbl.Insert( SW_EVENT_END_INS_GLOSSARY, new SvxMacro(*pEnd));
720     sal_uInt16 nIdx = pGlos->GetIndex( rShortName );
721     if( !pGlos->SetMacroTable( nIdx, aMacroTbl ) && pGlos->GetError() )
722         ErrorHandler::HandleError( pGlos->GetError() );
723 
724     if(!pCurGrp && !pGlossary)
725         rStatGlossaries.PutGroupDoc(pGlos);
726 }
727 
728 void SwGlossaryHdl::GetMacros( const String &rShortName,
729                                 SvxMacro& rStart,
730                                 SvxMacro& rEnd,
731                                 SwTextBlocks *pGlossary  )
732 {
733     SwTextBlocks *pGlos = pGlossary ? pGlossary
734                                     : pCurGrp ? pCurGrp
735                                         : rStatGlossaries.GetGroupDoc(aCurGrp);
736     sal_uInt16 nIndex = pGlos->GetIndex( rShortName );
737     if( nIndex != USHRT_MAX )
738     {
739         SvxMacroTableDtor aMacroTbl;
740         if( pGlos->GetMacroTable( nIndex, aMacroTbl ) )
741         {
742             SvxMacro *pMacro = aMacroTbl.Get( SW_EVENT_START_INS_GLOSSARY );
743             if( pMacro )
744                 rStart = *pMacro;
745 
746             pMacro = aMacroTbl.Get( SW_EVENT_END_INS_GLOSSARY );
747             if( pMacro )
748                 rEnd = *pMacro;
749         }
750     }
751 
752     if( !pCurGrp && !pGlossary )
753         rStatGlossaries.PutGroupDoc( pGlos );
754 }
755 
756 
757 /*------------------------------------------------------------------------
758     Beschreibung:   ctor, dtor
759 ------------------------------------------------------------------------*/
760 
761 
762 SwGlossaryHdl::SwGlossaryHdl(SfxViewFrame* pVwFrm, SwWrtShell *pSh)
763     : rStatGlossaries( *::GetGlossaries() ),
764     aCurGrp( rStatGlossaries.GetDefName() ),
765     pViewFrame( pVwFrm ),
766     pWrtShell( pSh ),
767     pCurGrp( 0 )
768 {
769 }
770 
771 
772 SwGlossaryHdl::~SwGlossaryHdl()
773 {
774     if( pCurGrp )
775         rStatGlossaries.PutGroupDoc( pCurGrp );
776 }
777 
778 /*------------------------------------------------------------------------
779     Beschreibung:   Umbenennen eines Textbausteines
780 ------------------------------------------------------------------------*/
781 
782 
783 sal_Bool SwGlossaryHdl::Rename(const String& rOldShort, const String& rNewShortName,
784                            const String& rNewName )
785 {
786     sal_Bool bRet = sal_False;
787     SwTextBlocks *pGlossary = pCurGrp ? pCurGrp
788                                     : rStatGlossaries.GetGroupDoc(aCurGrp);
789     if(pGlossary)
790     {
791         if(!ConvertToNew(*pGlossary))
792             return sal_False;
793 
794         sal_uInt16 nIdx = pGlossary->GetIndex( rOldShort );
795         sal_uInt16 nOldLongIdx = pGlossary->GetLongIndex( rNewName );
796         sal_uInt16 nOldIdx = pGlossary->GetIndex( rNewShortName );
797 
798         if( nIdx != USHRT_MAX &&
799                 (nOldLongIdx == USHRT_MAX || nOldLongIdx == nIdx )&&
800                     (nOldIdx == USHRT_MAX || nOldIdx == nIdx ))
801         {
802             String aNewShort( rNewShortName );
803             String aNewName( rNewName );
804             pGlossary->Rename( nIdx, &aNewShort, &aNewName );
805             bRet = pGlossary->GetError() == 0;
806         }
807         if( !pCurGrp )
808             rStatGlossaries.PutGroupDoc(pGlossary);
809     }
810     return bRet;
811 }
812 
813 
814 sal_Bool SwGlossaryHdl::IsReadOnly( const String* pGrpNm ) const
815 {
816     SwTextBlocks *pGlossary = 0;
817 
818     if (pGrpNm)
819         pGlossary = rStatGlossaries.GetGroupDoc( *pGrpNm );
820     else if (pCurGrp)
821         pGlossary = pCurGrp;
822     else
823         pGlossary = rStatGlossaries.GetGroupDoc(aCurGrp);
824 
825     sal_Bool bRet = pGlossary ? pGlossary->IsReadOnly() : sal_True;
826     if( pGrpNm || !pCurGrp )
827         delete pGlossary;
828     return bRet;
829 }
830 
831 
832 sal_Bool SwGlossaryHdl::IsOld() const
833 {
834     SwTextBlocks *pGlossary = pCurGrp ? pCurGrp
835                                       : rStatGlossaries.GetGroupDoc(aCurGrp);
836     sal_Bool bRet = pGlossary ? pGlossary->IsOld() : sal_False;
837     if( !pCurGrp )
838         delete pGlossary;
839     return bRet;
840 }
841 
842 /*-----------------09.06.97 16:15-------------------
843     Gruppe ohne Pfadindex finden
844 --------------------------------------------------*/
845 sal_Bool SwGlossaryHdl::FindGroupName(String & rGroup)
846 {
847     return rStatGlossaries.FindGroupName(rGroup);
848 }
849 
850 /* -----------------29.07.99 08:34-------------------
851 
852  --------------------------------------------------*/
853 sal_Bool SwGlossaryHdl::CopyToClipboard(SwWrtShell& rSh, const String& rShortName)
854 {
855     SwTextBlocks *pGlossary = pCurGrp ? pCurGrp
856                                     : rStatGlossaries.GetGroupDoc(aCurGrp);
857 
858     SwTransferable* pTransfer = new SwTransferable( rSh );
859 /*??*/uno::Reference<
860         datatransfer::XTransferable > xRef( pTransfer );
861 
862     int nRet = pTransfer->CopyGlossary( *pGlossary, rShortName );
863     if( !pCurGrp )
864         rStatGlossaries.PutGroupDoc( pGlossary );
865     return 0 != nRet;
866 }
867 
868 sal_Bool SwGlossaryHdl::ImportGlossaries( const String& rName )
869 {
870     sal_Bool bRet = sal_False;
871     if( rName.Len() )
872     {
873         const SfxFilter* pFilter = 0;
874         SfxMedium* pMed = new SfxMedium( rName, STREAM_READ, sal_True, 0, 0 );
875         SfxFilterMatcher aMatcher( String::CreateFromAscii("swriter") );
876         pMed->UseInteractionHandler( sal_True );
877         if( !aMatcher.GuessFilter( *pMed, &pFilter, sal_False ) )
878         {
879             SwTextBlocks *pGlossary;
880             pMed->SetFilter( pFilter );
881             Reader* pR = SwReaderWriter::GetReader( pFilter->GetUserData() );
882             if( pR && 0 != ( pGlossary = pCurGrp ? pCurGrp
883                                     : rStatGlossaries.GetGroupDoc(aCurGrp)) )
884             {
885                 SwReader aReader( *pMed, rName );
886                 if( aReader.HasGlossaries( *pR ) )
887                 {
888                     const SvxAutoCorrCfg* pCfg = SvxAutoCorrCfg::Get();
889                     bRet = aReader.ReadGlossaries( *pR, *pGlossary,
890                                 pCfg->IsSaveRelFile() );
891                 }
892             }
893         }
894         DELETEZ(pMed);
895     }
896     return bRet;
897 }
898 
899