xref: /trunk/main/sw/source/ui/fldui/flddinf.cxx (revision cdf0e10c)
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_sw.hxx"
30 
31 #ifdef SW_DLLIMPLEMENTATION
32 #undef SW_DLLIMPLEMENTATION
33 #endif
34 
35 #include <sfx2/request.hxx>
36 #include <sfx2/frame.hxx>
37 #include <vcl/svapp.hxx>
38 #include <svl/zforlist.hxx>
39 #include <svl/zformat.hxx>
40 
41 #include <helpid.h>
42 #include <swtypes.hxx>
43 #include <globals.hrc>
44 #include <fldbas.hxx>
45 #include <docufld.hxx>
46 #include <wrtsh.hxx>
47 
48 #include <fldui.hrc>
49 
50 #ifndef _FLDTDLG_HRC
51 #include <fldtdlg.hrc>
52 #endif
53 #ifndef _FLDDINF_HXX
54 #include <flddinf.hxx>
55 #endif
56 #include <swmodule.hxx>
57 #ifndef _VIEW_HXX
58 #include <view.hxx>
59 #endif
60 #include <com/sun/star/beans/XPropertySet.hpp>
61 #include <com/sun/star/util/Time.hpp>
62 #include <com/sun/star/util/DateTime.hpp>
63 #include <com/sun/star/util/Date.hpp>
64 
65 #define USER_DATA_VERSION_1 "1"
66 #define USER_DATA_VERSION USER_DATA_VERSION_1
67 
68 using namespace nsSwDocInfoSubType;
69 using namespace com::sun::star;
70 /*--------------------------------------------------------------------
71 	Beschreibung:
72  --------------------------------------------------------------------*/
73 
74 SwFldDokInfPage::SwFldDokInfPage(Window* pWindow, const SfxItemSet& rCoreSet ) :
75 	SwFldPage( pWindow, SW_RES( TP_FLD_DOKINF ), rCoreSet ),
76 
77 	aTypeFT		(this, SW_RES(FT_DOKINFTYPE)),
78 	aTypeTLB	(this, SW_RES(TLB_DOKINFTYPE)),
79 	aSelectionFT(this, SW_RES(FT_DOKINFSELECTION)),
80 	aSelectionLB(this, SW_RES(LB_DOKINFSELECTION)),
81 	aFormatFT	(this, SW_RES(FT_DOKINFFORMAT)),
82 	aFormatLB	(this, SW_RES(LB_DOKINFFORMAT)),
83 	aFixedCB	(this, SW_RES(CB_DOKINFFIXEDCONTENT)),
84 
85     pSelEntry   (0),
86     aInfoStr    (SW_RES(STR_DOKINF_INFO))
87 {
88 	FreeResource();
89 
90 	aTypeTLB.SetHelpId(HID_FIELD_DINF_TYPE);
91 	aTypeTLB.SetSelectionMode(SINGLE_SELECTION);
92 	aTypeTLB.SetStyle(aTypeTLB.GetStyle()|WB_HASLINES|WB_CLIPCHILDREN|WB_SORT|WB_HASBUTTONS|WB_HASBUTTONSATROOT|WB_HSCROLL);
93 	// Font nicht setzen, damit der Font des Controls uebernommen wird!
94 	// Sonst bei falschem Font Bug an OV.
95 	aTypeTLB.SetSpaceBetweenEntries(0);
96 
97 	aTypeTLB.SetNodeDefaultImages();
98     //enable 'active' language selection
99     aFormatLB.SetShowLanguageControl(sal_True);
100 
101 	SFX_ITEMSET_ARG( &rCoreSet, pItem, SfxUnoAnyItem, SID_DOCINFO, sal_False );
102 	if ( pItem )
103         pItem->GetValue() >>= xCustomPropertySet;
104 }
105 
106 /*--------------------------------------------------------------------
107 	Beschreibung:
108  --------------------------------------------------------------------*/
109 
110 __EXPORT SwFldDokInfPage::~SwFldDokInfPage()
111 {
112 }
113 
114 /*--------------------------------------------------------------------
115 	Beschreibung:
116  --------------------------------------------------------------------*/
117 
118 void __EXPORT SwFldDokInfPage::Reset(const SfxItemSet& )
119 {
120 	Init();	// Allgemeine initialisierung
121 
122 	// TypeListBox initialisieren
123 	aTypeTLB.SetUpdateMode(sal_False);
124 	aTypeTLB.Clear();
125 	pSelEntry = 0;
126 
127 	// SubTypes in der TypeLB anzeigen
128 	sal_uInt16 nTypeId = TYP_DOCINFOFLD;
129 	SvLBoxEntry* pEntry = 0;
130 
131 	SvLBoxEntry* pInfo = 0;
132 
133 	sal_uInt16 nSubType = USHRT_MAX;
134 	if (IsFldEdit())
135     {
136         const SwField* pCurField = GetCurField();
137         nSubType = ((SwDocInfoField*)pCurField)->GetSubType() & 0xff;
138         if( nSubType == DI_CUSTOM )
139         {
140             m_sOldCustomFieldName = static_cast<const SwDocInfoField*>(pCurField)->GetName();
141         }
142         aFormatLB.SetAutomaticLanguage(pCurField->IsAutomaticLanguage());
143         SwWrtShell *pSh = GetWrtShell();
144         if(pSh)
145         {
146             const SvNumberformat* pFormat = pSh->GetNumberFormatter()->GetEntry(pCurField->GetFormat());
147             if(pFormat)
148                 aFormatLB.SetLanguage(pFormat->GetLanguage());
149         }
150     }
151 
152 	sal_uInt16 nSelEntryData = USHRT_MAX;
153 	String sUserData = GetUserData();
154 	if(sUserData.GetToken(0, ';').EqualsIgnoreCaseAscii(USER_DATA_VERSION_1))
155 	{
156 		String sVal = sUserData.GetToken(1, ';');
157         nSelEntryData = static_cast< sal_uInt16 >(sVal.ToInt32());
158 	}
159 
160     SvStringsDtor aLst;
161     GetFldMgr().GetSubTypes(nTypeId, aLst);
162     for (sal_uInt16 i = 0; i < aLst.Count(); ++i)
163 	{
164 		if (!IsFldEdit() || nSubType == i)
165 		{
166 			if (DI_CUSTOM == i)
167 			{
168                 if(xCustomPropertySet.is() )
169 				{
170                     uno::Reference< beans::XPropertySetInfo > xSetInfo = xCustomPropertySet->getPropertySetInfo();
171                     const uno::Sequence< beans::Property > rProperties = xSetInfo->getProperties();
172 //                    uno::Sequence< ::rtl::OUString > aPropertyNames(rProperties.getLength());
173 //                    for (sal_Int32 i = 0; i < rProperties.getLength(); ++i) {
174 //                        aPropertyNames[i] = rProperties[i].Name;
175 //                    }
176                     //if ( !IsFldEdit() )
177                     if( rProperties.getLength() )
178                     {
179                         pInfo = aTypeTLB.InsertEntry( String(SW_RES( STR_CUSTOM )) );
180 						pInfo->SetUserData(reinterpret_cast<void*>(USHRT_MAX));
181 
182                         for (sal_Int32 n=0; n < rProperties.getLength(); n++)
183                         {
184                             rtl::OUString sEntry = rProperties[n].Name;
185                             pEntry = aTypeTLB.InsertEntry(sEntry, pInfo);
186                             if(m_sOldCustomFieldName.equals( sEntry ))
187                             {
188                                 pSelEntry = pEntry;
189                                 aTypeTLB.Expand( pInfo );
190                             }
191                             pEntry->SetUserData(reinterpret_cast<void*>(i));
192                         }
193                     }
194 				}
195 			}
196 			else
197 			{
198 				if (!(IsFldDlgHtmlMode() && (i == DI_EDIT || i == DI_THEMA || i == DI_PRINT)))
199 				{
200                     pEntry = aTypeTLB.InsertEntry(*aLst[i]);
201                     pEntry->SetUserData(reinterpret_cast<void*>(i));
202 				}
203 			}
204 			if(nSelEntryData == i)
205 				pSelEntry = pEntry;
206 		}
207 	}
208 
209 	// alte Pos selektieren
210 	if (pSelEntry != 0)
211 	{
212 		aTypeTLB.Select(pSelEntry);
213 		nSubType = (sal_uInt16)(sal_uLong)pSelEntry->GetUserData();
214 	}
215     else if ( aTypeTLB.GetEntry(0) )
216 	{
217 		pSelEntry = aTypeTLB.GetEntry(0);
218 		nSubType = (sal_uInt16)(sal_uLong)pSelEntry->GetUserData();
219 	}
220 
221 	FillSelectionLB(nSubType);
222     if ( pSelEntry )
223         TypeHdl();
224 
225 	aTypeTLB.SetUpdateMode(sal_True);
226 	aTypeTLB.SetSelectHdl(LINK(this, SwFldDokInfPage, TypeHdl));
227 	aTypeTLB.SetDoubleClickHdl(LINK(this, SwFldDokInfPage, InsertHdl));
228 	aSelectionLB.SetSelectHdl(LINK(this, SwFldDokInfPage, SubTypeHdl));
229 	aSelectionLB.SetDoubleClickHdl(LINK(this, SwFldDokInfPage, InsertHdl));
230 	aFormatLB.SetDoubleClickHdl(LINK(this, SwFldDokInfPage, InsertHdl));
231 
232 	if (IsFldEdit())
233 	{
234 		nOldSel = aSelectionLB.GetSelectEntryPos();
235 		nOldFormat = GetCurField()->GetFormat();
236 		aFixedCB.SaveValue();
237 	}
238 }
239 
240 /*--------------------------------------------------------------------
241 	Beschreibung:
242  --------------------------------------------------------------------*/
243 
244 IMPL_LINK( SwFldDokInfPage, TypeHdl, ListBox *, EMPTYARG )
245 {
246 	// Alte ListBoxPos sichern
247 	SvLBoxEntry* pOldEntry = pSelEntry;
248 
249 	// Aktuelle ListBoxPos
250 	pSelEntry = aTypeTLB.FirstSelected();
251 
252 	if(!pSelEntry)
253 	{
254 		pSelEntry = aTypeTLB.GetEntry(0);
255 		aTypeTLB.Select(pSelEntry);
256 	}
257 	else
258 
259 	if (pOldEntry != pSelEntry)
260 		FillSelectionLB((sal_uInt16)(sal_uLong)pSelEntry->GetUserData());
261 
262 	SubTypeHdl();
263 
264 	return 0;
265 }
266 
267 /*--------------------------------------------------------------------
268 	Beschreibung:
269  --------------------------------------------------------------------*/
270 IMPL_LINK( SwFldDokInfPage, SubTypeHdl, ListBox *, EMPTYARG )
271 {
272 	sal_uInt16 nSubType = (sal_uInt16)(sal_uLong)pSelEntry->GetUserData();
273 	sal_uInt16 nPos = aSelectionLB.GetSelectEntryPos();
274 	sal_uInt16 nExtSubType;
275 	sal_uInt16 nNewType = 0;
276 
277 	if (nSubType != DI_EDIT)
278 	{
279 		if (nPos == LISTBOX_ENTRY_NOTFOUND)
280 		{
281 			if (!aSelectionLB.GetEntryCount())
282 			{
283 				aFormatLB.Clear();
284 				aFormatLB.Enable(sal_False);
285 				aFormatFT.Enable(sal_False);
286                 if( nSubType == DI_CUSTOM )
287                 {
288                     //find out which type the custom field has - for a start set to DATE format
289                     ::rtl::OUString sName = aTypeTLB.GetEntryText(pSelEntry);
290                     try
291                     {
292                         uno::Any aVal = xCustomPropertySet->getPropertyValue( sName );
293                         const uno::Type& rValueType = aVal.getValueType();
294                         if( rValueType == ::getCppuType( (util::DateTime*)0 ))
295                         {
296                             nNewType = NUMBERFORMAT_DATETIME;
297                         }
298                         else if( rValueType == ::getCppuType( (util::Date*)0 ))
299                         {
300                             nNewType = NUMBERFORMAT_DATE;
301                         }
302                         else if( rValueType == ::getCppuType( (util::Time*)0 ))
303                         {
304                             nNewType = NUMBERFORMAT_TIME;
305                         }
306                     }
307                     catch( const uno::Exception& )
308                     {
309                     }
310                 }
311                 else
312                     return 0;
313 			}
314 			nPos = 0;
315 		}
316 
317 		nExtSubType = (sal_uInt16)(sal_uLong)aSelectionLB.GetEntryData(nPos);
318 	}
319 	else
320 		nExtSubType = DI_SUB_TIME;
321 
322 	sal_uInt16 nOldType = 0;
323 	sal_Bool bEnable = sal_False;
324 	sal_Bool bOneArea = sal_False;
325 
326 	if (aFormatLB.IsEnabled())
327 		nOldType = aFormatLB.GetFormatType();
328 
329 	switch (nExtSubType)
330 	{
331 		case DI_SUB_AUTHOR:
332 			break;
333 
334 		case DI_SUB_DATE:
335 			nNewType = NUMBERFORMAT_DATE;
336 			bOneArea = sal_True;
337 			break;
338 
339 		case DI_SUB_TIME:
340 			nNewType = NUMBERFORMAT_TIME;
341 			bOneArea = sal_True;
342 			break;
343 	}
344 	if (!nNewType)
345 	{
346 		aFormatLB.Clear();
347 	}
348 	else
349 	{
350 		if (nOldType != nNewType)
351 		{
352 			aFormatLB.SetFormatType(nNewType);
353 			aFormatLB.SetOneArea(bOneArea);
354 		}
355 		bEnable = sal_True;
356 	}
357 
358 	sal_uLong nFormat = IsFldEdit() ? ((SwDocInfoField*)GetCurField())->GetFormat() : 0;
359 
360 	sal_uInt16 nOldSubType = IsFldEdit() ? (((SwDocInfoField*)GetCurField())->GetSubType() & 0xff00) : 0;
361 
362 	if (IsFldEdit())
363 	{
364         nPos = aSelectionLB.GetSelectEntryPos();
365 		if (nPos != LISTBOX_ENTRY_NOTFOUND )
366 		{
367 			nSubType = (sal_uInt16)(sal_uLong)aSelectionLB.GetEntryData(nPos);
368 
369 			nOldSubType &= ~DI_SUB_FIXED;
370 			if (nOldSubType == nSubType)
371 			{
372 				if (!nFormat && (nNewType == NUMBERFORMAT_DATE || nNewType == NUMBERFORMAT_TIME))
373 				{
374                     SwWrtShell *pSh = GetWrtShell();
375                     if(pSh)
376                     {
377                         SvNumberFormatter* pFormatter = pSh->GetNumberFormatter();
378                         LanguageType eLang = aFormatLB.GetCurLanguage();
379                         if (nNewType == NUMBERFORMAT_DATE)
380                             nFormat = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_SHORT, eLang);
381                         else if (nNewType == NUMBERFORMAT_TIME)
382                             nFormat = pFormatter->GetFormatIndex( NF_TIME_HHMM, eLang);
383                     }
384 				}
385 				aFormatLB.SetDefFormat(nFormat);
386 			}
387 		}
388         else if( (nSubType == DI_CUSTOM)  && (nNewType != 0) )
389         {
390     		aFormatLB.SetDefFormat(nFormat);
391         }
392 	}
393 
394 	aFormatLB.Enable(bEnable);
395 	aFormatFT.Enable(bEnable);
396 
397 	if (bEnable && aFormatLB.GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND)
398 	{
399 		aFormatLB.SelectEntryPos(0);
400 	}
401 
402 	return 0;
403 }
404 
405 /*--------------------------------------------------------------------
406 	Beschreibung:
407  --------------------------------------------------------------------*/
408 
409 sal_uInt16 SwFldDokInfPage::FillSelectionLB(sal_uInt16 nSubType)
410 {
411 	// Format-Listbox fuellen
412 	sal_uInt16 nTypeId = TYP_DOCINFOFLD;
413 
414 	EnableInsert(nSubType != USHRT_MAX);
415 
416 	if (nSubType == USHRT_MAX)	// Info-Text
417 		nSubType = DI_SUBTYPE_BEGIN;
418 
419 	aSelectionLB.Clear();
420 
421 	sal_uInt16 nSize = 0;
422 	sal_uInt16 nSelPos = USHRT_MAX;
423 	sal_uInt16 nExtSubType = IsFldEdit() ? (((SwDocInfoField*)GetCurField())->GetSubType() & 0xff00) : 0;
424 
425 	if (IsFldEdit())
426 	{
427 		aFixedCB.Check((nExtSubType & DI_SUB_FIXED) != 0);
428 		nExtSubType = ((nExtSubType & ~DI_SUB_FIXED) >> 8) - 1;
429 	}
430 
431 	if (nSubType < DI_CREATE || nSubType == DI_DOCNO || nSubType == DI_EDIT|| nSubType == DI_CUSTOM )
432 	{
433 		// Format Box ist fuer Title und Time leer
434 	}
435 	else
436 	{
437 		nSize = GetFldMgr().GetFormatCount(nTypeId, sal_False, IsFldDlgHtmlMode());
438 		for (sal_uInt16 i = 0; i < nSize; i++)
439 		{
440 			sal_uInt16 nPos = aSelectionLB.InsertEntry(GetFldMgr().GetFormatStr(nTypeId, i));
441             aSelectionLB.SetEntryData(nPos, reinterpret_cast<void*>(GetFldMgr().GetFormatId(nTypeId, i)));
442 			if (IsFldEdit() && i == nExtSubType)
443 				nSelPos = nPos;
444 		}
445 	}
446 
447 	sal_Bool bEnable = nSize != 0;
448 
449 	if (nSize)
450 	{
451 		if (!aSelectionLB.GetSelectEntryCount())
452 			aSelectionLB.SelectEntryPos(nSelPos == USHRT_MAX ? 0 : nSelPos);
453 
454 		bEnable = sal_True;
455 	}
456 
457 	aSelectionFT.Enable(bEnable);
458 	aSelectionLB.Enable(bEnable);
459 
460 	return nSize;
461 }
462 
463 /*--------------------------------------------------------------------
464 	Beschreibung:
465  --------------------------------------------------------------------*/
466 
467 sal_Bool __EXPORT SwFldDokInfPage::FillItemSet(SfxItemSet& )
468 {
469 	if (!pSelEntry || (sal_uInt16)(sal_uLong)pSelEntry->GetUserData() == USHRT_MAX)
470 		return sal_False;
471 
472 	sal_uInt16 nTypeId = TYP_DOCINFOFLD;
473 	sal_uInt16 nSubType = (sal_uInt16)(sal_uLong)pSelEntry->GetUserData();
474 
475 	sal_uLong nFormat = 0;
476 
477 	sal_uInt16 nPos = aSelectionLB.GetSelectEntryPos();
478 
479     ::rtl::OUString aName;
480     if (DI_CUSTOM == nSubType)
481         aName = aTypeTLB.GetEntryText(pSelEntry);
482 
483 	if (nPos != LISTBOX_ENTRY_NOTFOUND)
484 		nSubType |= (sal_uInt16)(sal_uLong)aSelectionLB.GetEntryData(nPos);
485 
486 	if (aFixedCB.IsChecked())
487 		nSubType |= DI_SUB_FIXED;
488 
489 	nPos = aFormatLB.GetSelectEntryPos();
490 	if(nPos != LISTBOX_ENTRY_NOTFOUND)
491 		nFormat = aFormatLB.GetFormat();
492 
493 	if (!IsFldEdit() || nOldSel != aSelectionLB.GetSelectEntryPos() ||
494 		nOldFormat != nFormat || aFixedCB.GetState() != aFixedCB.GetSavedValue()
495         || (DI_CUSTOM == nSubType && !aName.equals( m_sOldCustomFieldName )))
496 	{
497         InsertFld(nTypeId, nSubType, aName, aEmptyStr, nFormat,
498                 ' ', aFormatLB.IsAutomaticLanguage());
499 	}
500 
501 	return sal_False;
502 }
503 
504 /*--------------------------------------------------------------------
505 	Beschreibung:
506  --------------------------------------------------------------------*/
507 
508 SfxTabPage* __EXPORT SwFldDokInfPage::Create( 	Window* pParent,
509 						const SfxItemSet& rAttrSet )
510 {
511 	return ( new SwFldDokInfPage( pParent, rAttrSet ) );
512 }
513 
514 /*--------------------------------------------------------------------
515 	Beschreibung:
516  --------------------------------------------------------------------*/
517 
518 sal_uInt16 SwFldDokInfPage::GetGroup()
519 {
520 	return GRP_REG;
521 }
522 /* -----------------12.01.99 11:21-------------------
523  *
524  * --------------------------------------------------*/
525 void	SwFldDokInfPage::FillUserData()
526 {
527 	String sData( String::CreateFromAscii(
528 							RTL_CONSTASCII_STRINGPARAM( USER_DATA_VERSION )));
529 	sData += ';';
530 	SvLBoxEntry* pEntry = aTypeTLB.FirstSelected();
531     sal_uInt16 nTypeSel = pEntry ? sal::static_int_cast< sal_uInt16 >(reinterpret_cast< sal_uIntPtr >(pEntry->GetUserData())) : USHRT_MAX;
532 	sData += String::CreateFromInt32( nTypeSel );
533 	SetUserData(sData);
534 }
535 
536 
537 
538