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_chart2.hxx"
26 
27 #include "dlg_DataEditor.hxx"
28 #include "dlg_DataEditor.hrc"
29 #include "Strings.hrc"
30 #include "DataBrowser.hxx"
31 
32 #include "ResId.hxx"
33 #include "Strings.hrc"
34 #include "SchSlotIds.hxx"
35 #include <sfx2/dispatch.hxx>
36 #include <vcl/msgbox.hxx>
37 #include <vcl/taskpanelist.hxx>
38 #include <svtools/miscopt.hxx>
39 #include <unotools/pathoptions.hxx>
40 
41 // for SfxBoolItem
42 #include <svl/eitem.hxx>
43 
44 #include <vcl/edit.hxx>
45 
46 #include <com/sun/star/frame/XStorable.hpp>
47 #include <com/sun/star/chart2/XChartDocument.hpp>
48 
49 // for storing/reading the position and size of the dialog
50 // #include <svtools/viewoptions.hxx>
51 
52 using namespace ::com::sun::star;
53 using ::com::sun::star::uno::Reference;
54 using ::rtl::OUString;
55 
56 
57 namespace chart
58 {
59 
DataEditor(Window * pParent,const Reference<chart2::XChartDocument> & xChartDoc,const Reference<uno::XComponentContext> & xContext)60 DataEditor::DataEditor(
61     Window* pParent,
62     const Reference< chart2::XChartDocument > & xChartDoc,
63     const Reference< uno::XComponentContext > & xContext ) :
64         ModalDialog( pParent, SchResId( DLG_DIAGRAM_DATA )),
65         m_bReadOnly( false ),
66         m_apBrwData( new DataBrowser( this, SchResId( CTL_DATA ), true /* bLiveUpdate */)),
67         m_aTbxData( this, SchResId( TBX_DATA )),
68         m_xChartDoc( xChartDoc ),
69         m_xContext( xContext ),
70         m_aToolboxImageList( SchResId( IL_DIAGRAM_DATA )),
71         m_aToolboxImageListHighContrast( SchResId( IL_HC_DIAGRAM_DATA ))
72 {
73     FreeResource();
74 
75     // set min size to current size
76     SetMinOutputSizePixel( GetOutputSizePixel() );
77 
78     ApplyImageList();
79 
80     m_aTbxData.SetSizePixel( m_aTbxData.CalcWindowSizePixel() );
81     m_aTbxData.SetSelectHdl( LINK( this, DataEditor, ToolboxHdl ));
82 
83     m_apBrwData->SetCursorMovedHdl( LINK( this, DataEditor,   BrowserCursorMovedHdl ));
84     m_apBrwData->SetCellModifiedHdl( LINK( this, DataEditor,  CellModified ));
85 
86     UpdateData();
87     GrabFocus();
88     m_apBrwData->GrabFocus();
89 
90     bool bReadOnly = true;
91     Reference< frame::XStorable > xStor( m_xChartDoc, uno::UNO_QUERY );
92     if( xStor.is())
93         bReadOnly = xStor->isReadonly();
94     SetReadOnly( bReadOnly );
95 
96     // #101228# change buttons to flat-look if set so by user
97     SvtMiscOptions aMiscOptions;
98     const sal_Int16 nStyle( aMiscOptions.GetToolboxStyle() );
99     // react on changes
100     aMiscOptions.AddListenerLink( LINK( this, DataEditor, MiscHdl ) );
101     m_aTbxData.SetOutStyle( nStyle );
102 
103     // set good window width
104     Size aWinSize( GetOutputSizePixel());
105     Size aWinSizeWithBorder( GetSizePixel());
106     Point aWinPos( OutputToAbsoluteScreenPixel( GetPosPixel()));
107     sal_Int32 nMinWidth = aWinSize.getWidth();
108     sal_Int32 nMaxWidth = GetDesktopRectPixel().getWidth() -
109         (aWinSizeWithBorder.getWidth() - aWinSize.getWidth() + aWinPos.getX()) - 10; // leave some space
110     sal_Int32 nBrowserWidth = m_apBrwData->GetTotalWidth() + 12 + 16; // plus padding + 16?
111     sal_Int32 nWindowWidth = ::std::max( nMinWidth, nBrowserWidth );
112     nWindowWidth = ::std::min( nMaxWidth, nBrowserWidth );
113     aWinSize.setWidth( nWindowWidth );
114     SetOutputSizePixel( aWinSize );
115     AdaptBrowseBoxSize();
116 
117 //     ImplAdjustHeaderControls( false /* bRefreshFromModel */ );
118 
119     // allow travelling to toolbar with F6
120     notifySystemWindow( this, & m_aTbxData, ::comphelper::mem_fun( & TaskPaneList::AddWindow ));
121 }
122 
~DataEditor()123 DataEditor::~DataEditor()
124 {
125     notifySystemWindow( this, & m_aTbxData, ::comphelper::mem_fun( & TaskPaneList::RemoveWindow ));
126 
127     SvtMiscOptions aMiscOptions;
128     aMiscOptions.RemoveListenerLink( LINK( this, DataEditor, MiscHdl ) );
129 
130     OSL_TRACE( "DataEditor: DTOR" );
131 }
132 
133 // react on click (or keypress) on toolbar icon
IMPL_LINK(DataEditor,ToolboxHdl,void *,EMPTYARG)134 IMPL_LINK( DataEditor, ToolboxHdl, void *, EMPTYARG )
135 {
136     switch( m_aTbxData.GetCurItemId() )
137     {
138         case TBI_DATA_INSERT_ROW:
139             m_apBrwData->InsertRow();
140             break;
141         case TBI_DATA_INSERT_COL:
142             m_apBrwData->InsertColumn();
143             break;
144         case TBI_DATA_INSERT_TEXT_COL:
145             m_apBrwData->InsertTextColumn();
146             break;
147         case TBI_DATA_DELETE_ROW:
148             m_apBrwData->RemoveRow();
149             break;
150         case TBI_DATA_DELETE_COL:
151             m_apBrwData->RemoveColumn();
152             break;
153         case TBI_DATA_SWAP_COL :
154             m_apBrwData->SwapColumn ();
155             break;
156         case TBI_DATA_SWAP_ROW :
157             m_apBrwData->SwapRow ();
158             break;
159     }
160 
161     return 0;
162 }
163 
164 // refresh toolbar icons according to currently selected cell in browse box
IMPL_LINK(DataEditor,BrowserCursorMovedHdl,void *,EMPTYARG)165 IMPL_LINK( DataEditor, BrowserCursorMovedHdl, void *, EMPTYARG )
166 {
167     if( m_bReadOnly )
168         return 0;
169 
170     bool bIsDataValid = m_apBrwData->IsEnableItem();
171 
172     m_aTbxData.EnableItem( TBI_DATA_INSERT_ROW, bIsDataValid && m_apBrwData->MayInsertRow() );
173     m_aTbxData.EnableItem( TBI_DATA_INSERT_COL, bIsDataValid && m_apBrwData->MayInsertColumn() );
174     m_aTbxData.EnableItem( TBI_DATA_INSERT_TEXT_COL, bIsDataValid && m_apBrwData->MayInsertColumn() );
175     m_aTbxData.EnableItem( TBI_DATA_DELETE_ROW, m_apBrwData->MayDeleteRow() );
176     m_aTbxData.EnableItem( TBI_DATA_DELETE_COL, m_apBrwData->MayDeleteColumn() );
177 
178     m_aTbxData.EnableItem( TBI_DATA_SWAP_COL,   bIsDataValid && m_apBrwData->MaySwapColumns() );
179     m_aTbxData.EnableItem( TBI_DATA_SWAP_ROW,   bIsDataValid && m_apBrwData->MaySwapRows() );
180 
181     return 0;
182 }
183 
184 // disable all modifying controls
SetReadOnly(bool bReadOnly)185 void DataEditor::SetReadOnly( bool bReadOnly )
186 {
187     m_bReadOnly = bReadOnly;
188     if( m_bReadOnly )
189     {
190         m_aTbxData.EnableItem( TBI_DATA_INSERT_ROW, sal_False );
191         m_aTbxData.EnableItem( TBI_DATA_INSERT_COL, sal_False );
192         m_aTbxData.EnableItem( TBI_DATA_INSERT_TEXT_COL, sal_False );
193         m_aTbxData.EnableItem( TBI_DATA_DELETE_ROW, sal_False );
194         m_aTbxData.EnableItem( TBI_DATA_DELETE_COL, sal_False );
195         m_aTbxData.EnableItem( TBI_DATA_SWAP_COL, sal_False );
196         m_aTbxData.EnableItem( TBI_DATA_SWAP_ROW, sal_False );
197     }
198 
199     m_apBrwData->SetReadOnly( m_bReadOnly );
200 }
201 
IMPL_LINK(DataEditor,MiscHdl,void *,EMPTYARG)202 IMPL_LINK( DataEditor, MiscHdl, void*, EMPTYARG )
203 {
204     SvtMiscOptions aMiscOptions;
205     sal_Int16 nStyle( aMiscOptions.GetToolboxStyle() );
206 
207     m_aTbxData.SetOutStyle( nStyle );
208 
209     return 0L;
210 }
211 
IMPL_LINK(DataEditor,CellModified,void *,EMPTYARG)212 IMPL_LINK( DataEditor, CellModified, void*, EMPTYARG )
213 {
214     return 0;
215 }
216 
217 // IMPL_LINK( DataEditor, BrowserColumnResized, void*, EMPTYARG )
218 // {
219 //     ImplAdjustHeaderControls( false /* bRefreshFromModel */ );
220 //     return 0;
221 // }
222 
223 // IMPL_LINK( DataEditor, BrowserContentScrolled, void*, EMPTYARG )
224 // {
225 //     ImplAdjustHeaderControls( false /* bRefreshFromModel */ );
226 //     return 0;
227 // }
228 
UpdateData()229 void DataEditor::UpdateData()
230 {
231     m_apBrwData->SetDataFromModel( m_xChartDoc, m_xContext );
232 }
233 
234 // react on the change of the underlying document by displaying the new data
235 // void DataEditor::SFX_NOTIFY(
236 //     SfxBroadcaster& rBC,
237 //     const TypeId& rBCType,
238 //     const SfxHint& rHint,
239 //     const TypeId& rHintType )
240 // {
241 //     if( rHint.Type() == TYPE(SfxSimpleHint) )
242 //     {
243 //         // note: if dynamic_cast works this should be changed
244 //         switch( static_cast< const SfxSimpleHint & >( rHint ).GetId())
245 //         {
246 //             case SFX_HINT_DOCCHANGED:
247 //                 UpdateData();
248 //                 break;
249 
250 //             case SFX_HINT_DYING:
251 //                 break;
252 //         }
253 //     }
254 // }
255 
256 // {
257 //     sal_Bool bRet = sal_True;
258 
259 //     // confirm changes currently made and not saved
260 //     m_apBrwData->EndEditing();
261 
262 //     if( m_apBrwData->IsDirty() )
263 //     {
264 //         QueryBox aSafetyQuery( this, WB_YES_NO_CANCEL | WB_DEF_YES,
265 //                                String( SchResId( STR_DIAGRAM_DATA_SAFETY_QUERY )));
266 //         long nQueryResult = aSafetyQuery.Execute();
267 
268 //         bRet = ( nQueryResult != RET_CANCEL );
269 
270 //         if( nQueryResult == RET_YES )
271 //         {
272 //             // save changes
273 //             ApplyChangesToModel();
274 //         }
275 //     }
276 
277 //     if( bRet )
278 //     {
279 //         // close child window
280 //         SfxBoolItem aItem( SID_DIAGRAM_DATA, sal_False );
281 //         if( m_pBindings )
282 //         {
283 //             SfxDispatcher* pDisp = m_pBindings->GetDispatcher();
284 //             if( pDisp )
285 //                 pDisp->Execute( SID_DIAGRAM_DATA, SFX_CALLMODE_ASYNCHRON, &aItem, 0L);
286 //             else
287 //                 DBG_ERROR( "Couldn't dispatch command" );
288 //         }
289 //     }
290 
291 //     return ( bRet? SfxFloatingWindow::Close(): sal_False );
292 // }
293 
AdaptBrowseBoxSize()294 void DataEditor::AdaptBrowseBoxSize()
295 {
296     Size aSize( PixelToLogic( GetResizeOutputSizePixel(), MAP_APPFONT ));
297     Size aDataSize;
298 
299     aDataSize.setWidth( aSize.getWidth() - 12 );
300     aDataSize.setHeight( aSize.getHeight() - 31 -24 );
301 
302     m_apBrwData->SetSizePixel( LogicToPixel( aDataSize, MAP_APPFONT ));
303 }
304 
Resize()305 void DataEditor::Resize()
306 {
307     Dialog::Resize();
308     AdaptBrowseBoxSize();
309 //     ImplAdjustHeaderControls( false /* bRefreshFromModel */ );
310 }
311 
Close()312 sal_Bool DataEditor::Close()
313 {
314     if( ApplyChangesToModel() )
315         return ModalDialog::Close();
316     else
317         return sal_True;
318 }
319 
ApplyChangesToModel()320 bool DataEditor::ApplyChangesToModel()
321 {
322     return m_apBrwData->EndEditing();
323 }
324 
325 // sets the correct toolbar icons depending on the current mode (e.g. high contrast)
ApplyImageList()326 void DataEditor::ApplyImageList()
327 {
328     bool bIsHighContrast = ( true && GetSettings().GetStyleSettings().GetHighContrastMode() );
329 
330     ImageList& rImgLst = bIsHighContrast
331         ? m_aToolboxImageListHighContrast
332         : m_aToolboxImageList;
333 
334     m_aTbxData.SetImageList( rImgLst );
335 }
336 
337 // add/remove a window (the toolbar) to/from the global list, so that F6
338 // travels/no longer travels over this window. _rMemFunc may be
339 // TaskPaneList::AddWindow or TaskPaneList::RemoveWindow
notifySystemWindow(Window * pWindow,Window * pToRegister,::comphelper::mem_fun1_t<TaskPaneList,Window * > rMemFunc)340 void DataEditor::notifySystemWindow(
341     Window* pWindow, Window* pToRegister,
342     ::comphelper::mem_fun1_t< TaskPaneList, Window* > rMemFunc )
343 {
344     OSL_ENSURE( pWindow, "Window must not be null!" );
345     if( !pWindow )
346         return;
347     Window* pParent = pWindow->GetParent();
348     while( pParent && ! pParent->IsSystemWindow() )
349     {
350         pParent = pParent->GetParent();
351     }
352     if ( pParent && pParent->IsSystemWindow())
353     {
354         SystemWindow* pSystemWindow = static_cast< SystemWindow* >( pParent );
355         rMemFunc( pSystemWindow->GetTaskPaneList(),( pToRegister ));
356     }
357 }
358 
359 } // namespace chart
360