Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "impviewframe.hxx"
22 : #include "statcach.hxx"
23 : #include "sfx2/viewfac.hxx"
24 : #include "workwin.hxx"
25 :
26 : #include "sfx2/app.hxx"
27 : #include "sfx2/bindings.hxx"
28 : #include "sfx2/ctrlitem.hxx"
29 : #include "sfx2/dispatch.hxx"
30 : #include "sfx2/docfac.hxx"
31 : #include "sfx2/docfile.hxx"
32 : #include "sfx2/objitem.hxx"
33 : #include "sfx2/objsh.hxx"
34 : #include "sfx2/request.hxx"
35 : #include "sfx2/viewfrm.hxx"
36 : #include "sfx2/viewsh.hxx"
37 :
38 : #include <com/sun/star/util/XCloseable.hpp>
39 :
40 : #include <comphelper/componentcontext.hxx>
41 : #include <svtools/asynclink.hxx>
42 : #include <svl/eitem.hxx>
43 : #include <svl/intitem.hxx>
44 : #include <svl/rectitem.hxx>
45 : #include <svl/stritem.hxx>
46 : #include <tools/diagnose_ex.h>
47 : #include <tools/urlobj.hxx>
48 : #include <vcl/window.hxx>
49 :
50 : using namespace ::com::sun::star;
51 : using namespace ::com::sun::star::uno;
52 : using namespace ::com::sun::star::frame;
53 : using namespace ::com::sun::star::util;
54 : using namespace ::com::sun::star::container;
55 : using namespace ::com::sun::star::beans;
56 : using ::com::sun::star::lang::XMultiServiceFactory;
57 : using ::com::sun::star::lang::XComponent;
58 :
59 : //--------------------------------------------------------------------
60 586 : void SfxFrameViewWindow_Impl::StateChanged( StateChangedType nStateChange )
61 : {
62 586 : if ( nStateChange == STATE_CHANGE_INITSHOW )
63 : {
64 236 : SfxObjectShell* pDoc = pFrame->GetObjectShell();
65 236 : if ( pDoc && !pFrame->IsVisible() )
66 142 : pFrame->Show();
67 :
68 236 : pFrame->Resize();
69 : }
70 : else
71 350 : Window::StateChanged( nStateChange );
72 586 : }
73 :
74 567 : void SfxFrameViewWindow_Impl::Resize()
75 : {
76 567 : if ( IsReallyVisible() || IsReallyShown() || GetOutputSizePixel().Width() )
77 469 : pFrame->Resize();
78 567 : }
79 :
80 : //========================================================================
81 :
82 : //--------------------------------------------------------------------
83 798 : void SfxViewFrame::UpdateTitle()
84 :
85 : /* [Description]
86 :
87 : With this method, can the SfxViewFrame be forced to immediately provide
88 : the new title from the <SfxObjectShell>.
89 :
90 : [Note]
91 :
92 : This is for example necessary if one listens to the SfxObjectShell as
93 : SfxListener and then react on the <SfxSimpleHint> SFX_HINT_TITLECHANGED,
94 : then query the title of his views. However these views (SfxTopViewFrames)
95 : are also SfxListener and because the order of notifications might not be
96 : fixed, the title update will be enforced in advance.
97 :
98 : [Example]
99 :
100 : void SwDocShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
101 : {
102 : if ( rHint.IsA(TYPE(SfxSimpleHint)) )
103 : {
104 : switch( ( (SfxSimpleHint&) rHint ).GetId() )
105 : {
106 : case SFX_HINT_TITLECHANGED:
107 : for ( SfxViewFrame *pTop = SfxViewFrame::GetFirst( this );
108 : pTop;
109 : pTop = SfxViewFrame::GetNext( this );
110 : {
111 : pTop->UpdateTitle();
112 : ... pTop->GetName() ...
113 : }
114 : break;
115 : ...
116 : }
117 : }
118 : }
119 : */
120 :
121 : {
122 : DBG_CHKTHIS(SfxViewFrame, 0);
123 :
124 798 : const SfxObjectFactory &rFact = GetObjectShell()->GetFactory();
125 798 : pImp->aFactoryName = rtl::OUString::createFromAscii(rFact.GetShortName());
126 :
127 798 : SfxObjectShell *pObjSh = GetObjectShell();
128 798 : if ( !pObjSh )
129 798 : return;
130 :
131 :
132 798 : const SfxMedium *pMedium = pObjSh->GetMedium();
133 798 : String aURL;
134 798 : GetFrame(); // -Wall required??
135 798 : if ( pObjSh->HasName() )
136 : {
137 781 : INetURLObject aTmp( pMedium->GetName() );
138 781 : aURL = aTmp.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
139 : }
140 :
141 798 : if ( aURL != pImp->aActualURL )
142 : // URL has changed
143 235 : pImp->aActualURL = aURL;
144 :
145 : // SbxObjects name
146 798 : String aSbxName = pObjSh->SfxShell::GetName();
147 798 : if ( IsVisible() )
148 : {
149 538 : aSbxName += ':';
150 538 : aSbxName += String::CreateFromInt32(pImp->nDocViewNo);
151 : }
152 :
153 798 : SetName( aSbxName );
154 798 : GetBindings().Invalidate( SID_CURRENT_URL );
155 798 : GetBindings().Invalidate( SID_NEWDOCDIRECT );
156 : }
157 :
158 0 : void SfxViewFrame::Exec_Impl(SfxRequest &rReq )
159 : {
160 : // If presently the shells are replaced...
161 0 : if ( !GetObjectShell() || !GetViewShell() )
162 0 : return;
163 :
164 0 : switch ( rReq.GetSlot() )
165 : {
166 : case SID_SHOWPOPUPS :
167 : {
168 0 : SFX_REQUEST_ARG(rReq, pShowItem, SfxBoolItem, SID_SHOWPOPUPS, sal_False);
169 0 : sal_Bool bShow = pShowItem ? pShowItem->GetValue() : sal_True;
170 0 : SFX_REQUEST_ARG(rReq, pIdItem, SfxUInt16Item, SID_CONFIGITEMID, sal_False);
171 0 : sal_uInt16 nId = pIdItem ? pIdItem->GetValue() : 0;
172 :
173 0 : SfxWorkWindow *pWorkWin = GetFrame().GetWorkWindow_Impl();
174 0 : if ( bShow )
175 : {
176 : // First, make the floats viewable
177 0 : pWorkWin->MakeChildrenVisible_Impl( bShow );
178 0 : GetDispatcher()->Update_Impl( sal_True );
179 :
180 : // Then view it
181 0 : GetBindings().HidePopups( !bShow );
182 : }
183 : else
184 : {
185 : // Hide all
186 0 : SfxBindings *pBind = &GetBindings();
187 0 : while ( pBind )
188 : {
189 0 : pBind->HidePopupCtrls_Impl( !bShow );
190 0 : pBind = pBind->GetSubBindings_Impl();
191 : }
192 :
193 0 : pWorkWin->HidePopups_Impl( !bShow, sal_True, nId );
194 0 : pWorkWin->MakeChildrenVisible_Impl( bShow );
195 : }
196 :
197 0 : Invalidate( rReq.GetSlot() );
198 0 : rReq.Done();
199 0 : break;
200 : }
201 :
202 : case SID_ACTIVATE:
203 : {
204 0 : MakeActive_Impl( sal_True );
205 0 : rReq.SetReturnValue( SfxObjectItem( 0, this ) );
206 0 : break;
207 : }
208 :
209 : case SID_NEWDOCDIRECT :
210 : {
211 0 : SFX_REQUEST_ARG( rReq, pFactoryItem, SfxStringItem, SID_NEWDOCDIRECT, sal_False);
212 0 : String aFactName;
213 0 : if ( pFactoryItem )
214 0 : aFactName = pFactoryItem->GetValue();
215 0 : else if ( pImp->aFactoryName.Len() )
216 0 : aFactName = pImp->aFactoryName;
217 : else
218 : {
219 : OSL_FAIL("Missing argument!");
220 : break;
221 : }
222 :
223 0 : SfxRequest aReq( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, GetPool() );
224 0 : String aFact = rtl::OUString("private:factory/");
225 0 : aFact += aFactName;
226 0 : aReq.AppendItem( SfxStringItem( SID_FILE_NAME, aFact ) );
227 0 : aReq.AppendItem( SfxFrameItem( SID_DOCFRAME, &GetFrame() ) );
228 0 : aReq.AppendItem( SfxStringItem( SID_TARGETNAME, rtl::OUString( "_blank" ) ) );
229 0 : SFX_APP()->ExecuteSlot( aReq );
230 0 : const SfxViewFrameItem* pItem = PTR_CAST( SfxViewFrameItem, aReq.GetReturnValue() );
231 0 : if ( pItem )
232 0 : rReq.SetReturnValue( SfxFrameItem( 0, pItem->GetFrame() ) );
233 0 : break;
234 : }
235 :
236 : case SID_CLOSEWIN:
237 : {
238 : // disable CloseWin, if frame is not a task
239 0 : Reference < XCloseable > xTask( GetFrame().GetFrameInterface(), UNO_QUERY );
240 0 : if ( !xTask.is() )
241 : break;
242 :
243 0 : if ( GetViewShell()->PrepareClose() )
244 : {
245 : // More Views on the same Document?
246 0 : SfxObjectShell *pDocSh = GetObjectShell();
247 0 : int bOther = sal_False;
248 0 : for ( const SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocSh );
249 : !bOther && pFrame;
250 : pFrame = SfxViewFrame::GetNext( *pFrame, pDocSh ) )
251 0 : bOther = (pFrame != this);
252 :
253 : // Document only needs to be queried, if no other View present.
254 0 : sal_Bool bClosed = sal_False;
255 0 : sal_Bool bUI = sal_True;
256 0 : if ( ( bOther || pDocSh->PrepareClose( bUI ) ) )
257 : {
258 0 : if ( !bOther )
259 0 : pDocSh->SetModified( sal_False );
260 0 : rReq.Done(); // Must call this before Close()!
261 0 : bClosed = sal_False;
262 : try
263 : {
264 0 : xTask->close(sal_True);
265 0 : bClosed = sal_True;
266 : }
267 0 : catch( CloseVetoException& )
268 : {
269 0 : bClosed = sal_False;
270 : }
271 : }
272 :
273 0 : rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), bClosed ));
274 : }
275 0 : return;
276 : }
277 : }
278 :
279 0 : rReq.Done();
280 : }
281 :
282 0 : void SfxViewFrame::GetState_Impl( SfxItemSet &rSet )
283 : {
284 0 : SfxObjectShell *pDocSh = GetObjectShell();
285 :
286 0 : if ( !pDocSh )
287 0 : return;
288 :
289 0 : const sal_uInt16 *pRanges = rSet.GetRanges();
290 : DBG_ASSERT(pRanges, "Set without Range");
291 0 : while ( *pRanges )
292 : {
293 0 : for ( sal_uInt16 nWhich = *pRanges++; nWhich <= *pRanges; ++nWhich )
294 : {
295 0 : switch(nWhich)
296 : {
297 : case SID_NEWDOCDIRECT :
298 : {
299 0 : if ( pImp->aFactoryName.Len() )
300 : {
301 0 : String aFact = rtl::OUString("private:factory/");
302 0 : aFact += pImp->aFactoryName;
303 0 : rSet.Put( SfxStringItem( nWhich, aFact ) );
304 : }
305 0 : break;
306 : }
307 :
308 : case SID_NEWWINDOW:
309 0 : rSet.DisableItem(nWhich);
310 0 : break;
311 :
312 : case SID_CLOSEWIN:
313 : {
314 : // disable CloseWin, if frame is not a task
315 0 : Reference < XCloseable > xTask( GetFrame().GetFrameInterface(), UNO_QUERY );
316 0 : if ( !xTask.is() )
317 0 : rSet.DisableItem(nWhich);
318 0 : break;
319 : }
320 :
321 : case SID_SHOWPOPUPS :
322 0 : break;
323 :
324 : case SID_OBJECT:
325 0 : if ( GetViewShell() && GetViewShell()->GetVerbs().getLength() && !GetObjectShell()->IsInPlaceActive() )
326 : {
327 0 : uno::Any aAny;
328 0 : aAny <<= GetViewShell()->GetVerbs();
329 0 : rSet.Put( SfxUnoAnyItem( sal_uInt16( SID_OBJECT ), aAny ) );
330 : }
331 : else
332 0 : rSet.DisableItem( SID_OBJECT );
333 0 : break;
334 :
335 : default:
336 : OSL_FAIL( "invalid message-id" );
337 : }
338 : }
339 0 : ++pRanges;
340 : }
341 : }
342 :
343 0 : void SfxViewFrame::INetExecute_Impl( SfxRequest &rRequest )
344 : {
345 0 : sal_uInt16 nSlotId = rRequest.GetSlot();
346 0 : switch( nSlotId )
347 : {
348 : case SID_BROWSE_FORWARD:
349 : case SID_BROWSE_BACKWARD:
350 : OSL_FAIL( "SfxViewFrame::INetExecute_Impl: SID_BROWSE_FORWARD/BACKWARD are dead!" );
351 0 : break;
352 : case SID_CREATELINK:
353 : {
354 : /*! (pb) we need new implementation to create a link
355 : */
356 0 : break;
357 : }
358 : case SID_FOCUSURLBOX:
359 : {
360 0 : SfxStateCache *pCache = GetBindings().GetAnyStateCache_Impl( SID_OPENURL );
361 0 : if( pCache )
362 : {
363 0 : SfxControllerItem* pCtrl = pCache->GetItemLink();
364 0 : while( pCtrl )
365 : {
366 0 : pCtrl->StateChanged( SID_FOCUSURLBOX, SFX_ITEM_UNKNOWN, 0 );
367 0 : pCtrl = pCtrl->GetItemLink();
368 : }
369 : }
370 : }
371 : }
372 :
373 : // Recording
374 0 : rRequest.Done();
375 0 : }
376 :
377 0 : void SfxViewFrame::INetState_Impl( SfxItemSet &rItemSet )
378 : {
379 0 : rItemSet.DisableItem( SID_BROWSE_FORWARD );
380 0 : rItemSet.DisableItem( SID_BROWSE_BACKWARD );
381 :
382 : // Add/SaveToBookmark at BASIC-IDE, QUERY-EDITOR etc. disable
383 0 : SfxObjectShell *pDocSh = GetObjectShell();
384 0 : sal_Bool bPseudo = pDocSh && !( pDocSh->GetFactory().GetFlags() & SFXOBJECTSHELL_HASOPENDOC );
385 0 : sal_Bool bEmbedded = pDocSh && pDocSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED;
386 0 : if ( !pDocSh || bPseudo || bEmbedded || !pDocSh->HasName() )
387 0 : rItemSet.DisableItem( SID_CREATELINK );
388 0 : }
389 :
390 0 : void SfxViewFrame::SetZoomFactor( const Fraction &rZoomX, const Fraction &rZoomY )
391 : {
392 0 : GetViewShell()->SetZoomFactor( rZoomX, rZoomY );
393 0 : }
394 :
395 236 : void SfxViewFrame::Activate( sal_Bool bMDI )
396 : {
397 : DBG_ASSERT(GetViewShell(), "No Shell");
398 236 : if ( bMDI )
399 236 : pImp->bActive = sal_True;
400 : //(mba): here maybe as in Beanframe NotifyEvent ?!
401 236 : }
402 :
403 236 : void SfxViewFrame::Deactivate( sal_Bool bMDI )
404 : {
405 : DBG_ASSERT(GetViewShell(), "No Shell");
406 236 : if ( bMDI )
407 236 : pImp->bActive = sal_False;
408 : //(mba): here maybe as in Beanframe NotifyEvent ?!
409 236 : }
410 :
411 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|