xref: /trunk/main/sc/source/ui/navipi/content.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 // INCLUDE ---------------------------------------------------------------
32 
33 #include <svx/svditer.hxx>
34 #include <svx/svdobj.hxx>
35 #include <svx/svdpage.hxx>
36 #include <svx/svdpagv.hxx>
37 #include <svx/svdview.hxx>
38 #include <svx/svdxcgv.hxx>
39 #include <sfx2/linkmgr.hxx>
40 #include <sfx2/docfile.hxx>
41 #include <sfx2/viewfrm.hxx>
42 #include <vcl/help.hxx>
43 #include <vcl/sound.hxx>
44 #include <vcl/svapp.hxx>
45 #include <tools/urlobj.hxx>
46 #include <svl/urlbmk.hxx>
47 #include <stdlib.h>
48 
49 #include "content.hxx"
50 #include "navipi.hxx"
51 #include "global.hxx"
52 #include "docsh.hxx"
53 #include "scmod.hxx"
54 #include "rangenam.hxx"
55 #include "dbcolect.hxx"
56 #include "tablink.hxx"			// fuer Loader
57 #include "popmenu.hxx"
58 #include "drwlayer.hxx"
59 #include "transobj.hxx"
60 #include "drwtrans.hxx"
61 #include "lnktrans.hxx"
62 #include "cell.hxx"
63 #include "dociter.hxx"
64 #include "scresid.hxx"
65 #include "globstr.hrc"
66 #include "navipi.hrc"
67 #include "arealink.hxx"
68 #include "navicfg.hxx"
69 #include "navsett.hxx"
70 #include "postit.hxx"
71 #include "clipparam.hxx"
72 
73 using namespace com::sun::star;
74 
75 //	Reihenfolge der Kategorien im Navigator -------------------------------------
76 
77 static sal_uInt16 pTypeList[SC_CONTENT_COUNT] =
78 {
79 	SC_CONTENT_ROOT,			// ROOT (0) muss vorne stehen
80 	SC_CONTENT_TABLE,
81 	SC_CONTENT_RANGENAME,
82 	SC_CONTENT_DBAREA,
83 	SC_CONTENT_AREALINK,
84 	SC_CONTENT_GRAPHIC,
85 	SC_CONTENT_OLEOBJECT,
86 	SC_CONTENT_NOTE,
87 	SC_CONTENT_DRAWING
88 };
89 
90 sal_Bool ScContentTree::bIsInDrag = sal_False;
91 
92 
93 ScDocShell* ScContentTree::GetManualOrCurrent()
94 {
95 	ScDocShell* pSh = NULL;
96 	if ( aManualDoc.Len() )
97 	{
98 		TypeId aScType = TYPE(ScDocShell);
99 		SfxObjectShell* pObjSh = SfxObjectShell::GetFirst( &aScType );
100 		while ( pObjSh && !pSh )
101 		{
102 			if ( pObjSh->GetTitle() == aManualDoc )
103 				pSh = PTR_CAST( ScDocShell, pObjSh );
104 			pObjSh = SfxObjectShell::GetNext( *pObjSh, &aScType );
105 		}
106 	}
107 	else
108 	{
109 		//	Current nur, wenn keine manuell eingestellt ist
110 		//	(damit erkannt wird, wenn das Dokument nicht mehr existiert)
111 
112 		SfxViewShell* pViewSh = SfxViewShell::Current();
113 		if ( pViewSh )
114 		{
115 			SfxObjectShell* pObjSh = pViewSh->GetViewFrame()->GetObjectShell();
116 			pSh = PTR_CAST( ScDocShell, pObjSh );
117 		}
118 	}
119 
120 	return pSh;
121 }
122 
123 //
124 //			ScContentTree
125 //
126 
127 ScContentTree::ScContentTree( Window* pParent, const ResId& rResId ) :
128 	SvTreeListBox	( pParent, rResId ),
129 	aEntryImages	( ScResId( RID_IMAGELIST_NAVCONT ) ),
130 	aHCEntryImages	( ScResId( RID_IMAGELIST_H_NAVCONT ) ),
131 	nRootType		( SC_CONTENT_ROOT ),
132 	bHiddenDoc		( sal_False ),
133 	pHiddenDocument	( NULL )
134 {
135 	sal_uInt16 i;
136 	for (i=0; i<SC_CONTENT_COUNT; i++)
137 		pPosList[pTypeList[i]] = i;			// invers zum suchen
138 
139 	pParentWindow = (ScNavigatorDlg*)pParent;
140 
141 	pRootNodes[0] = NULL;
142 	for (i=1; i<SC_CONTENT_COUNT; i++)
143 		InitRoot(i);
144 
145 	SetNodeDefaultImages();
146 
147     SetDoubleClickHdl( LINK( this, ScContentTree, ContentDoubleClickHdl ) );
148 
149     SetStyle( GetStyle() | WB_QUICK_SEARCH );
150 }
151 
152 ScContentTree::~ScContentTree()
153 {
154 }
155 
156 void ScContentTree::InitRoot( sal_uInt16 nType )
157 {
158 	if ( !nType )
159 		return;
160 
161 	if ( nRootType && nRootType != nType )				// ausgeblendet ?
162 	{
163 		pRootNodes[nType] = NULL;
164 		return;
165 	}
166 
167 	const Image& rImage = aEntryImages.GetImage( nType );
168 	String aName( ScResId( SCSTR_CONTENT_ROOT + nType ) );
169 	// wieder an die richtige Position:
170 	sal_uInt16 nPos = nRootType ? 0 : pPosList[nType]-1;
171 	SvLBoxEntry* pNew = InsertEntry( aName, rImage, rImage, NULL, sal_False, nPos );
172 
173 	const Image& rHCImage = aHCEntryImages.GetImage( nType );
174 	SetExpandedEntryBmp( pNew, rHCImage, BMP_COLOR_HIGHCONTRAST );
175 	SetCollapsedEntryBmp( pNew, rHCImage, BMP_COLOR_HIGHCONTRAST );
176 
177 	pRootNodes[nType] = pNew;
178 }
179 
180 void ScContentTree::ClearAll()
181 {
182 	Clear();
183 	for (sal_uInt16 i=1; i<SC_CONTENT_COUNT; i++)
184 		InitRoot(i);
185 }
186 
187 void ScContentTree::ClearType(sal_uInt16 nType)
188 {
189 	if (!nType)
190 		ClearAll();
191 	else
192 	{
193 		SvLBoxEntry* pParent = pRootNodes[nType];
194 		if ( !pParent || GetChildCount(pParent) )		// nicht, wenn ohne Children schon da
195 		{
196 			if (pParent)
197 				GetModel()->Remove( pParent );			// mit allen Children
198 			InitRoot( nType );							// ggf. neu eintragen
199 		}
200 	}
201 }
202 
203 void ScContentTree::InsertContent( sal_uInt16 nType, const String& rValue )
204 {
205 	if (nType >= SC_CONTENT_COUNT)
206 	{
207 		DBG_ERROR("ScContentTree::InsertContent mit falschem Typ");
208 		return;
209 	}
210 
211 	SvLBoxEntry* pParent = pRootNodes[nType];
212 	if (pParent)
213 		InsertEntry( rValue, pParent );
214 	else
215 	{
216 		DBG_ERROR("InsertContent ohne Parent");
217 	}
218 }
219 
220 void ScContentTree::GetEntryIndexes( sal_uInt16& rnRootIndex, sal_uLong& rnChildIndex, SvLBoxEntry* pEntry ) const
221 {
222     rnRootIndex = SC_CONTENT_ROOT;
223     rnChildIndex = SC_CONTENT_NOCHILD;
224 
225     if( !pEntry )
226         return;
227 
228     SvLBoxEntry* pParent = GetParent( pEntry );
229     bool bFound = false;
230     for( sal_uInt16 nRoot = 1; !bFound && (nRoot < SC_CONTENT_COUNT); ++nRoot )
231     {
232         if( pEntry == pRootNodes[ nRoot ] )
233         {
234             rnRootIndex = nRoot;
235             rnChildIndex = ~0UL;
236             bFound = true;
237         }
238         else if( pParent && (pParent == pRootNodes[ nRoot ]) )
239         {
240             rnRootIndex = nRoot;
241 
242             // search the entry in all child entries of the parent
243             sal_uLong nEntry = 0;
244             SvLBoxEntry* pIterEntry = FirstChild( pParent );
245             while( !bFound && pIterEntry )
246             {
247                 if ( pEntry == pIterEntry )
248                 {
249                     rnChildIndex = nEntry;
250                     bFound = true;  // exit the while loop
251                 }
252                 pIterEntry = NextSibling( pIterEntry );
253                 ++nEntry;
254             }
255 
256             bFound = true;  // exit the for loop
257         }
258     }
259 }
260 
261 sal_uLong ScContentTree::GetChildIndex( SvLBoxEntry* pEntry ) const
262 {
263     sal_uInt16 nRoot;
264     sal_uLong nChild;
265     GetEntryIndexes( nRoot, nChild, pEntry );
266     return nChild;
267 }
268 
269 String lcl_GetDBAreaRange( ScDocument* pDoc, const String& rDBName )
270 {
271 	String aRet;
272 	if (pDoc)
273 	{
274 		ScDBCollection*	pDbNames = pDoc->GetDBCollection();
275 		sal_uInt16 nCount = pDbNames->GetCount();
276 		for ( sal_uInt16 i=0; i<nCount; i++ )
277 		{
278 			ScDBData* pData = (*pDbNames)[i];
279 			if ( pData->GetName() == rDBName )
280 			{
281 				ScRange aRange;
282 				pData->GetArea(aRange);
283 				aRange.Format( aRet, SCR_ABS_3D, pDoc );
284 				break;
285 			}
286 		}
287 	}
288 	return aRet;
289 }
290 
291 IMPL_LINK( ScContentTree, ContentDoubleClickHdl, ScContentTree *, EMPTYARG )
292 {
293     sal_uInt16 nType;
294     sal_uLong nChild;
295     SvLBoxEntry* pEntry = GetCurEntry();
296     GetEntryIndexes( nType, nChild, pEntry );
297 
298     if( pEntry && (nType != SC_CONTENT_ROOT) && (nChild != SC_CONTENT_NOCHILD) )
299 	{
300 		if ( bHiddenDoc )
301 			return 0;				//! spaeter...
302 
303         String aText( GetEntryText( pEntry ) );
304 
305 		if ( aManualDoc.Len() )
306 			pParentWindow->SetCurrentDoc( aManualDoc );
307 
308 		switch( nType )
309 		{
310 			case SC_CONTENT_TABLE:
311 				pParentWindow->SetCurrentTableStr( aText );
312             break;
313 
314             case SC_CONTENT_RANGENAME:
315 				pParentWindow->SetCurrentCellStr( aText );
316             break;
317 
318             case SC_CONTENT_DBAREA:
319             {
320                 //  #47905# Wenn gleiche Bereichs- und DB-Namen existieren, wird
321                 //  bei SID_CURRENTCELL der Bereichsname genommen.
322                 //  DB-Bereiche darum direkt ueber die Adresse anspringen.
323 
324                 String aRangeStr = lcl_GetDBAreaRange( GetSourceDocument(), aText );
325                 if (aRangeStr.Len())
326                     pParentWindow->SetCurrentCellStr( aRangeStr );
327             }
328             break;
329 
330             case SC_CONTENT_OLEOBJECT:
331 			case SC_CONTENT_GRAPHIC:
332 			case SC_CONTENT_DRAWING:
333 				pParentWindow->SetCurrentObject( aText );
334             break;
335 
336             case SC_CONTENT_NOTE:
337             {
338                 ScAddress aPos = GetNotePos( nChild );
339                 pParentWindow->SetCurrentTable( aPos.Tab() );
340                 pParentWindow->SetCurrentCell( aPos.Col(), aPos.Row() );
341             }
342             break;
343 
344             case SC_CONTENT_AREALINK:
345             {
346                 const ScAreaLink* pLink = GetLink( nChild );
347                 if( pLink )
348                 {
349                     ScRange aRange = pLink->GetDestArea();
350                     String aRangeStr;
351                     ScDocument* pSrcDoc = GetSourceDocument();
352                     aRange.Format( aRangeStr, SCR_ABS_3D, pSrcDoc, pSrcDoc->GetAddressConvention() );
353                     pParentWindow->SetCurrentCellStr( aRangeStr );
354                 }
355             }
356             break;
357 		}
358 
359 		ScNavigatorDlg::ReleaseFocus();		// set focus into document
360 	}
361 
362 	return 0;
363 }
364 
365 void ScContentTree::MouseButtonDown( const MouseEvent& rMEvt )
366 {
367     SvTreeListBox::MouseButtonDown( rMEvt );
368     StoreSettings();
369 }
370 
371 void ScContentTree::KeyInput( const KeyEvent& rKEvt )
372 {
373 	sal_Bool bUsed = sal_False;
374 
375 	const KeyCode aCode = rKEvt.GetKeyCode();
376 	if (aCode.GetCode() == KEY_RETURN)
377 	{
378 		switch (aCode.GetModifier())
379 		{
380 			case KEY_MOD1:
381 				ToggleRoot();		// toggle root mode (as in Writer)
382 				bUsed = sal_True;
383 				break;
384 			case 0:
385             {
386                 SvLBoxEntry* pEntry = GetCurEntry();
387                 if( pEntry )
388                 {
389                     sal_uInt16 nType;
390                     sal_uLong nChild;
391                     GetEntryIndexes( nType, nChild, pEntry );
392 
393                     if( (nType != SC_CONTENT_ROOT) && (nChild == SC_CONTENT_NOCHILD) )
394                     {
395                         String aText( GetEntryText( pEntry ) );
396                         if ( IsExpanded( pEntry ) )
397                             Collapse( pEntry );
398                         else
399                             Expand( pEntry );
400                     }
401                     else
402                         ContentDoubleClickHdl(0);      // select content as if double clicked
403                 }
404 
405                 bUsed = sal_True;
406             }
407             break;
408 		}
409 	}
410     StoreSettings();
411 
412     if( !bUsed )
413 		SvTreeListBox::KeyInput(rKEvt);
414 }
415 
416 //sal_Bool __EXPORT ScContentTree::Drop( const DropEvent& rEvt )
417 //{
418 //	return pParentWindow->Drop(rEvt);			// Drop auf Navigator
419 //}
420 
421 //sal_Bool __EXPORT ScContentTree::QueryDrop( DropEvent& rEvt )
422 //{
423 //	return pParentWindow->QueryDrop(rEvt);		// Drop auf Navigator
424 //}
425 
426 sal_Int8 ScContentTree::AcceptDrop( const AcceptDropEvent& /* rEvt */ )
427 {
428 	return DND_ACTION_NONE;
429 }
430 
431 sal_Int8 ScContentTree::ExecuteDrop( const ExecuteDropEvent& /* rEvt */ )
432 {
433 	return DND_ACTION_NONE;
434 }
435 
436 void ScContentTree::StartDrag( sal_Int8 /* nAction */, const Point& /* rPosPixel */ )
437 {
438 	DoDrag();
439 }
440 
441 void ScContentTree::DragFinished( sal_Int8 /* nAction */ )
442 {
443 }
444 
445 void __EXPORT ScContentTree::Command( const CommandEvent& rCEvt )
446 {
447 	sal_Bool bDone = sal_False;
448 
449 	switch ( rCEvt.GetCommand() )
450 	{
451 		case COMMAND_STARTDRAG:
452 			//	Aus dem ExecuteDrag heraus kann der Navigator geloescht werden
453 			//	(beim Umschalten auf einen anderen Dokument-Typ), das wuerde aber
454 			//	den StarView MouseMove-Handler, der Command() aufruft, umbringen.
455 			//	Deshalb Drag&Drop asynchron:
456 
457 //			DoDrag();
458 
459 			Application::PostUserEvent( STATIC_LINK( this, ScContentTree, ExecDragHdl ) );
460 
461 			bDone = sal_True;
462 			break;
463 
464 		case COMMAND_CONTEXTMENU:
465 			{
466 				//	Drag-Drop Modus
467 
468 				PopupMenu aPop;
469 				ScPopupMenu aDropMenu( ScResId( RID_POPUP_DROPMODE ) );
470 				aDropMenu.CheckItem( RID_DROPMODE_URL + pParentWindow->GetDropMode() );
471 				aPop.InsertItem( 1, pParentWindow->GetStrDragMode() );
472 				aPop.SetPopupMenu( 1, &aDropMenu );
473 
474 				//	angezeigtes Dokument
475 
476 				ScPopupMenu aDocMenu;
477 				aDocMenu.SetMenuFlags( aDocMenu.GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
478 				sal_uInt16 i=0;
479 				sal_uInt16 nPos=0;
480 				//	geladene Dokumente
481 				ScDocShell* pCurrentSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() );
482 				SfxObjectShell* pSh = SfxObjectShell::GetFirst();
483 				while ( pSh )
484 				{
485 					if ( pSh->ISA(ScDocShell) )
486 					{
487 						String aName = pSh->GetTitle();
488 						String aEntry = aName;
489 						if ( pSh == pCurrentSh )
490 							aEntry += pParentWindow->aStrActive;
491 						else
492 							aEntry += pParentWindow->aStrNotActive;
493 						aDocMenu.InsertItem( ++i, aEntry );
494 						if ( !bHiddenDoc && aName == aManualDoc )
495 							nPos = i;
496 					}
497 					pSh = SfxObjectShell::GetNext( *pSh );
498 				}
499 				//	"aktives Fenster"
500 				aDocMenu.InsertItem( ++i, pParentWindow->aStrActiveWin );
501 				if (!bHiddenDoc && !aManualDoc.Len())
502 					nPos = i;
503 				//	verstecktes Dokument
504 				if ( aHiddenTitle.Len() )
505 				{
506 					String aEntry = aHiddenTitle;
507 					aEntry += pParentWindow->aStrHidden;
508 					aDocMenu.InsertItem( ++i, aEntry );
509 					if (bHiddenDoc)
510 						nPos = i;
511 				}
512 				aDocMenu.CheckItem( nPos );
513 				aPop.InsertItem( 2, pParentWindow->GetStrDisplay() );
514 				aPop.SetPopupMenu( 2, &aDocMenu );
515 
516 				//	ausfuehren
517 
518 				aPop.Execute( this, rCEvt.GetMousePosPixel() );
519 
520 				if ( aDropMenu.WasHit() )				//	Drag-Drop Modus
521 				{
522 					sal_uInt16 nId = aDropMenu.GetSelected();
523 					if ( nId >= RID_DROPMODE_URL && nId <= RID_DROPMODE_COPY )
524 						pParentWindow->SetDropMode( nId - RID_DROPMODE_URL );
525 				}
526 				else if ( aDocMenu.WasHit() )			//	angezeigtes Dokument
527 				{
528 					sal_uInt16 nId = aDocMenu.GetSelected();
529 					String aName = aDocMenu.GetItemText(nId);
530 					SelectDoc( aName );
531 				}
532 			}
533 			break;
534 	}
535 
536 	if (!bDone)
537 		SvTreeListBox::Command(rCEvt);
538 }
539 
540 void __EXPORT ScContentTree::RequestHelp( const HelpEvent& rHEvt )
541 {
542 	sal_Bool bDone = sal_False;
543 	if( rHEvt.GetMode() & HELPMODE_QUICK )
544 	{
545 		Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ));
546 		SvLBoxEntry* pEntry = GetEntry( aPos );
547 		if ( pEntry )
548 		{
549 			sal_Bool bRet = sal_False;
550 			String aHelpText;
551 			SvLBoxEntry* pParent = GetParent(pEntry);
552 			if ( !pParent )									// Top-Level ?
553 			{
554 				aHelpText = String::CreateFromInt32( GetChildCount(pEntry) );
555 				aHelpText += ' ';
556 				aHelpText += GetEntryText(pEntry);
557 				bRet = sal_True;
558 			}
559 			else if ( pParent == pRootNodes[SC_CONTENT_NOTE] )
560 			{
561 				aHelpText = GetEntryText(pEntry);			// Notizen als Help-Text
562 				bRet = sal_True;
563 			}
564 			else if ( pParent == pRootNodes[SC_CONTENT_AREALINK] )
565 			{
566                 sal_uLong nIndex = GetChildIndex(pEntry);
567                 if( nIndex != SC_CONTENT_NOCHILD )
568                 {
569                     const ScAreaLink* pLink = GetLink(nIndex);
570                     if (pLink)
571                     {
572                         aHelpText = pLink->GetFile();           // Source-Datei als Help-Text
573                         bRet = sal_True;
574                     }
575                 }
576 			}
577 
578 			if (bRet)
579 			{
580 				SvLBoxTab* pTab;
581 				SvLBoxString* pItem = (SvLBoxString*)(GetItem( pEntry, aPos.X(), &pTab ));
582 				if( pItem )
583 				{
584 					aPos = GetEntryPosition( pEntry );
585 					aPos.X() = GetTabPos( pEntry, pTab );
586 					aPos = OutputToScreenPixel(aPos);
587 					Size aSize( pItem->GetSize( this, pEntry ) );
588 
589 					Rectangle aItemRect( aPos, aSize );
590 					Help::ShowQuickHelp( this, aItemRect, aHelpText );
591 					bDone = sal_True;
592 				}
593 			}
594 		}
595 	}
596 	if (!bDone)
597 		Window::RequestHelp( rHEvt );
598 }
599 
600 ScDocument* ScContentTree::GetSourceDocument()
601 {
602 	if (bHiddenDoc)
603 		return pHiddenDocument;
604 	else
605 	{
606 		ScDocShell* pSh = GetManualOrCurrent();
607 		if (pSh)
608 			return pSh->GetDocument();
609 
610 	}
611 	return NULL;
612 }
613 
614 void ScContentTree::Refresh( sal_uInt16 nType )
615 {
616 	if ( bHiddenDoc && !pHiddenDocument )
617 		return;									// anderes Dokument angezeigt
618 
619 	//	wenn sich nichts geaendert hat, gleich abbrechen (gegen Geflacker)
620 
621 	if ( nType == SC_CONTENT_NOTE )
622 		if (!NoteStringsChanged())
623 			return;
624 	if ( nType == SC_CONTENT_GRAPHIC )
625 		if (!DrawNamesChanged(SC_CONTENT_GRAPHIC))
626 			return;
627 	if ( nType == SC_CONTENT_OLEOBJECT )
628 		if (!DrawNamesChanged(SC_CONTENT_OLEOBJECT))
629 			return;
630 	if ( nType == SC_CONTENT_DRAWING )
631 		if (!DrawNamesChanged(SC_CONTENT_DRAWING))
632 			return;
633 
634 	SetUpdateMode(sal_False);
635 
636 	ClearType( nType );
637 
638 	if ( !nType || nType == SC_CONTENT_TABLE )
639 		GetTableNames();
640 	if ( !nType || nType == SC_CONTENT_RANGENAME )
641 		GetAreaNames();
642 	if ( !nType || nType == SC_CONTENT_DBAREA )
643 		GetDbNames();
644 	if ( !nType || nType == SC_CONTENT_GRAPHIC )
645 		GetGraphicNames();
646 	if ( !nType || nType == SC_CONTENT_OLEOBJECT )
647 		GetOleNames();
648 	if ( !nType || nType == SC_CONTENT_DRAWING )
649 		GetDrawingNames();
650 	if ( !nType || nType == SC_CONTENT_NOTE )
651 		GetNoteStrings();
652 	if ( !nType || nType == SC_CONTENT_AREALINK )
653 		GetLinkNames();
654 
655     ApplySettings();
656 	SetUpdateMode(sal_True);
657 }
658 
659 void ScContentTree::GetTableNames()
660 {
661 	if ( nRootType && nRootType != SC_CONTENT_TABLE )		// ausgeblendet ?
662 		return;
663 
664 	ScDocument* pDoc = GetSourceDocument();
665 	if (!pDoc)
666 		return;
667 
668 	String aName;
669 	SCTAB nCount = pDoc->GetTableCount();
670 	for ( SCTAB i=0; i<nCount; i++ )
671 	{
672 		pDoc->GetName( i, aName );
673 		InsertContent( SC_CONTENT_TABLE, aName );
674 	}
675 }
676 
677 void ScContentTree::GetAreaNames()
678 {
679 	if ( nRootType && nRootType != SC_CONTENT_RANGENAME )		// ausgeblendet ?
680 		return;
681 
682 	ScDocument* pDoc = GetSourceDocument();
683 	if (!pDoc)
684 		return;
685 
686 	ScRangeName* pRangeNames = pDoc->GetRangeName();
687 	sal_uInt16 nCount = pRangeNames->GetCount();
688 	if ( nCount > 0 )
689 	{
690 		sal_uInt16 nValidCount = 0;
691 		ScRange aDummy;
692 		sal_uInt16 i;
693 		for ( i=0; i<nCount; i++ )
694 		{
695 			ScRangeData* pData = (*pRangeNames)[i];
696 			if (pData->IsValidReference(aDummy))
697 				nValidCount++;
698 		}
699 		if ( nValidCount )
700 		{
701 			ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ];
702 			sal_uInt16 j;
703 			for ( i=0, j=0; i<nCount; i++ )
704 			{
705 				ScRangeData* pData = (*pRangeNames)[i];
706 				if (pData->IsValidReference(aDummy))
707 					ppSortArray[j++] = pData;
708 			}
709 #ifndef ICC
710 			qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
711 				&ScRangeData_QsortNameCompare );
712 #else
713 			qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
714 				ICCQsortNameCompare );
715 #endif
716 			for ( j=0; j<nValidCount; j++ )
717 				InsertContent( SC_CONTENT_RANGENAME, ppSortArray[j]->GetName() );
718 			delete [] ppSortArray;
719 		}
720 	}
721 }
722 
723 void ScContentTree::GetDbNames()
724 {
725 	if ( nRootType && nRootType != SC_CONTENT_DBAREA )		// ausgeblendet ?
726 		return;
727 
728 	ScDocument* pDoc = GetSourceDocument();
729 	if (!pDoc)
730 		return;
731 
732 	ScDBCollection*	pDbNames = pDoc->GetDBCollection();
733 	sal_uInt16 nCount = pDbNames->GetCount();
734 	if ( nCount > 0 )
735 	{
736 		String aStrNoName( ScGlobal::GetRscString(STR_DB_NONAME) );
737 		for ( sal_uInt16 i=0; i<nCount; i++ )
738 		{
739 			ScDBData* pData = (*pDbNames)[i];
740 			String aStrName = pData->GetName();
741 			if ( aStrName != aStrNoName )
742 				InsertContent( SC_CONTENT_DBAREA, aStrName );
743 		}
744 	}
745 }
746 
747 bool ScContentTree::IsPartOfType( sal_uInt16 nContentType, sal_uInt16 nObjIdentifier )  // static
748 {
749     bool bRet = false;
750     switch ( nContentType )
751     {
752         case SC_CONTENT_GRAPHIC:
753             bRet = ( nObjIdentifier == OBJ_GRAF );
754             break;
755         case SC_CONTENT_OLEOBJECT:
756             bRet = ( nObjIdentifier == OBJ_OLE2 );
757             break;
758         case SC_CONTENT_DRAWING:
759             bRet = ( nObjIdentifier != OBJ_GRAF && nObjIdentifier != OBJ_OLE2 );    // everything else
760             break;
761         default:
762             DBG_ERROR("unknown content type");
763     }
764     return bRet;
765 }
766 
767 void ScContentTree::GetDrawNames( sal_uInt16 nType )
768 {
769 	if ( nRootType && nRootType != nType )				// ausgeblendet ?
770 		return;
771 
772 	ScDocument* pDoc = GetSourceDocument();
773 	if (!pDoc)
774 		return;
775 
776 	// iterate in flat mode for groups
777 	SdrIterMode eIter = ( nType == SC_CONTENT_DRAWING ) ? IM_FLAT : IM_DEEPNOGROUPS;
778 
779 	ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
780 	SfxObjectShell* pShell = pDoc->GetDocumentShell();
781 	if (pDrawLayer && pShell)
782 	{
783 		SCTAB nTabCount = pDoc->GetTableCount();
784 		for (SCTAB nTab=0; nTab<nTabCount; nTab++)
785 		{
786 			SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
787 			DBG_ASSERT(pPage,"Page ?");
788 			if (pPage)
789 			{
790 				SdrObjListIter aIter( *pPage, eIter );
791 				SdrObject* pObject = aIter.Next();
792 				while (pObject)
793 				{
794                     if ( IsPartOfType( nType, pObject->GetObjIdentifier() ) )
795 					{
796 						String aName = ScDrawLayer::GetVisibleName( pObject );
797 						if (aName.Len())
798 							InsertContent( nType, aName );
799 					}
800 
801 					pObject = aIter.Next();
802 				}
803 			}
804 		}
805 	}
806 }
807 
808 void ScContentTree::GetGraphicNames()
809 {
810 	GetDrawNames( SC_CONTENT_GRAPHIC );
811 }
812 
813 void ScContentTree::GetOleNames()
814 {
815 	GetDrawNames( SC_CONTENT_OLEOBJECT );
816 }
817 
818 void ScContentTree::GetDrawingNames()
819 {
820 	GetDrawNames( SC_CONTENT_DRAWING );
821 }
822 
823 void ScContentTree::GetLinkNames()
824 {
825 	if ( nRootType && nRootType != SC_CONTENT_AREALINK )				// ausgeblendet ?
826 		return;
827 
828 	ScDocument* pDoc = GetSourceDocument();
829 	if (!pDoc)
830 		return;
831 
832 	sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
833 	DBG_ASSERT(pLinkManager, "kein LinkManager am Dokument?");
834 	const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
835 	sal_uInt16 nCount = rLinks.Count();
836 	for (sal_uInt16 i=0; i<nCount; i++)
837 	{
838 		::sfx2::SvBaseLink* pBase = *rLinks[i];
839 		if (pBase->ISA(ScAreaLink))
840 			InsertContent( SC_CONTENT_AREALINK, ((ScAreaLink*)pBase)->GetSource() );
841 
842 			//	in der Liste die Namen der Quellbereiche
843 	}
844 }
845 
846 const ScAreaLink* ScContentTree::GetLink( sal_uLong nIndex )
847 {
848 	ScDocument* pDoc = GetSourceDocument();
849 	if (!pDoc)
850 		return NULL;
851 
852 	sal_uLong nFound = 0;
853 	sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
854 	DBG_ASSERT(pLinkManager, "kein LinkManager am Dokument?");
855 	const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
856 	sal_uInt16 nCount = rLinks.Count();
857 	for (sal_uInt16 i=0; i<nCount; i++)
858 	{
859 		::sfx2::SvBaseLink* pBase = *rLinks[i];
860 		if (pBase->ISA(ScAreaLink))
861 		{
862 			if (nFound == nIndex)
863 				return (const ScAreaLink*) pBase;
864 			++nFound;
865 		}
866 	}
867 
868 	DBG_ERROR("Link nicht gefunden");
869 	return NULL;
870 }
871 
872 String lcl_NoteString( const ScPostIt& rNote )
873 {
874     String aText = rNote.GetText();
875 	xub_StrLen nAt;
876     while ( (nAt = aText.Search( '\n' )) != STRING_NOTFOUND )
877 		aText.SetChar( nAt, ' ' );
878 	return aText;
879 }
880 
881 void ScContentTree::GetNoteStrings()
882 {
883 	if ( nRootType && nRootType != SC_CONTENT_NOTE )		// ausgeblendet ?
884 		return;
885 
886 	ScDocument* pDoc = GetSourceDocument();
887 	if (!pDoc)
888 		return;
889 
890 	SCTAB nTabCount = pDoc->GetTableCount();
891 	for (SCTAB nTab=0; nTab<nTabCount; nTab++)
892 	{
893 		ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab );
894         for( ScBaseCell* pCell = aIter.GetFirst(); pCell; pCell = aIter.GetNext() )
895             if( const ScPostIt* pNote = pCell->GetNote() )
896                 InsertContent( SC_CONTENT_NOTE, lcl_NoteString( *pNote ) );
897 	}
898 }
899 
900 ScAddress ScContentTree::GetNotePos( sal_uLong nIndex )
901 {
902 	ScDocument* pDoc = GetSourceDocument();
903 	if (!pDoc)
904 		return ScAddress();
905 
906 	sal_uLong nFound = 0;
907 	SCTAB nTabCount = pDoc->GetTableCount();
908 	for (SCTAB nTab=0; nTab<nTabCount; nTab++)
909 	{
910 		ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab );
911 		ScBaseCell* pCell = aIter.GetFirst();
912 		while (pCell)
913 		{
914             if( pCell->HasNote() )
915 			{
916 				if (nFound == nIndex)
917 					return ScAddress( aIter.GetCol(), aIter.GetRow(), nTab );	// gefunden
918 				++nFound;
919 			}
920 			pCell = aIter.GetNext();
921 		}
922 	}
923 
924 	DBG_ERROR("Notiz nicht gefunden");
925 	return ScAddress();
926 }
927 
928 sal_Bool ScContentTree::NoteStringsChanged()
929 {
930 	ScDocument* pDoc = GetSourceDocument();
931 	if (!pDoc)
932 		return sal_False;
933 
934 	SvLBoxEntry* pParent = pRootNodes[SC_CONTENT_NOTE];
935 	if (!pParent)
936 		return sal_False;
937 
938 	SvLBoxEntry* pEntry = FirstChild( pParent );
939 
940 	sal_Bool bEqual = sal_True;
941 	SCTAB nTabCount = pDoc->GetTableCount();
942 	for (SCTAB nTab=0; nTab<nTabCount && bEqual; nTab++)
943 	{
944 		ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab );
945 		ScBaseCell* pCell = aIter.GetFirst();
946 		while (pCell && bEqual)
947 		{
948             if( const ScPostIt* pNote = pCell->GetNote() )
949 			{
950 				if ( !pEntry )
951 					bEqual = sal_False;
952 				else
953 				{
954                     if ( lcl_NoteString( *pNote ) != GetEntryText(pEntry) )
955 						bEqual = sal_False;
956 
957 					pEntry = NextSibling( pEntry );
958 				}
959 			}
960 			pCell = aIter.GetNext();
961 		}
962 	}
963 
964 	if ( pEntry )
965 		bEqual = sal_False;				// kommt noch was
966 
967 	return !bEqual;
968 }
969 
970 sal_Bool ScContentTree::DrawNamesChanged( sal_uInt16 nType )
971 {
972 	ScDocument* pDoc = GetSourceDocument();
973 	if (!pDoc)
974 		return sal_False;
975 
976 	SvLBoxEntry* pParent = pRootNodes[nType];
977 	if (!pParent)
978 		return sal_False;
979 
980 	SvLBoxEntry* pEntry = FirstChild( pParent );
981 
982 	// iterate in flat mode for groups
983 	SdrIterMode eIter = ( nType == SC_CONTENT_DRAWING ) ? IM_FLAT : IM_DEEPNOGROUPS;
984 
985 	sal_Bool bEqual = sal_True;
986 	ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
987 	SfxObjectShell* pShell = pDoc->GetDocumentShell();
988 	if (pDrawLayer && pShell)
989 	{
990 		SCTAB nTabCount = pDoc->GetTableCount();
991 		for (SCTAB nTab=0; nTab<nTabCount && bEqual; nTab++)
992 		{
993 			SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
994 			DBG_ASSERT(pPage,"Page ?");
995 			if (pPage)
996 			{
997 				SdrObjListIter aIter( *pPage, eIter );
998 				SdrObject* pObject = aIter.Next();
999 				while (pObject && bEqual)
1000 				{
1001                     if ( IsPartOfType( nType, pObject->GetObjIdentifier() ) )
1002 					{
1003 						if ( !pEntry )
1004 							bEqual = sal_False;
1005 						else
1006 						{
1007 							if ( ScDrawLayer::GetVisibleName( pObject ) != GetEntryText(pEntry) )
1008 								bEqual = sal_False;
1009 
1010 							pEntry = NextSibling( pEntry );
1011 						}
1012 					}
1013 					pObject = aIter.Next();
1014 				}
1015 			}
1016 		}
1017 	}
1018 
1019 	if ( pEntry )
1020 		bEqual = sal_False;				// kommt noch was
1021 
1022 	return !bEqual;
1023 }
1024 
1025 sal_Bool lcl_GetRange( ScDocument* pDoc, sal_uInt16 nType, const String& rName, ScRange& rRange )
1026 {
1027 	sal_Bool bFound = sal_False;
1028 	sal_uInt16 nPos;
1029 
1030 	if ( nType == SC_CONTENT_RANGENAME )
1031 	{
1032 		ScRangeName* pList = pDoc->GetRangeName();
1033 		if (pList)
1034 			if (pList->SearchName( rName, nPos ))
1035 				if ( (*pList)[nPos]->IsValidReference( rRange ) )
1036 					bFound = sal_True;
1037 	}
1038 	else if ( nType == SC_CONTENT_DBAREA )
1039 	{
1040 		ScDBCollection*	pList = pDoc->GetDBCollection();
1041 		if (pList)
1042 			if (pList->SearchName( rName, nPos ))
1043 			{
1044                 SCTAB nTab;
1045                 SCCOL nCol1, nCol2;
1046                 SCROW nRow1, nRow2;
1047                 (*pList)[nPos]->GetArea(nTab,nCol1,nRow1,nCol2,nRow2);
1048 				rRange = ScRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab );
1049 				bFound = sal_True;
1050 			}
1051 	}
1052 
1053 	return bFound;
1054 }
1055 
1056 void lcl_DoDragObject( ScDocShell* pSrcShell, const String& rName, sal_uInt16 nType, Window* pWin )
1057 {
1058 	ScDocument* pSrcDoc = pSrcShell->GetDocument();
1059 	ScDrawLayer* pModel = pSrcDoc->GetDrawLayer();
1060 	if (pModel)
1061 	{
1062 		sal_Bool bOle = ( nType == SC_CONTENT_OLEOBJECT );
1063 		sal_Bool bGraf = ( nType == SC_CONTENT_GRAPHIC );
1064         sal_uInt16 nDrawId = sal::static_int_cast<sal_uInt16>( bOle ? OBJ_OLE2 : ( bGraf ? OBJ_GRAF : OBJ_GRUP ) );
1065 		SCTAB nTab = 0;
1066 		SdrObject* pObject = pModel->GetNamedObject( rName, nDrawId, nTab );
1067 		if (pObject)
1068 		{
1069 			SdrView aEditView( pModel );
1070 			aEditView.ShowSdrPage(aEditView.GetModel()->GetPage(nTab));
1071 			SdrPageView* pPV = aEditView.GetSdrPageView();
1072 			aEditView.MarkObj(pObject, pPV);
1073 
1074 			SdrModel* pDragModel = aEditView.GetAllMarkedModel();
1075 
1076 			TransferableObjectDescriptor aObjDesc;
1077 			pSrcShell->FillTransferableObjectDescriptor( aObjDesc );
1078 			aObjDesc.maDisplayName = pSrcShell->GetMedium()->GetURLObject().GetURLNoPass();
1079 			// maSize is set in ScDrawTransferObj ctor
1080 
1081 			ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pDragModel, pSrcShell, aObjDesc );
1082 			uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
1083 
1084 			pTransferObj->SetDragSourceObj( pObject, nTab );
1085 			pTransferObj->SetDragSourceFlags( SC_DROP_NAVIGATOR );
1086 
1087 			SC_MOD()->SetDragObject( NULL, pTransferObj );
1088 			pWin->ReleaseMouse();
1089 			pTransferObj->StartDrag( pWin, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
1090 		}
1091 	}
1092 }
1093 
1094 void lcl_DoDragCells( ScDocShell* pSrcShell, const ScRange& rRange, sal_uInt16 nFlags, Window* pWin )
1095 {
1096 	ScMarkData aMark;
1097 	aMark.SelectTable( rRange.aStart.Tab(), sal_True );
1098 	aMark.SetMarkArea( rRange );
1099 
1100 	ScDocument* pSrcDoc = pSrcShell->GetDocument();
1101 	if ( !pSrcDoc->HasSelectedBlockMatrixFragment( rRange.aStart.Col(), rRange.aStart.Row(),
1102 												   rRange.aEnd.Col(),   rRange.aEnd.Row(),
1103 												   aMark ) )
1104 	{
1105 		ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
1106         ScClipParam aClipParam(rRange, false);
1107         pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aMark);
1108 		// pClipDoc->ExtendMerge( rRange, sal_True );
1109 
1110 		TransferableObjectDescriptor aObjDesc;
1111 		pSrcShell->FillTransferableObjectDescriptor( aObjDesc );
1112 		aObjDesc.maDisplayName = pSrcShell->GetMedium()->GetURLObject().GetURLNoPass();
1113 		// maSize is set in ScTransferObj ctor
1114 
1115 		ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
1116 		uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
1117 
1118 		pTransferObj->SetDragSource( pSrcShell, aMark );
1119 		pTransferObj->SetDragSourceFlags( nFlags );
1120 
1121 		SC_MOD()->SetDragObject( pTransferObj, NULL );		// for internal D&D
1122 		pWin->ReleaseMouse();
1123 		pTransferObj->StartDrag( pWin, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
1124 	}
1125 }
1126 
1127 void ScContentTree::DoDrag()
1128 {
1129 	ScDocumentLoader* pDocLoader = NULL;
1130 	bIsInDrag = sal_True;
1131 
1132 	ScModule* pScMod = SC_MOD();
1133 
1134     sal_uInt16 nType;
1135     sal_uLong nChild;
1136     SvLBoxEntry* pEntry = GetCurEntry();
1137     GetEntryIndexes( nType, nChild, pEntry );
1138 
1139     if( pEntry &&
1140         (nChild != SC_CONTENT_NOCHILD) &&
1141         (nType != SC_CONTENT_ROOT) &&
1142         (nType != SC_CONTENT_NOTE) &&
1143         (nType != SC_CONTENT_AREALINK) )
1144     {
1145         String aText( GetEntryText( pEntry ) );
1146 
1147 		ScDocument* pLocalDoc = NULL;					// fuer URL-Drop
1148 		String aDocName;
1149 		if (bHiddenDoc)
1150 			aDocName = aHiddenName;
1151 		else
1152 		{
1153 			ScDocShell* pDocSh = GetManualOrCurrent();
1154 			if (pDocSh)
1155 			{
1156 				if (pDocSh->HasName())
1157 					aDocName = pDocSh->GetMedium()->GetName();
1158 				else
1159 					pLocalDoc = pDocSh->GetDocument();		// Drop nur in dieses Dokument
1160 			}
1161 		}
1162 
1163 		sal_Bool bDoLinkTrans = sal_False;		// use ScLinkTransferObj
1164 		String aLinkURL;				// for ScLinkTransferObj
1165 		String aLinkText;
1166 
1167 		sal_uInt16 nDropMode = pParentWindow->GetDropMode();
1168 		switch ( nDropMode )
1169 		{
1170 			case SC_DROPMODE_URL:
1171 				{
1172 					String aUrl = aDocName;
1173 					aUrl += '#';
1174 					aUrl += aText;
1175 
1176 					pScMod->SetDragJump( pLocalDoc, aUrl, aText );
1177 
1178 					if (aDocName.Len())
1179 					{
1180 						//	provide URL to outside only if the document has a name
1181 						//	(without name, only internal D&D via SetDragJump)
1182 
1183 						aLinkURL = aUrl;
1184 						aLinkText = aText;
1185 					}
1186 					bDoLinkTrans = sal_True;
1187 				}
1188 				break;
1189 			case SC_DROPMODE_LINK:
1190 				{
1191 					if ( aDocName.Len() )			// link only to named documents
1192 					{
1193 						// for internal D&D, set flag to insert a link
1194 
1195 						switch ( nType )
1196 						{
1197 							case SC_CONTENT_TABLE:
1198 								pScMod->SetDragLink( aDocName, aText, EMPTY_STRING );
1199 								bDoLinkTrans = sal_True;
1200 								break;
1201 							case SC_CONTENT_RANGENAME:
1202 							case SC_CONTENT_DBAREA:
1203 								pScMod->SetDragLink( aDocName, EMPTY_STRING, aText );
1204 								bDoLinkTrans = sal_True;
1205 								break;
1206 
1207 							// other types cannot be linked
1208 						}
1209 					}
1210 				}
1211 				break;
1212 			case SC_DROPMODE_COPY:
1213 				{
1214 					ScDocShell* pSrcShell = NULL;
1215 					if ( bHiddenDoc )
1216 					{
1217 						String aFilter, aOptions;
1218 						pDocLoader = new ScDocumentLoader( aHiddenName, aFilter, aOptions );
1219 						if (!pDocLoader->IsError())
1220 							pSrcShell = pDocLoader->GetDocShell();
1221 					}
1222 					else
1223 						pSrcShell = GetManualOrCurrent();
1224 
1225 					if ( pSrcShell )
1226 					{
1227 						ScDocument* pSrcDoc = pSrcShell->GetDocument();
1228 						if ( nType == SC_CONTENT_RANGENAME || nType == SC_CONTENT_DBAREA )
1229 						{
1230 							ScRange aRange;
1231 							if ( lcl_GetRange( pSrcDoc, nType, aText, aRange ) )
1232 							{
1233 								lcl_DoDragCells( pSrcShell, aRange, SC_DROP_NAVIGATOR, this );
1234 							}
1235 						}
1236 						else if ( nType == SC_CONTENT_TABLE )
1237 						{
1238 							SCTAB nTab;
1239 							if ( pSrcDoc->GetTable( aText, nTab ) )
1240 							{
1241 								ScRange aRange( 0,0,nTab, MAXCOL,MAXROW,nTab );
1242 								lcl_DoDragCells( pSrcShell, aRange, SC_DROP_NAVIGATOR | SC_DROP_TABLE, this );
1243 							}
1244 						}
1245 						else if ( nType == SC_CONTENT_GRAPHIC || nType == SC_CONTENT_OLEOBJECT ||
1246 									nType == SC_CONTENT_DRAWING )
1247 						{
1248 							lcl_DoDragObject( pSrcShell, aText, nType, this );
1249 
1250 							//	in ExecuteDrag kann der Navigator geloescht worden sein
1251 							//	-> nicht mehr auf Member zugreifen !!!
1252 						}
1253 					}
1254 				}
1255 				break;
1256 		}
1257 
1258 		if (bDoLinkTrans)
1259 		{
1260 			ScLinkTransferObj* pTransferObj = new ScLinkTransferObj;
1261 			uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
1262 
1263 			if ( aLinkURL.Len() )
1264 				pTransferObj->SetLinkURL( aLinkURL, aLinkText );
1265 
1266 			//	SetDragJump / SetDragLink has been done above
1267 
1268 			ReleaseMouse();
1269 			pTransferObj->StartDrag( this, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
1270 		}
1271 	}
1272 
1273 	bIsInDrag = sal_False;				// static Member
1274 
1275 	delete pDocLoader;				// falls Dokument zum Draggen geladen wurde
1276 }
1277 
1278 IMPL_STATIC_LINK(ScContentTree, ExecDragHdl, void*, EMPTYARG)
1279 {
1280 	//	als Link, damit asynchron ohne ImpMouseMoveMsg auf dem Stack auch der
1281 	//	Navigator geloescht werden darf
1282 
1283 	pThis->DoDrag();
1284 	return 0;
1285 }
1286 
1287 //UNUSED2008-05  void ScContentTree::AdjustTitle()
1288 //UNUSED2008-05  {
1289 //UNUSED2008-05      String aTitle = pParentWindow->aTitleBase;
1290 //UNUSED2008-05      if (bHiddenDoc)
1291 //UNUSED2008-05      {
1292 //UNUSED2008-05          aTitle.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " - " ));
1293 //UNUSED2008-05          aTitle += aHiddenTitle;
1294 //UNUSED2008-05      }
1295 //UNUSED2008-05      pParentWindow->SetText(aTitle);
1296 //UNUSED2008-05  }
1297 
1298 sal_Bool ScContentTree::LoadFile( const String& rUrl )
1299 {
1300 	String aDocName = rUrl;
1301 	xub_StrLen nPos = aDocName.Search('#');
1302 	if ( nPos != STRING_NOTFOUND )
1303 		aDocName.Erase(nPos);			// nur der Name, ohne #...
1304 
1305 	sal_Bool bReturn = sal_False;
1306 	String aFilter, aOptions;
1307 	ScDocumentLoader aLoader( aDocName, aFilter, aOptions );
1308 	if ( !aLoader.IsError() )
1309 	{
1310 		bHiddenDoc = sal_True;
1311 		aHiddenName = aDocName;
1312 		aHiddenTitle = aLoader.GetTitle();
1313 		pHiddenDocument = aLoader.GetDocument();
1314 
1315 		Refresh();						// Inhalte aus geladenem Dokument holen
1316 
1317 		pHiddenDocument = NULL;
1318 //		AdjustTitle();
1319 
1320 		pParentWindow->GetDocNames( &aHiddenTitle );			// Liste fuellen
1321 	}
1322 	else
1323 		Sound::Beep();			// Fehler beim Laden
1324 
1325 	//	Dokument wird im dtor von ScDocumentLoader wieder geschlossen
1326 
1327 	return bReturn;
1328 }
1329 
1330 void ScContentTree::InitWindowBits( sal_Bool bButtons )
1331 {
1332 	WinBits nFlags = GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL;
1333 	if (bButtons)
1334 		nFlags |= WB_HASBUTTONS|WB_HASBUTTONSATROOT;
1335 
1336 	SetStyle( nFlags );
1337 }
1338 
1339 void ScContentTree::SetRootType( sal_uInt16 nNew )
1340 {
1341 	if ( nNew != nRootType )
1342 	{
1343 		nRootType = nNew;
1344 		InitWindowBits( nNew == 0 );
1345 		Refresh();
1346 
1347 		ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
1348 		rCfg.SetRootType( nRootType );
1349 	}
1350 }
1351 
1352 void ScContentTree::ToggleRoot()		// nach Selektion
1353 {
1354 	sal_uInt16 nNew = SC_CONTENT_ROOT;
1355 	if ( nRootType == SC_CONTENT_ROOT )
1356 	{
1357 		SvLBoxEntry* pEntry = GetCurEntry();
1358 		if (pEntry)
1359 		{
1360 			SvLBoxEntry* pParent = GetParent(pEntry);
1361 			for (sal_uInt16 i=1; i<SC_CONTENT_COUNT; i++)
1362 				if ( pEntry == pRootNodes[i] || pParent == pRootNodes[i] )
1363 					nNew = i;
1364 		}
1365 	}
1366 
1367 	SetRootType( nNew );
1368 }
1369 
1370 void ScContentTree::ResetManualDoc()
1371 {
1372 	aManualDoc.Erase();
1373 	bHiddenDoc = sal_False;
1374 
1375 	ActiveDocChanged();
1376 }
1377 
1378 void ScContentTree::ActiveDocChanged()
1379 {
1380 	if ( !bHiddenDoc && !aManualDoc.Len() )
1381 		Refresh();									// Inhalte nur wenn automatisch
1382 
1383 		//	Listbox muss immer geupdated werden, wegen aktiv-Flag
1384 
1385 	String aCurrent;
1386 	if ( bHiddenDoc )
1387 		aCurrent = aHiddenTitle;
1388 	else
1389 	{
1390 		ScDocShell* pSh = GetManualOrCurrent();
1391 		if (pSh)
1392 			aCurrent = pSh->GetTitle();
1393 		else
1394 		{
1395 			//	eingestelltes Dokument existiert nicht mehr
1396 
1397 			aManualDoc.Erase();				// wieder automatisch
1398 			Refresh();
1399 			pSh = GetManualOrCurrent();		// sollte jetzt aktives sein
1400 			if (pSh)
1401 				aCurrent = pSh->GetTitle();
1402 		}
1403 	}
1404 	pParentWindow->GetDocNames( &aCurrent );		// selektieren
1405 }
1406 
1407 void ScContentTree::SetManualDoc(const String& rName)
1408 {
1409 	aManualDoc = rName;
1410 	if (!bHiddenDoc)
1411 	{
1412 		Refresh();
1413 		pParentWindow->GetDocNames( &aManualDoc );		// selektieren
1414 	}
1415 }
1416 
1417 void ScContentTree::SelectDoc(const String& rName)		// rName wie im Menue/Listbox angezeigt
1418 {
1419 	if ( rName == pParentWindow->aStrActiveWin )
1420 	{
1421 		ResetManualDoc();
1422 		return;
1423 	}
1424 
1425 	//	"aktiv" oder "inaktiv" weglassen
1426 
1427 	String aRealName = rName;
1428 	xub_StrLen nLen = rName.Len();
1429 	xub_StrLen nActiveStart = nLen - pParentWindow->aStrActive.Len();
1430 	if ( rName.Copy( nActiveStart ) == pParentWindow->aStrActive )
1431 		aRealName = rName.Copy( 0, nActiveStart );
1432 	xub_StrLen nNotActiveStart = nLen - pParentWindow->aStrNotActive.Len();
1433 	if ( rName.Copy( nNotActiveStart ) == pParentWindow->aStrNotActive )
1434 		aRealName = rName.Copy( 0, nNotActiveStart );
1435 
1436 	//
1437 
1438 	sal_Bool bLoaded = sal_False;
1439 
1440 		// ist es ein normal geladenes Doc ?
1441 
1442 	SfxObjectShell* pSh = SfxObjectShell::GetFirst();
1443 	while ( pSh && !bLoaded )
1444 	{
1445 		if ( pSh->ISA(ScDocShell) )
1446 			if ( pSh->GetTitle() == aRealName )
1447 				bLoaded = sal_True;
1448 		pSh = SfxObjectShell::GetNext( *pSh );
1449 	}
1450 
1451 	if (bLoaded)
1452 	{
1453 		bHiddenDoc = sal_False;
1454 		SetManualDoc(aRealName);
1455 	}
1456 	else if (aHiddenTitle.Len())				// verstecktes ausgewaehlt
1457 	{
1458 		if (!bHiddenDoc)
1459 			LoadFile(aHiddenName);
1460 	}
1461 	else
1462 	{
1463 		DBG_ERROR("SelectDoc: nicht gefunden");
1464 	}
1465 }
1466 
1467 void ScContentTree::ApplySettings()
1468 {
1469     const ScNavigatorSettings* pSettings = pParentWindow->GetNavigatorSettings();
1470     if( pSettings )
1471     {
1472         sal_uInt16 nRootSel = pSettings->GetRootSelected();
1473         sal_uLong nChildSel = pSettings->GetChildSelected();
1474 
1475         for( sal_uInt16 nEntry = 1; nEntry < SC_CONTENT_COUNT; ++nEntry )
1476         {
1477             if( pRootNodes[ nEntry ] )
1478             {
1479                 // expand
1480                 sal_Bool bExp = pSettings->IsExpanded( nEntry );
1481                 if( bExp != IsExpanded( pRootNodes[ nEntry ] ) )
1482                 {
1483                     if( bExp )
1484                         Expand( pRootNodes[ nEntry ] );
1485                     else
1486                         Collapse( pRootNodes[ nEntry ] );
1487                 }
1488 
1489                 // select
1490                 if( nRootSel == nEntry )
1491                 {
1492                     SvLBoxEntry* pEntry = NULL;
1493                     if( bExp && (nChildSel != SC_CONTENT_NOCHILD) )
1494                         pEntry = GetEntry( pRootNodes[ nEntry ], nChildSel );
1495                     Select( pEntry ? pEntry : pRootNodes[ nEntry ] );
1496                 }
1497             }
1498         }
1499     }
1500 }
1501 
1502 void ScContentTree::StoreSettings() const
1503 {
1504     ScNavigatorSettings* pSettings = pParentWindow->GetNavigatorSettings();
1505     if( pSettings )
1506     {
1507         for( sal_uInt16 nEntry = 1; nEntry < SC_CONTENT_COUNT; ++nEntry )
1508         {
1509             sal_Bool bExp = pRootNodes[ nEntry ] && IsExpanded( pRootNodes[ nEntry ] );
1510             pSettings->SetExpanded( nEntry, bExp );
1511         }
1512         sal_uInt16 nRoot;
1513         sal_uLong nChild;
1514         GetEntryIndexes( nRoot, nChild, GetCurEntry() );
1515         pSettings->SetRootSelected( nRoot );
1516         pSettings->SetChildSelected( nChild );
1517     }
1518 }
1519 
1520 
1521 //
1522 //------------------------------------------------------------------------
1523 //
1524 
1525 
1526 
1527 
1528 
1529