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