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