/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #define _SVSTDARR_STRINGSSORTDTOR #define _SVSTDARR_USHORTSSORT #define _SVSTDARR_USHORTS #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef _REDLNDLG_HXX #define _REDLNACCEPTDLG #include #endif #include #include #include #include #include #include #include // -> #111827# #include #include #include // <- #111827# #include #include #include #include #include #include /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ SFX_IMPL_MODELESSDIALOG( SwRedlineAcceptChild, FN_REDLINE_ACCEPT ) SV_IMPL_PTRARR(SwRedlineDataParentArr, SwRedlineDataParentPtr) SV_IMPL_OP_PTRARR_SORT(SwRedlineDataParentSortArr, SwRedlineDataParentPtr) SV_IMPL_PTRARR(SwRedlineDataChildArr, SwRedlineDataChildPtr) SV_IMPL_PTRARR(SvLBoxEntryArr, SvLBoxEntryPtr) static sal_uInt16 nSortMode = 0xffff; static sal_Bool bSortDir = sal_True; /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ SwRedlineAcceptChild::SwRedlineAcceptChild( Window* _pParent, sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* pInfo ) : SwChildWinWrapper( _pParent, nId ) { pWindow = new SwModelessRedlineAcceptDlg( pBindings, this, _pParent); ((SwModelessRedlineAcceptDlg *)pWindow)->Initialize(pInfo); } /*-------------------------------------------------------------------- Beschreibung: Nach Dok-Wechsel Dialog neu initialisieren --------------------------------------------------------------------*/ sal_Bool SwRedlineAcceptChild::ReInitDlg(SwDocShell *pDocSh) { sal_Bool bRet; if ((bRet = SwChildWinWrapper::ReInitDlg(pDocSh)) == sal_True) // Sofort aktualisieren, Dok-Wechsel ((SwModelessRedlineAcceptDlg*)GetWindow())->Activate(); return bRet; } /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ SwModelessRedlineAcceptDlg::SwModelessRedlineAcceptDlg( SfxBindings* _pBindings, SwChildWinWrapper* pChild, Window *_pParent) : SfxModelessDialog(_pBindings, pChild, _pParent, SW_RES(DLG_REDLINE_ACCEPT)), pChildWin (pChild) { pImplDlg = new SwRedlineAcceptDlg(this); FreeResource(); } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ void SwModelessRedlineAcceptDlg::Activate() { SwView *pView = ::GetActiveView(); if (!pView) // Kann passieren, wenn man auf eine andere App umschaltet, wenn return; // vorher eine Listbox im Dialog den Focus hatte (eigentlich THs Bug) SwDocShell *pDocSh = pView->GetDocShell(); if (pChildWin->GetOldDocShell() != pDocSh) { // Dok-Wechsel SwWait aWait( *pDocSh, false ); SwWrtShell* pSh = pView->GetWrtShellPtr(); pChildWin->SetOldDocShell(pDocSh); // Rekursion vermeiden (durch Modified-Hdl) sal_Bool bMod = pSh->IsModified(); SfxBoolItem aShow(FN_REDLINE_SHOW, sal_True); pSh->GetView().GetViewFrame()->GetDispatcher()->Execute( FN_REDLINE_SHOW, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD, &aShow, 0L); if (!bMod) pSh->ResetModified(); pImplDlg->Init(); return; } pImplDlg->Activate(); } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ void SwModelessRedlineAcceptDlg::Initialize(SfxChildWinInfo *pInfo) { String aStr; if (pInfo != NULL) pImplDlg->Initialize(pInfo->aExtraString); SfxModelessDialog::Initialize(pInfo); } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ void SwModelessRedlineAcceptDlg::FillInfo(SfxChildWinInfo& rInfo) const { SfxModelessDialog::FillInfo(rInfo); pImplDlg->FillInfo(rInfo.aExtraString); } /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ void SwModelessRedlineAcceptDlg::Resize() { pImplDlg->Resize(); SfxModelessDialog::Resize(); } /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ SwModelessRedlineAcceptDlg::~SwModelessRedlineAcceptDlg() { delete pImplDlg; } /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ SwRedlineAcceptDlg::SwRedlineAcceptDlg(Dialog *pParent, sal_Bool bAutoFmt) : pParentDlg (pParent), aTabPagesCTRL (pParent, SW_RES(CTRL_TABPAGES)), aPopup (SW_RES(MN_REDLINE_POPUP)), sInserted (SW_RES(STR_REDLINE_INSERTED)), sDeleted (SW_RES(STR_REDLINE_DELETED)), sFormated (SW_RES(STR_REDLINE_FORMATED)), sTableChgd (SW_RES(STR_REDLINE_TABLECHG)), sFmtCollSet (SW_RES(STR_REDLINE_FMTCOLLSET)), sAutoFormat (SW_RES(STR_REDLINE_AUTOFMT)), bOnlyFormatedRedlines( sal_False ), bHasReadonlySel ( sal_False ), bRedlnAutoFmt (bAutoFmt), bInhibitActivate( false ) { aTabPagesCTRL.SetHelpId(HID_REDLINE_CTRL); pTPView = aTabPagesCTRL.GetViewPage(); pTable = pTPView->GetTableControl(); pTPView->InsertWriterHeader(); pTPView->SetAcceptClickHdl(LINK(this, SwRedlineAcceptDlg, AcceptHdl)); pTPView->SetAcceptAllClickHdl(LINK(this, SwRedlineAcceptDlg, AcceptAllHdl)); pTPView->SetRejectClickHdl(LINK(this, SwRedlineAcceptDlg, RejectHdl)); pTPView->SetRejectAllClickHdl(LINK(this, SwRedlineAcceptDlg, RejectAllHdl)); pTPView->SetUndoClickHdl(LINK(this, SwRedlineAcceptDlg, UndoHdl)); aTabPagesCTRL.GetFilterPage()->SetReadyHdl(LINK(this, SwRedlineAcceptDlg, FilterChangedHdl)); ListBox *pActLB = aTabPagesCTRL.GetFilterPage()->GetLbAction(); pActLB->InsertEntry(sInserted); pActLB->InsertEntry(sDeleted); pActLB->InsertEntry(sFormated); pActLB->InsertEntry(sTableChgd); if (HasRedlineAutoFmt()) { pActLB->InsertEntry(sFmtCollSet); pActLB->InsertEntry(sAutoFormat); pTPView->ShowUndo(sal_True); pTPView->DisableUndo(); // Noch gibts keine UNDO-Events } pActLB->SelectEntryPos(0); pTable->SetStyle(pTable->GetStyle()|WB_HASLINES|WB_CLIPCHILDREN|WB_HASBUTTONS|WB_HASBUTTONSATROOT|WB_HSCROLL); pTable->SetNodeDefaultImages(); pTable->SetSelectionMode(MULTIPLE_SELECTION); pTable->SetHighlightRange(1); static long aStaticTabs[]= { 4,10,70,120,170 }; pTable->SetTabs(aStaticTabs); // Minimalgroesse setzen Size aMinSz(aTabPagesCTRL.GetMinSizePixel()); Point aPos(aTabPagesCTRL.GetPosPixel()); aMinSz.Width() += (aPos.X() * 2 - 1); aMinSz.Height() += (aPos.Y() * 2 - 1); pParentDlg->SetMinOutputSizePixel(aMinSz); if (pParentDlg->GetOutputSizePixel().Width() < aMinSz.Width()) pParentDlg->SetOutputSizePixel(Size(aMinSz.Width(), pParentDlg->GetOutputSizePixel().Height())); if (pParentDlg->GetOutputSizePixel().Height() < aMinSz.Height()) pParentDlg->SetOutputSizePixel(Size(pParentDlg->GetOutputSizePixel().Width(), aMinSz.Height())); pTable->SortByCol(nSortMode, bSortDir); aOldSelectHdl = pTable->GetSelectHdl(); aOldDeselectHdl = pTable->GetDeselectHdl(); pTable->SetSelectHdl(LINK(this, SwRedlineAcceptDlg, SelectHdl)); pTable->SetDeselectHdl(LINK(this, SwRedlineAcceptDlg, DeselectHdl)); pTable->SetCommandHdl(LINK(this, SwRedlineAcceptDlg, CommandHdl)); // Flackern der Buttons vermeiden: aDeselectTimer.SetTimeout(100); aDeselectTimer.SetTimeoutHdl(LINK(this, SwRedlineAcceptDlg, SelectHdl)); // Mehrfachselektion der selben Texte vermeiden: aSelectTimer.SetTimeout(100); aSelectTimer.SetTimeoutHdl(LINK(this, SwRedlineAcceptDlg, GotoHdl)); } /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ SwRedlineAcceptDlg::~SwRedlineAcceptDlg() { } /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ void SwRedlineAcceptDlg::Init(sal_uInt16 nStart) { SwWait aWait( *::GetActiveView()->GetDocShell(), false ); pTable->SetUpdateMode(sal_False); aUsedSeqNo.Remove((sal_uInt16)0, aUsedSeqNo.Count()); if (nStart) RemoveParents(nStart, aRedlineParents.Count() - 1); else { pTable->Clear(); aRedlineChilds.DeleteAndDestroy(0, aRedlineChilds.Count()); aRedlineParents.DeleteAndDestroy(nStart, aRedlineParents.Count() - nStart); } // Parents einfuegen InsertParents(nStart); InitAuthors(); pTable->SetUpdateMode(sal_True); // #i69618# this moves the list box to the right position, visually SvLBoxEntry* pSelEntry = pTable->FirstSelected(); if( pSelEntry ) pTable->MakeVisible( pSelEntry, sal_True ); //#i70937#, force the scroll } /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ void SwRedlineAcceptDlg::InitAuthors() { SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr(); SvxTPFilter *pFilterPage = aTabPagesCTRL.GetFilterPage(); String sAuthor; SvStringsSortDtor aStrings; String sOldAuthor(pFilterPage->GetSelectedAuthor()); pFilterPage->ClearAuthors(); String sParent; const sal_uInt16 nRedlineCount = pSh->GetRedlineCount(); bOnlyFormatedRedlines = sal_True; bHasReadonlySel = sal_False; sal_Bool bIsNotFormated = sal_False; sal_uInt16 i; // Autoren ermitteln for ( i = 0; i < nRedlineCount; i++) { const SwRedline& rRedln = pSh->GetRedline(i); if( bOnlyFormatedRedlines && nsRedlineType_t::REDLINE_FORMAT != rRedln.GetType() ) bOnlyFormatedRedlines = sal_False; //JP 27.9.2001: make no sense if we handle readonly sections // if( !bHasReadonlySel && rRedln.HasReadonlySel() ) // bHasReadonlySel = sal_True; String *pAuthor = new String(rRedln.GetAuthorString()); if (!aStrings.Insert(pAuthor)) delete pAuthor; for (sal_uInt16 nStack = 1; nStack < rRedln.GetStackCount(); nStack++) { pAuthor = new String(rRedln.GetAuthorString(nStack)); if (!aStrings.Insert(pAuthor)) delete pAuthor; } } for (i = 0; i < aStrings.Count(); i++) pFilterPage->InsertAuthor(*aStrings[i]); if (pFilterPage->SelectAuthor(sOldAuthor) == LISTBOX_ENTRY_NOTFOUND && aStrings.Count()) pFilterPage->SelectAuthor(*aStrings[0]); sal_Bool bEnable = pTable->GetEntryCount() != 0 && !pSh->getIDocumentRedlineAccess()->GetRedlinePassword().getLength(); sal_Bool bSel = pTable->FirstSelected() != 0; { SvLBoxEntry* pSelEntry = pTable->FirstSelected(); while (pSelEntry) { const sal_uInt16 nPos = GetRedlinePos(*pSelEntry); if ( nPos < nRedlineCount ) { const SwRedline& rRedln = pSh->GetRedline( nPos ); bIsNotFormated |= nsRedlineType_t::REDLINE_FORMAT != rRedln.GetType(); } pSelEntry = pTable->NextSelected(pSelEntry); } } pTPView->EnableAccept( bEnable && bSel ); pTPView->EnableReject( bEnable && bIsNotFormated && bSel ); pTPView->EnableAcceptAll( bEnable && !bHasReadonlySel ); pTPView->EnableRejectAll( bEnable && !bHasReadonlySel && !bOnlyFormatedRedlines ); } /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ String SwRedlineAcceptDlg::GetRedlineText( const SwRedline& rRedln, DateTime &rDateTime, sal_uInt16 nStack) { String sEntry(GetActionText(rRedln, nStack)); sEntry += '\t'; sEntry += rRedln.GetAuthorString(nStack); sEntry += '\t'; const DateTime &rDT = rRedln.GetTimeStamp(nStack); rDateTime = rDT; sEntry += GetAppLangDateTimeString( rDT ); sEntry += '\t'; sEntry += rRedln.GetComment(nStack); return sEntry; } /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ const String &SwRedlineAcceptDlg::GetActionText(const SwRedline& rRedln, sal_uInt16 nStack) { switch( rRedln.GetType(nStack) ) { case nsRedlineType_t::REDLINE_INSERT: return sInserted; case nsRedlineType_t::REDLINE_DELETE: return sDeleted; case nsRedlineType_t::REDLINE_FORMAT: return sFormated; case nsRedlineType_t::REDLINE_TABLE: return sTableChgd; case nsRedlineType_t::REDLINE_FMTCOLL: return sFmtCollSet; default:;//prevent warning } return aEmptyStr; } /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ void SwRedlineAcceptDlg::Resize() { Size aSz(pParentDlg->GetOutputSizePixel()); Point aPos(aTabPagesCTRL.GetPosPixel()); aSz.Width() -= (aPos.X() * 2 - 1); aSz.Height() -= (aPos.Y() * 2 - 1); aTabPagesCTRL.SetOutputSizePixel(aSz); } /*-------------------------------------------------------------------- Beschreibung: Nach Aktivierung neu initialisieren --------------------------------------------------------------------*/ void SwRedlineAcceptDlg::Activate() { // prevent update if flag is set (#102547#) if( bInhibitActivate ) return; SwView *pView = ::GetActiveView(); SwWait aWait( *pView->GetDocShell(), false ); aUsedSeqNo.Remove((sal_uInt16)0, aUsedSeqNo.Count()); if (!pView) // Kann passieren, wenn man auf eine andere App umschaltet, wenn return; // vorher eine Listbox im Dialog den Focus hatte (eigentlich THs Bug) /* if (HasRedlineAutoFmt()) { Init(); return; }*/ // Hat sich was geaendert? SwWrtShell* pSh = pView->GetWrtShellPtr(); sal_uInt16 nCount = pSh->GetRedlineCount(); // Anzahl und Pointer ueberpruefen SwRedlineDataParent *pParent = 0; sal_uInt16 i; for ( i = 0; i < nCount; i++) { const SwRedline& rRedln = pSh->GetRedline(i); if (i >= aRedlineParents.Count()) { // Neue Eintraege wurden angehaengt Init(i); return; } pParent = aRedlineParents[i]; if (&rRedln.GetRedlineData() != pParent->pData) { // Redline-Parents wurden eingefuegt, geaendert oder geloescht if ((i = CalcDiff(i, sal_False)) == USHRT_MAX) return; continue; } const SwRedlineData *pRedlineData = rRedln.GetRedlineData().Next(); const SwRedlineDataChild *pBackupData = pParent->pNext; if (!pRedlineData && pBackupData) { // Redline-Childs wurden geloescht if ((i = CalcDiff(i, sal_True)) == USHRT_MAX) return; continue; } else { while (pRedlineData) { if (pRedlineData != pBackupData->pChild) { // Redline-Childs wurden eingefuegt, geaendert oder geloescht if ((i = CalcDiff(i, sal_True)) == USHRT_MAX) return; continue; } if (pBackupData) pBackupData = pBackupData->pNext; pRedlineData = pRedlineData->Next(); } } } if (nCount != aRedlineParents.Count()) { // Redlines wurden am Ende geloescht Init(nCount); return; } // Kommentar ueberpruefen for (i = 0; i < nCount; i++) { const SwRedline& rRedln = pSh->GetRedline(i); pParent = aRedlineParents[i]; if(!rRedln.GetComment().Equals(pParent->sComment)) { if (pParent->pTLBParent) { // Nur Kommentar aktualisieren String sComment(rRedln.GetComment()); sComment.SearchAndReplaceAll((sal_Unicode)_LF,(sal_Unicode)' '); pTable->SetEntryText(sComment, pParent->pTLBParent, 3); } pParent->sComment = rRedln.GetComment(); } } InitAuthors(); } /* -----------------05.06.98 13:06------------------- * * --------------------------------------------------*/ sal_uInt16 SwRedlineAcceptDlg::CalcDiff(sal_uInt16 nStart, sal_Bool bChild) { if (!nStart) { Init(); return USHRT_MAX; } pTable->SetUpdateMode(sal_False); SwView *pView = ::GetActiveView(); SwWrtShell* pSh = pView->GetWrtShellPtr(); sal_uInt16 nAutoFmt = HasRedlineAutoFmt() ? nsRedlineType_t::REDLINE_FORM_AUTOFMT : 0; SwRedlineDataParent *pParent = aRedlineParents[nStart]; const SwRedline& rRedln = pSh->GetRedline(nStart); if (bChild) // Sollte eigentlich nie vorkommen, aber sicher ist sicher... { // Alle Childs des Eintrags wegwerfen und neu initialisieren SwRedlineDataChildPtr pBackupData = (SwRedlineDataChildPtr)pParent->pNext; SwRedlineDataChildPtr pNext; while (pBackupData) { pNext = (SwRedlineDataChildPtr)pBackupData->pNext; if (pBackupData->pTLBChild) pTable->RemoveEntry(pBackupData->pTLBChild); aRedlineChilds.DeleteAndDestroy(aRedlineChilds.GetPos(pBackupData), 1); pBackupData = pNext; } pParent->pNext = 0; // Neue Childs einfuegen InsertChilds(pParent, rRedln, nAutoFmt); pTable->SetUpdateMode(sal_True); return nStart; } // Wurden Eintraege geloescht? const SwRedlineData *pRedlineData = &rRedln.GetRedlineData(); sal_uInt16 i; for ( i = nStart + 1; i < aRedlineParents.Count(); i++) { if (aRedlineParents[i]->pData == pRedlineData) { // Eintraege von nStart bis i-1 entfernen RemoveParents(nStart, i - 1); pTable->SetUpdateMode(sal_True); return nStart - 1; } } // Wurden Eintraege eingefuegt? sal_uInt16 nCount = pSh->GetRedlineCount(); pRedlineData = aRedlineParents[nStart]->pData; for (i = nStart + 1; i < nCount; i++) { if (&pSh->GetRedline(i).GetRedlineData() == pRedlineData) { // Eintraege von nStart bis i-1 einfuegen InsertParents(nStart, i - 1); pTable->SetUpdateMode(sal_True); return nStart - 1; } } pTable->SetUpdateMode(sal_True); Init(nStart); // Alle Eintraege bis zum Ende abgleichen return USHRT_MAX; } /* -----------------05.06.98 13:57------------------- * * --------------------------------------------------*/ void SwRedlineAcceptDlg::InsertChilds(SwRedlineDataParent *pParent, const SwRedline& rRedln, const sal_uInt16 nAutoFmt) { String sChild; SwRedlineDataChild *pLastRedlineChild = 0; const SwRedlineData *pRedlineData = &rRedln.GetRedlineData(); sal_Bool bAutoFmt = (rRedln.GetRealType() & nAutoFmt) != 0; const String *pAction = &GetActionText(rRedln); sal_Bool bValidParent = !sFilterAction.Len() || sFilterAction == *pAction; bValidParent = bValidParent && pTable->IsValidEntry(&rRedln.GetAuthorString(), &rRedln.GetTimeStamp(), &rRedln.GetComment()); if (nAutoFmt) { sal_uInt16 nPos; if (pParent->pData->GetSeqNo() && !aUsedSeqNo.Insert(pParent, nPos)) // Gibts schon { if (pParent->pTLBParent) { pTable->SetEntryText(sAutoFormat, aUsedSeqNo[nPos]->pTLBParent, 0); pTable->RemoveEntry(pParent->pTLBParent); pParent->pTLBParent = 0; } return; } bValidParent = bValidParent && bAutoFmt; } sal_Bool bValidTree = bValidParent; for (sal_uInt16 nStack = 1; nStack < rRedln.GetStackCount(); nStack++) { pRedlineData = pRedlineData->Next(); SwRedlineDataChildPtr pRedlineChild = new SwRedlineDataChild; pRedlineChild->pChild = pRedlineData; aRedlineChilds.Insert(pRedlineChild, aRedlineChilds.Count()); if ( pLastRedlineChild ) pLastRedlineChild->pNext = pRedlineChild; else pParent->pNext = pRedlineChild; pAction = &GetActionText(rRedln, nStack); sal_Bool bValidChild = !sFilterAction.Len() || sFilterAction == *pAction; bValidChild = bValidChild && pTable->IsValidEntry(&rRedln.GetAuthorString(nStack), &rRedln.GetTimeStamp(nStack), &rRedln.GetComment()); if (nAutoFmt) bValidChild = bValidChild && bAutoFmt; bValidTree |= bValidChild; if (bValidChild) { RedlinData *pData = new RedlinData; pData->pData = pRedlineChild; pData->bDisabled = sal_True; sChild = GetRedlineText(rRedln, pData->aDateTime, nStack); SvLBoxEntry* pChild = pTable->InsertEntry(sChild, pData, pParent->pTLBParent); pRedlineChild->pTLBChild = pChild; if (!bValidParent) pTable->Expand(pParent->pTLBParent); } else pRedlineChild->pTLBChild = 0; pLastRedlineChild = pRedlineChild; } if (pLastRedlineChild) pLastRedlineChild->pNext = 0; if (!bValidTree && pParent->pTLBParent) { pTable->RemoveEntry(pParent->pTLBParent); pParent->pTLBParent = 0; if (nAutoFmt) aUsedSeqNo.Remove(pParent); } } /* -----------------05.06.98 15:20------------------- * * --------------------------------------------------*/ void SwRedlineAcceptDlg::RemoveParents(sal_uInt16 nStart, sal_uInt16 nEnd) { SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr(); sal_uInt16 nCount = pSh->GetRedlineCount(); SvLBoxEntryArr aLBoxArr; // Wegen Bug der TLB, die bei Remove den SelectHandler IMMER ruft: pTable->SetSelectHdl(aOldSelectHdl); pTable->SetDeselectHdl(aOldDeselectHdl); sal_Bool bChildsRemoved = sal_False; pTable->SelectAll(sal_False); // Hinter dem letzten Eintrag Cursor setzen, da sonst Performance-Problem in TLB. // TLB wuerde sonst bei jedem Remove den Cursor erneut umsetzen (teuer) sal_uInt16 nPos = Min((sal_uInt16)nCount, (sal_uInt16)aRedlineParents.Count()); SvLBoxEntry *pCurEntry = NULL; while( ( pCurEntry == NULL ) && ( nPos > 0 ) ) { --nPos; pCurEntry = aRedlineParents[nPos]->pTLBParent; } if (pCurEntry) pTable->SetCurEntry(pCurEntry); SvLBoxTreeList* pModel = pTable->GetModel(); for (sal_uInt16 i = nStart; i <= nEnd; i++) { if (!bChildsRemoved && aRedlineParents[i]->pNext) { SwRedlineDataChildPtr pChildPtr = (SwRedlineDataChildPtr)aRedlineParents[i]->pNext; sal_uInt16 nChildPos = aRedlineChilds.GetPos(pChildPtr); if (nChildPos != USHRT_MAX) { sal_uInt16 nChilds = 0; while (pChildPtr) { pChildPtr = (SwRedlineDataChildPtr)pChildPtr->pNext; nChilds++; } aRedlineChilds.DeleteAndDestroy(nChildPos, nChilds); bChildsRemoved = sal_True; } } SvLBoxEntry *pEntry = aRedlineParents[i]->pTLBParent; if (pEntry) { long nIdx = aLBoxArr.Count() - 1L; sal_uLong nAbsPos = pModel->GetAbsPos(pEntry); while (nIdx >= 0 && pModel->GetAbsPos(aLBoxArr[ static_cast< sal_uInt16 >(nIdx) ]) > nAbsPos) nIdx--; aLBoxArr.Insert( pEntry, static_cast< sal_uInt16 >(++nIdx) ); } } // TLB von hinten abraeumen long nIdx = (long)aLBoxArr.Count() - 1L; while (nIdx >= 0) pTable->RemoveEntry(aLBoxArr[ static_cast< sal_uInt16 >(nIdx--) ]); pTable->SetSelectHdl(LINK(this, SwRedlineAcceptDlg, SelectHdl)); pTable->SetDeselectHdl(LINK(this, SwRedlineAcceptDlg, DeselectHdl)); // Durch Remove wurde leider wieder dauernd von der TLB selektiert... pTable->SelectAll(sal_False); aRedlineParents.DeleteAndDestroy( nStart, nEnd - nStart + 1); } /* -----------------05.06.98 15:20------------------- * * --------------------------------------------------*/ void SwRedlineAcceptDlg::InsertParents(sal_uInt16 nStart, sal_uInt16 nEnd) { SwView *pView = ::GetActiveView(); SwWrtShell* pSh = pView->GetWrtShellPtr(); sal_uInt16 nAutoFmt = HasRedlineAutoFmt() ? nsRedlineType_t::REDLINE_FORM_AUTOFMT : 0; String sParent; const sal_uInt16 nCount = pSh->GetRedlineCount(); nEnd = Min((sal_uInt16)nEnd, (sal_uInt16)(nCount - 1)); // Handelt auch nEnd=USHRT_MAX (bis zum Ende) ab if (nEnd == USHRT_MAX) return; // Keine Redlines im Dokument RedlinData *pData; SvLBoxEntry *pParent; SwRedlineDataParentPtr pRedlineParent; const SwRedline* pCurrRedline; if( !nStart && !pTable->FirstSelected() ) { pCurrRedline = pSh->GetCurrRedline(); if( !pCurrRedline ) { pSh->SwCrsrShell::Push(); if( 0 == (pCurrRedline = pSh->SelNextRedline())) pCurrRedline = pSh->SelPrevRedline(); pSh->SwCrsrShell::Pop( sal_False ); } } else pCurrRedline = 0; for (sal_uInt16 i = nStart; i <= nEnd; i++) { const SwRedline& rRedln = pSh->GetRedline(i); const SwRedlineData *pRedlineData = &rRedln.GetRedlineData(); pRedlineParent = new SwRedlineDataParent; pRedlineParent->pData = pRedlineData; pRedlineParent->pNext = 0; String sComment(rRedln.GetComment()); sComment.SearchAndReplaceAll((sal_Unicode)_LF,(sal_Unicode)' '); pRedlineParent->sComment = sComment; aRedlineParents.Insert(pRedlineParent, i); pData = new RedlinData; pData->pData = pRedlineParent; pData->bDisabled = sal_False; sParent = GetRedlineText(rRedln, pData->aDateTime); pParent = pTable->InsertEntry(sParent, pData, 0, i); if( pCurrRedline == &rRedln ) { pTable->SetCurEntry( pParent ); pTable->Select( pParent ); pTable->MakeVisible( pParent ); } pRedlineParent->pTLBParent = pParent; InsertChilds(pRedlineParent, rRedln, nAutoFmt); } } /* -----------------05.06.98 13:06------------------- * * --------------------------------------------------*/ void SwRedlineAcceptDlg::CallAcceptReject( sal_Bool bSelect, sal_Bool bAccept ) { SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr(); SvLBoxEntry* pEntry = bSelect ? pTable->FirstSelected() : pTable->First(); sal_uLong nPos = LONG_MAX; typedef std::vector ListBoxEntries_t; ListBoxEntries_t aRedlines; // don't activate DBG_ASSERT( bInhibitActivate == false, "recursive call of CallAcceptReject?"); bInhibitActivate = true; // collect redlines-to-be-accepted/rejected in aRedlines vector while( pEntry ) { if( !pTable->GetParent( pEntry ) ) { if( bSelect && LONG_MAX == nPos ) nPos = pTable->GetModel()->GetAbsPos( pEntry ); RedlinData *pData = (RedlinData *)pEntry->GetUserData(); if( !pData->bDisabled ) aRedlines.push_back( pEntry ); } pEntry = bSelect ? pTable->NextSelected(pEntry) : pTable->Next(pEntry); } sal_Bool (SwEditShell:: *FnAccRej)( sal_uInt16 ) = &SwEditShell::AcceptRedline; if( !bAccept ) FnAccRej = &SwEditShell::RejectRedline; SwWait aWait( *pSh->GetView().GetDocShell(), true ); pSh->StartAction(); // #111827# if (aRedlines.size() > 1) { String aTmpStr; { SwRewriter aRewriter; aRewriter.AddRule(UNDO_ARG1, String::CreateFromInt32(aRedlines.size())); aTmpStr = aRewriter.Apply(String(SW_RES(STR_N_REDLINES))); } SwRewriter aRewriter; aRewriter.AddRule(UNDO_ARG1, aTmpStr); pSh->StartUndo(bAccept? UNDO_ACCEPT_REDLINE : UNDO_REJECT_REDLINE, &aRewriter); } // accept/reject the redlines in aRedlines. The absolute // position may change during the process (e.g. when two redlines // are merged in result of another one being deleted), so the // position must be resolved late and checked before using it. // (cf #102547#) ListBoxEntries_t::iterator aEnd = aRedlines.end(); for( ListBoxEntries_t::iterator aIter = aRedlines.begin(); aIter != aEnd; aIter++ ) { const sal_uInt16 nPosition = GetRedlinePos( **aIter ); if( nPosition != USHRT_MAX ) (pSh->*FnAccRej)( nPosition ); } // #111827# if (aRedlines.size() > 1) { pSh->EndUndo(); } pSh->EndAction(); bInhibitActivate = false; Activate(); if( ULONG_MAX != nPos && pTable->GetEntryCount() ) { if( nPos >= pTable->GetEntryCount() ) nPos = pTable->GetEntryCount() - 1; pEntry = pTable->GetEntry( nPos ); if( !pEntry && nPos-- ) pEntry = pTable->GetEntry( nPos ); if( pEntry ) { pTable->Select( pEntry ); pTable->MakeVisible( pEntry ); pTable->SetCurEntry(pEntry); } } pTPView->EnableUndo(); } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ sal_uInt16 SwRedlineAcceptDlg::GetRedlinePos( const SvLBoxEntry& rEntry ) const { SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr(); return pSh->FindRedlineOfData( *((SwRedlineDataParent*)((RedlinData *) rEntry.GetUserData())->pData)->pData ); } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ IMPL_LINK( SwRedlineAcceptDlg, AcceptHdl, void*, EMPTYARG) { CallAcceptReject( sal_True, sal_True ); return 0; } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ IMPL_LINK( SwRedlineAcceptDlg, AcceptAllHdl, void*, EMPTYARG ) { CallAcceptReject( sal_False, sal_True ); return 0; } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ IMPL_LINK( SwRedlineAcceptDlg, RejectHdl, void*, EMPTYARG ) { CallAcceptReject( sal_True, sal_False ); return 0; } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ IMPL_LINK( SwRedlineAcceptDlg, RejectAllHdl, void*, EMPTYARG ) { CallAcceptReject( sal_False, sal_False ); return 0; } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ IMPL_LINK( SwRedlineAcceptDlg, UndoHdl, void*, EMPTYARG ) { SwView * pView = ::GetActiveView(); pView->GetViewFrame()->GetDispatcher()-> Execute(SID_UNDO, SFX_CALLMODE_SYNCHRON); pTPView->EnableUndo(pView->GetSlotState(SID_UNDO) != 0); Activate(); return 0; } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ IMPL_LINK( SwRedlineAcceptDlg, FilterChangedHdl, void*, EMPTYARG ) { SvxTPFilter *pFilterTP = aTabPagesCTRL.GetFilterPage(); if (pFilterTP->IsAction()) sFilterAction = pFilterTP->GetLbAction()->GetSelectEntry(); else sFilterAction = aEmptyStr; Init(); return 0; } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ IMPL_LINK( SwRedlineAcceptDlg, DeselectHdl, void*, EMPTYARG ) { // Flackern der Buttons vermeiden: aDeselectTimer.Start(); return 0; } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ IMPL_LINK( SwRedlineAcceptDlg, SelectHdl, void*, EMPTYARG ) { aDeselectTimer.Stop(); aSelectTimer.Start(); return 0; } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ IMPL_LINK( SwRedlineAcceptDlg, GotoHdl, void*, EMPTYARG ) { SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr(); aSelectTimer.Stop(); sal_Bool bIsNotFormated = sal_False; sal_Bool bSel = sal_False; //#98883# don't select redlines while the dialog is not focussed //#107938# But not only ask pTable if it has the focus. To move // the selection to the selected redline any child of pParentDlg // may the focus. SvLBoxEntry* pSelEntry = 0; if (pParentDlg->HasChildPathFocus()) pSelEntry = pTable->FirstSelected(); if( pSelEntry ) { SvLBoxEntry* pActEntry = pSelEntry; pSh->StartAction(); pSh->EnterStdMode(); pSh->SetCareWin(pParentDlg); while (pSelEntry) { if (pTable->GetParent(pSelEntry)) { pActEntry = pTable->GetParent(pSelEntry); if (pTable->IsSelected(pActEntry)) { pSelEntry = pActEntry = pTable->NextSelected(pSelEntry); continue; // Nicht zweimal selektieren } } else bSel = sal_True; // #98864# find the selected redline (ignore, if the redline is already gone) const sal_uInt16 nPos = GetRedlinePos(*pActEntry); if ( nPos < pSh->GetRedlineCount() ) { const SwRedline& rRedln = pSh->GetRedline( nPos ); bIsNotFormated |= nsRedlineType_t::REDLINE_FORMAT != rRedln.GetType(); if (pSh->GotoRedline(nPos, sal_True)) { pSh->SetInSelect(); pSh->EnterAddMode(); } } pSelEntry = pActEntry = pTable->NextSelected(pSelEntry); } pSh->LeaveAddMode(); pSh->EndAction(); pSh->SetCareWin(NULL); } sal_Bool bEnable = !pSh->getIDocumentRedlineAccess()->GetRedlinePassword().getLength(); pTPView->EnableAccept( bEnable && bSel /*&& !bReadonlySel*/ ); pTPView->EnableReject( bEnable && bSel && bIsNotFormated /*&& !bReadonlySel*/ ); pTPView->EnableRejectAll( bEnable && !bOnlyFormatedRedlines && !bHasReadonlySel ); return 0; } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ IMPL_LINK( SwRedlineAcceptDlg, CommandHdl, void*, EMPTYARG ) { const CommandEvent aCEvt(pTable->GetCommandEvent()); switch ( aCEvt.GetCommand() ) { case COMMAND_CONTEXTMENU: { SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr(); SvLBoxEntry* pEntry = pTable->FirstSelected(); const SwRedline *pRed = 0; if (pEntry) { SvLBoxEntry* pTopEntry = pEntry; if (pTable->GetParent(pEntry)) pTopEntry = pTable->GetParent(pEntry); const sal_uInt16 nPos = GetRedlinePos(*pTopEntry); // Bei geschuetzten Bereichen kommentieren disablen if ((pRed = pSh->GotoRedline(nPos, sal_True)) != 0) { if( pSh->IsCrsrPtAtEnd() ) pSh->SwapPam(); pSh->SetInSelect(); } } aPopup.EnableItem( MN_EDIT_COMMENT, pEntry && pRed && !pTable->GetParent(pEntry) && !pTable->NextSelected(pEntry) //JP 27.9.2001: make no sense if we handle readonly sections // && pRed->HasReadonlySel() ); aPopup.EnableItem( MN_SUB_SORT, pTable->First() != 0 ); sal_uInt16 nColumn = pTable->GetSortedCol(); if (nColumn == 0xffff) nColumn = 4; PopupMenu *pSubMenu = aPopup.GetPopupMenu(MN_SUB_SORT); if (pSubMenu) { for (sal_uInt16 i = MN_SORT_ACTION; i < MN_SORT_ACTION + 5; i++) pSubMenu->CheckItem(i, sal_False); pSubMenu->CheckItem(nColumn + MN_SORT_ACTION); } sal_uInt16 nRet = aPopup.Execute(pTable, aCEvt.GetMousePosPixel()); switch( nRet ) { case MN_EDIT_COMMENT: { String sComment; if (pEntry) { if (pTable->GetParent(pEntry)) pEntry = pTable->GetParent(pEntry); const sal_uInt16 nPos = GetRedlinePos(*pEntry); if ( nPos >= pSh->GetRedlineCount() ) { break; } const SwRedline &rRedline = pSh->GetRedline(nPos); /* enable again once we have redline comments in the margin sComment = rRedline.GetComment(); if ( sComment == String(::rtl::OUString::createFromAscii("")) ) GetActiveView()->GetDocShell()->Broadcast(SwRedlineHint(&rRedline,SWREDLINE_INSERTED)); const_cast(rRedline).Broadcast(SwRedlineHint(&rRedline,SWREDLINE_FOCUS)); */ sComment = rRedline.GetComment(); SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); DBG_ASSERT(pFact, "Dialogdiet fail!"); ::DialogGetRanges fnGetRange = pFact->GetDialogGetRangesFunc( RID_SVXDLG_POSTIT ); DBG_ASSERT(fnGetRange, "Dialogdiet fail! GetRanges()"); SfxItemSet aSet( pSh->GetAttrPool(), fnGetRange() ); aSet.Put(SvxPostItTextItem(sComment.ConvertLineEnd(), SID_ATTR_POSTIT_TEXT)); aSet.Put(SvxPostItAuthorItem(rRedline.GetAuthorString(), SID_ATTR_POSTIT_AUTHOR)); aSet.Put(SvxPostItDateItem( GetAppLangDateTimeString( rRedline.GetRedlineData().GetTimeStamp() ), SID_ATTR_POSTIT_DATE )); AbstractSvxPostItDialog* pDlg = pFact->CreateSvxPostItDialog( pParentDlg, aSet, sal_False ); DBG_ASSERT(pDlg, "Dialogdiet fail!"); pDlg->HideAuthor(); sal_uInt16 nResId = 0; switch( rRedline.GetType() ) { case nsRedlineType_t::REDLINE_INSERT: nResId = STR_REDLINE_INSERTED; break; case nsRedlineType_t::REDLINE_DELETE: nResId = STR_REDLINE_DELETED; break; case nsRedlineType_t::REDLINE_FORMAT: nResId = STR_REDLINE_FORMATED; break; case nsRedlineType_t::REDLINE_TABLE: nResId = STR_REDLINE_TABLECHG; break; default:;//prevent warning } String sTitle(SW_RES(STR_REDLINE_COMMENT)); if( nResId ) sTitle += SW_RESSTR( nResId ); pDlg->SetText(sTitle); pSh->SetCareWin(pDlg->GetWindow()); if ( pDlg->Execute() == RET_OK ) { const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); String sMsg(((const SvxPostItTextItem&)pOutSet->Get(SID_ATTR_POSTIT_TEXT)).GetValue()); // Kommentar einfuegen bzw aendern pSh->SetRedlineComment(sMsg); sMsg.SearchAndReplaceAll((sal_Unicode)_LF,(sal_Unicode)' '); pTable->SetEntryText(sMsg, pEntry, 3); } delete pDlg; pSh->SetCareWin(NULL); } } break; case MN_SORT_ACTION: case MN_SORT_AUTHOR: case MN_SORT_DATE: case MN_SORT_COMMENT: case MN_SORT_POSITION: { bSortDir = sal_True; if (nRet - MN_SORT_ACTION == 4 && pTable->GetSortedCol() == 0xffff) break; // Haben wir schon nSortMode = nRet - MN_SORT_ACTION; if (nSortMode == 4) nSortMode = 0xffff; // unsortiert bzw sortiert nach Position if (pTable->GetSortedCol() == nSortMode) bSortDir = !pTable->GetSortDirection(); SwWait aWait( *::GetActiveView()->GetDocShell(), false ); pTable->SortByCol(nSortMode, bSortDir); if (nSortMode == 0xffff) Init(); // Alles neu fuellen } break; } } break; } return 0; } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ void SwRedlineAcceptDlg::Initialize(const String& rExtraData) { if (rExtraData.Len()) { sal_uInt16 nPos = rExtraData.Search(C2S("AcceptChgDat:")); // Versuche, den Alignment-String "ALIGN:(...)" einzulesen; wenn // er nicht vorhanden ist, liegt eine "altere Version vor if (nPos != STRING_NOTFOUND) { sal_uInt16 n1 = rExtraData.Search('(', nPos); if (n1 != STRING_NOTFOUND) { sal_uInt16 n2 = rExtraData.Search(')', n1); if (n2 != STRING_NOTFOUND) { // Alignment-String herausschneiden String aStr = rExtraData.Copy(nPos, n2 - nPos + 1); aStr.Erase(0, n1 - nPos + 1); if (aStr.Len()) { sal_uInt16 nCount = static_cast< sal_uInt16 >(aStr.ToInt32()); for (sal_uInt16 i = 0; i < nCount; i++) { sal_uInt16 n3 = aStr.Search(';'); aStr.Erase(0, n3 + 1); pTable->SetTab(i, aStr.ToInt32(), MAP_PIXEL); } } } } } } } /*-------------------------------------------------------------------- Beschreibung: --------------------------------------------------------------------*/ void SwRedlineAcceptDlg::FillInfo(String &rExtraData) const { rExtraData.AppendAscii("AcceptChgDat:("); sal_uInt16 nCount = pTable->TabCount(); rExtraData += String::CreateFromInt32(nCount); rExtraData += ';'; for(sal_uInt16 i = 0; i < nCount; i++) { rExtraData += String::CreateFromInt32( pTable->GetTab(i) ); rExtraData += ';'; } rExtraData += ')'; }