Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_STANDARDCONTROL_HXX
21 : #define INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_STANDARDCONTROL_HXX
22 :
23 : #include "commoncontrol.hxx"
24 : #include "pcrcommon.hxx"
25 :
26 : #include <com/sun/star/inspection/XNumericControl.hpp>
27 : #include <com/sun/star/inspection/XStringListControl.hpp>
28 : #include <com/sun/star/inspection/XHyperlinkControl.hpp>
29 : #include <com/sun/star/uno/Sequence.hxx>
30 : #include <vcl/field.hxx>
31 : #include <vcl/longcurr.hxx>
32 : #include <svtools/ctrlbox.hxx>
33 : #include <vcl/lstbox.hxx>
34 : #include <vcl/combobox.hxx>
35 : #include <svtools/calendar.hxx>
36 : #include <svtools/fmtfield.hxx>
37 :
38 : #include <set>
39 :
40 : class PushButton;
41 : class MultiLineEdit;
42 :
43 : namespace pcr
44 : {
45 :
46 :
47 :
48 : //= ListLikeControlWithModifyHandler
49 :
50 : /** Very small helper class which adds a SetModifyHdl to a ListBox-derived class,
51 : thus giving this class the same API (as far as the CommonBehaviourControl is concerned)
52 : as all other windows.
53 : */
54 : template< class LISTBOX_WINDOW >
55 0 : class ListLikeControlWithModifyHandler : public ControlWindow< LISTBOX_WINDOW >
56 : {
57 : protected:
58 : typedef ControlWindow< LISTBOX_WINDOW > ListBoxType;
59 :
60 : public:
61 0 : ListLikeControlWithModifyHandler( vcl::Window* _pParent, WinBits _nStyle )
62 0 : :ListBoxType( _pParent, _nStyle )
63 : {
64 0 : }
65 :
66 0 : void SetModifyHdl( const Link& _rLink ) { ListBoxType::SetSelectHdl( _rLink ); }
67 :
68 : protected:
69 : bool PreNotify( NotifyEvent& _rNEvt );
70 : };
71 :
72 :
73 : template< class LISTBOX_WINDOW >
74 0 : bool ListLikeControlWithModifyHandler< LISTBOX_WINDOW >::PreNotify( NotifyEvent& _rNEvt )
75 : {
76 0 : if ( _rNEvt.GetType() == EVENT_KEYINPUT )
77 : {
78 0 : const ::KeyEvent* pKeyEvent = _rNEvt.GetKeyEvent();
79 0 : if ( ( pKeyEvent->GetKeyCode().GetModifier() == 0 )
80 0 : && ( ( pKeyEvent->GetKeyCode().GetCode() == KEY_PAGEUP )
81 0 : || ( pKeyEvent->GetKeyCode().GetCode() == KEY_PAGEDOWN )
82 : )
83 : )
84 : {
85 0 : if ( !ListBoxType::IsInDropDown() )
86 : {
87 : // don't give the base class a chance to consume the event, in the property browser, it is
88 : // intended to scroll the complete property page
89 0 : return ListBoxType::GetParent()->PreNotify( _rNEvt );
90 : }
91 : }
92 : }
93 0 : return ListBoxType::PreNotify( _rNEvt );
94 : }
95 :
96 :
97 : //= OTimeControl
98 :
99 : typedef CommonBehaviourControl< ::com::sun::star::inspection::XPropertyControl, ControlWindow< TimeField > > OTimeControl_Base;
100 0 : class OTimeControl : public OTimeControl_Base
101 : {
102 : public:
103 : OTimeControl( vcl::Window* pParent, WinBits nWinStyle );
104 :
105 : // XPropertyControl
106 : virtual ::com::sun::star::uno::Any SAL_CALL getValue() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
107 : virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& _value ) throw (::com::sun::star::beans::IllegalTypeException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
108 : virtual ::com::sun::star::uno::Type SAL_CALL getValueType() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
109 : };
110 :
111 :
112 : //= ODateControl
113 :
114 : typedef CommonBehaviourControl< ::com::sun::star::inspection::XPropertyControl, ControlWindow< CalendarField > > ODateControl_Base;
115 0 : class ODateControl : public ODateControl_Base
116 : {
117 : public:
118 : ODateControl( vcl::Window* pParent, WinBits nWinStyle );
119 :
120 : // XPropertyControl
121 : virtual ::com::sun::star::uno::Any SAL_CALL getValue() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
122 : virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& _value ) throw (::com::sun::star::beans::IllegalTypeException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
123 : virtual ::com::sun::star::uno::Type SAL_CALL getValueType() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
124 : };
125 :
126 :
127 : //= OEditControl
128 :
129 : typedef CommonBehaviourControl< ::com::sun::star::inspection::XPropertyControl, ControlWindow< Edit > > OEditControl_Base;
130 0 : class OEditControl : public OEditControl_Base
131 : {
132 : protected:
133 : bool m_bIsPassword : 1;
134 :
135 : public:
136 : OEditControl( vcl::Window* _pParent, bool _bPassWord, WinBits nWinStyle );
137 :
138 : // XPropertyControl
139 : virtual ::com::sun::star::uno::Any SAL_CALL getValue() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
140 : virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& _value ) throw (::com::sun::star::beans::IllegalTypeException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
141 : virtual ::com::sun::star::uno::Type SAL_CALL getValueType() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
142 :
143 : protected:
144 : virtual void modified() SAL_OVERRIDE;
145 : };
146 :
147 :
148 : //= ODateTimeControl
149 :
150 : typedef CommonBehaviourControl< ::com::sun::star::inspection::XPropertyControl, ControlWindow< FormattedField > > ODateTimeControl_Base;
151 0 : class ODateTimeControl : public ODateTimeControl_Base
152 : {
153 : public:
154 : ODateTimeControl( vcl::Window* pParent,WinBits nWinStyle );
155 :
156 : // XPropertyControl
157 : virtual ::com::sun::star::uno::Any SAL_CALL getValue() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
158 : virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& _value ) throw (::com::sun::star::beans::IllegalTypeException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
159 : virtual ::com::sun::star::uno::Type SAL_CALL getValueType() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
160 : };
161 :
162 :
163 : //= HyperlinkInput
164 :
165 0 : class HyperlinkInput : public Edit
166 : {
167 : private:
168 : Point m_aMouseButtonDownPos;
169 : Link m_aClickHandler;
170 :
171 : public:
172 : HyperlinkInput( vcl::Window* _pParent, WinBits _nWinStyle );
173 :
174 : /** sets the handler which will (asynchronously, with locked SolarMutex) be called
175 : when the hyperlink has been clicked by the user
176 : */
177 0 : void SetClickHdl( const Link& _rHdl ) { m_aClickHandler = _rHdl; }
178 : const Link& GetClickHdl( ) const { return m_aClickHandler; }
179 :
180 : protected:
181 : virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE;
182 : virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
183 : virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE;
184 : virtual void Tracking( const TrackingEvent& rTEvt ) SAL_OVERRIDE;
185 :
186 : private:
187 : void impl_checkEndClick( const MouseEvent rMEvt );
188 : bool impl_textHitTest( const Point& _rWindowPos );
189 : };
190 :
191 :
192 : //= OHyperlinkControl
193 :
194 : typedef CommonBehaviourControl< ::com::sun::star::inspection::XHyperlinkControl, ControlWindow< HyperlinkInput > > OHyperlinkControl_Base;
195 0 : class OHyperlinkControl : public OHyperlinkControl_Base
196 : {
197 : private:
198 : ::cppu::OInterfaceContainerHelper m_aActionListeners;
199 :
200 : public:
201 : OHyperlinkControl( vcl::Window* _pParent, WinBits _nWinStyle );
202 :
203 : // XPropertyControl
204 : virtual ::com::sun::star::uno::Any SAL_CALL getValue() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
205 : virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& _value ) throw (::com::sun::star::beans::IllegalTypeException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
206 : virtual ::com::sun::star::uno::Type SAL_CALL getValueType() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
207 :
208 : // XHyperlinkControl
209 : virtual void SAL_CALL addActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener >& listener ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
210 : virtual void SAL_CALL removeActionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XActionListener >& listener ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
211 :
212 : protected:
213 : // XComponent
214 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
215 :
216 : protected:
217 : DECL_LINK( OnHyperlinkClicked, void* );
218 : };
219 :
220 :
221 : //= CustomConvertibleNumericField
222 :
223 0 : class CustomConvertibleNumericField : public ControlWindow< MetricField >
224 : {
225 : typedef ControlWindow< MetricField > BaseClass;
226 :
227 : public:
228 0 : CustomConvertibleNumericField( vcl::Window* _pParent, WinBits _nStyle )
229 0 : :BaseClass( _pParent, _nStyle )
230 : {
231 0 : }
232 :
233 0 : sal_Int64 GetLastValue() const { return mnLastValue; }
234 : };
235 :
236 :
237 : //= ONumericControl
238 :
239 : typedef CommonBehaviourControl< ::com::sun::star::inspection::XNumericControl, CustomConvertibleNumericField > ONumericControl_Base;
240 0 : class ONumericControl : public ONumericControl_Base
241 : {
242 : private:
243 : FieldUnit m_eValueUnit;
244 : sal_Int16 m_nFieldToUNOValueFactor;
245 :
246 : public:
247 : ONumericControl( vcl::Window* pParent, WinBits nWinStyle );
248 :
249 : // XPropertyControl
250 : virtual ::com::sun::star::uno::Any SAL_CALL getValue() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
251 : virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& _value ) throw (::com::sun::star::beans::IllegalTypeException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
252 : virtual ::com::sun::star::uno::Type SAL_CALL getValueType() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
253 :
254 : // XNumericControl
255 : virtual ::sal_Int16 SAL_CALL getDecimalDigits() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
256 : virtual void SAL_CALL setDecimalDigits( ::sal_Int16 _decimaldigits ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
257 : virtual ::com::sun::star::beans::Optional< double > SAL_CALL getMinValue() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
258 : virtual void SAL_CALL setMinValue( const ::com::sun::star::beans::Optional< double >& _minvalue ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
259 : virtual ::com::sun::star::beans::Optional< double > SAL_CALL getMaxValue() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
260 : virtual void SAL_CALL setMaxValue( const ::com::sun::star::beans::Optional< double >& _maxvalue ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
261 : virtual ::sal_Int16 SAL_CALL getDisplayUnit() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
262 : virtual void SAL_CALL setDisplayUnit( ::sal_Int16 _displayunit ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
263 : virtual ::sal_Int16 SAL_CALL getValueUnit() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
264 : virtual void SAL_CALL setValueUnit( ::sal_Int16 _valueunit ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
265 :
266 : private:
267 : /** converts an API value (<code>double</code>, as passed into <code>set[Max|Min|]Value) into
268 : a <code>long</code> value which can be passed to our NumericField.
269 :
270 : The conversion respects our decimal digits as well as our value factor (<member>m_nFieldToUNOValueFactor</member>).
271 : */
272 : long impl_apiValueToFieldValue_nothrow( double _nApiValue ) const;
273 :
274 : /** converts a control value, as obtained from our Numeric field, into a value which can passed
275 : to outer callers via our UNO API.
276 : */
277 : double impl_fieldValueToApiValue_nothrow( sal_Int64 _nFieldValue ) const;
278 : };
279 :
280 :
281 : //= OColorControl
282 :
283 : typedef CommonBehaviourControl < ::com::sun::star::inspection::XStringListControl
284 : , ListLikeControlWithModifyHandler< ColorListBox >
285 : > OColorControl_Base;
286 0 : class OColorControl : public OColorControl_Base
287 : {
288 : private:
289 : ::std::set< OUString > m_aNonColorEntries;
290 :
291 : public:
292 : OColorControl( vcl::Window* pParent, WinBits nWinStyle );
293 :
294 : // XPropertyControl
295 : virtual ::com::sun::star::uno::Any SAL_CALL getValue() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
296 : virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& _value ) throw (::com::sun::star::beans::IllegalTypeException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
297 : virtual ::com::sun::star::uno::Type SAL_CALL getValueType() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
298 :
299 : // XStringListControl
300 : virtual void SAL_CALL clearList( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
301 : virtual void SAL_CALL prependListEntry( const OUString& NewEntry ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
302 : virtual void SAL_CALL appendListEntry( const OUString& NewEntry ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
303 : virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getListEntries( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
304 :
305 : protected:
306 : virtual void modified() SAL_OVERRIDE;
307 : };
308 :
309 :
310 : //= OListboxControl
311 :
312 : typedef CommonBehaviourControl < ::com::sun::star::inspection::XStringListControl
313 : , ListLikeControlWithModifyHandler< ListBox >
314 : > OListboxControl_Base;
315 0 : class OListboxControl : public OListboxControl_Base
316 : {
317 : public:
318 : OListboxControl( vcl::Window* pParent, WinBits nWinStyle );
319 :
320 : // XPropertyControl
321 : virtual ::com::sun::star::uno::Any SAL_CALL getValue() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
322 : virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& _value ) throw (::com::sun::star::beans::IllegalTypeException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
323 : virtual ::com::sun::star::uno::Type SAL_CALL getValueType() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
324 :
325 : // XStringListControl
326 : virtual void SAL_CALL clearList( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
327 : virtual void SAL_CALL prependListEntry( const OUString& NewEntry ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
328 : virtual void SAL_CALL appendListEntry( const OUString& NewEntry ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
329 : virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getListEntries( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
330 :
331 : protected:
332 : virtual void modified() SAL_OVERRIDE;
333 : };
334 :
335 :
336 : //= OComboboxControl
337 :
338 : typedef CommonBehaviourControl< ::com::sun::star::inspection::XStringListControl, ControlWindow< ComboBox > > OComboboxControl_Base;
339 0 : class OComboboxControl : public OComboboxControl_Base
340 : {
341 : public:
342 : OComboboxControl( vcl::Window* pParent, WinBits nWinStyle );
343 :
344 : // XPropertyControl
345 : virtual ::com::sun::star::uno::Any SAL_CALL getValue() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
346 : virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& _value ) throw (::com::sun::star::beans::IllegalTypeException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
347 : virtual ::com::sun::star::uno::Type SAL_CALL getValueType() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
348 :
349 : // XStringListControl
350 : virtual void SAL_CALL clearList( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
351 : virtual void SAL_CALL prependListEntry( const OUString& NewEntry ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
352 : virtual void SAL_CALL appendListEntry( const OUString& NewEntry ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
353 : virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getListEntries( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
354 :
355 : protected:
356 : DECL_LINK( OnEntrySelected, void* );
357 : };
358 :
359 :
360 : //= DropDownEditControl
361 :
362 : enum MultiLineOperationMode
363 : {
364 : eStringList,
365 : eMultiLineText
366 : };
367 :
368 : //= DropDownEditControl
369 :
370 : class OMultilineFloatingEdit;
371 : typedef ControlWindow< Edit > DropDownEditControl_Base;
372 : /** an Edit field which can be used as ControlWindow, and has a drop-down button
373 : */
374 : class DropDownEditControl : public DropDownEditControl_Base
375 : {
376 : private:
377 : OMultilineFloatingEdit* m_pFloatingEdit;
378 : MultiLineEdit* m_pImplEdit;
379 : PushButton* m_pDropdownButton;
380 : MultiLineOperationMode m_nOperationMode;
381 : bool m_bDropdown : 1;
382 :
383 : public:
384 : DropDownEditControl( vcl::Window* _pParent, WinBits _nStyle );
385 : virtual ~DropDownEditControl();
386 :
387 0 : void setOperationMode( MultiLineOperationMode _eMode ) { m_nOperationMode = _eMode; }
388 0 : MultiLineOperationMode getOperationMode() const { return m_nOperationMode; }
389 :
390 : void SetTextValue( const OUString& _rText );
391 : OUString GetTextValue() const;
392 :
393 : void SetStringListValue( const StlSyntaxSequence< OUString >& _rStrings );
394 : StlSyntaxSequence< OUString >
395 : GetStringListValue() const;
396 :
397 : // ControlWindow overridables
398 : virtual void setControlHelper( ControlHelper& _rControlHelper ) SAL_OVERRIDE;
399 :
400 : protected:
401 : // Window overridables
402 : virtual bool PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
403 : virtual void Resize() SAL_OVERRIDE;
404 :
405 : protected:
406 : long FindPos(long nSinglePos);
407 :
408 : private:
409 : DECL_LINK( ReturnHdl, OMultilineFloatingEdit* );
410 : DECL_LINK( DropDownHdl, PushButton* );
411 :
412 : bool ShowDropDown( bool bShow );
413 : };
414 :
415 :
416 : //= OMultilineEditControl
417 :
418 : typedef CommonBehaviourControl< ::com::sun::star::inspection::XPropertyControl, DropDownEditControl > OMultilineEditControl_Base;
419 0 : class OMultilineEditControl : public OMultilineEditControl_Base
420 : {
421 : public:
422 : OMultilineEditControl( vcl::Window* pParent, MultiLineOperationMode _eMode, WinBits nWinStyle );
423 :
424 : // XPropertyControl
425 : virtual ::com::sun::star::uno::Any SAL_CALL getValue() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
426 : virtual void SAL_CALL setValue( const ::com::sun::star::uno::Any& _value ) throw (::com::sun::star::beans::IllegalTypeException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
427 : virtual ::com::sun::star::uno::Type SAL_CALL getValueType() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
428 : };
429 :
430 :
431 : } // namespace pcr
432 :
433 :
434 : #endif // INCLUDED_EXTENSIONS_SOURCE_PROPCTRLR_STANDARDCONTROL_HXX
435 :
436 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|