/************************************************************** * * 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_sc.hxx" // INCLUDE --------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "content.hxx" #include "navipi.hxx" #include "global.hxx" #include "docsh.hxx" #include "scmod.hxx" #include "rangenam.hxx" #include "dbcolect.hxx" #include "tablink.hxx" // fuer Loader #include "popmenu.hxx" #include "drwlayer.hxx" #include "transobj.hxx" #include "drwtrans.hxx" #include "lnktrans.hxx" #include "cell.hxx" #include "dociter.hxx" #include "scresid.hxx" #include "globstr.hrc" #include "navipi.hrc" #include "arealink.hxx" #include "navicfg.hxx" #include "navsett.hxx" #include "postit.hxx" #include "clipparam.hxx" using namespace com::sun::star; // Reihenfolge der Kategorien im Navigator ------------------------------------- static sal_uInt16 pTypeList[SC_CONTENT_COUNT] = { SC_CONTENT_ROOT, // ROOT (0) muss vorne stehen SC_CONTENT_TABLE, SC_CONTENT_RANGENAME, SC_CONTENT_DBAREA, SC_CONTENT_AREALINK, SC_CONTENT_GRAPHIC, SC_CONTENT_OLEOBJECT, SC_CONTENT_NOTE, SC_CONTENT_DRAWING }; sal_Bool ScContentTree::bIsInDrag = sal_False; ScDocShell* ScContentTree::GetManualOrCurrent() { ScDocShell* pSh = NULL; if ( aManualDoc.Len() ) { TypeId aScType = TYPE(ScDocShell); SfxObjectShell* pObjSh = SfxObjectShell::GetFirst( &aScType ); while ( pObjSh && !pSh ) { if ( pObjSh->GetTitle() == aManualDoc ) pSh = PTR_CAST( ScDocShell, pObjSh ); pObjSh = SfxObjectShell::GetNext( *pObjSh, &aScType ); } } else { // Current nur, wenn keine manuell eingestellt ist // (damit erkannt wird, wenn das Dokument nicht mehr existiert) SfxViewShell* pViewSh = SfxViewShell::Current(); if ( pViewSh ) { SfxObjectShell* pObjSh = pViewSh->GetViewFrame()->GetObjectShell(); pSh = PTR_CAST( ScDocShell, pObjSh ); } } return pSh; } // // ScContentTree // ScContentTree::ScContentTree( Window* pParent, const ResId& rResId ) : SvTreeListBox ( pParent, rResId ), aEntryImages ( ScResId( RID_IMAGELIST_NAVCONT ) ), aHCEntryImages ( ScResId( RID_IMAGELIST_H_NAVCONT ) ), nRootType ( SC_CONTENT_ROOT ), bHiddenDoc ( sal_False ), pHiddenDocument ( NULL ) { sal_uInt16 i; for (i=0; iRemove( pParent ); // mit allen Children InitRoot( nType ); // ggf. neu eintragen } } } void ScContentTree::InsertContent( sal_uInt16 nType, const String& rValue ) { if (nType >= SC_CONTENT_COUNT) { DBG_ERROR("ScContentTree::InsertContent mit falschem Typ"); return; } SvLBoxEntry* pParent = pRootNodes[nType]; if (pParent) InsertEntry( rValue, pParent ); else { DBG_ERROR("InsertContent ohne Parent"); } } void ScContentTree::GetEntryIndexes( sal_uInt16& rnRootIndex, sal_uLong& rnChildIndex, SvLBoxEntry* pEntry ) const { rnRootIndex = SC_CONTENT_ROOT; rnChildIndex = SC_CONTENT_NOCHILD; if( !pEntry ) return; SvLBoxEntry* pParent = GetParent( pEntry ); bool bFound = false; for( sal_uInt16 nRoot = 1; !bFound && (nRoot < SC_CONTENT_COUNT); ++nRoot ) { if( pEntry == pRootNodes[ nRoot ] ) { rnRootIndex = nRoot; rnChildIndex = ~0UL; bFound = true; } else if( pParent && (pParent == pRootNodes[ nRoot ]) ) { rnRootIndex = nRoot; // search the entry in all child entries of the parent sal_uLong nEntry = 0; SvLBoxEntry* pIterEntry = FirstChild( pParent ); while( !bFound && pIterEntry ) { if ( pEntry == pIterEntry ) { rnChildIndex = nEntry; bFound = true; // exit the while loop } pIterEntry = NextSibling( pIterEntry ); ++nEntry; } bFound = true; // exit the for loop } } } sal_uLong ScContentTree::GetChildIndex( SvLBoxEntry* pEntry ) const { sal_uInt16 nRoot; sal_uLong nChild; GetEntryIndexes( nRoot, nChild, pEntry ); return nChild; } String lcl_GetDBAreaRange( ScDocument* pDoc, const String& rDBName ) { String aRet; if (pDoc) { ScDBCollection* pDbNames = pDoc->GetDBCollection(); sal_uInt16 nCount = pDbNames->GetCount(); for ( sal_uInt16 i=0; iGetName() == rDBName ) { ScRange aRange; pData->GetArea(aRange); aRange.Format( aRet, SCR_ABS_3D, pDoc ); break; } } } return aRet; } IMPL_LINK( ScContentTree, ContentDoubleClickHdl, ScContentTree *, EMPTYARG ) { sal_uInt16 nType; sal_uLong nChild; SvLBoxEntry* pEntry = GetCurEntry(); GetEntryIndexes( nType, nChild, pEntry ); if( pEntry && (nType != SC_CONTENT_ROOT) && (nChild != SC_CONTENT_NOCHILD) ) { if ( bHiddenDoc ) return 0; //! spaeter... String aText( GetEntryText( pEntry ) ); if ( aManualDoc.Len() ) pParentWindow->SetCurrentDoc( aManualDoc ); switch( nType ) { case SC_CONTENT_TABLE: pParentWindow->SetCurrentTableStr( aText ); break; case SC_CONTENT_RANGENAME: pParentWindow->SetCurrentCellStr( aText ); break; case SC_CONTENT_DBAREA: { // #47905# Wenn gleiche Bereichs- und DB-Namen existieren, wird // bei SID_CURRENTCELL der Bereichsname genommen. // DB-Bereiche darum direkt ueber die Adresse anspringen. String aRangeStr = lcl_GetDBAreaRange( GetSourceDocument(), aText ); if (aRangeStr.Len()) pParentWindow->SetCurrentCellStr( aRangeStr ); } break; case SC_CONTENT_OLEOBJECT: case SC_CONTENT_GRAPHIC: case SC_CONTENT_DRAWING: pParentWindow->SetCurrentObject( aText ); break; case SC_CONTENT_NOTE: { ScAddress aPos = GetNotePos( nChild ); pParentWindow->SetCurrentTable( aPos.Tab() ); pParentWindow->SetCurrentCell( aPos.Col(), aPos.Row() ); } break; case SC_CONTENT_AREALINK: { const ScAreaLink* pLink = GetLink( nChild ); if( pLink ) { ScRange aRange = pLink->GetDestArea(); String aRangeStr; ScDocument* pSrcDoc = GetSourceDocument(); aRange.Format( aRangeStr, SCR_ABS_3D, pSrcDoc, pSrcDoc->GetAddressConvention() ); pParentWindow->SetCurrentCellStr( aRangeStr ); } } break; } ScNavigatorDlg::ReleaseFocus(); // set focus into document } return 0; } void ScContentTree::MouseButtonDown( const MouseEvent& rMEvt ) { SvTreeListBox::MouseButtonDown( rMEvt ); StoreSettings(); } void ScContentTree::KeyInput( const KeyEvent& rKEvt ) { sal_Bool bUsed = sal_False; const KeyCode aCode = rKEvt.GetKeyCode(); if (aCode.GetCode() == KEY_RETURN) { switch (aCode.GetModifier()) { case KEY_MOD1: ToggleRoot(); // toggle root mode (as in Writer) bUsed = sal_True; break; case 0: { SvLBoxEntry* pEntry = GetCurEntry(); if( pEntry ) { sal_uInt16 nType; sal_uLong nChild; GetEntryIndexes( nType, nChild, pEntry ); if( (nType != SC_CONTENT_ROOT) && (nChild == SC_CONTENT_NOCHILD) ) { String aText( GetEntryText( pEntry ) ); if ( IsExpanded( pEntry ) ) Collapse( pEntry ); else Expand( pEntry ); } else ContentDoubleClickHdl(0); // select content as if double clicked } bUsed = sal_True; } break; } } StoreSettings(); if( !bUsed ) SvTreeListBox::KeyInput(rKEvt); } //sal_Bool __EXPORT ScContentTree::Drop( const DropEvent& rEvt ) //{ // return pParentWindow->Drop(rEvt); // Drop auf Navigator //} //sal_Bool __EXPORT ScContentTree::QueryDrop( DropEvent& rEvt ) //{ // return pParentWindow->QueryDrop(rEvt); // Drop auf Navigator //} sal_Int8 ScContentTree::AcceptDrop( const AcceptDropEvent& /* rEvt */ ) { return DND_ACTION_NONE; } sal_Int8 ScContentTree::ExecuteDrop( const ExecuteDropEvent& /* rEvt */ ) { return DND_ACTION_NONE; } void ScContentTree::StartDrag( sal_Int8 /* nAction */, const Point& /* rPosPixel */ ) { DoDrag(); } void ScContentTree::DragFinished( sal_Int8 /* nAction */ ) { } void __EXPORT ScContentTree::Command( const CommandEvent& rCEvt ) { sal_Bool bDone = sal_False; switch ( rCEvt.GetCommand() ) { case COMMAND_STARTDRAG: // Aus dem ExecuteDrag heraus kann der Navigator geloescht werden // (beim Umschalten auf einen anderen Dokument-Typ), das wuerde aber // den StarView MouseMove-Handler, der Command() aufruft, umbringen. // Deshalb Drag&Drop asynchron: // DoDrag(); Application::PostUserEvent( STATIC_LINK( this, ScContentTree, ExecDragHdl ) ); bDone = sal_True; break; case COMMAND_CONTEXTMENU: { // Drag-Drop Modus PopupMenu aPop; ScPopupMenu aDropMenu( ScResId( RID_POPUP_DROPMODE ) ); aDropMenu.CheckItem( RID_DROPMODE_URL + pParentWindow->GetDropMode() ); aPop.InsertItem( 1, pParentWindow->GetStrDragMode() ); aPop.SetPopupMenu( 1, &aDropMenu ); // angezeigtes Dokument ScPopupMenu aDocMenu; aDocMenu.SetMenuFlags( aDocMenu.GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS ); sal_uInt16 i=0; sal_uInt16 nPos=0; // geladene Dokumente ScDocShell* pCurrentSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() ); SfxObjectShell* pSh = SfxObjectShell::GetFirst(); while ( pSh ) { if ( pSh->ISA(ScDocShell) ) { String aName = pSh->GetTitle(); String aEntry = aName; if ( pSh == pCurrentSh ) aEntry += pParentWindow->aStrActive; else aEntry += pParentWindow->aStrNotActive; aDocMenu.InsertItem( ++i, aEntry ); if ( !bHiddenDoc && aName == aManualDoc ) nPos = i; } pSh = SfxObjectShell::GetNext( *pSh ); } // "aktives Fenster" aDocMenu.InsertItem( ++i, pParentWindow->aStrActiveWin ); if (!bHiddenDoc && !aManualDoc.Len()) nPos = i; // verstecktes Dokument if ( aHiddenTitle.Len() ) { String aEntry = aHiddenTitle; aEntry += pParentWindow->aStrHidden; aDocMenu.InsertItem( ++i, aEntry ); if (bHiddenDoc) nPos = i; } aDocMenu.CheckItem( nPos ); aPop.InsertItem( 2, pParentWindow->GetStrDisplay() ); aPop.SetPopupMenu( 2, &aDocMenu ); // ausfuehren aPop.Execute( this, rCEvt.GetMousePosPixel() ); if ( aDropMenu.WasHit() ) // Drag-Drop Modus { sal_uInt16 nId = aDropMenu.GetSelected(); if ( nId >= RID_DROPMODE_URL && nId <= RID_DROPMODE_COPY ) pParentWindow->SetDropMode( nId - RID_DROPMODE_URL ); } else if ( aDocMenu.WasHit() ) // angezeigtes Dokument { sal_uInt16 nId = aDocMenu.GetSelected(); String aName = aDocMenu.GetItemText(nId); SelectDoc( aName ); } } break; } if (!bDone) SvTreeListBox::Command(rCEvt); } void __EXPORT ScContentTree::RequestHelp( const HelpEvent& rHEvt ) { sal_Bool bDone = sal_False; if( rHEvt.GetMode() & HELPMODE_QUICK ) { Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() )); SvLBoxEntry* pEntry = GetEntry( aPos ); if ( pEntry ) { sal_Bool bRet = sal_False; String aHelpText; SvLBoxEntry* pParent = GetParent(pEntry); if ( !pParent ) // Top-Level ? { aHelpText = String::CreateFromInt32( GetChildCount(pEntry) ); aHelpText += ' '; aHelpText += GetEntryText(pEntry); bRet = sal_True; } else if ( pParent == pRootNodes[SC_CONTENT_NOTE] ) { aHelpText = GetEntryText(pEntry); // Notizen als Help-Text bRet = sal_True; } else if ( pParent == pRootNodes[SC_CONTENT_AREALINK] ) { sal_uLong nIndex = GetChildIndex(pEntry); if( nIndex != SC_CONTENT_NOCHILD ) { const ScAreaLink* pLink = GetLink(nIndex); if (pLink) { aHelpText = pLink->GetFile(); // Source-Datei als Help-Text bRet = sal_True; } } } if (bRet) { SvLBoxTab* pTab; SvLBoxString* pItem = (SvLBoxString*)(GetItem( pEntry, aPos.X(), &pTab )); if( pItem ) { aPos = GetEntryPosition( pEntry ); aPos.X() = GetTabPos( pEntry, pTab ); aPos = OutputToScreenPixel(aPos); Size aSize( pItem->GetSize( this, pEntry ) ); Rectangle aItemRect( aPos, aSize ); Help::ShowQuickHelp( this, aItemRect, aHelpText ); bDone = sal_True; } } } } if (!bDone) Window::RequestHelp( rHEvt ); } ScDocument* ScContentTree::GetSourceDocument() { if (bHiddenDoc) return pHiddenDocument; else { ScDocShell* pSh = GetManualOrCurrent(); if (pSh) return pSh->GetDocument(); } return NULL; } void ScContentTree::Refresh( sal_uInt16 nType ) { if ( bHiddenDoc && !pHiddenDocument ) return; // anderes Dokument angezeigt // wenn sich nichts geaendert hat, gleich abbrechen (gegen Geflacker) if ( nType == SC_CONTENT_NOTE ) if (!NoteStringsChanged()) return; if ( nType == SC_CONTENT_GRAPHIC ) if (!DrawNamesChanged(SC_CONTENT_GRAPHIC)) return; if ( nType == SC_CONTENT_OLEOBJECT ) if (!DrawNamesChanged(SC_CONTENT_OLEOBJECT)) return; if ( nType == SC_CONTENT_DRAWING ) if (!DrawNamesChanged(SC_CONTENT_DRAWING)) return; SetUpdateMode(sal_False); ClearType( nType ); if ( !nType || nType == SC_CONTENT_TABLE ) GetTableNames(); if ( !nType || nType == SC_CONTENT_RANGENAME ) GetAreaNames(); if ( !nType || nType == SC_CONTENT_DBAREA ) GetDbNames(); if ( !nType || nType == SC_CONTENT_GRAPHIC ) GetGraphicNames(); if ( !nType || nType == SC_CONTENT_OLEOBJECT ) GetOleNames(); if ( !nType || nType == SC_CONTENT_DRAWING ) GetDrawingNames(); if ( !nType || nType == SC_CONTENT_NOTE ) GetNoteStrings(); if ( !nType || nType == SC_CONTENT_AREALINK ) GetLinkNames(); ApplySettings(); SetUpdateMode(sal_True); } void ScContentTree::GetTableNames() { if ( nRootType && nRootType != SC_CONTENT_TABLE ) // ausgeblendet ? return; ScDocument* pDoc = GetSourceDocument(); if (!pDoc) return; String aName; SCTAB nCount = pDoc->GetTableCount(); for ( SCTAB i=0; iGetName( i, aName ); InsertContent( SC_CONTENT_TABLE, aName ); } } void ScContentTree::GetAreaNames() { if ( nRootType && nRootType != SC_CONTENT_RANGENAME ) // ausgeblendet ? return; ScDocument* pDoc = GetSourceDocument(); if (!pDoc) return; ScRangeName* pRangeNames = pDoc->GetRangeName(); sal_uInt16 nCount = pRangeNames->GetCount(); if ( nCount > 0 ) { sal_uInt16 nValidCount = 0; ScRange aDummy; sal_uInt16 i; for ( i=0; iIsValidReference(aDummy)) nValidCount++; } if ( nValidCount ) { ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ]; sal_uInt16 j; for ( i=0, j=0; iIsValidReference(aDummy)) ppSortArray[j++] = pData; } #ifndef ICC qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*), &ScRangeData_QsortNameCompare ); #else qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*), ICCQsortNameCompare ); #endif for ( j=0; jGetName() ); delete [] ppSortArray; } } } void ScContentTree::GetDbNames() { if ( nRootType && nRootType != SC_CONTENT_DBAREA ) // ausgeblendet ? return; ScDocument* pDoc = GetSourceDocument(); if (!pDoc) return; ScDBCollection* pDbNames = pDoc->GetDBCollection(); sal_uInt16 nCount = pDbNames->GetCount(); if ( nCount > 0 ) { String aStrNoName( ScGlobal::GetRscString(STR_DB_NONAME) ); for ( sal_uInt16 i=0; iGetName(); //if ( aStrName != aStrNoName ) if ( !pData->IsBuildin() ) InsertContent( SC_CONTENT_DBAREA, aStrName ); } } } bool ScContentTree::IsPartOfType( sal_uInt16 nContentType, sal_uInt16 nObjIdentifier ) // static { bool bRet = false; switch ( nContentType ) { case SC_CONTENT_GRAPHIC: bRet = ( nObjIdentifier == OBJ_GRAF ); break; case SC_CONTENT_OLEOBJECT: bRet = ( nObjIdentifier == OBJ_OLE2 ); break; case SC_CONTENT_DRAWING: bRet = ( nObjIdentifier != OBJ_GRAF && nObjIdentifier != OBJ_OLE2 ); // everything else break; default: DBG_ERROR("unknown content type"); } return bRet; } void ScContentTree::GetDrawNames( sal_uInt16 nType ) { if ( nRootType && nRootType != nType ) // ausgeblendet ? return; ScDocument* pDoc = GetSourceDocument(); if (!pDoc) return; // iterate in flat mode for groups SdrIterMode eIter = ( nType == SC_CONTENT_DRAWING ) ? IM_FLAT : IM_DEEPNOGROUPS; ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); SfxObjectShell* pShell = pDoc->GetDocumentShell(); if (pDrawLayer && pShell) { SCTAB nTabCount = pDoc->GetTableCount(); for (SCTAB nTab=0; nTabGetPage(static_cast(nTab)); DBG_ASSERT(pPage,"Page ?"); if (pPage) { SdrObjListIter aIter( *pPage, eIter ); SdrObject* pObject = aIter.Next(); while (pObject) { if ( IsPartOfType( nType, pObject->GetObjIdentifier() ) ) { String aName = ScDrawLayer::GetVisibleName( pObject ); if (aName.Len()) InsertContent( nType, aName ); } pObject = aIter.Next(); } } } } } void ScContentTree::GetGraphicNames() { GetDrawNames( SC_CONTENT_GRAPHIC ); } void ScContentTree::GetOleNames() { GetDrawNames( SC_CONTENT_OLEOBJECT ); } void ScContentTree::GetDrawingNames() { GetDrawNames( SC_CONTENT_DRAWING ); } void ScContentTree::GetLinkNames() { if ( nRootType && nRootType != SC_CONTENT_AREALINK ) // ausgeblendet ? return; ScDocument* pDoc = GetSourceDocument(); if (!pDoc) return; sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager(); DBG_ASSERT(pLinkManager, "kein LinkManager am Dokument?"); const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks(); sal_uInt16 nCount = rLinks.Count(); for (sal_uInt16 i=0; iISA(ScAreaLink)) InsertContent( SC_CONTENT_AREALINK, ((ScAreaLink*)pBase)->GetSource() ); // in der Liste die Namen der Quellbereiche } } const ScAreaLink* ScContentTree::GetLink( sal_uLong nIndex ) { ScDocument* pDoc = GetSourceDocument(); if (!pDoc) return NULL; sal_uLong nFound = 0; sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager(); DBG_ASSERT(pLinkManager, "kein LinkManager am Dokument?"); const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks(); sal_uInt16 nCount = rLinks.Count(); for (sal_uInt16 i=0; iISA(ScAreaLink)) { if (nFound == nIndex) return (const ScAreaLink*) pBase; ++nFound; } } DBG_ERROR("Link nicht gefunden"); return NULL; } String lcl_NoteString( const ScPostIt& rNote ) { String aText = rNote.GetText(); xub_StrLen nAt; while ( (nAt = aText.Search( '\n' )) != STRING_NOTFOUND ) aText.SetChar( nAt, ' ' ); return aText; } void ScContentTree::GetNoteStrings() { if ( nRootType && nRootType != SC_CONTENT_NOTE ) // ausgeblendet ? return; ScDocument* pDoc = GetSourceDocument(); if (!pDoc) return; SCTAB nTabCount = pDoc->GetTableCount(); for (SCTAB nTab=0; nTabGetNote() ) InsertContent( SC_CONTENT_NOTE, lcl_NoteString( *pNote ) ); } } ScAddress ScContentTree::GetNotePos( sal_uLong nIndex ) { ScDocument* pDoc = GetSourceDocument(); if (!pDoc) return ScAddress(); sal_uLong nFound = 0; SCTAB nTabCount = pDoc->GetTableCount(); for (SCTAB nTab=0; nTabHasNote() ) { if (nFound == nIndex) return ScAddress( aIter.GetCol(), aIter.GetRow(), nTab ); // gefunden ++nFound; } pCell = aIter.GetNext(); } } DBG_ERROR("Notiz nicht gefunden"); return ScAddress(); } sal_Bool ScContentTree::NoteStringsChanged() { ScDocument* pDoc = GetSourceDocument(); if (!pDoc) return sal_False; SvLBoxEntry* pParent = pRootNodes[SC_CONTENT_NOTE]; if (!pParent) return sal_False; SvLBoxEntry* pEntry = FirstChild( pParent ); sal_Bool bEqual = sal_True; SCTAB nTabCount = pDoc->GetTableCount(); for (SCTAB nTab=0; nTabGetNote() ) { if ( !pEntry ) bEqual = sal_False; else { if ( lcl_NoteString( *pNote ) != GetEntryText(pEntry) ) bEqual = sal_False; pEntry = NextSibling( pEntry ); } } pCell = aIter.GetNext(); } } if ( pEntry ) bEqual = sal_False; // kommt noch was return !bEqual; } sal_Bool ScContentTree::DrawNamesChanged( sal_uInt16 nType ) { ScDocument* pDoc = GetSourceDocument(); if (!pDoc) return sal_False; SvLBoxEntry* pParent = pRootNodes[nType]; if (!pParent) return sal_False; SvLBoxEntry* pEntry = FirstChild( pParent ); // iterate in flat mode for groups SdrIterMode eIter = ( nType == SC_CONTENT_DRAWING ) ? IM_FLAT : IM_DEEPNOGROUPS; sal_Bool bEqual = sal_True; ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); SfxObjectShell* pShell = pDoc->GetDocumentShell(); if (pDrawLayer && pShell) { SCTAB nTabCount = pDoc->GetTableCount(); for (SCTAB nTab=0; nTabGetPage(static_cast(nTab)); DBG_ASSERT(pPage,"Page ?"); if (pPage) { SdrObjListIter aIter( *pPage, eIter ); SdrObject* pObject = aIter.Next(); while (pObject && bEqual) { if ( IsPartOfType( nType, pObject->GetObjIdentifier() ) ) { if ( !pEntry ) bEqual = sal_False; else { if ( ScDrawLayer::GetVisibleName( pObject ) != GetEntryText(pEntry) ) bEqual = sal_False; pEntry = NextSibling( pEntry ); } } pObject = aIter.Next(); } } } } if ( pEntry ) bEqual = sal_False; // kommt noch was return !bEqual; } sal_Bool lcl_GetRange( ScDocument* pDoc, sal_uInt16 nType, const String& rName, ScRange& rRange ) { sal_Bool bFound = sal_False; sal_uInt16 nPos; if ( nType == SC_CONTENT_RANGENAME ) { ScRangeName* pList = pDoc->GetRangeName(); if (pList) if (pList->SearchName( rName, nPos )) if ( (*pList)[nPos]->IsValidReference( rRange ) ) bFound = sal_True; } else if ( nType == SC_CONTENT_DBAREA ) { ScDBCollection* pList = pDoc->GetDBCollection(); if (pList) if (pList->SearchName( rName, nPos )) { SCTAB nTab; SCCOL nCol1, nCol2; SCROW nRow1, nRow2; (*pList)[nPos]->GetArea(nTab,nCol1,nRow1,nCol2,nRow2); rRange = ScRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab ); bFound = sal_True; } } return bFound; } void lcl_DoDragObject( ScDocShell* pSrcShell, const String& rName, sal_uInt16 nType, Window* pWin ) { ScDocument* pSrcDoc = pSrcShell->GetDocument(); ScDrawLayer* pModel = pSrcDoc->GetDrawLayer(); if (pModel) { sal_Bool bOle = ( nType == SC_CONTENT_OLEOBJECT ); sal_Bool bGraf = ( nType == SC_CONTENT_GRAPHIC ); sal_uInt16 nDrawId = sal::static_int_cast( bOle ? OBJ_OLE2 : ( bGraf ? OBJ_GRAF : OBJ_GRUP ) ); SCTAB nTab = 0; SdrObject* pObject = pModel->GetNamedObject( rName, nDrawId, nTab ); if (pObject) { SdrView aEditView( pModel ); aEditView.ShowSdrPage(aEditView.GetModel()->GetPage(nTab)); SdrPageView* pPV = aEditView.GetSdrPageView(); aEditView.MarkObj(pObject, pPV); SdrModel* pDragModel = aEditView.GetAllMarkedModel(); TransferableObjectDescriptor aObjDesc; pSrcShell->FillTransferableObjectDescriptor( aObjDesc ); aObjDesc.maDisplayName = pSrcShell->GetMedium()->GetURLObject().GetURLNoPass(); // maSize is set in ScDrawTransferObj ctor ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pDragModel, pSrcShell, aObjDesc ); uno::Reference xTransferable( pTransferObj ); pTransferObj->SetDragSourceObj( pObject, nTab ); pTransferObj->SetDragSourceFlags( SC_DROP_NAVIGATOR ); SC_MOD()->SetDragObject( NULL, pTransferObj ); pWin->ReleaseMouse(); pTransferObj->StartDrag( pWin, DND_ACTION_COPYMOVE | DND_ACTION_LINK ); } } } void lcl_DoDragCells( ScDocShell* pSrcShell, const ScRange& rRange, sal_uInt16 nFlags, Window* pWin ) { ScMarkData aMark; aMark.SelectTable( rRange.aStart.Tab(), sal_True ); aMark.SetMarkArea( rRange ); ScDocument* pSrcDoc = pSrcShell->GetDocument(); if ( !pSrcDoc->HasSelectedBlockMatrixFragment( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), aMark ) ) { ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); ScClipParam aClipParam(rRange, false); pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aMark); // pClipDoc->ExtendMerge( rRange, sal_True ); TransferableObjectDescriptor aObjDesc; pSrcShell->FillTransferableObjectDescriptor( aObjDesc ); aObjDesc.maDisplayName = pSrcShell->GetMedium()->GetURLObject().GetURLNoPass(); // maSize is set in ScTransferObj ctor ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc ); uno::Reference xTransferable( pTransferObj ); pTransferObj->SetDragSource( pSrcShell, aMark ); pTransferObj->SetDragSourceFlags( nFlags ); SC_MOD()->SetDragObject( pTransferObj, NULL ); // for internal D&D pWin->ReleaseMouse(); pTransferObj->StartDrag( pWin, DND_ACTION_COPYMOVE | DND_ACTION_LINK ); } } void ScContentTree::DoDrag() { ScDocumentLoader* pDocLoader = NULL; bIsInDrag = sal_True; ScModule* pScMod = SC_MOD(); sal_uInt16 nType; sal_uLong nChild; SvLBoxEntry* pEntry = GetCurEntry(); GetEntryIndexes( nType, nChild, pEntry ); if( pEntry && (nChild != SC_CONTENT_NOCHILD) && (nType != SC_CONTENT_ROOT) && (nType != SC_CONTENT_NOTE) && (nType != SC_CONTENT_AREALINK) ) { String aText( GetEntryText( pEntry ) ); ScDocument* pLocalDoc = NULL; // fuer URL-Drop String aDocName; if (bHiddenDoc) aDocName = aHiddenName; else { ScDocShell* pDocSh = GetManualOrCurrent(); if (pDocSh) { if (pDocSh->HasName()) aDocName = pDocSh->GetMedium()->GetName(); else pLocalDoc = pDocSh->GetDocument(); // Drop nur in dieses Dokument } } sal_Bool bDoLinkTrans = sal_False; // use ScLinkTransferObj String aLinkURL; // for ScLinkTransferObj String aLinkText; sal_uInt16 nDropMode = pParentWindow->GetDropMode(); switch ( nDropMode ) { case SC_DROPMODE_URL: { String aUrl = aDocName; aUrl += '#'; aUrl += aText; pScMod->SetDragJump( pLocalDoc, aUrl, aText ); if (aDocName.Len()) { // provide URL to outside only if the document has a name // (without name, only internal D&D via SetDragJump) aLinkURL = aUrl; aLinkText = aText; } bDoLinkTrans = sal_True; } break; case SC_DROPMODE_LINK: { if ( aDocName.Len() ) // link only to named documents { // for internal D&D, set flag to insert a link switch ( nType ) { case SC_CONTENT_TABLE: pScMod->SetDragLink( aDocName, aText, EMPTY_STRING ); bDoLinkTrans = sal_True; break; case SC_CONTENT_RANGENAME: case SC_CONTENT_DBAREA: pScMod->SetDragLink( aDocName, EMPTY_STRING, aText ); bDoLinkTrans = sal_True; break; // other types cannot be linked } } } break; case SC_DROPMODE_COPY: { ScDocShell* pSrcShell = NULL; if ( bHiddenDoc ) { String aFilter, aOptions; pDocLoader = new ScDocumentLoader( aHiddenName, aFilter, aOptions ); if (!pDocLoader->IsError()) pSrcShell = pDocLoader->GetDocShell(); } else pSrcShell = GetManualOrCurrent(); if ( pSrcShell ) { ScDocument* pSrcDoc = pSrcShell->GetDocument(); if ( nType == SC_CONTENT_RANGENAME || nType == SC_CONTENT_DBAREA ) { ScRange aRange; if ( lcl_GetRange( pSrcDoc, nType, aText, aRange ) ) { lcl_DoDragCells( pSrcShell, aRange, SC_DROP_NAVIGATOR, this ); } } else if ( nType == SC_CONTENT_TABLE ) { SCTAB nTab; if ( pSrcDoc->GetTable( aText, nTab ) ) { ScRange aRange( 0,0,nTab, MAXCOL,MAXROW,nTab ); lcl_DoDragCells( pSrcShell, aRange, SC_DROP_NAVIGATOR | SC_DROP_TABLE, this ); } } else if ( nType == SC_CONTENT_GRAPHIC || nType == SC_CONTENT_OLEOBJECT || nType == SC_CONTENT_DRAWING ) { lcl_DoDragObject( pSrcShell, aText, nType, this ); // in ExecuteDrag kann der Navigator geloescht worden sein // -> nicht mehr auf Member zugreifen !!! } } } break; } if (bDoLinkTrans) { ScLinkTransferObj* pTransferObj = new ScLinkTransferObj; uno::Reference xTransferable( pTransferObj ); if ( aLinkURL.Len() ) pTransferObj->SetLinkURL( aLinkURL, aLinkText ); // SetDragJump / SetDragLink has been done above ReleaseMouse(); pTransferObj->StartDrag( this, DND_ACTION_COPYMOVE | DND_ACTION_LINK ); } } bIsInDrag = sal_False; // static Member delete pDocLoader; // falls Dokument zum Draggen geladen wurde } IMPL_STATIC_LINK(ScContentTree, ExecDragHdl, void*, EMPTYARG) { // als Link, damit asynchron ohne ImpMouseMoveMsg auf dem Stack auch der // Navigator geloescht werden darf pThis->DoDrag(); return 0; } //UNUSED2008-05 void ScContentTree::AdjustTitle() //UNUSED2008-05 { //UNUSED2008-05 String aTitle = pParentWindow->aTitleBase; //UNUSED2008-05 if (bHiddenDoc) //UNUSED2008-05 { //UNUSED2008-05 aTitle.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " - " )); //UNUSED2008-05 aTitle += aHiddenTitle; //UNUSED2008-05 } //UNUSED2008-05 pParentWindow->SetText(aTitle); //UNUSED2008-05 } sal_Bool ScContentTree::LoadFile( const String& rUrl ) { String aDocName = rUrl; xub_StrLen nPos = aDocName.Search('#'); if ( nPos != STRING_NOTFOUND ) aDocName.Erase(nPos); // nur der Name, ohne #... sal_Bool bReturn = sal_False; String aFilter, aOptions; ScDocumentLoader aLoader( aDocName, aFilter, aOptions ); if ( !aLoader.IsError() ) { bHiddenDoc = sal_True; aHiddenName = aDocName; aHiddenTitle = aLoader.GetTitle(); pHiddenDocument = aLoader.GetDocument(); Refresh(); // Inhalte aus geladenem Dokument holen pHiddenDocument = NULL; // AdjustTitle(); pParentWindow->GetDocNames( &aHiddenTitle ); // Liste fuellen } else Sound::Beep(); // Fehler beim Laden // Dokument wird im dtor von ScDocumentLoader wieder geschlossen return bReturn; } void ScContentTree::InitWindowBits( sal_Bool bButtons ) { WinBits nFlags = GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL; if (bButtons) nFlags |= WB_HASBUTTONS|WB_HASBUTTONSATROOT; SetStyle( nFlags ); } void ScContentTree::SetRootType( sal_uInt16 nNew ) { if ( nNew != nRootType ) { nRootType = nNew; InitWindowBits( nNew == 0 ); Refresh(); ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg(); rCfg.SetRootType( nRootType ); } } void ScContentTree::ToggleRoot() // nach Selektion { sal_uInt16 nNew = SC_CONTENT_ROOT; if ( nRootType == SC_CONTENT_ROOT ) { SvLBoxEntry* pEntry = GetCurEntry(); if (pEntry) { SvLBoxEntry* pParent = GetParent(pEntry); for (sal_uInt16 i=1; iGetTitle(); else { // eingestelltes Dokument existiert nicht mehr aManualDoc.Erase(); // wieder automatisch Refresh(); pSh = GetManualOrCurrent(); // sollte jetzt aktives sein if (pSh) aCurrent = pSh->GetTitle(); } } pParentWindow->GetDocNames( &aCurrent ); // selektieren } void ScContentTree::SetManualDoc(const String& rName) { aManualDoc = rName; if (!bHiddenDoc) { Refresh(); pParentWindow->GetDocNames( &aManualDoc ); // selektieren } } void ScContentTree::SelectDoc(const String& rName) // rName wie im Menue/Listbox angezeigt { if ( rName == pParentWindow->aStrActiveWin ) { ResetManualDoc(); return; } // "aktiv" oder "inaktiv" weglassen String aRealName = rName; xub_StrLen nLen = rName.Len(); xub_StrLen nActiveStart = nLen - pParentWindow->aStrActive.Len(); if ( rName.Copy( nActiveStart ) == pParentWindow->aStrActive ) aRealName = rName.Copy( 0, nActiveStart ); xub_StrLen nNotActiveStart = nLen - pParentWindow->aStrNotActive.Len(); if ( rName.Copy( nNotActiveStart ) == pParentWindow->aStrNotActive ) aRealName = rName.Copy( 0, nNotActiveStart ); // sal_Bool bLoaded = sal_False; // ist es ein normal geladenes Doc ? SfxObjectShell* pSh = SfxObjectShell::GetFirst(); while ( pSh && !bLoaded ) { if ( pSh->ISA(ScDocShell) ) if ( pSh->GetTitle() == aRealName ) bLoaded = sal_True; pSh = SfxObjectShell::GetNext( *pSh ); } if (bLoaded) { bHiddenDoc = sal_False; SetManualDoc(aRealName); } else if (aHiddenTitle.Len()) // verstecktes ausgewaehlt { if (!bHiddenDoc) LoadFile(aHiddenName); } else { DBG_ERROR("SelectDoc: nicht gefunden"); } } void ScContentTree::ApplySettings() { const ScNavigatorSettings* pSettings = pParentWindow->GetNavigatorSettings(); if( pSettings ) { sal_uInt16 nRootSel = pSettings->GetRootSelected(); sal_uLong nChildSel = pSettings->GetChildSelected(); for( sal_uInt16 nEntry = 1; nEntry < SC_CONTENT_COUNT; ++nEntry ) { if( pRootNodes[ nEntry ] ) { // expand sal_Bool bExp = pSettings->IsExpanded( nEntry ); if( bExp != IsExpanded( pRootNodes[ nEntry ] ) ) { if( bExp ) Expand( pRootNodes[ nEntry ] ); else Collapse( pRootNodes[ nEntry ] ); } // select if( nRootSel == nEntry ) { SvLBoxEntry* pEntry = NULL; if( bExp && (nChildSel != SC_CONTENT_NOCHILD) ) pEntry = GetEntry( pRootNodes[ nEntry ], nChildSel ); Select( pEntry ? pEntry : pRootNodes[ nEntry ] ); } } } } } void ScContentTree::StoreSettings() const { ScNavigatorSettings* pSettings = pParentWindow->GetNavigatorSettings(); if( pSettings ) { for( sal_uInt16 nEntry = 1; nEntry < SC_CONTENT_COUNT; ++nEntry ) { sal_Bool bExp = pRootNodes[ nEntry ] && IsExpanded( pRootNodes[ nEntry ] ); pSettings->SetExpanded( nEntry, bExp ); } sal_uInt16 nRoot; sal_uLong nChild; GetEntryIndexes( nRoot, nChild, GetCurEntry() ); pSettings->SetRootSelected( nRoot ); pSettings->SetChildSelected( nChild ); } } // //------------------------------------------------------------------------ //