xref: /AOO41X/main/sfx2/source/view/viewfrm2.cxx (revision d119d52d53d0b2180f2ae51341d882123be2af2b)
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