xref: /aoo41x/main/sfx2/source/view/viewfrm2.cxx (revision d119d52d)
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_sfx2.hxx"
26 
27 #include "impviewframe.hxx"
28 #include "statcach.hxx"
29 #include "sfx2/viewfac.hxx"
30 #include "workwin.hxx"
31 
32 #include "sfx2/app.hxx"
33 #include "sfx2/bindings.hxx"
34 #include "sfx2/ctrlitem.hxx"
35 #include "sfx2/dispatch.hxx"
36 #include "sfx2/docfac.hxx"
37 #include "sfx2/docfile.hxx"
38 #include "sfx2/objitem.hxx"
39 #include "sfx2/objsh.hxx"
40 #include "sfx2/request.hxx"
41 #include "sfx2/viewfrm.hxx"
42 #include "sfx2/viewsh.hxx"
43 
44 #include <com/sun/star/beans/NamedValue.hpp>
45 #include <com/sun/star/beans/XMaterialHolder.hpp>
46 #include <com/sun/star/util/XCloseable.hpp>
47 
48 #include <comphelper/componentcontext.hxx>
49 #include <comphelper/namedvaluecollection.hxx>
50 #include <comphelper/processfactory.hxx>
51 #include <svtools/asynclink.hxx>
52 #include <svl/eitem.hxx>
53 #include <svl/intitem.hxx>
54 #include <svl/rectitem.hxx>
55 #include <svl/stritem.hxx>
56 #include <tools/diagnose_ex.h>
57 #include <tools/urlobj.hxx>
58 #include <unotools/bootstrap.hxx>
59 #include <unotools/configmgr.hxx>
60 #include <vcl/window.hxx>
61 
62 using namespace ::com::sun::star;
63 using namespace ::com::sun::star::uno;
64 using namespace ::com::sun::star::frame;
65 using namespace ::com::sun::star::util;
66 using namespace ::com::sun::star::container;
67 using namespace ::com::sun::star::beans;
68 using ::com::sun::star::lang::XMultiServiceFactory;
69 using ::com::sun::star::lang::XComponent;
70 
71 //------------------------------------------------------------------------
72 
GetModuleName_Impl(const::rtl::OUString & sDocService)73 static ::rtl::OUString GetModuleName_Impl( const ::rtl::OUString& sDocService )
74 {
75     uno::Reference< container::XNameAccess > xMM( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.ModuleManager")), uno::UNO_QUERY );
76     ::rtl::OUString sVar;
77     if ( !xMM.is() )
78         return sVar;
79 
80     try
81     {
82         ::comphelper::NamedValueCollection aAnalyzer( xMM->getByName( sDocService ) );
83         sVar = aAnalyzer.getOrDefault( "ooSetupFactoryUIName", ::rtl::OUString() );
84     }
85     catch( uno::Exception& )
86     {
87         sVar = ::rtl::OUString();
88     }
89 
90     return sVar;
91 }
92 
93 //--------------------------------------------------------------------
StateChanged(StateChangedType nStateChange)94 void SfxFrameViewWindow_Impl::StateChanged( StateChangedType nStateChange )
95 {
96 	if ( nStateChange == STATE_CHANGE_INITSHOW )
97     {
98         SfxObjectShell* pDoc = pFrame->GetObjectShell();
99         if ( pDoc && !pFrame->IsVisible() )
100             pFrame->Show();
101 
102         pFrame->Resize();
103     }
104 	else
105         Window::StateChanged( nStateChange );
106 }
107 
Resize()108 void SfxFrameViewWindow_Impl::Resize()
109 {
110     if ( IsReallyVisible() || IsReallyShown() || GetOutputSizePixel().Width() )
111         pFrame->Resize();
112 }
113 
_getTabString()114 static String _getTabString()
115 {
116     String result;
117 
118     Reference < XMaterialHolder > xHolder(
119         ::comphelper::getProcessServiceFactory()->createInstance(
120         DEFINE_CONST_UNICODE("com.sun.star.tab.tabreg") ), UNO_QUERY );
121     if (xHolder.is())
122     {
123         rtl::OUString aTabString;
124         Sequence< NamedValue > sMaterial;
125         if (xHolder->getMaterial() >>= sMaterial) {
126             for (int i=0; i < sMaterial.getLength(); i++) {
127                 if ((sMaterial[i].Name.equalsAscii("title")) &&
128                     (sMaterial[i].Value >>= aTabString))
129                 {
130                     result += ' ';
131                     result += String(aTabString);
132                 }
133             }
134         }
135     }
136     return result;
137 }
138 
139 //========================================================================
140 
141 //--------------------------------------------------------------------
UpdateTitle()142 String SfxViewFrame::UpdateTitle()
143 
144 /*	[Beschreibung]
145 
146 	Mit dieser Methode kann der SfxViewFrame gezwungen werden, sich sofort
147 	den neuen Titel vom der <SfxObjectShell> zu besorgen.
148 
149 	[Anmerkung]
150 
151 	Dies ist z.B. dann notwendig, wenn man der SfxObjectShell als SfxListener
152 	zuh"ort und dort auf den <SfxSimpleHint> SFX_HINT_TITLECHANGED reagieren
153 	m"ochte, um dann die Titel seiner Views abzufragen. Diese Views (SfxTopViewFrames)
154 	jedoch sind ebenfalls SfxListener und da die Reihenfolge der Benachrichtigung
155 	nicht feststeht, mu\s deren Titel-Update vorab erzwungen werden.
156 
157 
158 	[Beispiel]
159 
160 	void SwDocShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
161 	{
162 		if ( rHint.IsA(TYPE(SfxSimpleHint)) )
163 		{
164 			switch( ( (SfxSimpleHint&) rHint ).GetId() )
165 			{
166 				case SFX_HINT_TITLECHANGED:
167 					for ( SfxViewFrame *pTop = SfxViewFrame::GetFirst( this );
168 						  pTop;
169 						  pTop = SfxViewFrame::GetNext( this );
170 					{
171 						pTop->UpdateTitle();
172 						... pTop->GetName() ...
173 					}
174 					break;
175 				...
176 			}
177 		}
178 	}
179 */
180 
181 {
182 	DBG_CHKTHIS(SfxViewFrame, 0);
183 
184     const SfxObjectFactory &rFact = GetObjectShell()->GetFactory();
185     pImp->aFactoryName = String::CreateFromAscii( rFact.GetShortName() );
186 
187     SfxObjectShell *pObjSh = GetObjectShell();
188 	if ( !pObjSh )
189         return String();
190 
191 //    if  ( pObjSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
192 //        // kein UpdateTitle mit Embedded-ObjectShell
193 //        return String();
194 
195     const SfxMedium *pMedium = pObjSh->GetMedium();
196 	String aURL;
197 	GetFrame();  // -Wall required??
198     if ( pObjSh->HasName() )
199 	{
200 		INetURLObject aTmp( pMedium->GetName() );
201         aURL = aTmp.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
202 	}
203 
204 	if ( aURL != pImp->aActualURL )
205         // URL hat sich ge"andert
206 		pImp->aActualURL = aURL;
207 
208     // gibt es noch eine weitere View?
209     sal_uInt16 nViews=0;
210     for ( SfxViewFrame *pView= GetFirst(pObjSh);
211           pView && nViews<2;
212           pView = GetNext(*pView,pObjSh) )
213         if ( ( pView->GetFrameType() & SFXFRAME_HASTITLE ) &&
214              !IsDowning_Impl())
215             nViews++;
216 
217     // Titel des Fensters
218     String aTitle;
219     if ( nViews == 2 || pImp->nDocViewNo > 1 )
220         // dann die Nummer dranh"angen
221         aTitle = pObjSh->UpdateTitle( NULL, pImp->nDocViewNo );
222     else
223         aTitle = pObjSh->UpdateTitle();
224 
225     // Name des SbxObjects
226     String aSbxName = pObjSh->SfxShell::GetName();
227     if ( IsVisible() )
228     {
229         aSbxName += ':';
230         aSbxName += String::CreateFromInt32(pImp->nDocViewNo);
231     }
232 
233     SetName( aSbxName );
234     pImp->aFrameTitle = aTitle;
235     GetBindings().Invalidate( SID_FRAMETITLE );
236     GetBindings().Invalidate( SID_CURRENT_URL );
237 
238     ::rtl::OUString aProductName;
239     ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::PRODUCTNAME) >>= aProductName;
240 
241     aTitle += String::CreateFromAscii( " - " );
242     aTitle += String(aProductName);
243     aTitle += ' ';
244     ::rtl::OUString aDocServiceName( GetObjectShell()->GetFactory().GetDocumentServiceName() );
245     aTitle += String( GetModuleName_Impl( aDocServiceName ) );
246 #ifdef DBG_UTIL
247 	::rtl::OUString	aDefault;
248 	aTitle += DEFINE_CONST_UNICODE(" [");
249 	String aVerId( utl::Bootstrap::getBuildIdData( aDefault ));
250 	aTitle += aVerId;
251 	aTitle += ']';
252 #endif
253 
254     // append TAB string if available
255     aTitle += _getTabString();
256 
257     GetBindings().Invalidate( SID_NEWDOCDIRECT );
258 
259     /* AS_TITLE
260     Window* pWindow = GetFrame()->GetTopWindow_Impl();
261     if ( pWindow && pWindow->GetText() != aTitle )
262         pWindow->SetText( aTitle );
263     */
264 	return aTitle;
265 }
266 
Exec_Impl(SfxRequest & rReq)267 void SfxViewFrame::Exec_Impl(SfxRequest &rReq )
268 {
269 	// Wenn gerade die Shells ausgetauscht werden...
270 	if ( !GetObjectShell() || !GetViewShell() )
271 		return;
272 
273 	switch ( rReq.GetSlot() )
274 	{
275         case SID_SHOWPOPUPS :
276         {
277 			SFX_REQUEST_ARG(rReq, pShowItem, SfxBoolItem, SID_SHOWPOPUPS, sal_False);
278 			sal_Bool bShow = pShowItem ? pShowItem->GetValue() : sal_True;
279 			SFX_REQUEST_ARG(rReq, pIdItem, SfxUInt16Item, SID_CONFIGITEMID, sal_False);
280 			sal_uInt16 nId = pIdItem ? pIdItem->GetValue() : 0;
281 
282 			// ausfuehren
283             SfxWorkWindow *pWorkWin = GetFrame().GetWorkWindow_Impl();
284 			if ( bShow )
285 			{
286 				// Zuerst die Floats auch anzeigbar machen
287 				pWorkWin->MakeChildsVisible_Impl( bShow );
288                 GetDispatcher()->Update_Impl( sal_True );
289 
290 				// Dann anzeigen
291                 GetBindings().HidePopups( !bShow );
292 			}
293             else
294 			{
295 				// Alles hiden
296 				SfxBindings *pBind = &GetBindings();
297 				while ( pBind )
298 				{
299 					pBind->HidePopupCtrls_Impl( !bShow );
300 					pBind = pBind->GetSubBindings_Impl();
301 				}
302 
303 				pWorkWin->HidePopups_Impl( !bShow, sal_True, nId );
304 				pWorkWin->MakeChildsVisible_Impl( bShow );
305 			}
306 
307             Invalidate( rReq.GetSlot() );
308             rReq.Done();
309 			break;
310         }
311 
312 		case SID_ACTIVATE:
313 		{
314             MakeActive_Impl( sal_True );
315             rReq.SetReturnValue( SfxObjectItem( 0, this ) );
316 			break;
317 		}
318 
319         case SID_NEWDOCDIRECT :
320         {
321             SFX_REQUEST_ARG( rReq, pFactoryItem, SfxStringItem, SID_NEWDOCDIRECT, sal_False);
322             String aFactName;
323             if ( pFactoryItem )
324                 aFactName = pFactoryItem->GetValue();
325             else if ( pImp->aFactoryName.Len() )
326 				aFactName = pImp->aFactoryName;
327 			else
328             {
329                 DBG_ERROR("Missing argument!");
330                 break;
331             }
332 
333             SfxRequest aReq( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, GetPool() );
334             String aFact = String::CreateFromAscii("private:factory/");
335             aFact += aFactName;
336             aReq.AppendItem( SfxStringItem( SID_FILE_NAME, aFact ) );
337             aReq.AppendItem( SfxFrameItem( SID_DOCFRAME, &GetFrame() ) );
338             aReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii( "_blank" ) ) );
339             SFX_APP()->ExecuteSlot( aReq );
340             const SfxViewFrameItem* pItem = PTR_CAST( SfxViewFrameItem, aReq.GetReturnValue() );
341             if ( pItem )
342                 rReq.SetReturnValue( SfxFrameItem( 0, pItem->GetFrame() ) );
343             break;
344         }
345 
346         case SID_CLOSEWIN:
347 		{
348 			// disable CloseWin, if frame is not a task
349             Reference < XCloseable > xTask( GetFrame().GetFrameInterface(),  UNO_QUERY );
350 			if ( !xTask.is() )
351 				break;
352 
353 			if ( GetViewShell()->PrepareClose() )
354 			{
355                 // weitere Views auf dasselbe Doc?
356 				SfxObjectShell *pDocSh = GetObjectShell();
357 				int bOther = sal_False;
358 				for ( const SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocSh );
359 					  !bOther && pFrame;
360 					  pFrame = SfxViewFrame::GetNext( *pFrame, pDocSh ) )
361 					bOther = (pFrame != this);
362 
363                 // Doc braucht nur gefragt zu werden, wenn keine weitere View
364 				sal_Bool bClosed = sal_False;
365                 sal_Bool bUI = sal_True;
366                 if ( ( bOther || pDocSh->PrepareClose( bUI ) ) )
367 				{
368 					if ( !bOther )
369                     	pDocSh->SetModified( sal_False );
370 					rReq.Done(); // unbedingt vor Close() rufen!
371                     bClosed = sal_False;
372 	                try
373 	                {
374 	                    xTask->close(sal_True);
375 	                    bClosed = sal_True;
376 	                }
377 	                catch( CloseVetoException& )
378 	                {
379 	                    bClosed = sal_False;
380 	                }
381 				}
382 
383 				rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bClosed ));
384 			}
385 			return;
386 		}
387 	}
388 
389 	rReq.Done();
390 }
391 
GetState_Impl(SfxItemSet & rSet)392 void SfxViewFrame::GetState_Impl( SfxItemSet &rSet )
393 {
394 	SfxObjectShell *pDocSh = GetObjectShell();
395 
396 	if ( !pDocSh )
397 		return;
398 
399 	const sal_uInt16 *pRanges = rSet.GetRanges();
400 	DBG_ASSERT(pRanges, "Set ohne Bereich");
401 	while ( *pRanges )
402 	{
403 		for ( sal_uInt16 nWhich = *pRanges++; nWhich <= *pRanges; ++nWhich )
404 		{
405 			switch(nWhich)
406 			{
407             case SID_NEWDOCDIRECT :
408             {
409 				if ( pImp->aFactoryName.Len() )
410 				{
411 	                String aFact = String::CreateFromAscii("private:factory/");
412 		            aFact += pImp->aFactoryName;
413 	                rSet.Put( SfxStringItem( nWhich, aFact ) );
414 				}
415                 break;
416             }
417 
418 			case SID_NEWWINDOW:
419 				rSet.DisableItem(nWhich);
420 				break;
421 
422 			case SID_CLOSEWIN:
423 			{
424 				// disable CloseWin, if frame is not a task
425                 Reference < XCloseable > xTask( GetFrame().GetFrameInterface(),  UNO_QUERY );
426 				if ( !xTask.is() )
427 					rSet.DisableItem(nWhich);
428 				break;
429 			}
430 
431             case SID_SHOWPOPUPS :
432 				break;
433 
434             case SID_OBJECT:
435                 if ( GetViewShell() && GetViewShell()->GetVerbs().getLength() && !GetObjectShell()->IsInPlaceActive() )
436 	            {
437 		            uno::Any aAny;
438 		            aAny <<= GetViewShell()->GetVerbs();
439                     rSet.Put( SfxUnoAnyItem( sal_uInt16( SID_OBJECT ), aAny ) );
440 	            }
441                 else
442                     rSet.DisableItem( SID_OBJECT );
443                 break;
444 
445 			default:
446 				DBG_ERROR( "invalid message-id" );
447 			}
448 		}
449 		++pRanges;
450 	}
451 }
452 
INetExecute_Impl(SfxRequest & rRequest)453 void SfxViewFrame::INetExecute_Impl( SfxRequest &rRequest )
454 {
455 	sal_uInt16 nSlotId = rRequest.GetSlot();
456 	switch( nSlotId )
457 	{
458 		case SID_BROWSE_FORWARD:
459 		case SID_BROWSE_BACKWARD:
460             OSL_ENSURE( false, "SfxViewFrame::INetExecute_Impl: SID_BROWSE_FORWARD/BACKWARD are dead!" );
461 			break;
462 		case SID_CREATELINK:
463 		{
464 /*! (pb) we need new implementation to create a link
465 */
466 			break;
467 		}
468 		case SID_FOCUSURLBOX:
469 		{
470             SfxStateCache *pCache = GetBindings().GetAnyStateCache_Impl( SID_OPENURL );
471 			if( pCache )
472 			{
473 				SfxControllerItem* pCtrl = pCache->GetItemLink();
474 				while( pCtrl )
475 				{
476                     pCtrl->StateChanged( SID_FOCUSURLBOX, SFX_ITEM_UNKNOWN, 0 );
477 					pCtrl = pCtrl->GetItemLink();
478 				}
479 			}
480 		}
481 	}
482 
483 	// Recording
484 	rRequest.Done();
485 }
486 
INetState_Impl(SfxItemSet & rItemSet)487 void SfxViewFrame::INetState_Impl( SfxItemSet &rItemSet )
488 {
489 	rItemSet.DisableItem( SID_BROWSE_FORWARD );
490 	rItemSet.DisableItem( SID_BROWSE_BACKWARD );
491 
492     // Add/SaveToBookmark bei BASIC-IDE, QUERY-EDITOR etc. disablen
493 	SfxObjectShell *pDocSh = GetObjectShell();
494     sal_Bool bPseudo = pDocSh && !( pDocSh->GetFactory().GetFlags() & SFXOBJECTSHELL_HASOPENDOC );
495     sal_Bool bEmbedded = pDocSh && pDocSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED;
496 	if ( !pDocSh || bPseudo || bEmbedded || !pDocSh->HasName() )
497 		rItemSet.DisableItem( SID_CREATELINK );
498 }
499 
SetZoomFactor(const Fraction & rZoomX,const Fraction & rZoomY)500 void SfxViewFrame::SetZoomFactor( const Fraction &rZoomX, const Fraction &rZoomY )
501 {
502 	GetViewShell()->SetZoomFactor( rZoomX, rZoomY );
503 }
504 
Activate(sal_Bool bMDI)505 void SfxViewFrame::Activate( sal_Bool bMDI )
506 {
507 	DBG_ASSERT(GetViewShell(), "Keine Shell");
508     if ( bMDI )
509         pImp->bActive = sal_True;
510 //(mba): hier evtl. wie in Beanframe NotifyEvent ?!
511 }
512 
Deactivate(sal_Bool bMDI)513 void SfxViewFrame::Deactivate( sal_Bool bMDI )
514 {
515 	DBG_ASSERT(GetViewShell(), "Keine Shell");
516     if ( bMDI )
517         pImp->bActive = sal_False;
518 //(mba): hier evtl. wie in Beanframe NotifyEvent ?!
519 }
520