bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / ui / misc / glossary.cxx
blobe39d6bf926fdf378abc4c1211f35cf029836503b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <hintids.hxx>
22 #include <vcl/menu.hxx>
23 #include <vcl/msgbox.hxx>
24 #include <vcl/help.hxx>
25 #include <svl/stritem.hxx>
26 #include <unotools/pathoptions.hxx>
27 #include <unotools/lingucfg.hxx>
28 #include <sfx2/request.hxx>
29 #include <sfx2/fcontnr.hxx>
31 #include <svx/svxdlg.hxx>
32 #include <svx/dialogs.hrc>
33 #include <editeng/acorrcfg.hxx>
34 #include <sfx2/viewfrm.hxx>
35 #include <unocrsr.hxx>
36 #include <unotools.hxx>
37 #include <comphelper/processfactory.hxx>
38 #include <comphelper/string.hxx>
39 #include <ucbhelper/content.hxx>
40 #include <com/sun/star/text/AutoTextContainer.hpp>
41 #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
42 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
43 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
44 #include <svl/urihelper.hxx>
45 #include <unotools/charclass.hxx>
46 #include "svtools/treelistentry.hxx"
47 #include <swwait.hxx>
48 #include <swtypes.hxx>
49 #include <wrtsh.hxx>
50 #include <view.hxx>
51 #include <basesh.hxx>
52 #include <glossary.hxx>
53 #include <gloshdl.hxx>
54 #include <glosbib.hxx>
55 #include <initui.hxx> // for ::GetGlossaries()
56 #include <glosdoc.hxx>
57 #include <macassgn.hxx>
58 #include <swevent.hxx>
59 #include <docsh.hxx>
60 #include <shellio.hxx>
62 #include <cmdid.h>
63 #include <helpid.h>
64 #include <swerror.h>
65 #include <globals.hrc>
66 #include <misc.hrc>
67 #include <swmodule.hxx>
68 #include <sfx2/filedlghelper.hxx>
70 #include "access.hrc"
72 using namespace ::com::sun::star;
73 using namespace ::com::sun::star::lang;
74 using namespace ::com::sun::star::uno;
75 using namespace ::com::sun::star::text;
76 using namespace ::com::sun::star::ucb;
77 using namespace ::com::sun::star::ui::dialogs;
78 using namespace ::ucbhelper;
79 using namespace ::sfx2;
81 static String lcl_GetValidShortCut( const String& rName )
83 const sal_uInt16 nSz = rName.Len();
85 if ( 0 == nSz )
86 return rName;
88 sal_uInt16 nStart = 1;
89 while( rName.GetChar( nStart-1 ) == ' ' && nStart < nSz )
90 nStart++;
92 String aBuf = OUString(rName.GetChar(nStart-1));
94 for( ; nStart < nSz; ++nStart )
96 if( rName.GetChar( nStart-1 ) == ' ' && rName.GetChar( nStart ) != ' ')
97 aBuf += rName.GetChar( nStart );
99 return aBuf;
102 struct GroupUserData
104 String sGroupName;
105 sal_uInt16 nPathIdx;
106 bool bReadonly;
108 GroupUserData()
109 : nPathIdx(0),
110 bReadonly(false) {}
113 /*------------------------------------------------------------------------
114 Description: dialog for new block name
115 ------------------------------------------------------------------------*/
116 class SwNewGlosNameDlg : public ModalDialog
118 Edit* m_pNewName;
119 NoSpaceEdit* m_pNewShort;
120 OKButton* m_pOk;
121 Edit* m_pOldName;
122 Edit* m_pOldShort;
124 protected:
125 DECL_LINK( Modify, Edit * );
126 DECL_LINK(Rename, void *);
128 public:
129 SwNewGlosNameDlg( Window* pParent,
130 const String& rOldName,
131 const String& rOldShort );
133 String GetNewName() const { return m_pNewName->GetText(); }
134 String GetNewShort() const { return m_pNewShort->GetText(); }
137 SwNewGlosNameDlg::SwNewGlosNameDlg(Window* pParent,
138 const String& rOldName,
139 const String& rOldShort )
140 : ModalDialog(pParent, "RenameAutoTextDialog",
141 "modules/swriter/ui/renameautotextdialog.ui")
143 get(m_pNewName, "newname");
144 get(m_pNewShort, "newsc");
145 get(m_pOk, "ok");
146 get(m_pOldName, "oldname");
147 get(m_pOldShort, "oldsc");
149 m_pOldName->SetText( rOldName );
150 m_pOldShort->SetText( rOldShort );
151 m_pNewName->SetModifyHdl(LINK(this, SwNewGlosNameDlg, Modify ));
152 m_pNewShort->SetModifyHdl(LINK(this, SwNewGlosNameDlg, Modify ));
153 m_pOk->SetClickHdl(LINK(this, SwNewGlosNameDlg, Rename ));
154 m_pNewName->GrabFocus();
157 /*------------------------------------------------------------------------
158 Description: query / set currently set group
159 ------------------------------------------------------------------------*/
160 String SwGlossaryDlg::GetCurrGroup()
162 if( ::GetCurrGlosGroup() && ::GetCurrGlosGroup()->Len() )
163 return *(::GetCurrGlosGroup());
164 return SwGlossaries::GetDefName();
167 void SwGlossaryDlg::SetActGroup(const String &rGrp)
169 if( !::GetCurrGlosGroup() )
170 ::SetCurrGlosGroup( new String );
171 *(::GetCurrGlosGroup()) = rGrp;
174 SwGlossaryDlg::SwGlossaryDlg(SfxViewFrame* pViewFrame,
175 SwGlossaryHdl * pGlosHdl, SwWrtShell *pWrtShell)
176 : SvxStandardDialog(&pViewFrame->GetWindow(), "AutoTextDialog",
177 "modules/swriter/ui/autotext.ui")
178 , sReadonlyPath(SW_RESSTR(STR_READONLY_PATH))
179 , pExampleFrame(0)
180 , pGlossaryHdl(pGlosHdl)
181 , bResume(false)
182 , bSelection(pWrtShell->IsSelection())
183 , bReadOnly(false)
184 , bIsOld(false)
185 , bIsDocReadOnly(false)
186 , pSh(pWrtShell)
188 get(m_pInsertTipCB, "inserttip");
189 get(m_pNameED, "name");
190 get(m_pShortNameLbl, "shortnameft");
191 get(m_pShortNameEdit, "shortname");
192 get(m_pCategoryBox, "category");
193 get(m_pFileRelCB, "relfile");
194 get(m_pNetRelCB, "relnet");
195 get(m_pInsertBtn, "insert");
196 get(m_pBibBtn, "categories");
197 get(m_pPathBtn, "path");
198 get(m_pExampleWIN, "example");
199 get(m_pEditBtn, "autotext");
201 SvtLinguConfig aLocalLinguConfig;
203 // initialise static-pointer
204 if( !::GetCurrGlosGroup() )
205 ::SetCurrGlosGroup(new String);
207 PopupMenu *pMenu = m_pEditBtn->GetPopupMenu();
208 assert(pMenu);
209 pMenu->SetActivateHdl(LINK(this,SwGlossaryDlg,EnableHdl));
210 pMenu->SetSelectHdl(LINK(this,SwGlossaryDlg,MenuHdl));
211 m_pEditBtn->SetSelectHdl(LINK(this,SwGlossaryDlg,EditHdl));
212 m_pPathBtn->SetClickHdl(LINK(this, SwGlossaryDlg, PathHdl));
214 m_pNameED->SetModifyHdl(LINK(this,SwGlossaryDlg,NameModify));
215 m_pShortNameEdit->SetModifyHdl(LINK(this,SwGlossaryDlg,NameModify));
217 m_pCategoryBox->SetDoubleClickHdl(LINK(this,SwGlossaryDlg, NameDoubleClick));
218 m_pCategoryBox->SetSelectHdl(LINK(this,SwGlossaryDlg,GrpSelect));
219 m_pBibBtn->SetClickHdl(LINK(this,SwGlossaryDlg,BibHdl));
221 m_pInsertBtn->SetClickHdl(LINK(this,SwGlossaryDlg,InsertHdl));
223 ShowPreview();
225 bIsDocReadOnly = pSh->GetView().GetDocShell()->IsReadOnly() ||
226 pSh->HasReadonlySel();
227 if( bIsDocReadOnly )
228 m_pInsertBtn->Enable(sal_False);
229 m_pNameED->GrabFocus();
230 m_pCategoryBox->SetStyle(m_pCategoryBox->GetStyle()|WB_HASBUTTONS|WB_HASBUTTONSATROOT|WB_HSCROLL|WB_VSCROLL|WB_CLIPCHILDREN|WB_SORT);
231 m_pCategoryBox->GetModel()->SetSortMode(SortAscending);
232 m_pCategoryBox->SetHighlightRange(); // select over full width
233 m_pCategoryBox->SetNodeDefaultImages( );
235 Init();
238 SwGlossaryDlg::~SwGlossaryDlg()
240 m_pCategoryBox->Clear();
241 delete pExampleFrame;
244 /*------------------------------------------------------------------------
245 Description: select new group
246 ------------------------------------------------------------------------*/
247 IMPL_LINK( SwGlossaryDlg, GrpSelect, SvTreeListBox *, pBox )
249 SvTreeListEntry* pEntry = pBox->FirstSelected();
250 if(!pEntry)
251 return 0;
252 SvTreeListEntry* pParent = pBox->GetParent(pEntry) ? pBox->GetParent(pEntry) : pEntry;
253 GroupUserData* pGroupData = (GroupUserData*)pParent->GetUserData();
254 String *pGlosGroup = ::GetCurrGlosGroup();
255 (*pGlosGroup) = pGroupData->sGroupName;
256 (*pGlosGroup) += GLOS_DELIM;
257 (*pGlosGroup) += OUString::number(pGroupData->nPathIdx);
258 pGlossaryHdl->SetCurGroup(*pGlosGroup);
259 // set current text block
260 bReadOnly = pGlossaryHdl->IsReadOnly();
261 EnableShortName( !bReadOnly );
262 m_pEditBtn->Enable(!bReadOnly);
263 bIsOld = pGlossaryHdl->IsOld();
264 if( pParent != pEntry)
266 OUString aName(pBox->GetEntryText(pEntry));
267 m_pNameED->SetText(aName);
268 m_pShortNameEdit->SetText(*(String*)pEntry->GetUserData());
269 pEntry = pBox->GetParent(pEntry);
270 m_pInsertBtn->Enable( !bIsDocReadOnly);
271 ShowAutoText(*::GetCurrGlosGroup(), m_pShortNameEdit->GetText());
273 else
274 ShowAutoText(aEmptyStr, aEmptyStr);
275 // update controls
276 NameModify(m_pShortNameEdit);
277 if( SfxRequest::HasMacroRecorder( pSh->GetView().GetViewFrame() ) )
279 SfxRequest aReq( pSh->GetView().GetViewFrame(), FN_SET_ACT_GLOSSARY );
280 String sTemp(*::GetCurrGlosGroup());
281 // the zeroth path is not being recorded!
282 if('0' == sTemp.GetToken(1, GLOS_DELIM).GetChar(0))
283 sTemp = sTemp.GetToken(0, GLOS_DELIM);
284 aReq.AppendItem(SfxStringItem(FN_SET_ACT_GLOSSARY, sTemp));
285 aReq.Done();
287 return 0;
290 void SwGlossaryDlg::Apply()
292 const String aGlosName(m_pShortNameEdit->GetText());
293 if(aGlosName.Len()) pGlossaryHdl->InsertGlossary(aGlosName);
294 if( SfxRequest::HasMacroRecorder( pSh->GetView().GetViewFrame() ) )
296 SfxRequest aReq( pSh->GetView().GetViewFrame(), FN_INSERT_GLOSSARY );
297 String sTemp(*::GetCurrGlosGroup());
298 // the zeroth path is not being recorded!
299 if('0' == sTemp.GetToken(1, GLOS_DELIM).GetChar(0))
300 sTemp = sTemp.GetToken(0, GLOS_DELIM);
301 aReq.AppendItem(SfxStringItem(FN_INSERT_GLOSSARY, sTemp));
302 aReq.AppendItem(SfxStringItem(FN_PARAM_1, aGlosName));
303 aReq.Done();
307 void SwGlossaryDlg::EnableShortName(sal_Bool bOn)
309 m_pShortNameLbl->Enable(bOn);
310 m_pShortNameEdit->Enable(bOn);
313 /* --------------------------------------------------
314 * does the title exist in the selected group?
315 * --------------------------------------------------*/
316 SvTreeListEntry* SwGlossaryDlg::DoesBlockExist(const String& rBlock,
317 const String& rShort)
319 // look for possible entry in TreeListBox
320 SvTreeListEntry* pEntry = m_pCategoryBox->FirstSelected();
321 if(pEntry)
323 if(m_pCategoryBox->GetParent(pEntry))
324 pEntry = m_pCategoryBox->GetParent(pEntry);
325 sal_uInt32 nChildCount = m_pCategoryBox->GetChildCount( pEntry );
326 for(sal_uInt32 i = 0; i < nChildCount; i++)
328 SvTreeListEntry* pChild = m_pCategoryBox->GetEntry( pEntry, i );
329 if(rBlock == m_pCategoryBox->GetEntryText(pChild) &&
330 (!rShort.Len() || rShort == *(String*)pChild->GetUserData()))
332 return pChild;
336 return 0;
339 IMPL_LINK( SwGlossaryDlg, NameModify, Edit *, pEdit )
341 String aName(m_pNameED->GetText());
342 bool bNameED = pEdit == m_pNameED;
343 if( !aName.Len() )
345 if(bNameED)
346 m_pShortNameEdit->SetText(aName);
347 m_pInsertBtn->Enable(sal_False);
348 return 0;
350 String sShortSearch;
351 if(!bNameED)
352 sShortSearch = pEdit->GetText();
353 bool bNotFound = !DoesBlockExist(aName, sShortSearch);
354 if(bNameED)
356 // did the text get in to the Listbbox in the Edit with a click?
357 if(bNotFound)
359 m_pShortNameEdit->SetText( lcl_GetValidShortCut( aName ) );
360 EnableShortName();
362 else
364 m_pShortNameEdit->SetText(pGlossaryHdl->GetGlossaryShortName(aName));
365 EnableShortName(!bReadOnly);
367 m_pInsertBtn->Enable(!bNotFound && !bIsDocReadOnly);
369 else
371 //ShortNameEdit
372 if(!bNotFound)
374 sal_Bool bEnable = !bNotFound;
375 bEnable &= !bIsDocReadOnly;
376 m_pInsertBtn->Enable(bEnable);
379 return 0;
382 IMPL_LINK_INLINE_START( SwGlossaryDlg, NameDoubleClick, SvTreeListBox*, pBox )
384 SvTreeListEntry* pEntry = pBox->FirstSelected();
385 if(pBox->GetParent(pEntry) && !bIsDocReadOnly)
386 EndDialog( RET_OK );
387 return 0;
389 IMPL_LINK_INLINE_END( SwGlossaryDlg, NameDoubleClick, SvTreeListBox*, pBox )
391 IMPL_LINK( SwGlossaryDlg, EnableHdl, Menu *, pMn )
393 SvTreeListEntry* pEntry = m_pCategoryBox->FirstSelected();
395 const String aEditText(m_pNameED->GetText());
396 const bool bHasEntry = aEditText.Len() && !m_pShortNameEdit->GetText().isEmpty();
397 const bool bExists = 0 != DoesBlockExist(aEditText, m_pShortNameEdit->GetText());
398 const bool bIsGroup = pEntry && !m_pCategoryBox->GetParent(pEntry);
399 pMn->EnableItem("new", bSelection && bHasEntry && !bExists);
400 pMn->EnableItem("newtext", bSelection && bHasEntry && !bExists);
401 pMn->EnableItem("copy", bExists && !bIsGroup);
402 pMn->EnableItem("replace", bSelection && bExists && !bIsGroup && !bIsOld );
403 pMn->EnableItem("replacetext", bSelection && bExists && !bIsGroup && !bIsOld );
404 pMn->EnableItem("edit", bExists && !bIsGroup );
405 pMn->EnableItem("rename", bExists && !bIsGroup );
406 pMn->EnableItem("delete", bExists && !bIsGroup );
407 pMn->EnableItem("macro", bExists && !bIsGroup && !bIsOld &&
408 !pGlossaryHdl->IsReadOnly() );
409 pMn->EnableItem("import", bIsGroup && !bIsOld && !pGlossaryHdl->IsReadOnly() );
410 return 1;
413 IMPL_LINK( SwGlossaryDlg, MenuHdl, Menu *, pMn )
415 OString sItemIdent(pMn->GetCurItemIdent());
417 if (sItemIdent == "replace")
419 pGlossaryHdl->NewGlossary(m_pNameED->GetText(),
420 m_pShortNameEdit->GetText(),
421 false, false);
423 else if (sItemIdent == "replacetext")
425 pGlossaryHdl->NewGlossary(m_pNameED->GetText(),
426 m_pShortNameEdit->GetText(),
427 false, true);
429 else if (sItemIdent == "new" || sItemIdent == "newtext")
431 bool bNoAttr = sItemIdent == "newtext";
433 const String aStr(m_pNameED->GetText());
434 const String aShortName(m_pShortNameEdit->GetText());
435 if(pGlossaryHdl->HasShortName(aShortName))
437 InfoBox(this, SW_RES(MSG_DOUBLE_SHORTNAME)).Execute();
438 m_pShortNameEdit->SetSelection(Selection(0, SELECTION_MAX));
439 m_pShortNameEdit->GrabFocus();
440 return 1;
442 if(pGlossaryHdl->NewGlossary(aStr, aShortName, sal_False, bNoAttr ))
444 SvTreeListEntry* pEntry = m_pCategoryBox->FirstSelected();
445 if(m_pCategoryBox->GetParent(pEntry))
446 pEntry = m_pCategoryBox->GetParent(pEntry);
448 SvTreeListEntry* pChild = m_pCategoryBox->InsertEntry(aStr, pEntry);
449 pChild->SetUserData(new String(aShortName));
450 m_pNameED->SetText(aStr);
451 m_pShortNameEdit->SetText(aShortName);
452 NameModify(m_pNameED); // for toggling the buttons
454 if( SfxRequest::HasMacroRecorder( pSh->GetView().GetViewFrame() ) )
456 SfxRequest aReq(pSh->GetView().GetViewFrame(), FN_NEW_GLOSSARY);
457 String sTemp(*::GetCurrGlosGroup());
458 // the zeroth path is not being recorded!
459 if('0' == sTemp.GetToken(1, GLOS_DELIM).GetChar(0))
460 sTemp = sTemp.GetToken(0, GLOS_DELIM);
461 aReq.AppendItem(SfxStringItem(FN_NEW_GLOSSARY, sTemp));
462 aReq.AppendItem(SfxStringItem(FN_PARAM_1, aShortName));
463 aReq.AppendItem(SfxStringItem(FN_PARAM_2, aStr));
464 aReq.Done();
468 else if (sItemIdent == "copy")
470 pGlossaryHdl->CopyToClipboard(*pSh, m_pShortNameEdit->GetText());
472 else if (sItemIdent == "rename")
474 m_pShortNameEdit->SetText(pGlossaryHdl->GetGlossaryShortName(m_pNameED->GetText()));
475 SwNewGlosNameDlg* pNewNameDlg = new SwNewGlosNameDlg(this, m_pNameED->GetText(),
476 m_pShortNameEdit->GetText() );
477 if( RET_OK == pNewNameDlg->Execute() &&
478 pGlossaryHdl->Rename( m_pShortNameEdit->GetText(),
479 pNewNameDlg->GetNewShort(),
480 pNewNameDlg->GetNewName()))
482 SvTreeListEntry* pEntry = m_pCategoryBox->FirstSelected();
483 SvTreeListEntry* pNewEntry = m_pCategoryBox->InsertEntry(
484 pNewNameDlg->GetNewName(), m_pCategoryBox->GetParent(pEntry));
485 pNewEntry->SetUserData(new String(pNewNameDlg->GetNewShort()));
486 delete (String*)pEntry->GetUserData();
487 m_pCategoryBox->GetModel()->Remove(pEntry);
488 m_pCategoryBox->Select(pNewEntry);
489 m_pCategoryBox->MakeVisible(pNewEntry);
491 GrpSelect(m_pCategoryBox);
492 delete pNewNameDlg;
494 else if (sItemIdent == "delete")
496 QueryBox aQuery(this, SW_RES(MSG_QUERY_DELETE));
497 if(RET_YES == aQuery.Execute())
499 const String aShortName(m_pShortNameEdit->GetText());
500 const String aTitle(m_pNameED->GetText());
501 if(aTitle.Len() && pGlossaryHdl->DelGlossary(aShortName))
503 SvTreeListEntry* pChild = DoesBlockExist(aTitle, aShortName);
504 OSL_ENSURE(pChild, "entry not found!");
505 SvTreeListEntry* pParent = m_pCategoryBox->GetParent(pChild);
506 m_pCategoryBox->Select(pParent);
508 m_pCategoryBox->GetModel()->Remove(pChild);
509 m_pNameED->SetText(OUString());
510 NameModify(m_pNameED);
514 else if (sItemIdent == "macro")
516 SfxItemSet aSet( pSh->GetAttrPool(), RES_FRMMACRO, RES_FRMMACRO, SID_EVENTCONFIG, SID_EVENTCONFIG, 0 );
518 SvxMacro aStart(aEmptyStr, aEmptyStr, STARBASIC);
519 SvxMacro aEnd(aEmptyStr, aEmptyStr, STARBASIC);
520 pGlossaryHdl->GetMacros(m_pShortNameEdit->GetText(), aStart, aEnd );
522 SvxMacroItem aItem(RES_FRMMACRO);
523 if( aStart.HasMacro() )
524 aItem.SetMacro( SW_EVENT_START_INS_GLOSSARY, aStart );
525 if( aEnd.HasMacro() )
526 aItem.SetMacro( SW_EVENT_END_INS_GLOSSARY, aEnd );
528 aSet.Put( aItem );
529 aSet.Put( SwMacroAssignDlg::AddEvents( MACASSGN_AUTOTEXT ) );
531 const SfxPoolItem* pItem;
532 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
533 SfxAbstractDialog* pMacroDlg = pFact->CreateSfxDialog( this, aSet,
534 pSh->GetView().GetViewFrame()->GetFrame().GetFrameInterface(), SID_EVENTCONFIG );
535 if ( pMacroDlg && pMacroDlg->Execute() == RET_OK &&
536 SFX_ITEM_SET == pMacroDlg->GetOutputItemSet()->GetItemState( RES_FRMMACRO, sal_False, &pItem ) )
538 const SvxMacroTableDtor& rTbl = ((SvxMacroItem*)pItem)->GetMacroTable();
539 pGlossaryHdl->SetMacros( m_pShortNameEdit->GetText(),
540 rTbl.Get( SW_EVENT_START_INS_GLOSSARY ),
541 rTbl.Get( SW_EVENT_END_INS_GLOSSARY ) );
544 delete pMacroDlg;
546 else if (sItemIdent == "import")
548 // call the FileOpenDialog do find WinWord - Files with templates
549 FileDialogHelper aDlgHelper( TemplateDescription::FILEOPEN_SIMPLE, 0 );
550 uno::Reference < XFilePicker > xFP = aDlgHelper.GetFilePicker();
552 SvtPathOptions aPathOpt;
553 xFP->setDisplayDirectory(aPathOpt.GetWorkPath() );
555 uno::Reference<XFilterManager> xFltMgr(xFP, UNO_QUERY);
556 SfxFilterMatcher aMatcher( OUString::createFromAscii(SwDocShell::Factory().GetShortName()) );
557 SfxFilterMatcherIter aIter( aMatcher );
558 const SfxFilter* pFilter = aIter.First();
559 while ( pFilter )
561 if( pFilter->GetUserData() == FILTER_WW8 )
563 xFltMgr->appendFilter( pFilter->GetUIName(),
564 pFilter->GetWildcard().getGlob() );
565 xFltMgr->setCurrentFilter( pFilter->GetUIName() ) ;
568 pFilter = aIter.Next();
571 if( aDlgHelper.Execute() == ERRCODE_NONE )
573 if( pGlossaryHdl->ImportGlossaries( xFP->getFiles().getConstArray()[0] ))
574 Init();
575 else
577 InfoBox(this, SW_RES( MSG_NO_GLOSSARIES )).Execute();
581 else
583 return 0;
585 return 1;
588 /*--------------------------------------------------------------------
589 Description: dialog manage regions
590 --------------------------------------------------------------------*/
591 IMPL_LINK_NOARG(SwGlossaryDlg, BibHdl)
593 SwGlossaries* pGloss = ::GetGlossaries();
594 if( pGloss->IsGlosPathErr() )
595 pGloss->ShowError();
596 else
598 //check if at least one glossary path is write enabled
599 SvtPathOptions aPathOpt;
600 String sGlosPath( aPathOpt.GetAutoTextPath() );
601 sal_uInt16 nPaths = comphelper::string::getTokenCount(sGlosPath, ';');
602 bool bIsWritable = false;
603 for(sal_uInt16 nPath = 0; nPath < nPaths; nPath++)
605 String sPath = URIHelper::SmartRel2Abs(
606 INetURLObject(), sGlosPath.GetToken(nPath, ';'),
607 URIHelper::GetMaybeFileHdl());
610 Content aTestContent( sPath,
611 uno::Reference< XCommandEnvironment >(),
612 comphelper::getProcessComponentContext() );
613 Any aAny = aTestContent.getPropertyValue( "IsReadOnly" );
614 if(aAny.hasValue())
616 bIsWritable = !*(sal_Bool*)aAny.getValue();
619 catch (const Exception&)
622 if(bIsWritable)
623 break;
625 if(bIsWritable)
628 SwGlossaryGroupDlg *pDlg = new SwGlossaryGroupDlg( this, pGloss->GetPathArray(), pGlossaryHdl );
629 if ( RET_OK == pDlg->Execute() )
631 Init();
632 //if new groups were created - select one of them
633 String sNewGroup = pDlg->GetCreatedGroupName();
634 SvTreeListEntry* pEntry = m_pCategoryBox->First();
635 while(sNewGroup.Len() && pEntry)
637 if(!m_pCategoryBox->GetParent(pEntry))
639 GroupUserData* pGroupData = (GroupUserData*)pEntry->GetUserData();
640 String sGroup = pGroupData->sGroupName;
641 sGroup += GLOS_DELIM;
642 sGroup += OUString::number(pGroupData->nPathIdx);
643 if(sGroup == sNewGroup)
645 m_pCategoryBox->Select(pEntry);
646 m_pCategoryBox->MakeVisible(pEntry);
647 GrpSelect(m_pCategoryBox);
648 break;
651 pEntry = m_pCategoryBox->Next(pEntry);
655 delete pDlg;
657 else
659 QueryBox aBox(this, WB_YES_NO, sReadonlyPath);
660 if(RET_YES == aBox.Execute())
661 PathHdl(m_pPathBtn);
664 return 0;
667 /*------------------------------------------------------------------------
668 Description: initialisation; from Ctor and after editing regions
669 ------------------------------------------------------------------------*/
670 void SwGlossaryDlg::Init()
672 m_pCategoryBox->SetUpdateMode( sal_False );
673 m_pCategoryBox->Clear();
674 // display text block regions
675 const sal_uInt16 nCnt = pGlossaryHdl->GetGroupCnt();
676 SvTreeListEntry* pSelEntry = 0;
677 const String sSelStr(::GetCurrGlosGroup()->GetToken(0, GLOS_DELIM));
678 const sal_uInt16 nSelPath = static_cast< sal_uInt16 >(::GetCurrGlosGroup()->GetToken(1, GLOS_DELIM).ToInt32());
679 // #i66304# - "My AutoText" comes from mytexts.bau, but should be translated
680 const String sMyAutoTextEnglish(RTL_CONSTASCII_USTRINGPARAM("My AutoText"));
681 const String sMyAutoTextTranslated(SW_RESSTR(STR_MY_AUTOTEXT));
682 for(sal_uInt16 nId = 0; nId < nCnt; ++nId )
684 String sTitle;
685 String sGroupName(pGlossaryHdl->GetGroupName(nId, &sTitle));
686 if(!sGroupName.Len())
687 continue;
688 if(!sTitle.Len())
689 sTitle = sGroupName.GetToken( 0, GLOS_DELIM );
690 if(sTitle == sMyAutoTextEnglish)
691 sTitle = sMyAutoTextTranslated;
692 SvTreeListEntry* pEntry = m_pCategoryBox->InsertEntry( sTitle );
693 sal_uInt16 nPath = static_cast< sal_uInt16 >(sGroupName.GetToken( 1, GLOS_DELIM ).ToInt32());
695 GroupUserData* pData = new GroupUserData;
696 pData->sGroupName = sGroupName.GetToken(0, GLOS_DELIM);
697 pData->nPathIdx = nPath;
698 pData->bReadonly = pGlossaryHdl->IsReadOnly(&sGroupName);
700 pEntry->SetUserData(pData);
701 if(sSelStr == pData->sGroupName && nSelPath == nPath)
702 pSelEntry = pEntry;
704 // fill entries for the groups
706 pGlossaryHdl->SetCurGroup(sGroupName, sal_False, sal_True);
707 const sal_uInt16 nCount = pGlossaryHdl->GetGlossaryCnt();
708 for(sal_uInt16 i = 0; i < nCount; ++i)
710 String sGroupTitle(pGlossaryHdl->GetGlossaryName(i));
711 SvTreeListEntry* pChild = m_pCategoryBox->InsertEntry(
712 sGroupTitle, pEntry);
713 pChild->SetUserData(new String(pGlossaryHdl->GetGlossaryShortName(i)));
717 // set current group and display text blocks
718 if(!pSelEntry)
720 //find a non-readonly group
721 SvTreeListEntry* pSearch = m_pCategoryBox->First();
722 while(pSearch)
724 if(!m_pCategoryBox->GetParent(pSearch))
726 GroupUserData* pData = (GroupUserData*)pSearch->GetUserData();
727 if(!pData->bReadonly)
729 pSelEntry = pSearch;
730 break;
733 pSearch = m_pCategoryBox->Next(pSearch);
735 if(!pSelEntry)
736 pSelEntry = m_pCategoryBox->GetEntry(0);
738 if(pSelEntry)
740 m_pCategoryBox->Expand(pSelEntry);
741 m_pCategoryBox->Select(pSelEntry);
742 m_pCategoryBox->MakeVisible(pSelEntry);
743 GrpSelect(m_pCategoryBox);
745 //JP 16.11.99: the SvxTreeListBox has a Bug. The Box dont recalc the
746 // outputsize, when all entries are insertet. The result is, that
747 // the Focus/Highlight rectangle is to large and paintet over the
748 // HScrollbar. -> Fix: call the resize
749 m_pCategoryBox->Resize();
751 m_pCategoryBox->GetModel()->Resort();
752 m_pCategoryBox->SetUpdateMode( sal_True );
753 m_pCategoryBox->Update();
755 const SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
756 m_pFileRelCB->Check( rCfg.IsSaveRelFile() );
757 m_pFileRelCB->SetClickHdl(LINK(this, SwGlossaryDlg, CheckBoxHdl));
758 m_pNetRelCB->Check( rCfg.IsSaveRelNet() );
759 m_pNetRelCB->SetClickHdl(LINK(this, SwGlossaryDlg, CheckBoxHdl));
760 m_pInsertTipCB->Check( rCfg.IsAutoTextTip() );
761 m_pInsertTipCB->SetClickHdl(LINK(this, SwGlossaryDlg, CheckBoxHdl));
764 IMPL_LINK_NOARG_INLINE_START(SwGlossaryDlg, EditHdl)
766 // EndDialog must not be called in MenuHdl
767 if (m_pEditBtn->GetCurItemIdent() == "edit")
769 SwTextBlocks *pGroup = ::GetGlossaries()->GetGroupDoc ( GetCurrGrpName () );
770 sal_Bool bRet = pGlossaryHdl->ConvertToNew ( *pGroup );
771 delete pGroup;
772 if ( bRet )
773 EndDialog(RET_EDIT);
775 return 0;
777 IMPL_LINK_NOARG_INLINE_END(SwGlossaryDlg, EditHdl)
779 /*------------------------------------------------------------------------
780 Description: KeyInput for ShortName - Edits without Spaces
781 ------------------------------------------------------------------------*/
782 IMPL_LINK( SwNewGlosNameDlg, Modify, Edit *, pBox )
784 OUString aName(m_pNewName->GetText());
785 SwGlossaryDlg* pDlg = (SwGlossaryDlg*)GetParent();
787 if (pBox == m_pNewName)
788 m_pNewShort->SetText( lcl_GetValidShortCut( aName ) );
790 sal_Bool bEnable = !aName.isEmpty() && !m_pNewShort->GetText().isEmpty() &&
791 (!pDlg->DoesBlockExist(aName, m_pNewShort->GetText())
792 || aName == m_pOldName->GetText());
793 m_pOk->Enable(bEnable);
794 return 0;
797 IMPL_LINK_NOARG(SwNewGlosNameDlg, Rename)
799 SwGlossaryDlg* pDlg = (SwGlossaryDlg*)GetParent();
800 OUString sNew = GetAppCharClass().uppercase(m_pNewShort->GetText());
801 if( pDlg->pGlossaryHdl->HasShortName(m_pNewShort->GetText())
802 && sNew != m_pOldShort->GetText() )
804 InfoBox(this, SW_RES(MSG_DOUBLE_SHORTNAME)).Execute();
805 m_pNewShort->GrabFocus();
807 else
808 EndDialog(sal_True);
809 return 0;
812 IMPL_LINK( SwGlossaryDlg, CheckBoxHdl, CheckBox *, pBox )
814 SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
815 bool bCheck = pBox->IsChecked();
816 if (pBox == m_pInsertTipCB)
817 rCfg.SetAutoTextTip(bCheck);
818 else if(pBox == m_pFileRelCB)
819 rCfg.SetSaveRelFile(bCheck);
820 else
821 rCfg.SetSaveRelNet(bCheck);
822 return 0;
825 /* --------------------------------------------------
826 * TreeListBox for groups and blocks
827 * --------------------------------------------------*/
828 SwGlTreeListBox::SwGlTreeListBox(Window* pParent, WinBits nBits)
829 : SvTreeListBox(pParent, nBits)
830 , sReadonly(SW_RESSTR(SW_STR_READONLY)),
831 pDragEntry(0)
833 SetDragDropMode( SV_DRAGDROP_CTRL_MOVE|SV_DRAGDROP_CTRL_COPY );
836 Size SwGlTreeListBox::GetOptimalSize() const
838 return LogicToPixel(Size(212, 84), MapMode(MAP_APPFONT));
841 extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeSwGlTreeListBox(Window *pParent, VclBuilder::stringmap &)
843 return new SwGlTreeListBox(pParent, WB_BORDER | WB_TABSTOP);
846 void SwGlTreeListBox::Clear()
848 SvTreeListEntry* pEntry = First();
849 while(pEntry)
851 if(GetParent(pEntry))
852 delete (String*)pEntry->GetUserData();
853 else
854 delete (GroupUserData*)pEntry->GetUserData();
855 pEntry = Next(pEntry);
857 SvTreeListBox::Clear();
860 void SwGlTreeListBox::RequestHelp( const HelpEvent& rHEvt )
862 Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ));
863 SvTreeListEntry* pEntry = GetEntry( aPos );
864 // there's only help for groups' names
865 if(pEntry)
867 SvLBoxTab* pTab;
868 SvLBoxItem* pItem = GetItem( pEntry, aPos.X(), &pTab );
869 if(pItem)
871 aPos = GetEntryPosition( pEntry );
872 Size aSize(pItem->GetSize( this, pEntry ));
873 aPos.X() = GetTabPos( pEntry, pTab );
875 if((aPos.X() + aSize.Width()) > GetSizePixel().Width())
876 aSize.Width() = GetSizePixel().Width() - aPos.X();
877 aPos = OutputToScreenPixel(aPos);
878 Rectangle aItemRect( aPos, aSize );
879 String sMsg;
880 if(!GetParent(pEntry))
882 GroupUserData* pData = (GroupUserData*)pEntry->GetUserData();
883 const std::vector<String> & rPathArr = ::GetGlossaries()->GetPathArray();
884 if( !rPathArr.empty() )
886 sMsg = rPathArr[pData->nPathIdx];
887 sMsg += INET_PATH_TOKEN;
888 sMsg += pData->sGroupName;
889 sMsg += SwGlossaries::GetExtension();
890 INetURLObject aTmp(sMsg);
891 sMsg = aTmp.GetPath();
893 if(pData->bReadonly)
895 sMsg += ' ';
896 sMsg += '(';
897 sMsg += sReadonly;
898 sMsg += ')';
904 else
905 sMsg = *(String*)pEntry->GetUserData();
906 Help::ShowQuickHelp( this, aItemRect, sMsg,
907 QUICKHELP_LEFT|QUICKHELP_VCENTER );
912 DragDropMode SwGlTreeListBox::NotifyStartDrag(
913 TransferDataContainer& /*rContainer*/,
914 SvTreeListEntry* pEntry )
916 DragDropMode eRet;
917 pDragEntry = pEntry;
918 if(!GetParent(pEntry))
919 eRet = SV_DRAGDROP_NONE;
920 else
922 SwGlossaryDlg* pDlg = (SwGlossaryDlg*)GetParentDialog();
923 SvTreeListEntry* pParent = GetParent(pEntry);
925 GroupUserData* pGroupData = (GroupUserData*)pParent->GetUserData();
926 String sEntry(pGroupData->sGroupName);
927 sEntry += GLOS_DELIM;
928 sEntry += OUString::number(pGroupData->nPathIdx);
929 sal_Int8 nDragOption = DND_ACTION_COPY;
930 eRet = SV_DRAGDROP_CTRL_COPY;
931 if(!pDlg->pGlossaryHdl->IsReadOnly(&sEntry))
933 eRet |= SV_DRAGDROP_CTRL_MOVE;
934 nDragOption |= DND_ACTION_MOVE;
936 SetDragOptions( nDragOption );
938 return eRet;
941 sal_Bool SwGlTreeListBox::NotifyAcceptDrop( SvTreeListEntry* pEntry)
943 // TODO: Readonly - check still missing!
944 SvTreeListEntry* pSrcParent = GetParent(pEntry) ? GetParent(pEntry) : pEntry;
945 SvTreeListEntry* pDestParent =
946 GetParent(pDragEntry ) ? GetParent(pDragEntry ) : pDragEntry ;
947 return pDestParent != pSrcParent;
951 sal_Bool SwGlTreeListBox::NotifyMoving( SvTreeListEntry* pTarget,
952 SvTreeListEntry* pEntry,
953 SvTreeListEntry*& /*rpNewParent*/,
954 sal_uLong& /*rNewChildPos*/
957 pDragEntry = 0;
958 if(!pTarget) // move to the beginning
960 pTarget = GetEntry(0);
962 // 1. move to different groups?
963 // 2. allowed to write in both groups?
964 SvTreeListEntry* pSrcParent = GetParent(pEntry);
965 SvTreeListEntry* pDestParent =
966 GetParent(pTarget) ? GetParent(pTarget) : pTarget;
967 sal_Bool bRet = sal_False;
968 if(pDestParent != pSrcParent)
970 SwGlossaryDlg* pDlg = (SwGlossaryDlg*)GetParentDialog();
971 SwWait aWait( *pDlg->pSh->GetView().GetDocShell(), sal_True );
973 GroupUserData* pGroupData = (GroupUserData*)pSrcParent->GetUserData();
974 String sSourceGroup(pGroupData->sGroupName);
975 sSourceGroup += GLOS_DELIM;
976 sSourceGroup += OUString::number(pGroupData->nPathIdx);
977 pDlg->pGlossaryHdl->SetCurGroup(sSourceGroup);
978 String sTitle(GetEntryText(pEntry));
979 String sShortName(*(String*)pEntry->GetUserData());
981 GroupUserData* pDestData = (GroupUserData*)pDestParent->GetUserData();
982 String sDestName = pDestData->sGroupName;
983 sDestName += GLOS_DELIM;
984 sDestName += OUString::number(pDestData->nPathIdx);
985 bRet = pDlg->pGlossaryHdl->CopyOrMove( sSourceGroup, sShortName,
986 sDestName, sTitle, sal_True );
987 if(bRet)
989 SvTreeListEntry* pChild = InsertEntry(sTitle, pDestParent);
990 pChild->SetUserData(new String(sShortName));
991 GetModel()->Remove(pEntry);
994 return sal_False; // otherwise the entry is being set automatically
997 sal_Bool SwGlTreeListBox::NotifyCopying( SvTreeListEntry* pTarget,
998 SvTreeListEntry* pEntry,
999 SvTreeListEntry*& /*rpNewParent*/,
1000 sal_uLong& /*rNewChildPos*/
1003 pDragEntry = 0;
1004 // 1. move in different groups?
1005 // 2. allowed to write to both groups?
1006 if(!pTarget) // move to the beginning
1008 pTarget = GetEntry(0);
1010 SvTreeListEntry* pSrcParent = GetParent(pEntry);
1011 SvTreeListEntry* pDestParent =
1012 GetParent(pTarget) ? GetParent(pTarget) : pTarget;
1013 sal_Bool bRet = sal_False;
1014 if(pDestParent != pSrcParent)
1016 SwGlossaryDlg* pDlg = (SwGlossaryDlg*)GetParentDialog();
1017 SwWait aWait( *pDlg->pSh->GetView().GetDocShell(), sal_True );
1019 GroupUserData* pGroupData = (GroupUserData*)pSrcParent->GetUserData();
1020 String sSourceGroup(pGroupData->sGroupName);
1021 sSourceGroup += GLOS_DELIM;
1022 sSourceGroup += OUString::number(pGroupData->nPathIdx);
1024 pDlg->pGlossaryHdl->SetCurGroup(sSourceGroup);
1025 String sTitle(GetEntryText(pEntry));
1026 String sShortName(*(String*)pEntry->GetUserData());
1028 GroupUserData* pDestData = (GroupUserData*)pDestParent->GetUserData();
1029 String sDestName = pDestData->sGroupName;
1030 sDestName += GLOS_DELIM;
1031 sDestName += OUString::number(pDestData->nPathIdx);
1033 bRet = pDlg->pGlossaryHdl->CopyOrMove( sSourceGroup, sShortName,
1034 sDestName, sTitle, sal_False );
1035 if(bRet)
1037 SvTreeListEntry* pChild = InsertEntry(sTitle, pDestParent);
1038 pChild->SetUserData(new String(sShortName));
1041 return sal_False; // otherwise the entry is being set automatically
1044 String SwGlossaryDlg::GetCurrGrpName() const
1046 SvTreeListEntry* pEntry = m_pCategoryBox->FirstSelected();
1047 String sRet;
1048 if(pEntry)
1050 pEntry =
1051 m_pCategoryBox->GetParent(pEntry) ? m_pCategoryBox->GetParent(pEntry) : pEntry;
1052 GroupUserData* pGroupData = (GroupUserData*)pEntry->GetUserData();
1053 sRet = pGroupData->sGroupName;
1054 sRet += GLOS_DELIM;
1055 sRet += OUString::number(pGroupData->nPathIdx);
1057 return sRet;
1060 IMPL_LINK( SwGlossaryDlg, PathHdl, Button *, pBtn )
1062 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1063 if(pFact)
1065 AbstractSvxMultiPathDialog* pDlg = pFact->CreateSvxMultiPathDialog( pBtn );
1066 OSL_ENSURE(pDlg, "Dialogdiet fail!");
1067 SvtPathOptions aPathOpt;
1068 String sGlosPath( aPathOpt.GetAutoTextPath() );
1069 pDlg->SetPath(sGlosPath);
1070 if(RET_OK == pDlg->Execute())
1072 String sTmp(pDlg->GetPath());
1073 if(sTmp != sGlosPath)
1075 aPathOpt.SetAutoTextPath( sTmp );
1076 ::GetGlossaries()->UpdateGlosPath( sal_True );
1077 Init();
1080 delete pDlg;
1082 return 0;
1085 IMPL_LINK_NOARG(SwGlossaryDlg, InsertHdl)
1087 EndDialog(true);
1088 return 0;
1091 void SwGlossaryDlg::ShowPreview()
1093 //create example
1094 if (!pExampleFrame)
1096 Link aLink(LINK(this, SwGlossaryDlg, PreviewLoadedHdl));
1097 pExampleFrame = new SwOneExampleFrame( *m_pExampleWIN,
1098 EX_SHOW_ONLINE_LAYOUT, &aLink );
1101 if (::GetCurrGlosGroup())
1102 ShowAutoText(*::GetCurrGlosGroup(), m_pShortNameEdit->GetText());
1105 IMPL_LINK_NOARG(SwGlossaryDlg, PreviewLoadedHdl)
1107 ResumeShowAutoText();
1108 return 0;
1111 void SwGlossaryDlg::ShowAutoText(const String& rGroup, const String& rShortName)
1113 if(m_pExampleWIN->IsVisible())
1115 SetResumeData(rGroup, rShortName);
1116 //try to make an Undo()
1117 pExampleFrame->ClearDocument( sal_True );
1121 void SwGlossaryDlg::ResumeShowAutoText()
1123 String sGroup, sShortName;
1124 if(GetResumeData(sGroup, sShortName) && m_pExampleWIN->IsVisible())
1126 if(!m_xAutoText.is())
1128 //now the AutoText ListBoxes have to be filled
1129 m_xAutoText = text::AutoTextContainer::create( comphelper::getProcessComponentContext() );
1132 uno::Reference< XTextCursor > & xCrsr = pExampleFrame->GetTextCursor();
1133 if(xCrsr.is())
1135 if(sShortName.Len())
1137 uno::Any aGroup = m_xAutoText->getByName(sGroup);
1138 uno::Reference< XAutoTextGroup > xGroup;
1139 OUString uShortName(sShortName);
1140 if((aGroup >>= xGroup) && xGroup->hasByName(uShortName))
1142 uno::Any aEntry(xGroup->getByName(uShortName));
1143 uno::Reference< XAutoTextEntry > xEntry;
1144 aEntry >>= xEntry;
1145 uno::Reference< XTextRange > xRange(xCrsr, uno::UNO_QUERY);
1146 xEntry->applyTo(xRange);
1151 ResetResumeData();
1154 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */