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_extensions.hxx"
30 #include "groupboxwiz.hxx"
31 #include "commonpagesdbp.hxx"
32 #include <tools/debug.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/msgbox.hxx>
35 #include "optiongrouplayouter.hxx"
36 #include "dbpilots.hrc"
37 
38 
39 //#define GBW_STATE_DATASELECTION		0
40 #define GBW_STATE_OPTIONLIST		0
41 #define GBW_STATE_DEFAULTOPTION		1
42 #define GBW_STATE_OPTIONVALUES		2
43 #define GBW_STATE_DBFIELD			3
44 #define GBW_STATE_FINALIZE			4
45 
46 //.........................................................................
47 namespace dbp
48 {
49 //.........................................................................
50 
51 	using namespace ::com::sun::star::uno;
52 	using namespace ::com::sun::star::lang;
53 	using namespace ::com::sun::star::beans;
54 	using namespace ::com::sun::star::form;
55 	using namespace ::svt;
56 
57 	//=====================================================================
58 	//= OGroupBoxWizard
59 	//=====================================================================
60 	//---------------------------------------------------------------------
61 	OGroupBoxWizard::OGroupBoxWizard( Window* _pParent,
62 			const Reference< XPropertySet >& _rxObjectModel, const Reference< XMultiServiceFactory >& _rxORB )
63 		:OControlWizard(_pParent, ModuleRes(RID_DLG_GROUPBOXWIZARD), _rxObjectModel, _rxORB)
64 		,m_bVisitedDefault(sal_False)
65 		,m_bVisitedDB(sal_False)
66 	{
67 		initControlSettings(&m_aSettings);
68 
69 		m_pPrevPage->SetHelpId(HID_GROUPWIZARD_PREVIOUS);
70 		m_pNextPage->SetHelpId(HID_GROUPWIZARD_NEXT);
71 		m_pCancel->SetHelpId(HID_GROUPWIZARD_CANCEL);
72 		m_pFinish->SetHelpId(HID_GROUPWIZARD_FINISH);
73 	}
74 
75 	//---------------------------------------------------------------------
76 	sal_Bool OGroupBoxWizard::approveControl(sal_Int16 _nClassId)
77 	{
78 		return FormComponentType::GROUPBOX == _nClassId;
79 	}
80 
81 	//---------------------------------------------------------------------
82 	OWizardPage* OGroupBoxWizard::createPage(::svt::WizardTypes::WizardState _nState)
83 	{
84 		switch (_nState)
85 		{
86 //			case GBW_STATE_DATASELECTION:
87 //				return new OTableSelectionPage(this);
88 //
89 			case GBW_STATE_OPTIONLIST:
90 				return new ORadioSelectionPage(this);
91 
92 			case GBW_STATE_DEFAULTOPTION:
93 				return new ODefaultFieldSelectionPage(this);
94 
95 			case GBW_STATE_OPTIONVALUES:
96 				return new OOptionValuesPage(this);
97 
98 			case GBW_STATE_DBFIELD:
99 				return new OOptionDBFieldPage(this);
100 
101 			case GBW_STATE_FINALIZE:
102 				return new OFinalizeGBWPage(this);
103 		}
104 
105 		return NULL;
106 	}
107 
108 	//---------------------------------------------------------------------
109 	WizardTypes::WizardState OGroupBoxWizard::determineNextState( ::svt::WizardTypes::WizardState _nCurrentState ) const
110 	{
111 		switch (_nCurrentState)
112 		{
113 //			case GBW_STATE_DATASELECTION:
114 //				return GBW_STATE_OPTIONLIST;
115 //
116 			case GBW_STATE_OPTIONLIST:
117 				return GBW_STATE_DEFAULTOPTION;
118 
119 			case GBW_STATE_DEFAULTOPTION:
120 				return GBW_STATE_OPTIONVALUES;
121 
122 			case GBW_STATE_OPTIONVALUES:
123 				if (getContext().aFieldNames.getLength())
124 					return GBW_STATE_DBFIELD;
125 				else
126 					return GBW_STATE_FINALIZE;
127 
128 			case GBW_STATE_DBFIELD:
129 				return GBW_STATE_FINALIZE;
130 		}
131 
132 		return WZS_INVALID_STATE;
133 	}
134 
135 	//---------------------------------------------------------------------
136 	void OGroupBoxWizard::enterState(::svt::WizardTypes::WizardState _nState)
137 	{
138 		// some stuff to do before calling the base class (modifying our settings)
139 		switch (_nState)
140 		{
141 			case GBW_STATE_DEFAULTOPTION:
142 				if (!m_bVisitedDefault)
143 				{	// assume that the first of the radio buttons should be selected
144 					DBG_ASSERT(m_aSettings.aLabels.size(), "OGroupBoxWizard::enterState: should never have reached this state!");
145 					m_aSettings.sDefaultField = m_aSettings.aLabels[0];
146 				}
147 				m_bVisitedDefault = sal_True;
148 				break;
149 
150 			case GBW_STATE_DBFIELD:
151 				if (!m_bVisitedDB)
152 				{	// try to generate a default for the DB field
153 					// (simply use the first field in the DB names collection)
154 					if (getContext().aFieldNames.getLength())
155 						m_aSettings.sDBField = getContext().aFieldNames[0];
156 				}
157 				m_bVisitedDB = sal_True;
158 				break;
159 		}
160 
161 		// setting the def button .... to be done before the base class is called, too, 'cause the base class
162 		// calls the pages, which are allowed to override our def button behaviour
163 		defaultButton(GBW_STATE_FINALIZE == _nState ? WZB_FINISH : WZB_NEXT);
164 
165 		// allow "finish" on the last page only
166 		enableButtons(WZB_FINISH, GBW_STATE_FINALIZE == _nState);
167 		// allow previous on all pages but the first one
168 		enableButtons(WZB_PREVIOUS, GBW_STATE_OPTIONLIST != _nState);
169 		// allow next on all pages but the last one
170 		enableButtons(WZB_NEXT, GBW_STATE_FINALIZE != _nState);
171 
172 		OControlWizard::enterState(_nState);
173 	}
174 
175 	//---------------------------------------------------------------------
176 	void OGroupBoxWizard::createRadios()
177 	{
178 		try
179 		{
180 			OOptionGroupLayouter aLayouter(getServiceFactory());
181 			aLayouter.doLayout(getContext(), getSettings());
182 		}
183 		catch(Exception&)
184 		{
185 			DBG_ERROR("OGroupBoxWizard::createRadios: caught an exception while creating the radio shapes!");
186 		}
187 	}
188 
189 	//---------------------------------------------------------------------
190 	sal_Bool OGroupBoxWizard::onFinish()
191 	{
192 		// commit the basic control setttings
193 		commitControlSettings(&m_aSettings);
194 
195 		// create the radio buttons
196 		createRadios();
197 
198 		return OControlWizard::onFinish();
199 	}
200 
201 	//=====================================================================
202 	//= ORadioSelectionPage
203 	//=====================================================================
204 	//---------------------------------------------------------------------
205 	ORadioSelectionPage::ORadioSelectionPage( OControlWizard* _pParent )
206 		:OGBWPage(_pParent, ModuleRes(RID_PAGE_GROUPRADIOSELECTION))
207 		,m_aFrame				(this, ModuleRes(FL_DATA))
208 		,m_aRadioNameLabel		(this, ModuleRes(FT_RADIOLABELS))
209 		,m_aRadioName			(this, ModuleRes(ET_RADIOLABELS))
210 		,m_aMoveRight			(this, ModuleRes(PB_MOVETORIGHT))
211 		,m_aMoveLeft			(this, ModuleRes(PB_MOVETOLEFT))
212 		,m_aExistingRadiosLabel	(this, ModuleRes(FT_RADIOBUTTONS))
213 		,m_aExistingRadios		(this, ModuleRes(LB_RADIOBUTTONS))
214 	{
215 		FreeResource();
216 
217 		if (getContext().aFieldNames.getLength())
218 		{
219 			enableFormDatasourceDisplay();
220 		}
221 		else
222 		{
223 			adjustControlForNoDSDisplay(&m_aFrame);
224 			adjustControlForNoDSDisplay(&m_aRadioNameLabel);
225 			adjustControlForNoDSDisplay(&m_aRadioName);
226 			adjustControlForNoDSDisplay(&m_aMoveRight);
227 			adjustControlForNoDSDisplay(&m_aMoveLeft);
228 			adjustControlForNoDSDisplay(&m_aExistingRadiosLabel);
229 			adjustControlForNoDSDisplay(&m_aExistingRadios, sal_True);
230 		}
231 
232 		m_aMoveLeft.SetClickHdl(LINK(this, ORadioSelectionPage, OnMoveEntry));
233 		m_aMoveRight.SetClickHdl(LINK(this, ORadioSelectionPage, OnMoveEntry));
234 		m_aRadioName.SetModifyHdl(LINK(this, ORadioSelectionPage, OnNameModified));
235 		m_aExistingRadios.SetSelectHdl(LINK(this, ORadioSelectionPage, OnEntrySelected));
236 
237 		implCheckMoveButtons();
238 		m_aExistingRadios.EnableMultiSelection(sal_True);
239 
240 		getDialog()->defaultButton(&m_aMoveRight);
241 
242 		m_aExistingRadios.SetAccessibleRelationMemberOf(&m_aExistingRadios);
243 		m_aExistingRadios.SetAccessibleRelationLabeledBy(&m_aExistingRadiosLabel);
244 	}
245 
246 	//---------------------------------------------------------------------
247 	void ORadioSelectionPage::ActivatePage()
248 	{
249 		OGBWPage::ActivatePage();
250 		m_aRadioName.GrabFocus();
251 	}
252 
253 	//---------------------------------------------------------------------
254 	void ORadioSelectionPage::initializePage()
255 	{
256 		OGBWPage::initializePage();
257 
258 		m_aRadioName.SetText(String());
259 
260 		// no need to initialize the list of radios here
261 		// (we're the only one affecting this special setting, so it will be in the same state as last time this
262 		// page was commited)
263 
264 		implCheckMoveButtons();
265 	}
266 
267 	//---------------------------------------------------------------------
268 	sal_Bool ORadioSelectionPage::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
269 	{
270 		if (!OGBWPage::commitPage(_eReason))
271 			return sal_False;
272 
273 		// copy the names of the radio buttons to be inserted
274 		// and initialize the values
275 		OOptionGroupSettings& rSettings = getSettings();
276 		rSettings.aLabels.clear();
277 		rSettings.aValues.clear();
278 		rSettings.aLabels.reserve(m_aExistingRadios.GetEntryCount());
279 		rSettings.aValues.reserve(m_aExistingRadios.GetEntryCount());
280 		for (::svt::WizardTypes::WizardState i=0; i<m_aExistingRadios.GetEntryCount(); ++i)
281 		{
282 			rSettings.aLabels.push_back(m_aExistingRadios.GetEntry(i));
283 			rSettings.aValues.push_back(String::CreateFromInt32((sal_Int32)(i + 1)));
284 		}
285 
286 		return sal_True;
287 	}
288 
289 	//---------------------------------------------------------------------
290 	IMPL_LINK( ORadioSelectionPage, OnMoveEntry, PushButton*, _pButton )
291 	{
292 		sal_Bool bMoveLeft = (&m_aMoveLeft == _pButton);
293 		if (bMoveLeft)
294 		{
295 			while (m_aExistingRadios.GetSelectEntryCount())
296 				m_aExistingRadios.RemoveEntry(m_aExistingRadios.GetSelectEntryPos(0));
297 		}
298 		else
299 		{
300 			m_aExistingRadios.InsertEntry(m_aRadioName.GetText());
301 			m_aRadioName.SetText(String());
302 		}
303 
304 		implCheckMoveButtons();
305 
306 		//adjust the focus
307 		if (bMoveLeft)
308 			m_aExistingRadios.GrabFocus();
309 		else
310 			m_aRadioName.GrabFocus();
311 		return 0L;
312 	}
313 
314 	//---------------------------------------------------------------------
315 	IMPL_LINK( ORadioSelectionPage, OnEntrySelected, ListBox*, /*_pList*/ )
316 	{
317 		implCheckMoveButtons();
318 		return 0L;
319 	}
320 
321 	//---------------------------------------------------------------------
322 	IMPL_LINK( ORadioSelectionPage, OnNameModified, Edit*, /*_pList*/ )
323 	{
324 		implCheckMoveButtons();
325 		return 0L;
326 	}
327 
328 	//---------------------------------------------------------------------
329 	bool ORadioSelectionPage::canAdvance() const
330 	{
331 		return 0 != m_aExistingRadios.GetEntryCount();
332 	}
333 
334 	//---------------------------------------------------------------------
335 	void ORadioSelectionPage::implCheckMoveButtons()
336 	{
337 		sal_Bool bHaveSome = (0 != m_aExistingRadios.GetEntryCount());
338 		sal_Bool bSelectedSome = (0 != m_aExistingRadios.GetSelectEntryCount());
339 		sal_Bool bUnfinishedInput = (0 != m_aRadioName.GetText().Len());
340 
341 		m_aMoveLeft.Enable(bSelectedSome);
342 		m_aMoveRight.Enable(bUnfinishedInput);
343 
344 		getDialog()->enableButtons(WZB_NEXT, bHaveSome);
345 
346 		if (bUnfinishedInput)
347 		{
348 			if (0 == (m_aMoveRight.GetStyle() & WB_DEFBUTTON))
349 				getDialog()->defaultButton(&m_aMoveRight);
350 		}
351 		else
352 		{
353 			if (WB_DEFBUTTON == (m_aMoveRight.GetStyle() & WB_DEFBUTTON))
354 				getDialog()->defaultButton(WZB_NEXT);
355 		}
356 	}
357 
358 	//=====================================================================
359 	//= ODefaultFieldSelectionPage
360 	//=====================================================================
361 	//---------------------------------------------------------------------
362 	ODefaultFieldSelectionPage::ODefaultFieldSelectionPage( OControlWizard* _pParent )
363 		:OMaybeListSelectionPage(_pParent, ModuleRes(RID_PAGE_DEFAULTFIELDSELECTION))
364 		,m_aFrame					(this, ModuleRes(FL_DEFAULTSELECTION))
365 		,m_aDefaultSelectionLabel	(this, ModuleRes(FT_DEFAULTSELECTION))
366 		,m_aDefSelYes				(this, ModuleRes(RB_DEFSELECTION_YES))
367 		,m_aDefSelNo				(this, ModuleRes(RB_DEFSELECTION_NO))
368 		,m_aDefSelection			(this, ModuleRes(LB_DEFSELECTIONFIELD))
369 	{
370 		FreeResource();
371 
372 		announceControls(m_aDefSelYes, m_aDefSelNo, m_aDefSelection);
373 		m_aDefSelection.SetDropDownLineCount(10);
374 		m_aDefSelection.SetAccessibleRelationLabeledBy( &m_aDefSelYes );
375 		m_aDefSelection.SetAccessibleRelationMemberOf(&m_aDefaultSelectionLabel);
376 	}
377 
378 	//---------------------------------------------------------------------
379 	void ODefaultFieldSelectionPage::initializePage()
380 	{
381 		OMaybeListSelectionPage::initializePage();
382 
383 		const OOptionGroupSettings& rSettings = getSettings();
384 
385 		// fill the listbox
386 		m_aDefSelection.Clear();
387 		for	(	ConstStringArrayIterator aLoop = rSettings.aLabels.begin();
388 				aLoop != rSettings.aLabels.end();
389 				++aLoop
390 			)
391 			m_aDefSelection.InsertEntry(*aLoop);
392 
393 
394 		implInitialize(rSettings.sDefaultField);
395 	}
396 
397 	//---------------------------------------------------------------------
398 	sal_Bool ODefaultFieldSelectionPage::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
399 	{
400 		if (!OMaybeListSelectionPage::commitPage(_eReason))
401 			return sal_False;
402 
403 		OOptionGroupSettings& rSettings = getSettings();
404 		implCommit(rSettings.sDefaultField);
405 
406 		return sal_True;
407 	}
408 
409 	//=====================================================================
410 	//= OOptionValuesPage
411 	//=====================================================================
412 	//---------------------------------------------------------------------
413 	OOptionValuesPage::OOptionValuesPage( OControlWizard* _pParent )
414 		:OGBWPage(_pParent, ModuleRes(RID_PAGE_OPTIONVALUES))
415 		,m_aFrame				(this, ModuleRes(FL_OPTIONVALUES))
416 		,m_aDescription			(this, ModuleRes(FT_OPTIONVALUES_EXPL))
417 		,m_aValueLabel			(this, ModuleRes(FT_OPTIONVALUES))
418 		,m_aValue				(this, ModuleRes(ET_OPTIONVALUE))
419 		,m_aOptionsLabel		(this, ModuleRes(FT_RADIOBUTTONS))
420 		,m_aOptions				(this, ModuleRes(LB_RADIOBUTTONS))
421 		,m_nLastSelection((::svt::WizardTypes::WizardState)-1)
422 	{
423 		FreeResource();
424 
425 		m_aOptions.SetSelectHdl(LINK(this, OOptionValuesPage, OnOptionSelected));
426 
427 		m_aOptions.SetAccessibleRelationMemberOf(&m_aOptions);
428 		m_aOptions.SetAccessibleRelationLabeledBy(&m_aOptionsLabel);
429 	}
430 
431 	//---------------------------------------------------------------------
432 	IMPL_LINK( OOptionValuesPage, OnOptionSelected, ListBox*, /*NOTINTERESTEDIN*/ )
433 	{
434 		implTraveledOptions();
435 		return 0L;
436 	}
437 
438 	//---------------------------------------------------------------------
439 	void OOptionValuesPage::ActivatePage()
440 	{
441 		OGBWPage::ActivatePage();
442 		m_aValue.GrabFocus();
443 	}
444 
445 	//---------------------------------------------------------------------
446 	void OOptionValuesPage::implTraveledOptions()
447 	{
448 		if ((::svt::WizardTypes::WizardState)-1 != m_nLastSelection)
449 		{
450 			// save the value for the last option
451 			DBG_ASSERT((size_t)m_nLastSelection < m_aUncommittedValues.size(), "OOptionValuesPage::implTraveledOptions: invalid previous selection index!");
452 			m_aUncommittedValues[m_nLastSelection] = m_aValue.GetText();
453 		}
454 
455 		m_nLastSelection = m_aOptions.GetSelectEntryPos();
456 		DBG_ASSERT((size_t)m_nLastSelection < m_aUncommittedValues.size(), "OOptionValuesPage::implTraveledOptions: invalid new selection index!");
457 		m_aValue.SetText(m_aUncommittedValues[m_nLastSelection]);
458 	}
459 
460 	//---------------------------------------------------------------------
461 	void OOptionValuesPage::initializePage()
462 	{
463 		OGBWPage::initializePage();
464 
465 		const OOptionGroupSettings& rSettings = getSettings();
466 		DBG_ASSERT(rSettings.aLabels.size(), "OOptionValuesPage::initializePage: no options!!");
467 		DBG_ASSERT(rSettings.aLabels.size() == rSettings.aValues.size(), "OOptionValuesPage::initializePage: inconsistent data!");
468 
469 		// fill the list with all available options
470 		m_aOptions.Clear();
471 		m_nLastSelection = -1;
472 		for	(	ConstStringArrayIterator aLoop = rSettings.aLabels.begin();
473 				aLoop != rSettings.aLabels.end();
474 				++aLoop
475 			)
476 			m_aOptions.InsertEntry(*aLoop);
477 
478 		// remember the values ... can't set them directly in the settings without the explicit commit call
479 		// so we need have a copy of the values
480 		m_aUncommittedValues = rSettings.aValues;
481 
482 		// select the first entry
483 		m_aOptions.SelectEntryPos(0);
484 		implTraveledOptions();
485 	}
486 
487 	//---------------------------------------------------------------------
488 	sal_Bool OOptionValuesPage::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
489 	{
490 		if (!OGBWPage::commitPage(_eReason))
491 			return sal_False;
492 
493 		OOptionGroupSettings& rSettings = getSettings();
494 
495 		// commit the current value
496 		implTraveledOptions();
497 		// copy the uncommitted values
498 		rSettings.aValues = m_aUncommittedValues;
499 
500 		return sal_True;
501 	}
502 
503 	//=====================================================================
504 	//= OOptionDBFieldPage
505 	//=====================================================================
506 	//---------------------------------------------------------------------
507 	OOptionDBFieldPage::OOptionDBFieldPage( OControlWizard* _pParent )
508 		:ODBFieldPage(_pParent)
509 	{
510 		setDescriptionText(String(ModuleRes(RID_STR_GROUPWIZ_DBFIELD)));
511 	}
512 
513 	//---------------------------------------------------------------------
514 	String& OOptionDBFieldPage::getDBFieldSetting()
515 	{
516 		return getSettings().sDBField;
517 	}
518 
519 	//=====================================================================
520 	//= OFinalizeGBWPage
521 	//=====================================================================
522 	//---------------------------------------------------------------------
523 	OFinalizeGBWPage::OFinalizeGBWPage( OControlWizard* _pParent )
524 		:OGBWPage(_pParent, ModuleRes(RID_PAGE_OPTIONS_FINAL))
525 		,m_aFrame			(this, ModuleRes(FL_NAMEIT))
526 		,m_aNameLabel		(this, ModuleRes(FT_NAMEIT))
527 		,m_aName			(this, ModuleRes(ET_NAMEIT))
528 		,m_aThatsAll		(this, ModuleRes(FT_THATSALL))
529 	{
530 		FreeResource();
531 	}
532 
533 	//---------------------------------------------------------------------
534 	void OFinalizeGBWPage::ActivatePage()
535 	{
536 		OGBWPage::ActivatePage();
537 		m_aName.GrabFocus();
538 	}
539 
540 	//---------------------------------------------------------------------
541 	bool OFinalizeGBWPage::canAdvance() const
542 	{
543 		return false;
544 	}
545 
546 	//---------------------------------------------------------------------
547 	void OFinalizeGBWPage::initializePage()
548 	{
549 		OGBWPage::initializePage();
550 
551 		const OOptionGroupSettings& rSettings = getSettings();
552 		m_aName.SetText(rSettings.sControlLabel);
553 	}
554 
555 	//---------------------------------------------------------------------
556 	sal_Bool OFinalizeGBWPage::commitPage( ::svt::WizardTypes::CommitPageReason _eReason )
557 	{
558 		if (!OGBWPage::commitPage(_eReason))
559 			return sal_False;
560 
561 		getSettings().sControlLabel = m_aName.GetText();
562 
563 		return sal_True;
564 	}
565 
566 //.........................................................................
567 }	// namespace dbp
568 //.........................................................................
569 
570