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