Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : : #include <comphelper/string.hxx>
21 : : #include <tools/urlobj.hxx>
22 : : #include <tools/stream.hxx>
23 : : #include <vcl/msgbox.hxx>
24 : : #include <vcl/help.hxx>
25 : : #include <unotools/transliterationwrapper.hxx>
26 : : #include <unotools/tempfile.hxx>
27 : :
28 : : #include <unotools/pathoptions.hxx>
29 : : #include <swtypes.hxx>
30 : : #include <glosbib.hxx>
31 : : #include <gloshdl.hxx>
32 : : #include <actctrl.hxx>
33 : : #include <glossary.hxx>
34 : : #include <glosdoc.hxx>
35 : : #include <swunohelper.hxx>
36 : :
37 : : #include <glosbib.hrc>
38 : : #include <misc.hrc>
39 : : #include <helpid.h>
40 : :
41 : :
42 : : #define PATH_CASE_SENSITIVE 0x01
43 : : #define PATH_READONLY 0x02
44 : :
45 : : #define RENAME_TOKEN_DELIM (sal_Unicode)1
46 : :
47 : 0 : SwGlossaryGroupDlg::SwGlossaryGroupDlg(Window * pParent,
48 : : std::vector<String> const& rPathArr,
49 : : SwGlossaryHdl *pHdl) :
50 : : SvxStandardDialog(pParent, SW_RES(DLG_BIB_BASE)),
51 : : aBibFT( this, SW_RES(FT_BIB)),
52 : : aNameED( this, SW_RES(ED_NAME)),
53 : : aPathFT( this, SW_RES(FT_PATH)),
54 : : aPathLB( this, SW_RES(LB_PATH)),
55 : : aSelectFT( this, SW_RES(FT_SELECT)),
56 : : aGroupTLB( this, SW_RES(TLB_GROUPS)),
57 : :
58 : : aOkPB( this, SW_RES(BT_OK)),
59 : : aCancelPB( this, SW_RES(BT_CANCEL)),
60 : : aHelpPB( this, SW_RES(BT_HELP)),
61 : : aNewPB( this, SW_RES(PB_NEW)),
62 : : aDelPB( this, SW_RES(PB_DELETE)),
63 : : aRenamePB( this, SW_RES(PB_RENAME)),
64 : :
65 : 0 : pGlosHdl(pHdl)
66 : : {
67 : 0 : FreeResource();
68 : :
69 : : long nTabs[] =
70 : : { 2, // Number of Tabs
71 : : 0, 160
72 : 0 : };
73 : :
74 : 0 : aGroupTLB.SetHelpId(HID_GLOS_GROUP_TREE);
75 : 0 : aGroupTLB.SetTabs( &nTabs[0], MAP_APPFONT );
76 : 0 : aGroupTLB.SetStyle(aGroupTLB.GetStyle()|WB_HSCROLL|WB_CLIPCHILDREN|WB_SORT);
77 : 0 : aGroupTLB.SetSelectHdl(LINK(this, SwGlossaryGroupDlg, SelectHdl));
78 : 0 : aGroupTLB.GetModel()->SetSortMode(SortAscending);
79 : 0 : aNewPB.SetClickHdl(LINK(this, SwGlossaryGroupDlg, NewHdl));
80 : 0 : aDelPB.SetClickHdl(LINK(this, SwGlossaryGroupDlg, DeleteHdl));
81 : 0 : aNameED.SetModifyHdl(LINK(this, SwGlossaryGroupDlg, ModifyHdl));
82 : 0 : aPathLB.SetSelectHdl(LINK(this, SwGlossaryGroupDlg, ModifyHdl));
83 : 0 : aRenamePB.SetClickHdl(LINK(this, SwGlossaryGroupDlg, RenameHdl));
84 : :
85 : 0 : for (size_t i = 0; i < rPathArr.size(); ++i)
86 : : {
87 : 0 : String sPath(rPathArr[i]);
88 : 0 : INetURLObject aTempURL(sPath);
89 : 0 : sPath = aTempURL.GetMainURL(INetURLObject::DECODE_WITH_CHARSET );
90 : 0 : aPathLB.InsertEntry(sPath);
91 : 0 : sal_uLong nCaseReadonly = 0;
92 : 0 : utl::TempFile aTempFile(&sPath);
93 : 0 : aTempFile.EnableKillingFile();
94 : 0 : if(!aTempFile.IsValid())
95 : 0 : nCaseReadonly |= PATH_READONLY;
96 : 0 : else if( SWUnoHelper::UCB_IsCaseSensitiveFileName( aTempFile.GetURL()))
97 : 0 : nCaseReadonly |= PATH_CASE_SENSITIVE;
98 : 0 : aPathLB.SetEntryData(i, (void*)nCaseReadonly);
99 : 0 : }
100 : 0 : aPathLB.SelectEntryPos(0);
101 : 0 : aPathLB.Enable(sal_True);
102 : :
103 : 0 : const sal_uInt16 nCount = pHdl->GetGroupCnt();
104 : 0 : for( sal_uInt16 i = 0; i < nCount; ++i)
105 : : {
106 : 0 : String sTitle;
107 : 0 : String sGroup = pHdl->GetGroupName(i, &sTitle);
108 : 0 : if(!sGroup.Len())
109 : 0 : continue;
110 : 0 : GlosBibUserData* pData = new GlosBibUserData;
111 : 0 : pData->sGroupName = sGroup;
112 : 0 : pData->sGroupTitle = sTitle;
113 : 0 : String sTemp(sTitle);
114 : 0 : sTemp += '\t';
115 : 0 : pData->sPath = aPathLB.GetEntry((sal_uInt16)sGroup.GetToken(1, GLOS_DELIM).ToInt32());
116 : 0 : sTemp += pData->sPath;
117 : 0 : SvLBoxEntry* pEntry = aGroupTLB.InsertEntry(sTemp);
118 : 0 : pEntry->SetUserData(pData);
119 : :
120 : 0 : }
121 : 0 : aGroupTLB.GetModel()->Resort();
122 : 0 : }
123 : :
124 : 0 : SwGlossaryGroupDlg::~SwGlossaryGroupDlg()
125 : : {
126 : 0 : }
127 : :
128 : 0 : void SwGlossaryGroupDlg::Apply()
129 : : {
130 : 0 : if(aNewPB.IsEnabled())
131 : 0 : NewHdl(&aNewPB);
132 : :
133 : 0 : String aActGroup = SwGlossaryDlg::GetCurrGroup();
134 : :
135 : 0 : for (OUVector_t::const_iterator it(m_RemovedArr.begin());
136 : 0 : it != m_RemovedArr.end(); ++it)
137 : : {
138 : : const String sDelGroup =
139 : 0 : ::comphelper::string::getToken(*it, 0, '\t');
140 : 0 : if( sDelGroup == aActGroup )
141 : : {
142 : : //when the current group is deleted, the current group has to be relocated
143 : 0 : if(aGroupTLB.GetEntryCount())
144 : : {
145 : 0 : SvLBoxEntry* pFirst = aGroupTLB.First();
146 : 0 : GlosBibUserData* pUserData = (GlosBibUserData*)pFirst->GetUserData();
147 : 0 : pGlosHdl->SetCurGroup(pUserData->sGroupName);
148 : : }
149 : : }
150 : 0 : String sMsg(SW_RES(STR_QUERY_DELETE_GROUP1));
151 : 0 : String sTitle( ::comphelper::string::getToken(*it, 1, '\t') );
152 : 0 : if(sTitle.Len())
153 : 0 : sMsg += sTitle;
154 : : else
155 : 0 : sDelGroup.GetToken(1, GLOS_DELIM);
156 : 0 : sMsg += SW_RESSTR(STR_QUERY_DELETE_GROUP2);
157 : 0 : QueryBox aQuery(this->GetParent(), WB_YES_NO|WB_DEF_NO, sMsg );
158 : 0 : if(RET_YES == aQuery.Execute())
159 : 0 : pGlosHdl->DelGroup( sDelGroup );
160 : 0 : }
161 : :
162 : : //don't rename before there was one
163 : 0 : for (OUVector_t::const_iterator it(m_RenamedArr.begin());
164 : 0 : it != m_RenamedArr.end(); ++it)
165 : : {
166 : : ::rtl::OUString const sOld(
167 : 0 : ::comphelper::string::getToken(*it, 0, RENAME_TOKEN_DELIM));
168 : : String sNew(
169 : 0 : ::comphelper::string::getToken(*it, 1, RENAME_TOKEN_DELIM));
170 : : ::rtl::OUString const sTitle(
171 : 0 : ::comphelper::string::getToken(*it, 2, RENAME_TOKEN_DELIM));
172 : 0 : pGlosHdl->RenameGroup(sOld, sNew, sTitle);
173 : 0 : if (it == m_RenamedArr.begin())
174 : : {
175 : 0 : sCreatedGroup = sNew;
176 : : }
177 : 0 : }
178 : 0 : for (OUVector_t::const_iterator it(m_InsertedArr.begin());
179 : 0 : it != m_InsertedArr.end(); ++it)
180 : : {
181 : 0 : String sNewGroup = *it;
182 : 0 : String sNewTitle = sNewGroup.GetToken(0, GLOS_DELIM);
183 : 0 : if( sNewGroup != aActGroup )
184 : : {
185 : 0 : pGlosHdl->NewGroup(sNewGroup, sNewTitle);
186 : 0 : if(!sCreatedGroup.Len())
187 : 0 : sCreatedGroup = sNewGroup;
188 : : }
189 : 0 : }
190 : 0 : }
191 : :
192 : 0 : IMPL_LINK( SwGlossaryGroupDlg, SelectHdl, SvTabListBox*, EMPTYARG )
193 : : {
194 : 0 : aNewPB.Enable(sal_False);
195 : 0 : SvLBoxEntry* pFirstEntry = aGroupTLB.FirstSelected();
196 : 0 : if(pFirstEntry)
197 : : {
198 : 0 : GlosBibUserData* pUserData = (GlosBibUserData*)pFirstEntry->GetUserData();
199 : 0 : String sEntry(pUserData->sGroupName);
200 : 0 : String sName(aNameED.GetText());
201 : 0 : sal_Bool bExists = sal_False;
202 : 0 : sal_uLong nPos = aGroupTLB.GetEntryPos(sName, 0);
203 : 0 : if( 0xffffffff > nPos)
204 : : {
205 : 0 : SvLBoxEntry* pEntry = aGroupTLB.GetEntry(nPos);
206 : 0 : GlosBibUserData* pFoundData = (GlosBibUserData*)pEntry->GetUserData();
207 : 0 : String sGroup = pFoundData->sGroupName;
208 : 0 : bExists = sGroup == sEntry;
209 : : }
210 : :
211 : 0 : aRenamePB.Enable(!bExists && sName.Len());
212 : 0 : aDelPB.Enable(IsDeleteAllowed(sEntry));
213 : : }
214 : 0 : return 0;
215 : : }
216 : :
217 : 0 : IMPL_LINK_NOARG(SwGlossaryGroupDlg, NewHdl)
218 : : {
219 : 0 : String sGroup(aNameED.GetText());
220 : 0 : sGroup += GLOS_DELIM;
221 : 0 : sGroup += String::CreateFromInt32(aPathLB.GetSelectEntryPos());
222 : : OSL_ENSURE(!pGlosHdl->FindGroupName(sGroup), "group already available!");
223 : 0 : m_InsertedArr.push_back(sGroup);
224 : 0 : String sTemp(aNameED.GetText());
225 : 0 : sTemp += '\t';
226 : 0 : sTemp += aPathLB.GetSelectEntry();
227 : 0 : SvLBoxEntry* pEntry = aGroupTLB.InsertEntry(sTemp);
228 : 0 : GlosBibUserData* pData = new GlosBibUserData;
229 : 0 : pData->sPath = aPathLB.GetSelectEntry();
230 : 0 : pData->sGroupName = sGroup;
231 : 0 : pData->sGroupTitle = aNameED.GetText();
232 : 0 : pEntry->SetUserData(pData);
233 : 0 : aGroupTLB.Select(pEntry);
234 : 0 : aGroupTLB.MakeVisible(pEntry);
235 : 0 : aGroupTLB.GetModel()->Resort();
236 : :
237 : 0 : return 0;
238 : : }
239 : :
240 : 0 : IMPL_LINK( SwGlossaryGroupDlg, DeleteHdl, Button*, pButton )
241 : : {
242 : 0 : SvLBoxEntry* pEntry = aGroupTLB.FirstSelected();
243 : 0 : if(!pEntry)
244 : : {
245 : 0 : pButton->Enable(sal_False);
246 : 0 : return 0;
247 : : }
248 : 0 : GlosBibUserData* pUserData = (GlosBibUserData*)pEntry->GetUserData();
249 : 0 : ::rtl::OUString const sEntry(pUserData->sGroupName);
250 : : // if the name to be deleted is among the new ones - get rid of it
251 : 0 : sal_Bool bDelete = sal_True;
252 : 0 : for (OUVector_t::iterator it(m_InsertedArr.begin());
253 : 0 : it != m_InsertedArr.end(); ++it)
254 : : {
255 : 0 : if (*it == sEntry)
256 : : {
257 : 0 : m_InsertedArr.erase(it);
258 : 0 : bDelete = sal_False;
259 : 0 : break;
260 : : }
261 : :
262 : : }
263 : : // it should probably be renamed?
264 : 0 : if(bDelete)
265 : : {
266 : 0 : for (OUVector_t::iterator it(m_RenamedArr.begin());
267 : 0 : it != m_RenamedArr.end(); ++it)
268 : : {
269 : 0 : if (::comphelper::string::getToken(*it, 0, RENAME_TOKEN_DELIM)
270 : 0 : == sEntry)
271 : : {
272 : 0 : m_RenamedArr.erase(it);
273 : 0 : bDelete = sal_False;
274 : 0 : break;
275 : : }
276 : : }
277 : : }
278 : 0 : if(bDelete)
279 : : {
280 : 0 : String sGroupEntry(pUserData->sGroupName);
281 : 0 : sGroupEntry += '\t';
282 : 0 : sGroupEntry += pUserData->sGroupTitle;
283 : 0 : m_RemovedArr.push_back(sGroupEntry);
284 : : }
285 : 0 : delete pUserData;
286 : 0 : aGroupTLB.GetModel()->Remove(pEntry);
287 : 0 : if(!aGroupTLB.First())
288 : 0 : pButton->Enable(sal_False);
289 : : //the content must be deleted - otherwise the new handler would be called in Apply()
290 : 0 : aNameED.SetText(aEmptyStr);
291 : 0 : return 0;
292 : : }
293 : :
294 : 0 : IMPL_LINK_NOARG(SwGlossaryGroupDlg, RenameHdl)
295 : : {
296 : 0 : SvLBoxEntry* pEntry = aGroupTLB.FirstSelected();
297 : 0 : GlosBibUserData* pUserData = (GlosBibUserData*)pEntry->GetUserData();
298 : 0 : String sEntryText(aGroupTLB.GetEntryText(pEntry));
299 : 0 : String sEntry(pUserData->sGroupName);
300 : :
301 : 0 : String sNewName(aNameED.GetText());
302 : 0 : String sNewTitle(sNewName);
303 : :
304 : 0 : sNewName += GLOS_DELIM;
305 : 0 : sNewName += String::CreateFromInt32(aPathLB.GetSelectEntryPos());
306 : : OSL_ENSURE(!pGlosHdl->FindGroupName(sNewName), "group already available!");
307 : :
308 : : // if the name to be renamed is among the new ones - replace
309 : 0 : sal_Bool bDone = sal_False;
310 : 0 : for (OUVector_t::iterator it(m_InsertedArr.begin());
311 : 0 : it != m_InsertedArr.end(); ++it)
312 : : {
313 : 0 : if (String(*it) == sEntry)
314 : : {
315 : 0 : m_InsertedArr.erase(it);
316 : 0 : m_InsertedArr.push_back(sNewName);
317 : 0 : bDone = sal_True;
318 : 0 : break;
319 : : }
320 : : }
321 : 0 : if(!bDone)
322 : : {
323 : 0 : sEntry += RENAME_TOKEN_DELIM;
324 : 0 : sEntry += sNewName;
325 : 0 : sEntry += RENAME_TOKEN_DELIM;
326 : 0 : sEntry += sNewTitle;
327 : 0 : m_RenamedArr.push_back(sEntry);
328 : : }
329 : 0 : delete (GlosBibUserData*)pEntry->GetUserData();
330 : 0 : aGroupTLB.GetModel()->Remove(pEntry);
331 : 0 : String sTemp(aNameED.GetText());
332 : 0 : sTemp += '\t';
333 : 0 : sTemp += aPathLB.GetSelectEntry();
334 : 0 : pEntry = aGroupTLB.InsertEntry(sTemp);
335 : 0 : GlosBibUserData* pData = new GlosBibUserData;
336 : 0 : pData->sPath = aPathLB.GetSelectEntry();
337 : 0 : pData->sGroupName = sNewName;
338 : 0 : pData->sGroupTitle = sNewTitle;
339 : 0 : pEntry->SetUserData(pData);
340 : 0 : aGroupTLB.Select(pEntry);
341 : 0 : aGroupTLB.MakeVisible(pEntry);
342 : 0 : aGroupTLB.GetModel()->Resort();
343 : 0 : return 0;
344 : : }
345 : :
346 : 0 : IMPL_LINK_NOARG(SwGlossaryGroupDlg, ModifyHdl)
347 : : {
348 : 0 : String sEntry(aNameED.GetText());
349 : 0 : sal_Bool bEnableNew = sal_True;
350 : 0 : sal_Bool bEnableDel = sal_False;
351 : : sal_uLong nCaseReadonly =
352 : 0 : (sal_uLong)aPathLB.GetEntryData(aPathLB.GetSelectEntryPos());
353 : 0 : sal_Bool bDirReadonly = 0 != (nCaseReadonly&PATH_READONLY);
354 : :
355 : 0 : if(!sEntry.Len() || bDirReadonly)
356 : 0 : bEnableNew = sal_False;
357 : 0 : else if(sEntry.Len())
358 : : {
359 : 0 : sal_uLong nPos = 0xffffffff;
360 : :
361 : :
362 : 0 : nPos = aGroupTLB.GetEntryPos(sEntry, 0);
363 : : //if it's not case sensitive you have to search for yourself
364 : 0 : if( 0xffffffff == nPos)
365 : : {
366 : 0 : const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
367 : 0 : for(sal_uInt16 i = 0; i < aGroupTLB.GetEntryCount(); i++)
368 : : {
369 : 0 : String sTemp = aGroupTLB.GetEntryText( i, 0 );
370 : : nCaseReadonly = (sal_uLong)aPathLB.GetEntryData(
371 : 0 : aPathLB.GetEntryPos(aGroupTLB.GetEntryText(i,1)));
372 : 0 : sal_Bool bCase = 0 != (nCaseReadonly & PATH_CASE_SENSITIVE);
373 : :
374 : 0 : if( !bCase && rSCmp.isEqual( sTemp, sEntry ))
375 : : {
376 : 0 : nPos = i;
377 : : break;
378 : : }
379 : 0 : }
380 : : }
381 : 0 : if( 0xffffffff > nPos)
382 : : {
383 : 0 : bEnableNew = sal_False;
384 : 0 : aGroupTLB.Select(aGroupTLB.GetEntry( nPos ));
385 : 0 : aGroupTLB.MakeVisible(aGroupTLB.GetEntry( nPos ));
386 : : }
387 : : }
388 : 0 : SvLBoxEntry* pEntry = aGroupTLB.FirstSelected();
389 : 0 : if(pEntry)
390 : : {
391 : 0 : GlosBibUserData* pUserData = (GlosBibUserData*)pEntry->GetUserData();
392 : 0 : bEnableDel = IsDeleteAllowed(pUserData->sGroupName);
393 : : }
394 : :
395 : 0 : aDelPB.Enable(bEnableDel);
396 : 0 : aNewPB.Enable(bEnableNew);
397 : 0 : aRenamePB.Enable(bEnableNew && pEntry);
398 : 0 : return 0;
399 : : }
400 : :
401 : 0 : sal_Bool SwGlossaryGroupDlg::IsDeleteAllowed(const String &rGroup)
402 : : {
403 : 0 : sal_Bool bDel = (!pGlosHdl->IsReadOnly(&rGroup));
404 : :
405 : : // OM: if the name is among the new region name, it is deletable
406 : : // as well! Because for non existing region names ReadOnly issues
407 : : // sal_True.
408 : :
409 : 0 : for (OUVector_t::const_iterator it(m_InsertedArr.begin());
410 : 0 : it != m_InsertedArr.end(); ++it)
411 : : {
412 : 0 : if (String(*it) == rGroup)
413 : : {
414 : 0 : bDel = sal_True;
415 : 0 : break;
416 : : }
417 : : }
418 : :
419 : 0 : return bDel;
420 : : }
421 : :
422 : 0 : void FEdit::KeyInput( const KeyEvent& rKEvent )
423 : : {
424 : 0 : KeyCode aCode = rKEvent.GetKeyCode();
425 : 0 : if( KEYGROUP_CURSOR == aCode.GetGroup() ||
426 : 0 : ( KEYGROUP_MISC == aCode.GetGroup() &&
427 : 0 : KEY_DELETE >= aCode.GetCode() ) ||
428 : 0 : SVT_SEARCHPATH_DELIMITER != rKEvent.GetCharCode() )
429 : 0 : Edit::KeyInput( rKEvent );
430 : 0 : }
431 : :
432 : 0 : void SwGlossaryGroupTLB::RequestHelp( const HelpEvent& rHEvt )
433 : : {
434 : 0 : Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ));
435 : 0 : SvLBoxEntry* pEntry = GetEntry( aPos );
436 : 0 : if(pEntry)
437 : : {
438 : : SvLBoxTab* pTab;
439 : 0 : SvLBoxItem* pItem = GetItem( pEntry, aPos.X(), &pTab );
440 : 0 : if(pItem)
441 : : {
442 : 0 : aPos = GetEntryPosition( pEntry );
443 : 0 : Size aSize(pItem->GetSize( this, pEntry ));
444 : 0 : aPos.X() = GetTabPos( pEntry, pTab );
445 : :
446 : 0 : if((aPos.X() + aSize.Width()) > GetSizePixel().Width())
447 : 0 : aSize.Width() = GetSizePixel().Width() - aPos.X();
448 : 0 : aPos = OutputToScreenPixel(aPos);
449 : 0 : Rectangle aItemRect( aPos, aSize );
450 : 0 : String sMsg;
451 : 0 : GlosBibUserData* pData = (GlosBibUserData*)pEntry->GetUserData();
452 : 0 : sMsg = pData->sPath;
453 : 0 : sMsg += INET_PATH_TOKEN;
454 : 0 : sMsg += pData->sGroupName.GetToken(0, GLOS_DELIM);
455 : 0 : sMsg += SwGlossaries::GetExtension();
456 : :
457 : : Help::ShowQuickHelp( this, aItemRect, sMsg,
458 : 0 : QUICKHELP_LEFT|QUICKHELP_VCENTER );
459 : : }
460 : : }
461 : 0 : }
462 : :
463 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|