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_dbaccess.hxx"
30 
31 #ifndef _DBAUI_MARKTREE_HXX_
32 #include "marktree.hxx"
33 #endif
34 #ifndef _DBU_CONTROL_HRC_
35 #include "dbu_control.hrc"
36 #endif
37 #ifndef _SV_SVAPP_HXX
38 #include <vcl/svapp.hxx>
39 #endif
40 
41 //.........................................................................
42 namespace dbaui
43 {
44 	using namespace ::com::sun::star::uno;
45 using namespace ::com::sun::star::lang;
46 //.........................................................................
47 #define SPACEBETWEENENTRIES		4
48 //========================================================================
49 //= OMarkableTreeListBox
50 //========================================================================
51 DBG_NAME(OMarkableTreeListBox)
52 //------------------------------------------------------------------------
53 OMarkableTreeListBox::OMarkableTreeListBox( Window* pParent, const Reference< XMultiServiceFactory >& _rxORB, WinBits nWinStyle )
54 	: DBTreeListBox(pParent,_rxORB,nWinStyle)
55 {
56     DBG_CTOR(OMarkableTreeListBox,NULL);
57 
58 	InitButtonData();
59 }
60 //------------------------------------------------------------------------
61 OMarkableTreeListBox::OMarkableTreeListBox( Window* pParent, const Reference< XMultiServiceFactory >& _rxORB, const ResId& rResId)
62 	: DBTreeListBox(pParent,_rxORB,rResId)
63 {
64     DBG_CTOR(OMarkableTreeListBox,NULL);
65 
66 	InitButtonData();
67 }
68 //------------------------------------------------------------------------
69 OMarkableTreeListBox::~OMarkableTreeListBox()
70 {
71 	delete m_pCheckButton;
72 
73     DBG_DTOR(OMarkableTreeListBox,NULL);
74 }
75 //------------------------------------------------------------------------
76 void OMarkableTreeListBox::Paint(const Rectangle& _rRect)
77 {
78 	if (!IsEnabled())
79 	{
80 		Font aOldFont = GetFont();
81 		Font aNewFont(aOldFont);
82 
83 		StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
84 		aNewFont.SetColor(aSystemStyle.GetDisableColor());
85 
86 		SetFont(aNewFont);
87 		DBTreeListBox::Paint(_rRect);
88 		SetFont(aOldFont);
89 	}
90 	else
91 		DBTreeListBox::Paint(_rRect);
92 }
93 //------------------------------------------------------------------------
94 void OMarkableTreeListBox::InitButtonData()
95 {
96 	m_pCheckButton = new SvLBoxButtonData( this );
97 	EnableCheckButton( m_pCheckButton );
98 }
99 //------------------------------------------------------------------------
100 void OMarkableTreeListBox::KeyInput( const KeyEvent& rKEvt )
101 {
102 	// nur wenn space
103 	if (rKEvt.GetKeyCode().GetCode() == KEY_SPACE && !rKEvt.GetKeyCode().IsShift() && !rKEvt.GetKeyCode().IsMod1())
104 	{
105 		SvLBoxEntry* pCurrentHandlerEntry = GetHdlEntry();
106 		if(pCurrentHandlerEntry)
107 		{
108 			SvButtonState eState = GetCheckButtonState( pCurrentHandlerEntry);
109 			if(eState == SV_BUTTON_CHECKED)
110 				SetCheckButtonState( pCurrentHandlerEntry, SV_BUTTON_UNCHECKED);
111 			else
112 				SetCheckButtonState( pCurrentHandlerEntry, SV_BUTTON_CHECKED);
113 
114 			CheckButtonHdl();
115 		}
116 		else
117 			DBTreeListBox::KeyInput(rKEvt);
118 	}
119 	else
120 		DBTreeListBox::KeyInput(rKEvt);
121 
122 }
123 //------------------------------------------------------------------------
124 SvButtonState OMarkableTreeListBox::implDetermineState(SvLBoxEntry* _pEntry)
125 {
126 	SvButtonState eState = GetCheckButtonState(_pEntry);
127 	if (!GetModel()->HasChilds(_pEntry))
128 		// nothing to do in this bottom-up routine if there are no children ...
129 		return eState;
130 #ifdef DBG_UTIL
131 	String sEntryText  =GetEntryText(_pEntry);
132 #endif
133 
134 	// loop through the children and check their states
135 	sal_uInt16 nCheckedChildren = 0;
136 	sal_uInt16 nChildrenOverall = 0;
137 
138 	SvLBoxEntry* pChildLoop = GetModel()->FirstChild(_pEntry);
139 	while (pChildLoop)
140 	{
141 #ifdef DBG_UTIL
142 		String sChildText  =GetEntryText(pChildLoop);
143 #endif
144 		SvButtonState eChildState = implDetermineState(pChildLoop);
145 		if (SV_BUTTON_TRISTATE == eChildState)
146 			break;
147 
148 		if (SV_BUTTON_CHECKED == eChildState)
149 			++nCheckedChildren;
150 		++nChildrenOverall;
151 
152 		pChildLoop = GetModel()->NextSibling(pChildLoop);
153 	}
154 
155 	if (pChildLoop)
156 	{
157 		// we did not finish the loop because at least one of the children is in tristate
158 		eState = SV_BUTTON_TRISTATE;
159 
160 		// but this means that we did not finish all the siblings of pChildLoop, so their checking may be
161 		// incorrect at the moment
162 		// -> correct this
163 		// 88485 - 20.06.2001 - frank.schoenheit@sun.com
164 		while (pChildLoop)
165 		{
166 			implDetermineState(pChildLoop);
167 			pChildLoop = GetModel()->NextSibling(pChildLoop);
168 		}
169 	}
170 	else
171 		// none if the children is in tristate
172 		if (nCheckedChildren)
173 			// we have at least one chil checked
174 			if (nCheckedChildren != nChildrenOverall)
175 				// not all children are checked
176 				eState = SV_BUTTON_TRISTATE;
177 			else
178 				// all children are checked
179 				eState = SV_BUTTON_CHECKED;
180 		else
181 			// no children are checked
182 			eState = SV_BUTTON_UNCHECKED;
183 
184 	// finally set the entry to the state we just determined
185 	SetCheckButtonState(_pEntry, eState);
186 
187 	// outta here
188 	return eState;
189 }
190 
191 //------------------------------------------------------------------------
192 void OMarkableTreeListBox::CheckButtons()
193 {
194 	SvLBoxEntry* pEntry = GetModel()->First();
195 	while (pEntry)
196 	{
197 		implDetermineState(pEntry);
198 		pEntry = GetModel()->NextSibling(pEntry);
199 	}
200 }
201 //------------------------------------------------------------------------
202 void OMarkableTreeListBox::CheckButtonHdl()
203 {
204 	checkedButton_noBroadcast(GetHdlEntry());
205 	if (m_aCheckButtonHandler.IsSet())
206 		m_aCheckButtonHandler.Call(this);
207 }
208 
209 //------------------------------------------------------------------------
210 void OMarkableTreeListBox::checkedButton_noBroadcast(SvLBoxEntry* _pEntry)
211 {
212 	SvButtonState eState = GetCheckButtonState( _pEntry);
213 	if (GetModel()->HasChilds(_pEntry))	// Falls Kinder, dann diese auch checken
214 	{
215 		SvLBoxEntry* pChildEntry = GetModel()->Next(_pEntry);
216 		SvLBoxEntry* pSiblingEntry = GetModel()->NextSibling(_pEntry);
217 		while(pChildEntry && pChildEntry != pSiblingEntry)
218 		{
219 			SetCheckButtonState(pChildEntry, eState);
220 			pChildEntry = GetModel()->Next(pChildEntry);
221 		}
222 	}
223 
224 	SvLBoxEntry* pEntry = IsSelected(_pEntry) ? FirstSelected() : NULL;
225 	while(pEntry)
226 	{
227 		SetCheckButtonState(pEntry,eState);
228 		if(GetModel()->HasChilds(pEntry))	// Falls Kinder, dann diese auch checken
229 		{
230 			SvLBoxEntry* pChildEntry = GetModel()->Next(pEntry);
231 			SvLBoxEntry* pSiblingEntry = GetModel()->NextSibling(pEntry);
232 			while(pChildEntry && pChildEntry != pSiblingEntry)
233 			{
234 				SetCheckButtonState(pChildEntry,eState);
235 				pChildEntry = GetModel()->Next(pChildEntry);
236 			}
237 		}
238 		pEntry = NextSelected(pEntry);
239 	}
240 	CheckButtons();
241 }
242 
243 //------------------------------------------------------------------------
244 //.........................................................................
245 }	// namespace dbaui
246 //.........................................................................
247 
248