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_cui.hxx"
30 
31 #include "connpooloptions.hxx"
32 #include "connpooloptions.hrc"
33 #include <svtools/editbrowsebox.hxx>
34 #include <vcl/field.hxx>
35 #include "connpoolsettings.hxx"
36 #include <svl/eitem.hxx>
37 #include <cuires.hrc>
38 #include "helpid.hrc"
39 #include <dialmgr.hxx>
40 
41 //........................................................................
42 namespace offapp
43 {
44 //........................................................................
45 
46 	//====================================================================
47 	//= DriverListControl
48 	//====================================================================
49 	typedef ::svt::EditBrowseBox DriverListControl_Base;
50 	class DriverListControl : public DriverListControl_Base
51 	{
52 		using Window::Update;
53 	protected:
54 		DriverPoolingSettings					m_aSavedSettings;
55 		DriverPoolingSettings					m_aSettings;
56 		DriverPoolingSettings::const_iterator	m_aSeekRow;
57 
58 		String									m_sYes;
59 		String									m_sNo;
60 
61 		Link									m_aRowChangeHandler;
62 
63 	public:
64 		DriverListControl( Window* _pParent, const ResId& _rId);
65 
66 		virtual	void Init();
67 				void Update(const DriverPoolingSettings& _rSettings);
68 		virtual String GetCellText( long nRow, sal_uInt16 nColId ) const;
69 
70 		// the handler will be called with a DriverPoolingSettings::const_iterator as parameter,
71 		// or NULL if no valid current row exists
72 		void SetRowChangeHandler(const Link& _rHdl) { m_aRowChangeHandler = _rHdl; }
73 		Link GetRowChangeHandler() const { return m_aRowChangeHandler; }
74 
75 		const DriverPooling* getCurrentRow() const;
76 		DriverPooling* getCurrentRow();
77 		void									updateCurrentRow();
78 
79 		const DriverPoolingSettings& getSettings() const { return m_aSettings; }
80 
81 		void		saveValue()				{ m_aSavedSettings = m_aSettings; }
82 		sal_Bool	isModified() const;
83 
84 	protected:
85 		virtual void InitController( ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol );
86 		virtual ::svt::CellController* GetController( long nRow, sal_uInt16 nCol );
87 
88 		virtual void PaintCell( OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColId ) const;
89 
90 		virtual sal_Bool SeekRow( long nRow );
91 		virtual sal_Bool SaveModified();
92 
93 		virtual sal_Bool IsTabAllowed(sal_Bool _bForward) const;
94 
95 		virtual void StateChanged( StateChangedType nStateChange );
96 
97 		virtual void CursorMoved();
98 
99 	protected:
100 		virtual sal_uInt32 GetTotalCellWidth(long nRow, sal_uInt16 nColId);
101 
102 
103 	private:
104 		String implGetCellText(DriverPoolingSettings::const_iterator _rPos, sal_uInt16 _nColId) const;
105 	};
106 
107 	//--------------------------------------------------------------------
108 	DriverListControl::DriverListControl( Window* _pParent, const ResId& _rId)
109 //		:DriverListControl_Base(_pParent, _rId, DBBF_NOROWPICTURE, BROWSER_AUTO_VSCROLL | BROWSER_AUTO_HSCROLL | BROWSER_COLUMNSELECTION | BROWSER_HLINESFULL | BROWSER_VLINESFULL | BROWSER_HIDESELECT | BROWSER_CURSOR_WO_FOCUS)
110 		:DriverListControl_Base(_pParent, _rId, EBBF_NOROWPICTURE, BROWSER_AUTO_VSCROLL | BROWSER_AUTO_HSCROLL | BROWSER_HIDECURSOR | BROWSER_AUTOSIZE_LASTCOL)
111 		,m_aSeekRow(m_aSettings.end())
112 		,m_sYes(ResId(STR_YES,*_rId.GetResMgr()))
113 		,m_sNo(ResId(STR_NO,*_rId.GetResMgr()))
114 	{
115 		SetStyle((GetStyle() & ~WB_HSCROLL) | WB_AUTOHSCROLL);
116 
117 		SetUniqueId(UID_OFA_CONNPOOL_DRIVERLIST_BACK);
118 		GetDataWindow().SetHelpId(HID_OFA_CONNPOOL_DRIVERLIST);
119 	}
120 
121 	//--------------------------------------------------------------------
122     sal_Bool DriverListControl::IsTabAllowed(sal_Bool /*_bForward*/) const
123 	{
124 		// no travinling within the fields via RETURN and TAB
125 		return sal_False;
126 	}
127 
128 	//--------------------------------------------------------------------
129 	sal_Bool DriverListControl::isModified() const
130 	{
131 		if (m_aSettings.size() != m_aSavedSettings.size())
132 			return sal_True;
133 
134 		DriverPoolingSettings::const_iterator aCurrent = m_aSettings.begin();
135 		DriverPoolingSettings::const_iterator aCurrentEnd = m_aSettings.end();
136 		DriverPoolingSettings::const_iterator aSaved = m_aSavedSettings.begin();
137 		for (;aCurrent != aCurrentEnd; ++aCurrent, ++aSaved)
138 		{
139 			if (*aCurrent != *aSaved)
140 				return sal_True;
141 		}
142 
143 		return sal_False;
144 	}
145 
146 	//--------------------------------------------------------------------
147 	void DriverListControl::Init()
148 	{
149 		DriverListControl_Base::Init();
150 
151 		Size aColWidth = LogicToPixel(Size(160, 0), MAP_APPFONT);
152 		InsertDataColumn(1, String(CUI_RES(STR_DRIVER_NAME)), aColWidth.Width());
153 		aColWidth = LogicToPixel(Size(30, 0), MAP_APPFONT);
154 		InsertDataColumn(2, String(CUI_RES(STR_POOLED_FLAG)), aColWidth.Width());
155 		aColWidth = LogicToPixel(Size(60, 0), MAP_APPFONT);
156 		InsertDataColumn(3, String(CUI_RES(STR_POOL_TIMEOUT)), aColWidth.Width());
157 			// Attention: the resource of the string is local to the resource of the enclosing dialog!
158 	}
159 
160 	//--------------------------------------------------------------------
161 	void DriverListControl::CursorMoved()
162 	{
163 		DriverListControl_Base::CursorMoved();
164 
165 		// call the row change handler
166 		if ( m_aRowChangeHandler.IsSet() )
167         {
168             if ( GetCurRow() >= 0 )
169             {   // == -1 may happen in case the browse box has just been cleared
170     			m_aRowChangeHandler.Call( getCurrentRow() );
171             }
172         }
173 	}
174 
175 	//--------------------------------------------------------------------
176 	const DriverPooling* DriverListControl::getCurrentRow() const
177 	{
178 		OSL_ENSURE( ( GetCurRow() < m_aSettings.size() ) && ( GetCurRow() >= 0 ),
179             "DriverListControl::getCurrentRow: invalid current row!");
180 
181         if ( ( GetCurRow() >= 0 ) && ( GetCurRow() < m_aSettings.size() ) )
182 			return &(*(m_aSettings.begin() + GetCurRow()));
183 
184 		return NULL;
185 	}
186 
187 	//--------------------------------------------------------------------
188 	DriverPooling* DriverListControl::getCurrentRow()
189 	{
190 		OSL_ENSURE( ( GetCurRow() < m_aSettings.size() ) && ( GetCurRow() >= 0 ),
191 		    "DriverListControl::getCurrentRow: invalid current row!");
192 
193         if ( ( GetCurRow() >= 0 ) && ( GetCurRow() < m_aSettings.size() ) )
194 			return &(*(m_aSettings.begin() + GetCurRow()));
195 
196 		return NULL;
197 	}
198 
199 	//--------------------------------------------------------------------
200 	void DriverListControl::updateCurrentRow()
201 	{
202 		Window::Invalidate( GetRowRectPixel( GetCurRow() ), INVALIDATE_UPDATE );
203 	}
204 
205 	//--------------------------------------------------------------------
206 	void DriverListControl::Update(const DriverPoolingSettings& _rSettings)
207 	{
208 		m_aSettings = _rSettings;
209 
210 		SetUpdateMode(sal_False);
211 		RowRemoved(0, GetRowCount());
212 		RowInserted(0, m_aSettings.size());
213 		SetUpdateMode(sal_True);
214 
215 		ActivateCell(1, 0);
216 	}
217 
218 	//--------------------------------------------------------------------
219 	sal_uInt32 DriverListControl::GetTotalCellWidth(long nRow, sal_uInt16 nColId)
220 	{
221 		return GetDataWindow().GetTextWidth(GetCellText(nRow, nColId));
222 	}
223 
224 	//--------------------------------------------------------------------
225 	String DriverListControl::implGetCellText(DriverPoolingSettings::const_iterator _rPos, sal_uInt16 _nColId) const
226 	{
227 		OSL_ENSURE(_rPos < m_aSettings.end(), "DriverListControl::implGetCellText: invalid position!");
228 
229 		String sReturn;
230 		switch (_nColId)
231 		{
232 			case 1:
233 				sReturn = _rPos->sName;
234 				break;
235 			case 2:
236 				sReturn = _rPos->bEnabled ? m_sYes : m_sNo;
237 				break;
238 			case 3:
239 				if (_rPos->bEnabled)
240 					sReturn = String::CreateFromInt32(_rPos->nTimeoutSeconds);
241 				break;
242 			default:
243 				OSL_ENSURE(sal_False, "DriverListControl::implGetCellText: invalid column id!");
244 		}
245 		return sReturn;
246 	}
247 
248 	//--------------------------------------------------------------------
249 	void DriverListControl::StateChanged( StateChangedType nStateChange )
250 	{
251 		if (STATE_CHANGE_ENABLE == nStateChange)
252 			Window::Invalidate(INVALIDATE_UPDATE);
253 		DriverListControl_Base::StateChanged( nStateChange );
254 	}
255 
256 	//--------------------------------------------------------------------
257 	String DriverListControl::GetCellText( long nRow, sal_uInt16 nColId ) const
258 	{
259 		String sReturn;
260 		if (nRow > m_aSettings.size())
261 		{
262 			OSL_ENSURE(sal_False, "DriverListControl::GetCellText: don't ask me for such rows!");
263 		}
264 		else
265 		{
266 			sReturn = implGetCellText(m_aSettings.begin() + nRow, nColId);
267 		}
268 		return sReturn;
269 	}
270 
271 	//--------------------------------------------------------------------
272 	void DriverListControl::InitController( ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol )
273 	{
274 		rController->GetWindow().SetText(GetCellText(nRow, nCol));
275 	}
276 
277 	//--------------------------------------------------------------------
278     ::svt::CellController* DriverListControl::GetController( long /*nRow*/, sal_uInt16 /*nCol*/ )
279 	{
280 		return NULL;
281 	}
282 
283 	//--------------------------------------------------------------------
284 	sal_Bool DriverListControl::SaveModified()
285 	{
286 		return sal_True;
287 	}
288 
289 	//--------------------------------------------------------------------
290 	sal_Bool DriverListControl::SeekRow( long _nRow )
291 	{
292 		DriverListControl_Base::SeekRow(_nRow);
293 
294 		if (_nRow < m_aSettings.size())
295 			m_aSeekRow = m_aSettings.begin() + _nRow;
296 		else
297 			m_aSeekRow = m_aSettings.end();
298 
299 		return m_aSeekRow != m_aSettings.end();
300 	}
301 
302 	//--------------------------------------------------------------------
303 	void DriverListControl::PaintCell( OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColId ) const
304 	{
305 		OSL_ENSURE(m_aSeekRow != m_aSettings.end(), "DriverListControl::PaintCell: invalid row!");
306 
307 		if (m_aSeekRow != m_aSettings.end())
308 		{
309 			rDev.SetClipRegion(rRect);
310 
311 			sal_uInt16 nStyle = TEXT_DRAW_CLIP;
312 			if (!IsEnabled())
313 				nStyle |= TEXT_DRAW_DISABLE;
314 			switch (nColId)
315 			{
316 				case 1: nStyle |= TEXT_DRAW_LEFT; break;
317 				case 2:
318 				case 3: nStyle |= TEXT_DRAW_CENTER; break;
319 			}
320 
321 			rDev.DrawText(rRect, implGetCellText(m_aSeekRow, nColId), nStyle);
322 
323 			rDev.SetClipRegion();
324 		}
325 	}
326 
327 	//====================================================================
328 	//= ConnectionPoolOptionsPage
329 	//====================================================================
330 	//--------------------------------------------------------------------
331 	ConnectionPoolOptionsPage::ConnectionPoolOptionsPage(Window* _pParent, const SfxItemSet& _rAttrSet)
332 		:SfxTabPage(_pParent, CUI_RES(RID_OFAPAGE_CONNPOOLOPTIONS ), _rAttrSet)
333 		,m_aFrame				(this,				CUI_RES(FL_POOLING))
334 		,m_aEnablePooling		(this,		CUI_RES(CB_POOL_CONNS))
335 		,m_aDriversLabel		(this,		CUI_RES(FT_DRIVERS))
336 		,m_pDriverList(new DriverListControl(this, CUI_RES(CTRL_DRIVER_LIST)))
337 		,m_aDriverLabel			(this,		CUI_RES(FT_DRIVERLABEL))
338 		,m_aDriver				(this,		CUI_RES(FT_DRIVER))
339 		,m_aDriverPoolingEnabled(this,		CUI_RES(CB_DRIVERPOOLING))
340 		,m_aTimeoutLabel		(this,		CUI_RES(FT_TIMEOUT))
341 		,m_aTimeout				(this,		CUI_RES(NF_TIMEOUT))
342 	{
343 		m_pDriverList->Init();
344 		m_pDriverList->Show();
345 
346 		FreeResource();
347 
348 		m_aEnablePooling.SetClickHdl( LINK(this, ConnectionPoolOptionsPage, OnEnabledDisabled) );
349 		m_aDriverPoolingEnabled.SetClickHdl( LINK(this, ConnectionPoolOptionsPage, OnEnabledDisabled) );
350 
351 		m_pDriverList->SetRowChangeHandler( LINK(this, ConnectionPoolOptionsPage, OnDriverRowChanged) );
352 	}
353 
354 	//--------------------------------------------------------------------
355 	SfxTabPage* ConnectionPoolOptionsPage::Create(Window* _pParent, const SfxItemSet& _rAttrSet)
356 	{
357 		return new ConnectionPoolOptionsPage(_pParent, _rAttrSet);
358 	}
359 
360 	//--------------------------------------------------------------------
361 	ConnectionPoolOptionsPage::~ConnectionPoolOptionsPage()
362 	{
363 		delete m_pDriverList;
364 	}
365 
366 	//--------------------------------------------------------------------
367 	void ConnectionPoolOptionsPage::implInitControls(const SfxItemSet& _rSet, sal_Bool /*_bFromReset*/)
368 	{
369 		// the enabled flag
370 		SFX_ITEMSET_GET( _rSet, pEnabled, SfxBoolItem, SID_SB_POOLING_ENABLED, sal_True );
371 		OSL_ENSURE(pEnabled, "ConnectionPoolOptionsPage::implInitControls: missing the Enabled item!");
372 		m_aEnablePooling.Check(pEnabled ? pEnabled->GetValue() : sal_True);
373 
374 		m_aEnablePooling.SaveValue();
375 
376 		// the settings for the single drivers
377 		SFX_ITEMSET_GET( _rSet, pDriverSettings, DriverPoolingSettingsItem, SID_SB_DRIVER_TIMEOUTS, sal_True );
378 		if (pDriverSettings)
379 			m_pDriverList->Update(pDriverSettings->getSettings());
380 		else
381 		{
382 			OSL_ENSURE(sal_False, "ConnectionPoolOptionsPage::implInitControls: missing the DriverTimeouts item!");
383 			m_pDriverList->Update(DriverPoolingSettings());
384 		}
385 		m_pDriverList->saveValue();
386 
387 		// reflect the new settings
388 		OnEnabledDisabled(&m_aEnablePooling);
389 	}
390 
391 	//--------------------------------------------------------------------
392 	long ConnectionPoolOptionsPage::Notify( NotifyEvent& _rNEvt )
393 	{
394 		if (EVENT_LOSEFOCUS == _rNEvt.GetType())
395 			if (m_aTimeout.IsWindowOrChild(_rNEvt.GetWindow()))
396 				commitTimeoutField();
397 
398 		return SfxTabPage::Notify(_rNEvt);
399 	}
400 
401 	//--------------------------------------------------------------------
402 	sal_Bool ConnectionPoolOptionsPage::FillItemSet(SfxItemSet& _rSet)
403 	{
404 		commitTimeoutField();
405 
406 		sal_Bool bModified = sal_False;
407 		// the enabled flag
408 		if (m_aEnablePooling.GetSavedValue() != m_aEnablePooling.IsChecked())
409 		{
410 			_rSet.Put(SfxBoolItem(SID_SB_POOLING_ENABLED, m_aEnablePooling.IsChecked()), SID_SB_POOLING_ENABLED);
411 			bModified = sal_True;
412 		}
413 
414 		// the settings for the single drivers
415 		if (m_pDriverList->isModified())
416 		{
417 			_rSet.Put(DriverPoolingSettingsItem(SID_SB_DRIVER_TIMEOUTS, m_pDriverList->getSettings()), SID_SB_DRIVER_TIMEOUTS);
418 			bModified = sal_True;
419 		}
420 
421 		return bModified;
422 	}
423 
424 	//--------------------------------------------------------------------
425 	void ConnectionPoolOptionsPage::ActivatePage( const SfxItemSet& _rSet)
426 	{
427 		SfxTabPage::ActivatePage(_rSet);
428 		implInitControls(_rSet, sal_False);
429 	}
430 
431 	//--------------------------------------------------------------------
432 	void ConnectionPoolOptionsPage::Reset(const SfxItemSet& _rSet)
433 	{
434 		implInitControls(_rSet, sal_True);
435 	}
436 
437 	//--------------------------------------------------------------------
438 	IMPL_LINK( ConnectionPoolOptionsPage, OnDriverRowChanged, const void*, _pRowIterator )
439 	{
440 		sal_Bool bValidRow = (NULL != _pRowIterator);
441 		m_aDriverPoolingEnabled.Enable(bValidRow && m_aEnablePooling.IsChecked());
442 		m_aTimeoutLabel.Enable(bValidRow);
443 		m_aTimeout.Enable(bValidRow);
444 
445 		if (!bValidRow)
446 		{	// positioned on an invalid row
447 			m_aDriver.SetText(String());
448 		}
449 		else
450 		{
451 			const DriverPooling *pDriverPos = static_cast<const DriverPooling*>(_pRowIterator);
452 
453 			m_aDriver.SetText(pDriverPos->sName);
454 			m_aDriverPoolingEnabled.Check(pDriverPos->bEnabled);
455 			m_aTimeout.SetText(String::CreateFromInt32(pDriverPos->nTimeoutSeconds));
456 
457 			OnEnabledDisabled(&m_aDriverPoolingEnabled);
458 		}
459 
460 		return 0L;
461 	}
462 
463 	//--------------------------------------------------------------------
464 	void ConnectionPoolOptionsPage::commitTimeoutField()
465 	{
466 		if (DriverPooling* pCurrentDriver = m_pDriverList->getCurrentRow())
467 		{
468 			pCurrentDriver->nTimeoutSeconds = static_cast<long>(m_aTimeout.GetValue());
469 			m_pDriverList->updateCurrentRow();
470 		}
471 	}
472 
473 	//--------------------------------------------------------------------
474 	IMPL_LINK( ConnectionPoolOptionsPage, OnEnabledDisabled, const CheckBox*, _pCheckBox )
475 	{
476 		sal_Bool bGloballyEnabled = m_aEnablePooling.IsChecked();
477 		sal_Bool bLocalDriverChanged = &m_aDriverPoolingEnabled == _pCheckBox;
478 
479 		if (&m_aEnablePooling == _pCheckBox)
480 		{
481 			m_aDriversLabel.Enable(bGloballyEnabled);
482 			m_pDriverList->Enable(bGloballyEnabled);
483 			m_aDriverLabel.Enable(bGloballyEnabled);
484 			m_aDriver.Enable(bGloballyEnabled);
485 			m_aDriverPoolingEnabled.Enable(bGloballyEnabled);
486 		}
487 		else
488 			OSL_ENSURE(bLocalDriverChanged, "ConnectionPoolOptionsPage::OnEnabledDisabled: where did this come from?");
489 
490 		m_aTimeoutLabel.Enable(bGloballyEnabled && m_aDriverPoolingEnabled.IsChecked());
491 		m_aTimeout.Enable(bGloballyEnabled && m_aDriverPoolingEnabled.IsChecked());
492 
493 		if (bLocalDriverChanged)
494 		{
495 			// update the list
496 			m_pDriverList->getCurrentRow()->bEnabled = m_aDriverPoolingEnabled.IsChecked();
497 			m_pDriverList->updateCurrentRow();
498 		}
499 
500 		return 0L;
501 	}
502 
503 //........................................................................
504 }	// namespace offapp
505 //........................................................................
506 
507 
508