/src/libreoffice/sfx2/source/view/viewfrm2.cxx
Line | Count | Source |
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 <workwin.hxx> |
24 | | |
25 | | #include <sfx2/app.hxx> |
26 | | #include <sfx2/bindings.hxx> |
27 | | #include <sfx2/ctrlitem.hxx> |
28 | | #include <sfx2/dispatch.hxx> |
29 | | #include <sfx2/docfac.hxx> |
30 | | #include <sfx2/docfile.hxx> |
31 | | #include <sfx2/objitem.hxx> |
32 | | #include <sfx2/objsh.hxx> |
33 | | #include <sfx2/request.hxx> |
34 | | #include <sfx2/sfxsids.hrc> |
35 | | #include <sfx2/viewfrm.hxx> |
36 | | #include <sfx2/viewsh.hxx> |
37 | | #include <com/sun/star/lang/DisposedException.hpp> |
38 | | #include <com/sun/star/util/CloseVetoException.hpp> |
39 | | #include <com/sun/star/util/XCloseable.hpp> |
40 | | #include <com/sun/star/embed/VerbDescriptor.hpp> |
41 | | |
42 | | #include <osl/diagnose.h> |
43 | | #include <svl/eitem.hxx> |
44 | | #include <svl/stritem.hxx> |
45 | | #include <tools/urlobj.hxx> |
46 | | #include <sal/log.hxx> |
47 | | |
48 | | using namespace ::com::sun::star; |
49 | | using namespace ::com::sun::star::uno; |
50 | | using namespace ::com::sun::star::util; |
51 | | |
52 | | |
53 | | void SfxFrameViewWindow_Impl::StateChanged( StateChangedType nStateChange ) |
54 | 3.93k | { |
55 | 3.93k | if ( nStateChange == StateChangedType::InitShow ) |
56 | 0 | { |
57 | 0 | SfxObjectShell* pDoc = pFrame->GetObjectShell(); |
58 | 0 | if ( pDoc && !pFrame->IsVisible() ) |
59 | 0 | pFrame->Show(); |
60 | |
|
61 | 0 | pFrame->Resize(); |
62 | 0 | } |
63 | 3.93k | else |
64 | 3.93k | Window::StateChanged( nStateChange ); |
65 | 3.93k | } |
66 | | |
67 | | void SfxFrameViewWindow_Impl::Resize() |
68 | 3.93k | { |
69 | 3.93k | if ( IsReallyVisible() || IsReallyShown() || GetOutputSizePixel().Width() ) |
70 | 0 | pFrame->Resize(); |
71 | 3.93k | } |
72 | | |
73 | | |
74 | | void SfxViewFrame::UpdateTitle() |
75 | | |
76 | | /* [Description] |
77 | | |
78 | | With this method, can the SfxViewFrame be forced to immediately provide |
79 | | the new title from the <SfxObjectShell>. |
80 | | |
81 | | [Note] |
82 | | |
83 | | This is for example necessary if one listens to the SfxObjectShell as |
84 | | SfxListener and then react on the <SfxSimpleHint> SfxHintId::TitleChanged, |
85 | | then query the title of his views. However these views (SfxTopViewFrames) |
86 | | are also SfxListener and because the order of notifications might not be |
87 | | fixed, the title update will be enforced in advance. |
88 | | |
89 | | [Example] |
90 | | |
91 | | void SwDocShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) |
92 | | { |
93 | | if ( dynamic_cast<const SfxSimpleHint *>(&rHint) != nullptr ) |
94 | | { |
95 | | switch( ( (SfxSimpleHint&) rHint ).GetId() ) |
96 | | { |
97 | | case SfxHintId::TitleChanged: |
98 | | for ( SfxViewFrame *pTop = SfxViewFrame::GetFirst( this ); |
99 | | pTop; |
100 | | pTop = SfxViewFrame::GetNext( this ); |
101 | | { |
102 | | pTop->UpdateTitle(); |
103 | | ... pTop->GetName() ... |
104 | | } |
105 | | break; |
106 | | ... |
107 | | } |
108 | | } |
109 | | } |
110 | | */ |
111 | | |
112 | 19.6k | { |
113 | | |
114 | 19.6k | const SfxObjectFactory &rFact = GetObjectShell()->GetFactory(); |
115 | 19.6k | m_pImpl->aFactoryName = rFact.GetFactoryName(); |
116 | | |
117 | 19.6k | SfxObjectShell *pObjSh = GetObjectShell(); |
118 | 19.6k | if ( !pObjSh ) |
119 | 0 | return; |
120 | | |
121 | | |
122 | 19.6k | const SfxMedium *pMedium = pObjSh->GetMedium(); |
123 | 19.6k | OUString aURL; |
124 | 19.6k | GetFrame(); // -Wall required?? |
125 | 19.6k | if ( pObjSh->HasName() ) |
126 | 0 | { |
127 | 0 | INetURLObject aTmp( pMedium->GetName() ); |
128 | 0 | aURL = aTmp.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset ); |
129 | 0 | } |
130 | | |
131 | 19.6k | if ( aURL != m_pImpl->aActualURL ) |
132 | | // URL has changed |
133 | 0 | m_pImpl->aActualURL = aURL; |
134 | | |
135 | | // SbxObjects name |
136 | 19.6k | OUString aSbxName = pObjSh->SfxShell::GetName(); |
137 | 19.6k | if ( IsVisible() ) |
138 | 15.7k | { |
139 | 15.7k | aSbxName += ":" + OUString::number(m_pImpl->nDocViewNo); |
140 | 15.7k | } |
141 | | |
142 | 19.6k | SetName( aSbxName ); |
143 | 19.6k | GetBindings().Invalidate( SID_CURRENT_URL ); |
144 | 19.6k | GetBindings().Invalidate( SID_NEWDOCDIRECT ); |
145 | 19.6k | } |
146 | | |
147 | | void SfxViewFrame::Exec_Impl(SfxRequest &rReq ) |
148 | 0 | { |
149 | | // If presently the shells are replaced... |
150 | 0 | if ( !GetObjectShell() || !GetViewShell() ) |
151 | 0 | return; |
152 | | |
153 | 0 | switch ( rReq.GetSlot() ) |
154 | 0 | { |
155 | 0 | case SID_SHOWPOPUPS : |
156 | 0 | { |
157 | 0 | const SfxBoolItem* pShowItem = rReq.GetArg<SfxBoolItem>(SID_SHOWPOPUPS); |
158 | 0 | bool bShow = pShowItem == nullptr || pShowItem->GetValue(); |
159 | |
|
160 | 0 | SfxWorkWindow *pWorkWin = GetFrame().GetWorkWindow_Impl(); |
161 | 0 | if ( bShow ) |
162 | 0 | { |
163 | | // First, make the floats viewable |
164 | 0 | pWorkWin->MakeChildrenVisible_Impl(true); |
165 | 0 | GetDispatcher()->Update_Impl( true ); |
166 | | |
167 | | // Then view it |
168 | 0 | GetBindings().HidePopups(false); |
169 | 0 | } |
170 | 0 | else |
171 | 0 | { |
172 | 0 | pWorkWin->HidePopups_Impl(true); |
173 | 0 | pWorkWin->MakeChildrenVisible_Impl(false); |
174 | 0 | } |
175 | |
|
176 | 0 | Invalidate( rReq.GetSlot() ); |
177 | 0 | rReq.Done(); |
178 | 0 | break; |
179 | 0 | } |
180 | | |
181 | 0 | case SID_ACTIVATE: |
182 | 0 | { |
183 | 0 | MakeActive_Impl( true ); |
184 | 0 | rReq.SetReturnValue(SfxObjectItem(0, this)); |
185 | 0 | break; |
186 | 0 | } |
187 | | |
188 | 0 | case SID_NEWDOCDIRECT : |
189 | 0 | { |
190 | 0 | const SfxStringItem* pFactoryItem = rReq.GetArg(SID_NEWDOCDIRECT); |
191 | 0 | OUString aFactName; |
192 | 0 | if ( pFactoryItem ) |
193 | 0 | aFactName = pFactoryItem->GetValue(); |
194 | 0 | else if ( !m_pImpl->aFactoryName.isEmpty() ) |
195 | 0 | aFactName = m_pImpl->aFactoryName; |
196 | 0 | else |
197 | 0 | { |
198 | 0 | SAL_WARN("sfx.view", "Missing argument!"); |
199 | 0 | break; |
200 | 0 | } |
201 | | |
202 | 0 | SfxRequest aReq( SID_OPENDOC, SfxCallMode::SYNCHRON, GetPool() ); |
203 | 0 | const OUString aFact("private:factory/" + aFactName); |
204 | 0 | aReq.AppendItem( SfxStringItem( SID_FILE_NAME, aFact ) ); |
205 | 0 | aReq.AppendItem( SfxFrameItem( SID_DOCFRAME, &GetFrame() ) ); |
206 | 0 | aReq.AppendItem( SfxStringItem( SID_TARGETNAME, u"_blank"_ustr ) ); |
207 | 0 | SfxGetpApp()->ExecuteSlot( aReq ); |
208 | |
|
209 | 0 | const SfxViewFrameItem* pItem(dynamic_cast<const SfxViewFrameItem*>(aReq.GetReturnValue().getItem())); |
210 | 0 | if (nullptr != pItem) |
211 | 0 | rReq.SetReturnValue(SfxFrameItem(0, pItem->GetFrame())); |
212 | 0 | break; |
213 | 0 | } |
214 | | |
215 | 0 | case SID_CLOSEWIN: |
216 | 0 | { |
217 | | // disable CloseWin, if frame is not a task |
218 | 0 | Reference < XCloseable > xTask( GetFrame().GetFrameInterface(), UNO_QUERY ); |
219 | 0 | if ( !xTask.is() ) |
220 | 0 | break; |
221 | | |
222 | 0 | if ( GetViewShell()->PrepareClose() ) |
223 | 0 | { |
224 | | // More Views on the same Document? |
225 | 0 | SfxObjectShell *pDocSh = GetObjectShell(); |
226 | 0 | bool bOther = false; |
227 | 0 | for ( const SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocSh ); |
228 | 0 | !bOther && pFrame; |
229 | 0 | pFrame = SfxViewFrame::GetNext( *pFrame, pDocSh ) ) |
230 | 0 | bOther = (pFrame != this); |
231 | | |
232 | | // Document only needs to be queried, if no other View present. |
233 | 0 | bool bClosed = false; |
234 | 0 | if ( bOther || pDocSh->PrepareClose( true/*bUI*/ ) ) |
235 | 0 | { |
236 | 0 | if ( !bOther ) |
237 | 0 | pDocSh->SetModified( false ); |
238 | 0 | rReq.Done(); // Must call this before Close()! |
239 | 0 | bClosed = false; |
240 | 0 | try |
241 | 0 | { |
242 | 0 | xTask->close(true); |
243 | 0 | bClosed = true; |
244 | 0 | } |
245 | 0 | catch (css::lang::DisposedException &) { |
246 | | // already closed; ignore |
247 | 0 | } |
248 | 0 | catch( CloseVetoException& ) |
249 | 0 | { |
250 | 0 | bClosed = false; |
251 | 0 | } |
252 | 0 | } |
253 | |
|
254 | 0 | rReq.SetReturnValue(SfxBoolItem(rReq.GetSlot(), bClosed)); |
255 | 0 | } |
256 | 0 | return; |
257 | 0 | } |
258 | 0 | } |
259 | | |
260 | 0 | rReq.Done(); |
261 | 0 | } |
262 | | |
263 | | void SfxViewFrame::GetState_Impl( SfxItemSet &rSet ) |
264 | 0 | { |
265 | 0 | SfxObjectShell *pDocSh = GetObjectShell(); |
266 | |
|
267 | 0 | if ( !pDocSh ) |
268 | 0 | return; |
269 | | |
270 | 0 | const WhichRangesContainer & pRanges = rSet.GetRanges(); |
271 | 0 | DBG_ASSERT(!pRanges.empty(), "Set without Range"); |
272 | 0 | for ( auto const & pRange : pRanges ) |
273 | 0 | { |
274 | 0 | for ( sal_uInt16 nWhich = pRange.first; nWhich <= pRange.second; ++nWhich ) |
275 | 0 | { |
276 | 0 | switch(nWhich) |
277 | 0 | { |
278 | 0 | case SID_NEWDOCDIRECT : |
279 | 0 | { |
280 | 0 | if ( !m_pImpl->aFactoryName.isEmpty() ) |
281 | 0 | { |
282 | 0 | rSet.Put( SfxStringItem( nWhich, "private:factory/"+m_pImpl->aFactoryName ) ); |
283 | 0 | } |
284 | 0 | break; |
285 | 0 | } |
286 | | |
287 | 0 | case SID_NEWWINDOW: |
288 | 0 | rSet.DisableItem(nWhich); |
289 | 0 | break; |
290 | | |
291 | 0 | case SID_CLOSEWIN: |
292 | 0 | { |
293 | | // disable CloseWin, if frame is not a task |
294 | 0 | Reference < XCloseable > xTask( GetFrame().GetFrameInterface(), UNO_QUERY ); |
295 | 0 | if ( !xTask.is() ) |
296 | 0 | rSet.DisableItem(nWhich); |
297 | 0 | break; |
298 | 0 | } |
299 | | |
300 | 0 | case SID_SHOWPOPUPS : |
301 | 0 | break; |
302 | | |
303 | 0 | case SID_OBJECT: |
304 | 0 | if ( GetViewShell() && GetViewShell()->GetVerbs().hasElements() && !GetObjectShell()->IsInPlaceActive() ) |
305 | 0 | { |
306 | 0 | uno::Any aAny(GetViewShell()->GetVerbs()); |
307 | 0 | rSet.Put( SfxUnoAnyItem( sal_uInt16( SID_OBJECT ), aAny ) ); |
308 | 0 | } |
309 | 0 | else |
310 | 0 | rSet.DisableItem( SID_OBJECT ); |
311 | 0 | break; |
312 | | |
313 | 0 | default: |
314 | 0 | OSL_FAIL( "invalid message-id" ); |
315 | 0 | } |
316 | 0 | } |
317 | 0 | } |
318 | 0 | } |
319 | | |
320 | | void SfxViewFrame::INetExecute_Impl( SfxRequest &rRequest ) |
321 | 0 | { |
322 | 0 | sal_uInt16 nSlotId = rRequest.GetSlot(); |
323 | 0 | switch( nSlotId ) |
324 | 0 | { |
325 | 0 | case SID_BROWSE_FORWARD: |
326 | 0 | case SID_BROWSE_BACKWARD: |
327 | 0 | OSL_FAIL( "SfxViewFrame::INetExecute_Impl: SID_BROWSE_FORWARD/BACKWARD are dead!" ); |
328 | 0 | break; |
329 | 0 | case SID_CREATELINK: |
330 | 0 | { |
331 | | /*! (pb) we need new implementation to create a link |
332 | | */ |
333 | 0 | break; |
334 | 0 | } |
335 | 0 | case SID_FOCUSURLBOX: |
336 | 0 | { |
337 | 0 | SfxStateCache *pCache = GetBindings().GetAnyStateCache_Impl( SID_OPENURL ); |
338 | 0 | if( pCache ) |
339 | 0 | { |
340 | 0 | SfxControllerItem* pCtrl = pCache->GetItemLink(); |
341 | 0 | while( pCtrl ) |
342 | 0 | { |
343 | 0 | pCtrl->StateChangedAtToolBoxControl( SID_FOCUSURLBOX, SfxItemState::UNKNOWN, nullptr ); |
344 | 0 | pCtrl = pCtrl->GetItemLink(); |
345 | 0 | } |
346 | 0 | } |
347 | 0 | } |
348 | 0 | } |
349 | | |
350 | | // Recording |
351 | 0 | rRequest.Done(); |
352 | 0 | } |
353 | | |
354 | | void SfxViewFrame::INetState_Impl( SfxItemSet &rItemSet ) |
355 | 0 | { |
356 | 0 | rItemSet.DisableItem( SID_BROWSE_FORWARD ); |
357 | 0 | rItemSet.DisableItem( SID_BROWSE_BACKWARD ); |
358 | | |
359 | | // Add/SaveToBookmark at BASIC-IDE, QUERY-EDITOR etc. disable |
360 | 0 | SfxObjectShell *pDocSh = GetObjectShell(); |
361 | 0 | bool bEmbedded = pDocSh && pDocSh->GetCreateMode() == SfxObjectCreateMode::EMBEDDED; |
362 | 0 | if ( !pDocSh || bEmbedded || !pDocSh->HasName() ) |
363 | 0 | rItemSet.DisableItem( SID_CREATELINK ); |
364 | 0 | } |
365 | | |
366 | | void SfxViewFrame::Activate( bool /*bMDI*/ ) |
367 | 3.93k | { |
368 | 3.93k | DBG_ASSERT(GetViewShell(), "No Shell"); |
369 | | //(mba): here maybe as in Beanframe NotifyEvent ?! |
370 | 3.93k | } |
371 | | |
372 | | void SfxViewFrame::Deactivate( bool /*bMDI*/ ) |
373 | 3.93k | { |
374 | 3.93k | DBG_ASSERT(GetViewShell(), "No Shell"); |
375 | | //(mba): here maybe as in Beanframe NotifyEvent ?! |
376 | 3.93k | } |
377 | | |
378 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |