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_basctl.hxx"
30 
31 // CLOOKS:
32 //#define _MENUBTN_HXX
33 #define _SPIN_HXX
34 #define _PRVWIN_HXX
35 //#define _FIELD_HXX ***
36 //#define _TAB_HXX ***
37 #define _DIALOGS_HXX
38 #define _SVRTF_HXX
39 #define _ISETBRW_HXX
40 #define _VCTRLS_HXX
41 #define SI_NOCONTROL
42 #define SI_NOSBXCONTROLS
43 
44 #define ITEMID_SIZE	0
45 
46 // Falls ohne PCH's:
47 #include <ide_pch.hxx>
48 
49 
50 #define _SOLAR__PRIVATE 1
51 #include <basic/sbx.hxx>
52 #include <svl/hint.hxx>
53 #include <tools/diagnose_ex.h>
54 #include <basidesh.hrc>
55 #include <basidesh.hxx>
56 #include <basdoc.hxx>
57 #include <basobj.hxx>
58 #include <bastypes.hxx>
59 #include <basicbox.hxx>
60 #include <objdlg.hxx>
61 #include <sbxitem.hxx>
62 #include <tbxctl.hxx>
63 #include <iderdll2.hxx>
64 #include <basidectrlr.hxx>
65 #include <localizationmgr.hxx>
66 
67 #define BasicIDEShell
68 #define SFX_TYPEMAP
69 #include <idetemp.hxx>
70 #include <basslots.hxx>
71 #include <iderdll.hxx>
72 #include <svx/pszctrl.hxx>
73 #include <svx/insctrl.hxx>
74 #include <svx/srchdlg.hxx>
75 #include <svx/lboxctrl.hxx>
76 #include <svx/tbcontrl.hxx>
77 #include <com/sun/star/script/XLibraryContainer.hpp>
78 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
79 #include <com/sun/star/container/XNameContainer.hpp>
80 #include <com/sun/star/container/XContainer.hpp>
81 #include <com/sun/star/container/XContainerListener.hpp>
82 #include <com/sun/star/script/XLibraryContainer.hpp>
83 
84 #include <svx/xmlsecctrl.hxx>
85 
86 using namespace ::com::sun::star::uno;
87 using namespace ::com::sun::star;
88 using ::rtl::OUString;
89 
90 static const rtl::OUString sStandardLibName(  rtl::OUString::createFromAscii("Standard") );
91 
92 typedef ::cppu::WeakImplHelper1< container::XContainerListener > ContainerListenerBASE;
93 
94 class ContainerListenerImpl : public ContainerListenerBASE
95 {
96     BasicIDEShell* mpShell;
97 public:
98 
99     ContainerListenerImpl( BasicIDEShell* pShell ) : mpShell( pShell ) {}
100 
101     ~ContainerListenerImpl()
102     {
103     }
104 
105     void addContainerListener( const ScriptDocument& rScriptDocument, const String& aLibName )
106     {
107         try
108         {
109             uno::Reference< container::XContainer > xContainer( rScriptDocument.getLibrary( E_SCRIPTS, aLibName, sal_False ), uno::UNO_QUERY );
110             if ( xContainer.is() )
111             {
112                 uno::Reference< container::XContainerListener > xContainerListener( this );
113                 xContainer->addContainerListener( xContainerListener );
114             }
115         }
116         catch( uno::Exception& ) {}
117     }
118     void removeContainerListener( const ScriptDocument& rScriptDocument, const String& aLibName )
119     {
120         try
121         {
122             uno::Reference< container::XContainer > xContainer( rScriptDocument.getLibrary( E_SCRIPTS, aLibName, sal_False ), uno::UNO_QUERY );
123             if ( xContainer.is() )
124             {
125                 uno::Reference< container::XContainerListener > xContainerListener( this );
126                 xContainer->removeContainerListener( xContainerListener );
127             }
128         }
129         catch( uno::Exception& ) {}
130     }
131 
132     // XEventListener
133     virtual void SAL_CALL disposing( const lang::EventObject& ) throw( uno::RuntimeException ) {}
134 
135     // XContainerListener
136     virtual void SAL_CALL elementInserted( const container::ContainerEvent& Event ) throw( uno::RuntimeException )
137     {
138         rtl::OUString sModuleName;
139         if( mpShell && ( Event.Accessor >>= sModuleName ) )
140             mpShell->FindBasWin( mpShell->m_aCurDocument, mpShell->m_aCurLibName, sModuleName, sal_True, sal_False );
141     }
142     virtual void SAL_CALL elementReplaced( const container::ContainerEvent& ) throw( com::sun::star::uno::RuntimeException ) { }
143     virtual void SAL_CALL elementRemoved( const container::ContainerEvent& Event ) throw( com::sun::star::uno::RuntimeException )
144     {
145         rtl::OUString sModuleName;
146         if( mpShell  && ( Event.Accessor >>= sModuleName ) )
147         {
148             IDEBaseWindow* pWin = mpShell->FindWindow( mpShell->m_aCurDocument, mpShell->m_aCurLibName, sModuleName, BASICIDE_TYPE_MODULE, sal_True );
149             if( pWin )
150                 mpShell->RemoveWindow( pWin, sal_True, sal_True );
151         }
152     }
153 
154 };
155 
156 TYPEINIT1( BasicIDEShell, SfxViewShell );
157 
158 SFX_IMPL_NAMED_VIEWFACTORY( BasicIDEShell, "Default" )
159 {
160 	SFX_VIEW_REGISTRATION( BasicDocShell );
161 }
162 
163 
164 SFX_IMPL_INTERFACE( BasicIDEShell, SfxViewShell, IDEResId( RID_STR_IDENAME ) )
165 {
166 	SFX_CHILDWINDOW_REGISTRATION( SID_SEARCH_DLG );
167     SFX_FEATURED_CHILDWINDOW_REGISTRATION(SID_SHOW_PROPERTYBROWSER, BASICIDE_UI_FEATURE_SHOW_BROWSER);
168     SFX_POPUPMENU_REGISTRATION( IDEResId( RID_POPUP_DLGED ) );
169 }
170 
171 
172 
173 #define IDE_VIEWSHELL_FLAGS		SFX_VIEW_CAN_PRINT|SFX_VIEW_NO_NEWWINDOW
174 
175 
176 // Hack for #101048
177 static sal_Int32 GnBasicIDEShellCount;
178 sal_Int32 getBasicIDEShellCount( void )
179     { return GnBasicIDEShellCount; }
180 
181 BasicIDEShell::BasicIDEShell( SfxViewFrame* pFrame_, SfxViewShell* /* pOldShell */ ) :
182 		SfxViewShell( pFrame_, IDE_VIEWSHELL_FLAGS ),
183         m_aCurDocument( ScriptDocument::getApplicationScriptDocument() ),
184 		aHScrollBar( &GetViewFrame()->GetWindow(), WinBits( WB_HSCROLL | WB_DRAG ) ),
185 		aVScrollBar( &GetViewFrame()->GetWindow(), WinBits( WB_VSCROLL | WB_DRAG ) ),
186 		aScrollBarBox( &GetViewFrame()->GetWindow(), WinBits( WB_SIZEABLE ) ),
187         m_bAppBasicModified( sal_False ),
188         m_aNotifier( *this )
189 {
190     m_xLibListener = new ContainerListenerImpl( this );
191 	Init();
192     GnBasicIDEShellCount++;
193 }
194 
195 
196 
197 void BasicIDEShell::Init()
198 {
199 	TbxControls::RegisterControl( SID_CHOOSE_CONTROLS );
200 	SvxPosSizeStatusBarControl::RegisterControl();
201 	SvxInsertStatusBarControl::RegisterControl();
202 	XmlSecStatusBarControl::RegisterControl( SID_SIGNATURE );
203     SvxSimpleUndoRedoController::RegisterControl( SID_UNDO );
204     SvxSimpleUndoRedoController::RegisterControl( SID_REDO );
205 
206 	SvxSearchDialogWrapper::RegisterChildWindow( sal_False );
207 
208 	IDE_DLL()->GetExtraData()->ShellInCriticalSection() = sal_True;
209 
210 	SetName( String( RTL_CONSTASCII_USTRINGPARAM( "BasicIDE" ) ) );
211 	SetHelpId( SVX_INTERFACE_BASIDE_VIEWSH );
212 
213 	LibBoxControl::RegisterControl( SID_BASICIDE_LIBSELECTOR );
214 	LanguageBoxControl::RegisterControl( SID_BASICIDE_CURRENT_LANG );
215 
216 	CreateModulWindowLayout();
217 
218     GetViewFrame()->GetWindow().SetBackground();
219 
220 	pCurWin = 0;
221     m_aCurDocument = ScriptDocument::getApplicationScriptDocument();
222 	pObjectCatalog = 0;
223 	bCreatingWindow = sal_False;
224 
225 	m_pCurLocalizationMgr = NULL;
226 
227 	pTabBar = new BasicIDETabBar( &GetViewFrame()->GetWindow() );
228 	pTabBar->SetSplitHdl( LINK( this, BasicIDEShell, TabBarSplitHdl ) );
229 	bTabBarSplitted = sal_False;
230 
231 	nCurKey = 100;
232 	InitScrollBars();
233 	InitTabBar();
234 
235     SetCurLib( ScriptDocument::getApplicationScriptDocument(), String::CreateFromAscii( "Standard" ), false, false );
236 
237     if ( IDE_DLL() && IDE_DLL()->pShell == NULL )
238         IDE_DLL()->pShell = this;
239 
240     IDE_DLL()->GetExtraData()->ShellInCriticalSection() = sal_False;
241 
242     // It's enough to create the controller ...
243     // It will be public by using magic :-)
244     new BasicIDEController( this );
245 
246     // Force updating the title ! Because it must be set to the controller
247     // it has to be called directly after creating those controller.
248     SetMDITitle ();
249 
250 	UpdateWindows();
251 }
252 
253 __EXPORT BasicIDEShell::~BasicIDEShell()
254 {
255     m_aNotifier.dispose();
256 
257     if ( IDE_DLL() && IDE_DLL()->pShell == this )
258         IDE_DLL()->pShell = NULL;
259 
260 	// Damit bei einem Basic-Fehler beim Speichern die Shell nicht sofort
261 	// wieder hoch kommt:
262 	IDE_DLL()->GetExtraData()->ShellInCriticalSection() = sal_True;
263 
264 	SetWindow( 0 );
265 	SetCurWindow( 0 );
266 
267 	// Alle Fenster zerstoeren:
268 	IDEBaseWindow* pWin = aIDEWindowTable.First();
269 	while ( pWin )
270 	{
271 		// Kein Store, passiert bereits, wenn die BasicManager zerstoert werden.
272 		delete pWin;
273 		pWin = aIDEWindowTable.Next();
274 	}
275 
276 	aIDEWindowTable.Clear();
277 	delete pTabBar;
278 	delete pObjectCatalog;
279 	DestroyModulWindowLayout();
280 
281         ContainerListenerImpl* pListener = static_cast< ContainerListenerImpl* >( m_xLibListener.get() );
282         // Destroy all ContainerListeners for Basic Container.
283         if ( pListener )
284             pListener->removeContainerListener( m_aCurDocument, m_aCurLibName );
285 
286 	// MI: Das gab einen GPF im SDT beim Schliessen da dann der ViewFrame die
287 	// ObjSh loslaesst. Es wusste auch keiner mehr wozu das gut war.
288 	// GetViewFrame()->GetObjectShell()->Broadcast( SfxSimpleHint( SFX_HINT_DYING ) );
289 
290 	IDE_DLL()->GetExtraData()->ShellInCriticalSection() = sal_False;
291 
292     GnBasicIDEShellCount--;
293 }
294 
295 void BasicIDEShell::onDocumentCreated( const ScriptDocument& /*_rDocument*/ )
296 {
297     UpdateWindows();
298 }
299 
300 void BasicIDEShell::onDocumentOpened( const ScriptDocument& /*_rDocument*/ )
301 {
302     UpdateWindows();
303 }
304 
305 void BasicIDEShell::onDocumentSave( const ScriptDocument& /*_rDocument*/ )
306 {
307     StoreAllWindowData();
308 }
309 
310 void BasicIDEShell::onDocumentSaveDone( const ScriptDocument& /*_rDocument*/ )
311 {
312     // #i115671: Update SID_SAVEDOC after saving is completed
313     SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
314     if ( pBindings )
315         pBindings->Invalidate( SID_SAVEDOC );
316 }
317 
318 void BasicIDEShell::onDocumentSaveAs( const ScriptDocument& /*_rDocument*/ )
319 {
320     StoreAllWindowData();
321 }
322 
323 void BasicIDEShell::onDocumentSaveAsDone( const ScriptDocument& /*_rDocument*/ )
324 {
325     // not interested in
326 }
327 
328 void BasicIDEShell::onDocumentClosed( const ScriptDocument& _rDocument )
329 {
330     if ( !_rDocument.isValid() )
331         return;
332 
333     bool bSetCurWindow = false;
334     bool bSetCurLib = ( _rDocument == m_aCurDocument );
335 
336     // remove all windows which belong to this document
337     for ( sal_uLong nWin = aIDEWindowTable.Count(); nWin; )
338     {
339         IDEBaseWindow* pWin = aIDEWindowTable.GetObject( --nWin );
340         if ( pWin->IsDocument( _rDocument ) )
341         {
342             if ( pWin->GetStatus() & (BASWIN_RUNNINGBASIC|BASWIN_INRESCHEDULE) )
343             {
344                 pWin->AddStatus( BASWIN_TOBEKILLED );
345                 pWin->Hide();
346                 StarBASIC::Stop();
347                 // there's no notify
348                 pWin->BasicStopped();
349             }
350             else
351             {
352                 pWin->StoreData();
353                 if ( pWin == pCurWin )
354                     bSetCurWindow = true;
355                 RemoveWindow( pWin, sal_True, sal_False );
356             }
357         }
358     }
359 
360     // remove lib info
361     BasicIDEData* pData = IDE_DLL()->GetExtraData();
362     if ( pData )
363         pData->GetLibInfos().RemoveInfoFor( _rDocument );
364 
365     if ( bSetCurLib )
366         SetCurLib( ScriptDocument::getApplicationScriptDocument(), String::CreateFromAscii( "Standard" ), true, false );
367     else if ( bSetCurWindow )
368         SetCurWindow( FindApplicationWindow(), sal_True );
369 }
370 
371 void BasicIDEShell::onDocumentTitleChanged( const ScriptDocument& /*_rDocument*/ )
372 {
373     SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
374     if ( pBindings )
375         pBindings->Invalidate( SID_BASICIDE_LIBSELECTOR, sal_True, sal_False );
376     SetMDITitle();
377 }
378 
379 void BasicIDEShell::onDocumentModeChanged( const ScriptDocument& _rDocument )
380 {
381     for ( sal_uLong nWin = aIDEWindowTable.Count(); nWin; )
382     {
383         IDEBaseWindow* pWin = aIDEWindowTable.GetObject( --nWin );
384         if ( pWin->IsDocument( _rDocument ) && _rDocument.isDocument() )
385             pWin->SetReadOnly( _rDocument.isReadOnly() );
386     }
387 }
388 
389 void BasicIDEShell::StoreAllWindowData( sal_Bool bPersistent )
390 {
391 	for ( sal_uLong nWin = 0; nWin < aIDEWindowTable.Count(); nWin++ )
392 	{
393 		IDEBaseWindow* pWin = aIDEWindowTable.GetObject( nWin );
394 		DBG_ASSERT( pWin, "PrepareClose: NULL-Pointer in Table?" );
395 		if ( !pWin->IsSuspended() )
396 			pWin->StoreData();
397 	}
398 
399 	if ( bPersistent  )
400 	{
401 		SFX_APP()->SaveBasicAndDialogContainer();
402         SetAppBasicModified( sal_False );
403 
404         SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
405         if ( pBindings )
406         {
407             pBindings->Invalidate( SID_SAVEDOC );
408             pBindings->Update( SID_SAVEDOC );
409         }
410 	}
411 }
412 
413 
414 sal_uInt16 __EXPORT BasicIDEShell::PrepareClose( sal_Bool bUI, sal_Bool bForBrowsing )
415 {
416 	(void)bForBrowsing;
417 
418 	// da es nach Drucken etc. (DocInfo) modifiziert ist, hier resetten
419 	GetViewFrame()->GetObjectShell()->SetModified(sal_False);
420 
421 	if ( StarBASIC::IsRunning() )
422 	{
423         if( bUI )
424         {
425 		    String aErrorStr( IDEResId( RID_STR_CANNOTCLOSE ) );
426 		    Window *pParent = &GetViewFrame()->GetWindow();
427 		    InfoBox( pParent, aErrorStr ).Execute();
428         }
429 		return sal_False;
430 	}
431 	else
432 	{
433 		// Hier unguenstig, wird zweimal gerufen...
434 //		StoreAllWindowData();
435 
436 		sal_Bool bCanClose = sal_True;
437 		for ( sal_uLong nWin = 0; bCanClose && ( nWin < aIDEWindowTable.Count() ); nWin++ )
438 		{
439 			IDEBaseWindow* pWin = aIDEWindowTable.GetObject( nWin );
440 			if ( /* !pWin->IsSuspended() && */ !pWin->CanClose() )
441 			{
442                 if ( m_aCurLibName.Len() && ( pWin->IsDocument( m_aCurDocument ) || pWin->GetLibName() != m_aCurLibName ) )
443                     SetCurLib( ScriptDocument::getApplicationScriptDocument(), String(), false );
444 				SetCurWindow( pWin, sal_True );
445 				bCanClose = sal_False;
446 			}
447 		}
448 
449 		if ( bCanClose )
450 			StoreAllWindowData( sal_False );	// Nicht auf Platte schreiben, das passiert am Ende automatisch
451 
452 		return bCanClose;
453 	}
454 }
455 
456 void BasicIDEShell::InitScrollBars()
457 {
458 	aVScrollBar.SetLineSize( 300 );
459 	aVScrollBar.SetPageSize( 2000 );
460 	aHScrollBar.SetLineSize( 300 );
461 	aHScrollBar.SetPageSize( 2000 );
462 	aHScrollBar.Enable();
463 	aVScrollBar.Enable();
464 	aVScrollBar.Show();
465 	aHScrollBar.Show();
466 	aScrollBarBox.Show();
467 }
468 
469 
470 
471 void BasicIDEShell::InitTabBar()
472 {
473 	pTabBar->Enable();
474 	pTabBar->Show();
475 	pTabBar->SetSelectHdl( LINK( this, BasicIDEShell, TabBarHdl ) );
476 }
477 
478 
479 Size __EXPORT BasicIDEShell::GetOptimalSizePixel() const
480 {
481 	return Size( 400, 300 );
482 }
483 
484 
485 
486 void __EXPORT BasicIDEShell::OuterResizePixel( const Point &rPos, const Size &rSize )
487 {
488 	// Adjust fliegt irgendwann raus...
489 	AdjustPosSizePixel( rPos, rSize );
490 }
491 
492 
493 IMPL_LINK_INLINE_START( BasicIDEShell, TabBarSplitHdl, TabBar *, pTBar )
494 {
495 	(void)pTBar;
496 	bTabBarSplitted = sal_True;
497 	ArrangeTabBar();
498 
499 	return 0;
500 }
501 IMPL_LINK_INLINE_END( BasicIDEShell, TabBarSplitHdl, TabBar *, pTBar )
502 
503 
504 
505 IMPL_LINK( BasicIDEShell, TabBarHdl, TabBar *, pCurTabBar )
506 {
507 	sal_uInt16 nCurId = pCurTabBar->GetCurPageId();
508 	IDEBaseWindow* pWin = aIDEWindowTable.Get( nCurId );
509 	DBG_ASSERT( pWin, "Eintrag in TabBar passt zu keinem Fenster!" );
510 	SetCurWindow( pWin );
511 
512 	return 0;
513 }
514 
515 
516 
517 sal_Bool BasicIDEShell::NextPage( sal_Bool bPrev )
518 {
519 	sal_Bool bRet = sal_False;
520 	sal_uInt16 nPos = pTabBar->GetPagePos( pTabBar->GetCurPageId() );
521 
522 	if ( bPrev )
523 		--nPos;
524 	else
525 		++nPos;
526 
527 	if ( nPos < pTabBar->GetPageCount() )
528 	{
529 		IDEBaseWindow* pWin = aIDEWindowTable.Get( pTabBar->GetPageId( nPos ) );
530 		SetCurWindow( pWin, sal_True );
531 		bRet = sal_True;
532 	}
533 
534 	return bRet;
535 }
536 
537 
538 
539 void BasicIDEShell::ArrangeTabBar()
540 {
541 	Size aSz( GetViewFrame()->GetWindow().GetOutputSizePixel() );
542 	long nBoxPos = aScrollBarBox.GetPosPixel().X() - 1;
543 	long nPos = pTabBar->GetSplitSize();
544 	if ( nPos <= nBoxPos )
545 	{
546 		Point aPnt( pTabBar->GetPosPixel() );
547 		long nH = aHScrollBar.GetSizePixel().Height();
548 		pTabBar->SetPosSizePixel( aPnt, Size( nPos, nH ) );
549 		long nScrlStart = aPnt.X() + nPos;
550 		aHScrollBar.SetPosSizePixel( Point( nScrlStart, aPnt.Y() ), Size( nBoxPos - nScrlStart + 2, nH ) );
551 		aHScrollBar.Update();
552 	}
553 }
554 
555 
556 
557 ::svl::IUndoManager* BasicIDEShell::GetUndoManager()
558 {
559 	::svl::IUndoManager* pMgr = NULL;
560 	if( pCurWin )
561 		pMgr = pCurWin->GetUndoManager();
562 
563 	return pMgr;
564 }
565 
566 
567 
568 void BasicIDEShell::ShowObjectDialog( sal_Bool bShow, sal_Bool bCreateOrDestroy )
569 {
570 	if ( bShow )
571 	{
572 		if ( !pObjectCatalog && bCreateOrDestroy )
573 		{
574 			pObjectCatalog = new ObjectCatalog( &GetViewFrame()->GetWindow() );
575 			// Position wird in BasicIDEData gemerkt und vom Dlg eingestellt
576             if ( pObjectCatalog )
577             {
578                 pObjectCatalog->SetCancelHdl( LINK( this, BasicIDEShell, ObjectDialogCancelHdl ) );
579                 BasicEntryDescriptor aDesc;
580                 IDEBaseWindow* pCurWin_ = GetCurWindow();
581                 if ( pCurWin_ )
582                     aDesc = pCurWin_->CreateEntryDescriptor();
583                 pObjectCatalog->SetCurrentEntry( aDesc );
584             }
585 		}
586 
587 		// Die allerletzten Aenderungen...
588 		if ( pCurWin )
589 			pCurWin->StoreData();
590 
591 		if ( pObjectCatalog )
592 		{
593 			pObjectCatalog->UpdateEntries();
594 			pObjectCatalog->Show();
595 		}
596 	}
597 	else if ( pObjectCatalog )
598 	{
599 		pObjectCatalog->Hide();
600 		if ( bCreateOrDestroy )
601 		{
602 			// Wegen OS/2-Focus-Problem pObjectCatalog vorm delete auf NULL
603 			ObjectCatalog* pTemp = pObjectCatalog;
604 			pObjectCatalog = 0;
605 			delete pTemp;
606 		}
607 	}
608 }
609 
610 
611 
612 void __EXPORT BasicIDEShell::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId&,
613 										const SfxHint& rHint, const TypeId& )
614 {
615     if ( IDE_DLL()->GetShell() )
616     {
617         if ( rHint.IsA( TYPE( SfxSimpleHint ) ) )
618         {
619             switch ( ((SfxSimpleHint&)rHint).GetId() )
620             {
621                 case SFX_HINT_DYING:
622                 {
623                     EndListening( rBC, sal_True /* Alle abmelden */ );
624                     if ( pObjectCatalog )
625                         pObjectCatalog->UpdateEntries();
626                 }
627                 break;
628             }
629 
630             if ( rHint.IsA( TYPE( SbxHint ) ) )
631             {
632                 SbxHint& rSbxHint = (SbxHint&)rHint;
633                 sal_uLong nHintId = rSbxHint.GetId();
634                 if (	( nHintId == SBX_HINT_BASICSTART ) ||
635                         ( nHintId == SBX_HINT_BASICSTOP ) )
636                 {
637                     SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
638                     if ( pBindings )
639                     {
640                         pBindings->Invalidate( SID_BASICRUN );
641                         pBindings->Update( SID_BASICRUN );
642                         pBindings->Invalidate( SID_BASICCOMPILE );
643                         pBindings->Update( SID_BASICCOMPILE );
644                         pBindings->Invalidate( SID_BASICSTEPOVER );
645                         pBindings->Update( SID_BASICSTEPOVER );
646                         pBindings->Invalidate( SID_BASICSTEPINTO );
647                         pBindings->Update( SID_BASICSTEPINTO );
648                         pBindings->Invalidate( SID_BASICSTEPOUT );
649                         pBindings->Update( SID_BASICSTEPOUT );
650                         pBindings->Invalidate( SID_BASICSTOP );
651                         pBindings->Update( SID_BASICSTOP );
652                         pBindings->Invalidate( SID_BASICIDE_TOGGLEBRKPNT );
653                         pBindings->Update( SID_BASICIDE_TOGGLEBRKPNT );
654                         pBindings->Invalidate( SID_BASICIDE_MANAGEBRKPNTS );
655                         pBindings->Update( SID_BASICIDE_MANAGEBRKPNTS );
656                         pBindings->Invalidate( SID_BASICIDE_MODULEDLG );
657                         pBindings->Update( SID_BASICIDE_MODULEDLG );
658                         pBindings->Invalidate( SID_BASICLOAD );
659                         pBindings->Update( SID_BASICLOAD );
660                     }
661 
662                     if ( nHintId == SBX_HINT_BASICSTOP )
663                     {
664                         // Nicht nur bei Error/Break oder explizitem anhalten,
665                         // falls durch einen Programmierfehler das Update abgeschaltet ist.
666                         BasicIDE::BasicStopped();
667                         UpdateModulWindowLayout( true );    // Leer machen...
668 						if( m_pCurLocalizationMgr )
669 							m_pCurLocalizationMgr->handleBasicStopped();
670                     }
671 					else if( m_pCurLocalizationMgr )
672                     {
673 						m_pCurLocalizationMgr->handleBasicStarted();
674                     }
675 
676                     IDEBaseWindow* pWin = aIDEWindowTable.First();
677                     while ( pWin )
678                     {
679                         if ( nHintId == SBX_HINT_BASICSTART )
680                             pWin->BasicStarted();
681                         else
682                             pWin->BasicStopped();
683                         pWin = aIDEWindowTable.Next();
684                     }
685                 }
686             }
687         }
688     }
689 }
690 
691 
692 
693 void BasicIDEShell::CheckWindows()
694 {
695 	sal_Bool bSetCurWindow = sal_False;
696 	for ( sal_uLong nWin = 0; nWin < aIDEWindowTable.Count(); nWin++ )
697 	{
698 		IDEBaseWindow* pWin = aIDEWindowTable.GetObject( nWin );
699 		if ( pWin->GetStatus() & BASWIN_TOBEKILLED )
700 		{
701 			pWin->StoreData();
702 			if ( pWin == pCurWin )
703 				bSetCurWindow = sal_True;
704 			RemoveWindow( pWin, sal_True, sal_False );
705 			nWin--;
706 		}
707 	}
708 	if ( bSetCurWindow )
709 		SetCurWindow( FindApplicationWindow(), sal_True );
710 }
711 
712 
713 
714 void BasicIDEShell::RemoveWindows( const ScriptDocument& rDocument, const String& rLibName, sal_Bool bDestroy )
715 {
716 	sal_Bool bChangeCurWindow = pCurWin ? sal_False : sal_True;
717 	for ( sal_uLong nWin = 0; nWin < aIDEWindowTable.Count(); nWin++ )
718 	{
719 		IDEBaseWindow* pWin = aIDEWindowTable.GetObject( nWin );
720         if ( pWin->IsDocument( rDocument ) && pWin->GetLibName() == rLibName )
721 		{
722 			if ( pWin == pCurWin )
723 				bChangeCurWindow = sal_True;
724 			pWin->StoreData();
725 			RemoveWindow( pWin, bDestroy, sal_False );
726 			nWin--;
727 		}
728 	}
729 	if ( bChangeCurWindow )
730 		SetCurWindow( FindApplicationWindow(), sal_True );
731 }
732 
733 
734 
735 void BasicIDEShell::UpdateWindows()
736 {
737 	// Alle Fenster, die nicht angezeigt werden duerfen, entfernen
738 	sal_Bool bChangeCurWindow = pCurWin ? sal_False : sal_True;
739     if ( m_aCurLibName.Len() )
740 	{
741 		for ( sal_uLong nWin = 0; nWin < aIDEWindowTable.Count(); nWin++ )
742 		{
743 			IDEBaseWindow* pWin = aIDEWindowTable.GetObject( nWin );
744             if ( !pWin->IsDocument( m_aCurDocument ) || pWin->GetLibName() != m_aCurLibName )
745 			{
746 				if ( pWin == pCurWin )
747 					bChangeCurWindow = sal_True;
748 				pWin->StoreData();
749 				// Die Abfrage auf RUNNING verhindert den Absturz, wenn in Reschedule.
750 				// Fenster bleibt erstmal stehen, spaeter sowieso mal umstellen,
751 				// dass Fenster nur als Hidden markiert werden und nicht
752 				// geloescht.
753 				if ( !(pWin->GetStatus() & ( BASWIN_TOBEKILLED | BASWIN_RUNNINGBASIC | BASWIN_SUSPENDED ) ) )
754 				{
755 					RemoveWindow( pWin, sal_False, sal_False );
756 					nWin--;
757 				}
758 			}
759 		}
760 	}
761 
762 	if ( bCreatingWindow )
763 		return;
764 
765     IDEBaseWindow* pNextActiveWindow = 0;
766 
767 	// Alle anzuzeigenden Fenster anzeigen
768     ScriptDocuments aDocuments( ScriptDocument::getAllScriptDocuments( ScriptDocument::AllWithApplication ) );
769     for (   ScriptDocuments::const_iterator doc = aDocuments.begin();
770             doc != aDocuments.end();
771             ++doc
772         )
773 	{
774 		StartListening( *doc->getBasicManager(), sal_True /* Nur einmal anmelden */ );
775 
776         // libraries
777         Sequence< ::rtl::OUString > aLibNames( doc->getLibraryNames() );
778         sal_Int32 nLibCount = aLibNames.getLength();
779 	    const ::rtl::OUString* pLibNames = aLibNames.getConstArray();
780 
781         for ( sal_Int32 i = 0 ; i < nLibCount ; i++ )
782 	    {
783             String aLibName = pLibNames[ i ];
784 
785             if ( !m_aCurLibName.Len() || ( *doc == m_aCurDocument && aLibName == m_aCurLibName ) )
786             {
787                 // check, if library is password protected and not verified
788                 sal_Bool bProtected = sal_False;
789                 Reference< script::XLibraryContainer > xModLibContainer( doc->getLibraryContainer( E_SCRIPTS ) );
790                 if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
791                 {
792                     Reference< script::XLibraryContainerPassword > xPasswd( xModLibContainer, UNO_QUERY );
793                     if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( aLibName ) && !xPasswd->isLibraryPasswordVerified( aLibName ) )
794                     {
795                         bProtected = sal_True;
796                     }
797                 }
798 
799                 if ( !bProtected )
800                 {
801                     LibInfoItem* pLibInfoItem = 0;
802                     BasicIDEData* pData = IDE_DLL()->GetExtraData();
803                     if ( pData )
804                         pLibInfoItem = pData->GetLibInfos().GetInfo( LibInfoKey( *doc, aLibName ) );
805 
806                     // modules
807                     if ( xModLibContainer.is() && xModLibContainer->hasByName( aLibName ) )
808                     {
809                         StarBASIC* pLib = doc->getBasicManager()->GetLib( aLibName );
810                         if ( pLib )
811                             ImplStartListening( pLib );
812 
813                         try
814 					    {
815                             Sequence< ::rtl::OUString > aModNames( doc->getObjectNames( E_SCRIPTS, aLibName ) );
816                             sal_Int32 nModCount = aModNames.getLength();
817 	                        const ::rtl::OUString* pModNames = aModNames.getConstArray();
818 
819                             for ( sal_Int32 j = 0 ; j < nModCount ; j++ )
820 				            {
821 					            String aModName = pModNames[ j ];
822 						        ModulWindow* pWin = FindBasWin( *doc, aLibName, aModName, sal_False );
823                                 if ( !pWin )
824 							        pWin = CreateBasWin( *doc, aLibName, aModName );
825                                 if ( !pNextActiveWindow && pLibInfoItem && pLibInfoItem->GetCurrentName() == aModName &&
826                                         pLibInfoItem->GetCurrentType() == BASICIDE_TYPE_MODULE )
827                                 {
828                                     pNextActiveWindow = (IDEBaseWindow*)pWin;
829                                 }
830                             }
831                         }
832 					    catch ( container::NoSuchElementException& )
833 					    {
834                             DBG_UNHANDLED_EXCEPTION();
835 					    }
836                     }
837 
838                     // dialogs
839                     Reference< script::XLibraryContainer > xDlgLibContainer( doc->getLibraryContainer( E_DIALOGS ) );
840                     if ( xDlgLibContainer.is() && xDlgLibContainer->hasByName( aLibName ) )
841                     {
842                         try
843                         {
844                             Sequence< ::rtl::OUString > aDlgNames = doc->getObjectNames( E_DIALOGS, aLibName );
845                             sal_Int32 nDlgCount = aDlgNames.getLength();
846 	                        const ::rtl::OUString* pDlgNames = aDlgNames.getConstArray();
847 
848                             for ( sal_Int32 j = 0 ; j < nDlgCount ; j++ )
849 				            {
850 					            String aDlgName = pDlgNames[ j ];
851                                 // this find only looks for non-suspended windows;
852                                 // suspended windows are handled in CreateDlgWin
853                                 DialogWindow* pWin = FindDlgWin( *doc, aLibName, aDlgName, sal_False );
854                                 if ( !pWin )
855 								    pWin = CreateDlgWin( *doc, aLibName, aDlgName );
856                                 if ( !pNextActiveWindow && pLibInfoItem && pLibInfoItem->GetCurrentName() == aDlgName &&
857                                         pLibInfoItem->GetCurrentType() == BASICIDE_TYPE_DIALOG )
858                                 {
859                                     pNextActiveWindow = (IDEBaseWindow*)pWin;
860                                 }
861                             }
862                         }
863 					    catch ( container::NoSuchElementException& )
864 					    {
865 						    DBG_UNHANDLED_EXCEPTION();
866 					    }
867                     }
868 				}
869             }
870         }
871 	}
872 
873 	if ( bChangeCurWindow )
874     {
875         if ( !pNextActiveWindow )
876             pNextActiveWindow = FindApplicationWindow();
877         SetCurWindow( pNextActiveWindow, sal_True );
878     }
879 }
880 
881 void BasicIDEShell::RemoveWindow( IDEBaseWindow* pWindow_, sal_Bool bDestroy, sal_Bool bAllowChangeCurWindow )
882 {
883 	DBG_ASSERT( pWindow_, "Kann keinen NULL-Pointer loeschen!" );
884 	sal_uLong nKey = aIDEWindowTable.GetKey( pWindow_ );
885 	pTabBar->RemovePage( (sal_uInt16)nKey );
886 	aIDEWindowTable.Remove( nKey );
887 	if ( pWindow_ == pCurWin )
888 	{
889 		if ( bAllowChangeCurWindow )
890 			SetCurWindow( FindApplicationWindow(), sal_True );
891 		else
892 			SetCurWindow( NULL, sal_False );
893 	}
894 	if ( bDestroy )
895 	{
896 		if ( !( pWindow_->GetStatus() & BASWIN_INRESCHEDULE ) )
897 		{
898 			delete pWindow_;
899 		}
900 		else
901 		{
902 			pWindow_->AddStatus( BASWIN_TOBEKILLED );
903 			pWindow_->Hide();
904             // In normal mode stop basic in windows to be deleted
905             // In VBA stop basic only if the running script is trying to delete
906             // its parent module
907             bool bStop = true;
908             if ( pWindow_->GetDocument().isInVBAMode() )
909             {
910                 SbModule* pMod = StarBASIC::GetActiveModule();
911                 if ( !pMod || ( pMod && ( pMod->GetName() != pWindow_->GetName() ) ) )
912                     bStop = false;
913             }
914             if ( bStop )
915             {
916                 StarBASIC::Stop();
917                 // Es kommt kein Notify...
918                 pWindow_->BasicStopped();
919             }
920 			aIDEWindowTable.Insert( nKey, pWindow_ );	// wieder einhaegen
921 		}
922 	}
923 	else
924 	{
925 		pWindow_->Hide();
926 		pWindow_->AddStatus( BASWIN_SUSPENDED );
927 		pWindow_->Deactivating();
928 		aIDEWindowTable.Insert( nKey, pWindow_ );	// wieder einhaegen
929 	}
930 
931 }
932 
933 
934 
935 sal_uInt16 BasicIDEShell::InsertWindowInTable( IDEBaseWindow* pNewWin )
936 {
937 	// Eigentlich prueffen,
938 	nCurKey++;
939 	aIDEWindowTable.Insert( nCurKey, pNewWin );
940 	return nCurKey;
941 }
942 
943 
944 
945 void BasicIDEShell::InvalidateBasicIDESlots()
946 {
947 	// Nur die, die eine optische Auswirkung haben...
948 
949 	if ( IDE_DLL()->GetShell() )
950 	{
951         SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
952         if ( pBindings )
953         {
954             pBindings->Invalidate( SID_UNDO );
955             pBindings->Invalidate( SID_REDO );
956             pBindings->Invalidate( SID_SAVEDOC );
957             pBindings->Invalidate( SID_SIGNATURE );
958             pBindings->Invalidate( SID_BASICIDE_CHOOSEMACRO );
959             pBindings->Invalidate( SID_BASICIDE_MODULEDLG );
960             pBindings->Invalidate( SID_BASICIDE_OBJCAT );
961             pBindings->Invalidate( SID_BASICSTOP );
962             pBindings->Invalidate( SID_BASICRUN );
963             pBindings->Invalidate( SID_BASICCOMPILE );
964             pBindings->Invalidate( SID_BASICLOAD );
965             pBindings->Invalidate( SID_BASICSAVEAS );
966             pBindings->Invalidate( SID_BASICIDE_MATCHGROUP );
967             pBindings->Invalidate( SID_BASICSTEPINTO );
968             pBindings->Invalidate( SID_BASICSTEPOVER );
969             pBindings->Invalidate( SID_BASICSTEPOUT );
970             pBindings->Invalidate( SID_BASICIDE_TOGGLEBRKPNT );
971             pBindings->Invalidate( SID_BASICIDE_MANAGEBRKPNTS );
972             pBindings->Invalidate( SID_BASICIDE_ADDWATCH );
973             pBindings->Invalidate( SID_BASICIDE_REMOVEWATCH );
974             pBindings->Invalidate( SID_CHOOSE_CONTROLS );
975             pBindings->Invalidate( SID_PRINTDOC );
976             pBindings->Invalidate( SID_PRINTDOCDIRECT );
977             pBindings->Invalidate( SID_SETUPPRINTER );
978             pBindings->Invalidate( SID_DIALOG_TESTMODE );
979 
980             pBindings->Invalidate( SID_DOC_MODIFIED );
981             pBindings->Invalidate( SID_BASICIDE_STAT_TITLE );
982             pBindings->Invalidate( SID_BASICIDE_STAT_POS );
983             pBindings->Invalidate( SID_ATTR_INSERT );
984             pBindings->Invalidate( SID_ATTR_SIZE );
985         }
986 	}
987 }
988 
989 void BasicIDEShell::EnableScrollbars( sal_Bool bEnable )
990 {
991 	if ( bEnable )
992 	{
993 		aHScrollBar.Enable();
994 		aVScrollBar.Enable();
995 	}
996 	else
997 	{
998 		aHScrollBar.Disable();
999 		aVScrollBar.Disable();
1000 	}
1001 }
1002 
1003 void BasicIDEShell::SetCurLib( const ScriptDocument& rDocument, String aLibName, bool bUpdateWindows, bool bCheck )
1004 {
1005     if ( !bCheck || ( rDocument != m_aCurDocument || aLibName != m_aCurLibName ) )
1006     {
1007         ContainerListenerImpl* pListener = static_cast< ContainerListenerImpl* >( m_xLibListener.get() );
1008 
1009         if ( pListener )
1010         	pListener->removeContainerListener( m_aCurDocument, m_aCurLibName );
1011 
1012         m_aCurDocument = rDocument;
1013 
1014         pListener->addContainerListener( m_aCurDocument, aLibName );
1015 
1016         m_aCurLibName = aLibName;
1017 
1018         if ( bUpdateWindows )
1019             UpdateWindows();
1020 
1021 		SetMDITitle();
1022 
1023 		SetCurLibForLocalization( rDocument, aLibName );
1024 
1025         SfxBindings* pBindings = BasicIDE::GetBindingsPtr();
1026         if ( pBindings )
1027 		{
1028             pBindings->Invalidate( SID_BASICIDE_LIBSELECTOR );
1029 			pBindings->Invalidate( SID_BASICIDE_CURRENT_LANG );
1030 			pBindings->Invalidate( SID_BASICIDE_MANAGE_LANG );
1031 		}
1032     }
1033 }
1034 
1035 void BasicIDEShell::SetCurLibForLocalization( const ScriptDocument& rDocument, String aLibName )
1036 {
1037     // Create LocalizationMgr
1038 	delete m_pCurLocalizationMgr;
1039 	Reference< resource::XStringResourceManager > xStringResourceManager;
1040 	try
1041 	{
1042 		if( aLibName.Len() )
1043 		{
1044 			Reference< container::XNameContainer > xDialogLib( rDocument.getLibrary( E_DIALOGS, aLibName, sal_True ) );
1045 			xStringResourceManager = LocalizationMgr::getStringResourceFromDialogLibrary( xDialogLib );
1046 	    }
1047 	}
1048     catch ( container::NoSuchElementException& )
1049 	{}
1050 	m_pCurLocalizationMgr = new LocalizationMgr
1051 		( this, rDocument, aLibName, xStringResourceManager );
1052 
1053 	m_pCurLocalizationMgr->handleTranslationbar();
1054 }
1055 
1056 void BasicIDEShell::ImplStartListening( StarBASIC* pBasic )
1057 {
1058 	StartListening( pBasic->GetBroadcaster(), sal_True /* Nur einmal anmelden */ );
1059 }
1060 
1061 
1062