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