update dev300-m58
[ooovba.git] / sw / source / ui / fldui / fldmgr.cxx
blob67c921f01109f5f6753e389eb8f5dc6cfb01a37a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fldmgr.cxx,v $
10 * $Revision: 1.53 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
34 #include <cmdid.h>
35 #include <hintids.hxx>
36 #include <svtools/stritem.hxx>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/container/XNameAccess.hpp>
39 #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
40 #include <com/sun/star/text/XNumberingTypeInfo.hpp>
41 #include <com/sun/star/style/NumberingType.hpp>
42 #include <com/sun/star/beans/XPropertySet.hpp>
43 #include <com/sun/star/sdbc/XConnection.hpp>
44 #include <com/sun/star/sdbc/XDataSource.hpp>
45 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
46 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
47 #include <comphelper/processfactory.hxx>
48 #include <svx/unolingu.hxx>
49 #include <unotools/localedatawrapper.hxx>
50 #include <sfx2/dispatch.hxx>
51 #include <sfx2/objsh.hxx>
52 #include <sfx2/linkmgr.hxx>
53 #include <sfx2/app.hxx>
54 #include <basic/basmgr.hxx>
55 #include <svx/langitem.hxx>
56 #include <svtools/macitem.hxx>
57 #include <basic/sbmod.hxx>
58 #include <fmtrfmrk.hxx>
59 #include <basic/sbmeth.hxx>
60 #include <basic/sbx.hxx>
61 #include <svtools/zforlist.hxx>
62 #include <svtools/zformat.hxx>
63 #include <vcl/mnemonic.hxx>
64 #include <view.hxx>
65 #include <wrtsh.hxx> // Actives Fenster
66 #include <doc.hxx> // Actives Fenster
67 #include <docsh.hxx> // Actives Fenster
68 #include <swmodule.hxx>
69 #include <charatr.hxx>
70 #include <fmtinfmt.hxx>
71 #include <cellatr.hxx>
72 #include <dbmgr.hxx>
73 #include <shellres.hxx>
74 #include <fldbas.hxx>
75 #include <docufld.hxx>
76 #include <chpfld.hxx>
77 #include <ddefld.hxx>
78 #include <expfld.hxx>
79 #include <reffld.hxx>
80 #include <usrfld.hxx>
81 #include <dbfld.hxx>
82 #include <authfld.hxx>
83 #include <flddat.hxx>
84 #include <fldmgr.hxx>
85 #include <crsskip.hxx>
86 #include <flddropdown.hxx>
87 #include <fldui.hrc>
88 #include <tox.hxx>
90 using rtl::OUString;
91 using namespace com::sun::star::uno;
92 using namespace com::sun::star::container;
93 using namespace com::sun::star::lang;
94 using namespace com::sun::star::beans;
95 using namespace com::sun::star::text;
96 using namespace com::sun::star::style;
97 using namespace com::sun::star::sdbc;
98 using namespace ::com::sun::star;
99 using namespace nsSwDocInfoSubType;
101 /*--------------------------------------------------------------------
102 Beschreibung: Gruppen der Felder
103 --------------------------------------------------------------------*/
104 enum
106 GRP_DOC_BEGIN = 0,
107 GRP_DOC_END = GRP_DOC_BEGIN + 11,
109 GRP_FKT_BEGIN = GRP_DOC_END,
110 GRP_FKT_END = GRP_FKT_BEGIN + 8,
112 GRP_REF_BEGIN = GRP_FKT_END,
113 GRP_REF_END = GRP_REF_BEGIN + 2,
115 GRP_REG_BEGIN = GRP_REF_END,
116 GRP_REG_END = GRP_REG_BEGIN + 1,
118 GRP_DB_BEGIN = GRP_REG_END,
119 GRP_DB_END = GRP_DB_BEGIN + 5,
121 GRP_VAR_BEGIN = GRP_DB_END,
122 GRP_VAR_END = GRP_VAR_BEGIN + 9
125 enum
127 GRP_WEB_DOC_BEGIN = 0,
128 GRP_WEB_DOC_END = GRP_WEB_DOC_BEGIN + 9,
130 GRP_WEB_FKT_BEGIN = GRP_WEB_DOC_END + 2,
131 GRP_WEB_FKT_END = GRP_WEB_FKT_BEGIN + 0, // Die Gruppe ist leer!
133 GRP_WEB_REF_BEGIN = GRP_WEB_FKT_END + 6, // Die Gruppe ist leer!
134 GRP_WEB_REF_END = GRP_WEB_REF_BEGIN + 0,
136 GRP_WEB_REG_BEGIN = GRP_WEB_REF_END + 2,
137 GRP_WEB_REG_END = GRP_WEB_REG_BEGIN + 1,
139 GRP_WEB_DB_BEGIN = GRP_WEB_REG_END, // Die Gruppe ist leer!
140 GRP_WEB_DB_END = GRP_WEB_DB_BEGIN + 0,
142 GRP_WEB_VAR_BEGIN = GRP_WEB_DB_END + 5,
143 GRP_WEB_VAR_END = GRP_WEB_VAR_BEGIN + 1
146 /*--------------------------------------------------------------------
147 Beschreibung: Formate in der richtigen Reihenfolge
148 --------------------------------------------------------------------*/
149 static const USHORT __FAR_DATA aSetFmt[] =
151 // die Reihenfolge muss zu Beginn mit den ResourceIds fuer FMT_SETVAR_???
152 // uebereinstimmen
157 static const USHORT __FAR_DATA aGetFmt[] =
159 // die Reihenfolge muss zu Beginn mit den ResourceIds fuer FMT_GETVAR_???
160 // uebereinstimmen
164 static const USHORT __FAR_DATA aUsrFmt[] =
166 // die Reihenfolge muss zu Beginn mit den ResourceIds fuer FMT_SETVAR_???
167 // uebereinstimmen
169 nsSwExtendedSubType::SUB_CMD
172 static const USHORT __FAR_DATA aDBFmt[] =
174 // die Reihenfolge muss zu Beginn mit den ResourceIds fuer FMT_DBFLD_???
175 // uebereinstimmen
176 nsSwExtendedSubType::SUB_OWN_FMT
179 static const USHORT VF_COUNT = sizeof(aGetFmt) / sizeof(USHORT);
180 static const USHORT VF_USR_COUNT = sizeof(aUsrFmt) / sizeof(USHORT);
181 static const USHORT VF_DB_COUNT = sizeof(aDBFmt) / sizeof(USHORT);
183 /*--------------------------------------------------------------------
184 Beschreibung: Feldtypen und Subtypes
185 --------------------------------------------------------------------*/
186 struct SwFldPack
188 USHORT nTypeId;
190 USHORT nSubTypeStart;
191 USHORT nSubTypeEnd;
193 ULONG nFmtBegin;
194 ULONG nFmtEnd;
197 /*--------------------------------------------------------------------
198 Beschreibung: Strings und Formate
199 --------------------------------------------------------------------*/
200 static const SwFldPack __FAR_DATA aSwFlds[] =
202 // Dokument
203 { TYP_EXTUSERFLD, FLD_EU_BEGIN, FLD_EU_END, 0, 0 },
204 { TYP_AUTHORFLD, 0, 0, FMT_AUTHOR_BEGIN, FMT_AUTHOR_END },
205 { TYP_DATEFLD, FLD_DATE_BEGIN, FLD_DATE_END, 0, 0 },
206 { TYP_TIMEFLD, FLD_TIME_BEGIN, FLD_TIME_END, 0, 0 },
207 { TYP_PAGENUMBERFLD, 0, 0, FMT_NUM_BEGIN, FMT_NUM_END-1 },
208 { TYP_NEXTPAGEFLD, 0, 0, FMT_NUM_BEGIN, FMT_NUM_END },
209 { TYP_PREVPAGEFLD, 0, 0, FMT_NUM_BEGIN, FMT_NUM_END },
210 { TYP_FILENAMEFLD, 0, 0, FMT_FF_BEGIN, FMT_FF_END },
211 { TYP_DOCSTATFLD, FLD_STAT_BEGIN, FLD_STAT_END, FMT_NUM_BEGIN, FMT_NUM_END-1 },
213 { TYP_CHAPTERFLD, 0, 0, FMT_CHAPTER_BEGIN, FMT_CHAPTER_END },
214 { TYP_TEMPLNAMEFLD, 0, 0, FMT_FF_BEGIN, FMT_FF_END },
216 // Funktion
217 { TYP_CONDTXTFLD, 0, 0, 0, 0 },
218 { TYP_DROPDOWN, 0, 0, 0, 0 },
219 { TYP_INPUTFLD, FLD_INPUT_BEGIN, FLD_INPUT_END, 0, 0 },
220 { TYP_MACROFLD, 0, 0, 0, 0 },
221 { TYP_JUMPEDITFLD, 0, 0, FMT_MARK_BEGIN, FMT_MARK_END },
222 { TYP_COMBINED_CHARS, 0, 0, 0, 0 },
223 { TYP_HIDDENTXTFLD, 0, 0, 0, 0 },
224 { TYP_HIDDENPARAFLD, 0, 0, 0, 0 },
226 // Referenzen
227 { TYP_SETREFFLD, 0, 0, 0, 0 },
228 { TYP_GETREFFLD, 0, 0, FMT_REF_BEGIN, FMT_REF_END },
230 // Ablage
231 { TYP_DOCINFOFLD, 0, 0, FMT_REG_BEGIN, FMT_REG_END },
233 // Datenbank
234 { TYP_DBFLD, 0, 0, FMT_DBFLD_BEGIN, FMT_DBFLD_END },
235 { TYP_DBNEXTSETFLD, 0, 0, 0, 0 },
236 { TYP_DBNUMSETFLD, 0, 0, 0, 0 },
237 { TYP_DBSETNUMBERFLD, 0, 0, FMT_NUM_BEGIN, FMT_NUM_END-2 },
238 { TYP_DBNAMEFLD, 0, 0, 0, 0 },
240 // Variablen
241 { TYP_SETFLD, 0, 0, FMT_SETVAR_BEGIN, FMT_SETVAR_END },
243 { TYP_GETFLD, 0, 0, FMT_GETVAR_BEGIN, FMT_GETVAR_END },
244 { TYP_DDEFLD, 0, 0, FMT_DDE_BEGIN, FMT_DDE_END },
245 { TYP_FORMELFLD, 0, 0, FMT_GETVAR_BEGIN, FMT_GETVAR_END },
246 { TYP_INPUTFLD, FLD_INPUT_BEGIN, FLD_INPUT_END, 0, 0 },
247 { TYP_SEQFLD, 0, 0, FMT_NUM_BEGIN, FMT_NUM_END-2 },
248 { TYP_SETREFPAGEFLD, FLD_PAGEREF_BEGIN, FLD_PAGEREF_END,0, 0 },
249 { TYP_GETREFPAGEFLD, 0, 0, FMT_NUM_BEGIN, FMT_NUM_END-1 },
250 { TYP_USERFLD, 0, 0, FMT_USERVAR_BEGIN, FMT_USERVAR_END }
253 /*--------------------------------------------------------------------
254 Beschreibung: Zugriff auf die Shell
255 --------------------------------------------------------------------*/
257 static SwWrtShell* lcl_GetShell()
259 SwView* pView;
260 if ( 0 != (pView = ::GetActiveView()) )
261 return pView->GetWrtShellPtr();
262 DBG_ERROR("no current shell found!");
263 return 0;
266 inline USHORT GetPackCount() { return sizeof(aSwFlds) / sizeof(SwFldPack); }
268 /*--------------------------------------------------------------------
269 Beschreibung: FieldManager regelt das Einfuegen und Updaten
270 von Feldern
271 --------------------------------------------------------------------*/
273 SwFldMgr::SwFldMgr(SwWrtShell* pSh ) :
274 pModule(0),
275 pMacroItem(0),
276 pWrtShell(pSh),
277 bEvalExp(TRUE)
279 // aktuelles Feld ermitteln falls vorhanden
280 GetCurFld();
284 SwFldMgr::~SwFldMgr()
288 /*--------------------------------------------------------------------
289 Beschreibung: RefMark ueber Namen organisieren
290 --------------------------------------------------------------------*/
292 BOOL SwFldMgr::CanInsertRefMark( const String& rStr )
294 BOOL bRet = FALSE;
295 SwWrtShell *pSh = pWrtShell ? pWrtShell : lcl_GetShell();
296 DBG_ASSERT(pSh, "no SwWrtShell found");
297 if(pSh)
299 USHORT nCnt = pSh->GetCrsrCnt();
301 // der letzte Crsr muss keine aufgespannte Selektion
302 if( 1 < nCnt && !pSh->SwCrsrShell::HasSelection() )
303 --nCnt;
305 bRet = 2 > nCnt && 0 == pSh->GetRefMark( rStr );
307 return bRet;
310 /*--------------------------------------------------------------------
311 Beschreibung: Zugriff ueber ResIds
312 --------------------------------------------------------------------*/
314 void SwFldMgr::RemoveFldType(USHORT nResId, const String& rName )
316 SwWrtShell * pSh = pWrtShell ? pWrtShell : lcl_GetShell();
317 DBG_ASSERT(pSh, "no SwWrtShell found");
318 if( pSh )
319 pSh->RemoveFldType(nResId, rName);
322 USHORT SwFldMgr::GetFldTypeCount(USHORT nResId) const
324 SwWrtShell * pSh = pWrtShell ? pWrtShell : lcl_GetShell();
325 DBG_ASSERT(pSh, "no SwWrtShell found");
326 return pSh ? pSh->GetFldTypeCount(nResId) : 0;
330 SwFieldType* SwFldMgr::GetFldType(USHORT nResId, USHORT nId) const
332 SwWrtShell * pSh = pWrtShell ? pWrtShell : lcl_GetShell();
333 DBG_ASSERT(pSh, "no SwWrtShell found");
334 return pSh ? pSh->GetFldType(nId, nResId) : 0;
338 SwFieldType* SwFldMgr::GetFldType(USHORT nResId, const String& rName) const
340 SwWrtShell * pSh = pWrtShell ? pWrtShell : lcl_GetShell();
341 DBG_ASSERT(pSh, "no SwWrtShell found");
342 return pSh ? pSh->GetFldType(nResId, rName) : 0;
346 /*--------------------------------------------------------------------
347 Beschreibung: Aktuelles Feld ermitteln
348 --------------------------------------------------------------------*/
349 SwField* SwFldMgr::GetCurFld()
351 SwWrtShell *pSh = pWrtShell ? pWrtShell : ::lcl_GetShell();
352 if ( pSh )
353 pCurFld = pSh->GetCurFld();
354 else
355 pCurFld = NULL;
357 // Strings und Format initialisieren
359 aCurPar1.Erase();
360 aCurPar2.Erase();
361 sCurFrame.Erase();
362 nCurFmt = 0;
364 if(!pCurFld)
365 return 0;
367 // Aktuelle Werte aufbereiten Parameter 1 und Parameter 2
368 // als auch das Format ermitteln
370 const USHORT nTypeId = pCurFld->GetTypeId();
372 nCurFmt = pCurFld->GetFormat();
373 aCurPar1 = pCurFld->GetPar1();
374 aCurPar2 = pCurFld->GetPar2();
376 switch( nTypeId )
378 case TYP_PAGENUMBERFLD:
379 case TYP_NEXTPAGEFLD:
380 case TYP_PREVPAGEFLD:
381 case TYP_GETREFPAGEFLD:
382 if( nCurFmt == SVX_NUM_PAGEDESC )
383 nCurFmt -= 2;
384 break;
386 return pCurFld;
389 /*--------------------------------------------------------------------
390 Beschreibung: Gruppen-Bereich liefern
391 --------------------------------------------------------------------*/
394 const SwFldGroupRgn& SwFldMgr::GetGroupRange(BOOL bHtmlMode, USHORT nGrpId) const
396 static SwFldGroupRgn __READONLY_DATA aRanges[] =
398 { /* Dokument */ GRP_DOC_BEGIN, GRP_DOC_END },
399 { /* Funktionen */ GRP_FKT_BEGIN, GRP_FKT_END },
400 { /* Referenzen */ GRP_REF_BEGIN, GRP_REF_END },
401 { /* Ablage */ GRP_REG_BEGIN, GRP_REG_END },
402 { /* DB */ GRP_DB_BEGIN, GRP_DB_END },
403 { /* User */ GRP_VAR_BEGIN, GRP_VAR_END }
405 static SwFldGroupRgn __READONLY_DATA aWebRanges[] =
407 { /* Dokument */ GRP_WEB_DOC_BEGIN, GRP_WEB_DOC_END },
408 { /* Funktionen */ GRP_WEB_FKT_BEGIN, GRP_WEB_FKT_END },
409 { /* Referenzen */ GRP_WEB_REF_BEGIN, GRP_WEB_REF_END },
410 { /* Ablage */ GRP_WEB_REG_BEGIN, GRP_WEB_REG_END },
411 { /* DB */ GRP_WEB_DB_BEGIN, GRP_WEB_DB_END },
412 { /* User */ GRP_WEB_VAR_BEGIN, GRP_WEB_VAR_END }
415 if (bHtmlMode)
416 return aWebRanges[(USHORT)nGrpId];
417 else
418 return aRanges[(USHORT)nGrpId];
421 /*--------------------------------------------------------------------
422 Beschreibung: GroupId bestimmen
423 --------------------------------------------------------------------*/
425 USHORT SwFldMgr::GetGroup(BOOL bHtmlMode, USHORT nTypeId, USHORT nSubType) const
427 if (nTypeId == TYP_SETINPFLD)
428 nTypeId = TYP_SETFLD;
430 if (nTypeId == TYP_INPUTFLD && (nSubType & INP_USR))
431 nTypeId = TYP_USERFLD;
433 if (nTypeId == TYP_FIXDATEFLD)
434 nTypeId = TYP_DATEFLD;
436 if (nTypeId == TYP_FIXTIMEFLD)
437 nTypeId = TYP_TIMEFLD;
439 for (USHORT i = GRP_DOC; i <= GRP_VAR; i++)
441 const SwFldGroupRgn& rRange = GetGroupRange(bHtmlMode, i);
442 for (USHORT nPos = rRange.nStart; nPos < rRange.nEnd; nPos++)
444 if (aSwFlds[nPos].nTypeId == nTypeId)
445 return i;
448 return USHRT_MAX;
451 /*--------------------------------------------------------------------
452 Beschreibung: Namen zur TypeId ermitteln
453 ZUGRIFF ueber TYP_....
454 --------------------------------------------------------------------*/
457 USHORT SwFldMgr::GetTypeId(USHORT nPos)
459 ASSERT(nPos < ::GetPackCount(), "unzulaessige Pos");
460 return aSwFlds[ nPos ].nTypeId;
464 const String& SwFldMgr::GetTypeStr(USHORT nPos)
466 ASSERT(nPos < ::GetPackCount(), "unzulaessige TypeId");
468 USHORT nFldWh = aSwFlds[ nPos ].nTypeId;
470 // Sonderbehandlung fuer Datum/Zeit Felder (ohne var/fix)
471 if( TYP_DATEFLD == nFldWh )
473 static String g_aDate( SW_RES( STR_DATEFLD ) );
474 return g_aDate;
476 if( TYP_TIMEFLD == nFldWh )
478 static String g_aTime( SW_RES( STR_TIMEFLD ) );
479 return g_aTime;
482 return SwFieldType::GetTypeStr( nFldWh );
485 /*--------------------------------------------------------------------
486 Beschreibung: Pos in der Liste bestimmen
487 --------------------------------------------------------------------*/
490 USHORT SwFldMgr::GetPos(USHORT nTypeId)
492 switch( nTypeId )
494 case TYP_FIXDATEFLD: nTypeId = TYP_DATEFLD; break;
495 case TYP_FIXTIMEFLD: nTypeId = TYP_TIMEFLD; break;
496 case TYP_SETINPFLD: nTypeId = TYP_SETFLD; break;
497 case TYP_USRINPFLD: nTypeId = TYP_USERFLD; break;
500 for(USHORT i = 0; i < GetPackCount(); i++)
501 if(aSwFlds[i].nTypeId == nTypeId)
502 return i;
504 return USHRT_MAX;
507 /*--------------------------------------------------------------------
508 Beschreibung: Subtypen eines Feldes lokalisieren
509 --------------------------------------------------------------------*/
511 BOOL SwFldMgr::GetSubTypes(USHORT nTypeId, SvStringsDtor& rToFill)
513 BOOL bRet = FALSE;
514 SwWrtShell *pSh = pWrtShell ? pWrtShell : lcl_GetShell();
515 DBG_ASSERT(pSh, "no SwWrtShell found");
516 if(pSh)
518 const USHORT nPos = GetPos(nTypeId);
520 switch(nTypeId)
522 case TYP_SETREFFLD:
523 case TYP_GETREFFLD:
525 // Referenzen sind keine Felder
526 pSh->GetRefMarks( &rToFill );
527 break;
529 case TYP_MACROFLD:
531 break;
533 case TYP_INPUTFLD:
534 { String* pNew = new SW_RESSTR(aSwFlds[nPos].nSubTypeStart);
535 rToFill.Insert(pNew, rToFill.Count());
536 // Weiter bei generischen Typen
538 case TYP_DDEFLD:
539 case TYP_SEQFLD:
540 case TYP_FORMELFLD:
541 case TYP_GETFLD:
542 case TYP_SETFLD:
543 case TYP_USERFLD:
546 const USHORT nCount = pSh->GetFldTypeCount();
547 for(USHORT i = 0; i < nCount; ++i)
549 SwFieldType* pFldType = pSh->GetFldType( i );
550 const USHORT nWhich = pFldType->Which();
552 if((nTypeId == TYP_DDEFLD && pFldType->Which() == RES_DDEFLD) ||
554 (nTypeId == TYP_USERFLD && nWhich == RES_USERFLD) ||
556 (nTypeId == TYP_GETFLD && nWhich == RES_SETEXPFLD &&
557 !(((SwSetExpFieldType*)pFldType)->GetType() & nsSwGetSetExpType::GSE_SEQ)) ||
559 (nTypeId == TYP_SETFLD && nWhich == RES_SETEXPFLD &&
560 !(((SwSetExpFieldType*)pFldType)->GetType() & nsSwGetSetExpType::GSE_SEQ)) ||
562 (nTypeId == TYP_SEQFLD && nWhich == RES_SETEXPFLD &&
563 (((SwSetExpFieldType*)pFldType)->GetType() & nsSwGetSetExpType::GSE_SEQ)) ||
565 ((nTypeId == TYP_INPUTFLD || nTypeId == TYP_FORMELFLD) &&
566 (nWhich == RES_USERFLD ||
567 nWhich == RES_SETEXPFLD &&
568 !(((SwSetExpFieldType*)pFldType)->GetType() & nsSwGetSetExpType::GSE_SEQ)) ) )
570 String* pNew = new String(pFldType->GetName());
571 rToFill.Insert(pNew, rToFill.Count());
574 break;
576 case TYP_DBNEXTSETFLD:
577 case TYP_DBNUMSETFLD:
578 case TYP_DBNAMEFLD:
579 case TYP_DBSETNUMBERFLD:
580 break;
582 default:
584 // statische SubTypes
585 if(nPos != USHRT_MAX)
587 USHORT nCount;
588 if (nTypeId == TYP_DOCINFOFLD)
589 nCount = DI_SUBTYPE_END - DI_SUBTYPE_BEGIN;
590 else
591 nCount = aSwFlds[nPos].nSubTypeEnd - aSwFlds[nPos].nSubTypeStart;
593 for(USHORT i = 0; i < nCount; ++i)
595 String* pNew;
596 if (nTypeId == TYP_DOCINFOFLD)
598 if ( i == DI_CUSTOM )
599 pNew = new String( String(SW_RES( STR_CUSTOM )) );
600 else
601 pNew = new String(*ViewShell::GetShellRes()->aDocInfoLst[i]);
603 else
604 pNew = new SW_RESSTR(aSwFlds[nPos].nSubTypeStart + i);
606 rToFill.Insert(pNew, rToFill.Count());
611 bRet = TRUE;
613 return bRet;
616 /*--------------------------------------------------------------------
617 Beschreibung: Format ermitteln
618 ZUGRIFF ueber TYP_....
619 --------------------------------------------------------------------*/
622 USHORT SwFldMgr::GetFormatCount(USHORT nTypeId, BOOL bIsText, BOOL bHtmlMode) const
624 ASSERT(nTypeId < TYP_END, "unzulaessige TypeId");
627 const USHORT nPos = GetPos(nTypeId);
629 if(nPos == USHRT_MAX || (bHtmlMode && nTypeId == TYP_SETFLD))
630 return 0;
632 ULONG nStart = aSwFlds[nPos].nFmtBegin;
633 ULONG nEnd = aSwFlds[nPos].nFmtEnd;
635 if (bIsText && nEnd - nStart >= 2)
636 return 2;
638 if (nTypeId == TYP_FILENAMEFLD)
639 nEnd -= 2; // Kein Bereich oder Vorlage
641 switch(nStart)
643 case FMT_GETVAR_BEGIN:
644 case FMT_SETVAR_BEGIN: return VF_COUNT;
645 case FMT_USERVAR_BEGIN: return VF_USR_COUNT;
646 case FMT_DBFLD_BEGIN: return VF_DB_COUNT;
647 case FMT_NUM_BEGIN:
649 USHORT nCount = (USHORT)(nEnd - nStart);
650 GetNumberingInfo();
651 if(xNumberingInfo.is())
653 Sequence<sal_Int16> aTypes = xNumberingInfo->getSupportedNumberingTypes();
654 const sal_Int16* pTypes = aTypes.getConstArray();
655 for(sal_Int32 nType = 0; nType < aTypes.getLength(); nType++)
657 sal_Int16 nCurrent = pTypes[nType];
658 //skip all values below or equal to CHARS_LOWER_LETTER_N
659 if(nCurrent > NumberingType::CHARS_LOWER_LETTER_N)
661 // #i28073# it's not necessarily a sorted sequence
662 ++nCount;
666 return nCount;
670 return (USHORT)(nEnd - nStart);
674 /*--------------------------------------------------------------------
675 Beschreibung: FormatString zu einem Typ ermitteln
676 --------------------------------------------------------------------*/
679 String SwFldMgr::GetFormatStr(USHORT nTypeId, ULONG nFormatId) const
681 String aRet;
682 ASSERT(nTypeId < TYP_END, "unzulaessige TypeId");
684 const USHORT nPos = GetPos(nTypeId);
686 if(nPos == USHRT_MAX)
687 return aRet;
689 ULONG nStart;
691 nStart = aSwFlds[nPos].nFmtBegin;
693 if (TYP_AUTHORFLD == nTypeId|| TYP_FILENAMEFLD == nTypeId)
694 nFormatId &= ~FF_FIXED; // Fixed-Flag ausmaskieren
696 if((nStart + nFormatId) < aSwFlds[nPos].nFmtEnd)
697 aRet = SW_RESSTR((USHORT)(nStart + nFormatId));
698 else if( FMT_NUM_BEGIN == nStart)
700 if(xNumberingInfo.is())
702 Sequence<sal_Int16> aTypes = xNumberingInfo->getSupportedNumberingTypes();
703 const sal_Int16* pTypes = aTypes.getConstArray();
704 sal_Int32 nOffset = aSwFlds[nPos].nFmtEnd - nStart;
705 sal_Int32 nValidEntry = 0;
706 for(sal_Int32 nType = 0; nType < aTypes.getLength(); nType++)
708 sal_Int16 nCurrent = pTypes[nType];
709 if(nCurrent > NumberingType::CHARS_LOWER_LETTER_N)
711 if(nValidEntry == ((sal_Int32)nFormatId) - nOffset)
713 aRet = xNumberingInfo->getNumberingIdentifier( pTypes[nType] );
714 break;
716 ++nValidEntry;
722 return aRet;
725 /*--------------------------------------------------------------------
726 Beschreibung: FormatId aus Pseudo-ID ermitteln
727 --------------------------------------------------------------------*/
729 USHORT SwFldMgr::GetFormatId(USHORT nTypeId, ULONG nFormatId) const
731 USHORT nId = (USHORT)nFormatId;
733 switch( nTypeId )
735 case TYP_DOCINFOFLD:
736 switch( aSwFlds[ GetPos( nTypeId ) ].nFmtBegin + nFormatId )
738 case FMT_REG_AUTHOR: nId = DI_SUB_AUTHOR; break;
739 case FMT_REG_TIME: nId = DI_SUB_TIME; break;
740 case FMT_REG_DATE: nId = DI_SUB_DATE; break;
742 break;
744 case TYP_PAGENUMBERFLD:
745 case TYP_NEXTPAGEFLD:
746 case TYP_PREVPAGEFLD:
747 case TYP_DOCSTATFLD:
748 case TYP_DBSETNUMBERFLD:
749 case TYP_SEQFLD:
750 case TYP_GETREFPAGEFLD:
752 USHORT nPos = GetPos( nTypeId );
753 ULONG nBegin = aSwFlds[ nPos ].nFmtBegin;
754 ULONG nEnd = aSwFlds[nPos].nFmtEnd;
755 if((nBegin + nFormatId) < nEnd)
757 switch( nBegin + nFormatId )
759 case FMT_NUM_ABC: nId = SVX_NUM_CHARS_UPPER_LETTER; break;
760 case FMT_NUM_SABC: nId = SVX_NUM_CHARS_LOWER_LETTER; break;
761 case FMT_NUM_ROMAN: nId = SVX_NUM_ROMAN_UPPER; break;
762 case FMT_NUM_SROMAN: nId = SVX_NUM_ROMAN_LOWER; break;
763 case FMT_NUM_ARABIC: nId = SVX_NUM_ARABIC; break;
764 case FMT_NUM_PAGEDESC: nId = SVX_NUM_PAGEDESC; break;
765 case FMT_NUM_PAGESPECIAL: nId = SVX_NUM_CHAR_SPECIAL; break;
766 case FMT_NUM_ABC_N: nId = SVX_NUM_CHARS_UPPER_LETTER_N; break;
767 case FMT_NUM_SABC_N: nId = SVX_NUM_CHARS_LOWER_LETTER_N; break;
770 else if(xNumberingInfo.is())
772 Sequence<sal_Int16> aTypes = xNumberingInfo->getSupportedNumberingTypes();
773 const sal_Int16* pTypes = aTypes.getConstArray();
774 sal_Int32 nOffset = nEnd - nBegin;
775 sal_Int32 nValidEntry = 0;
776 for(sal_Int32 nType = 0; nType < aTypes.getLength(); nType++)
778 sal_Int16 nCurrent = pTypes[nType];
779 if(nCurrent > NumberingType::CHARS_LOWER_LETTER_N)
781 if(nValidEntry == ((sal_Int32)nFormatId) - nOffset)
783 nId = pTypes[nType];
784 break;
786 ++nValidEntry;
791 break;
792 case TYP_DDEFLD:
793 switch ( aSwFlds[ GetPos( nTypeId ) ].nFmtBegin + nFormatId )
795 case FMT_DDE_NORMAL: nId = sfx2::LINKUPDATE_ONCALL; break;
796 case FMT_DDE_HOT: nId = sfx2::LINKUPDATE_ALWAYS; break;
798 break;
801 return nId;
805 /*--------------------------------------------------------------------
806 Beschreibung: Traveling
807 --------------------------------------------------------------------*/
810 BOOL SwFldMgr::GoNextPrev( BOOL bNext, SwFieldType* pTyp )
812 SwWrtShell* pSh = pWrtShell ? pWrtShell : ::lcl_GetShell();
813 if(!pSh)
814 return FALSE;
816 if( !pTyp && pCurFld )
818 const USHORT nTypeId = pCurFld->GetTypeId();
819 if( TYP_SETINPFLD == nTypeId || TYP_USRINPFLD == nTypeId )
820 pTyp = pSh->GetFldType( 0, RES_INPUTFLD );
821 else
822 pTyp = pCurFld->GetTyp();
825 if (pTyp && pTyp->Which() == RES_DBFLD)
827 // Fuer Feldbefehl-bearbeiten (alle DB-Felder anspringen)
828 return pSh->MoveFldType( 0, bNext, USHRT_MAX, RES_DBFLD );
831 return pTyp && pSh ? pSh->MoveFldType( pTyp, bNext ) : FALSE;
834 /*--------------------------------------------------------------------
835 Beschreibung: Feldtypen einfuegen
836 --------------------------------------------------------------------*/
839 void SwFldMgr::InsertFldType(SwFieldType& rType)
841 SwWrtShell* pSh = pWrtShell ? pWrtShell : ::lcl_GetShell();
842 DBG_ASSERT(pSh, "no SwWrtShell found");
843 if(pSh)
844 pSh->InsertFldType(rType);
847 /*--------------------------------------------------------------------
848 Beschreibung: Aktuelle TypeId ermitteln
849 --------------------------------------------------------------------*/
852 USHORT SwFldMgr::GetCurTypeId() const
854 return pCurFld ? pCurFld->GetTypeId() : USHRT_MAX;
857 /*--------------------------------------------------------------------
858 Beschreibung: Ueber String Feld einfuegen oder Update
859 --------------------------------------------------------------------*/
862 BOOL SwFldMgr::InsertFld( const SwInsertFld_Data& rData )
864 SwField* pFld = 0;
865 BOOL bExp = FALSE;
866 BOOL bTbl = FALSE;
867 BOOL bPageVar = FALSE;
868 ULONG nFormatId = rData.nFormatId;
869 USHORT nSubType = rData.nSubType;
870 sal_Unicode cSeparator = rData.cSeparator;
871 SwWrtShell* pCurShell = rData.pSh;
872 if(!pCurShell)
873 pCurShell = pWrtShell ? pWrtShell : ::lcl_GetShell();
874 DBG_ASSERT(pCurShell, "no SwWrtShell found");
875 if(!pCurShell)
876 return FALSE;
878 switch(rData.nTypeId)
879 { // ACHTUNG dieses Feld wird ueber einen gesonderten Dialog eingefuegt
880 case TYP_POSTITFLD:
882 SwPostItFieldType* pType = (SwPostItFieldType*)pCurShell->GetFldType(0, RES_POSTITFLD);
883 pFld = new SwPostItField(pType, rData.sPar1, rData.sPar2, DateTime());
884 break;
886 case TYP_SCRIPTFLD:
888 SwScriptFieldType* pType =
889 (SwScriptFieldType*)pCurShell->GetFldType(0, RES_SCRIPTFLD);
890 pFld = new SwScriptField(pType, rData.sPar1, rData.sPar2, (BOOL)nFormatId);
891 break;
893 case TYP_COMBINED_CHARS:
895 SwCombinedCharFieldType* pType = (SwCombinedCharFieldType*)
896 pCurShell->GetFldType( 0, RES_COMBINED_CHARS );
897 pFld = new SwCombinedCharField( pType, rData.sPar1 );
899 break;
900 case TYP_AUTHORITY:
902 SwAuthorityFieldType* pType =
903 (SwAuthorityFieldType*)pCurShell->GetFldType(0, RES_AUTHORITY);
904 if(!pType)
906 pType =
907 (SwAuthorityFieldType*)pCurShell->InsertFldType(
908 SwAuthorityFieldType(pCurShell->GetDoc()));
910 pFld = new SwAuthorityField(pType, rData.sPar1);
912 break;
913 case TYP_DATEFLD:
914 case TYP_TIMEFLD:
916 USHORT nSub = static_cast< USHORT >(rData.nTypeId == TYP_DATEFLD ? DATEFLD : TIMEFLD);
917 nSub |= nSubType == DATE_VAR ? 0 : FIXEDFLD;
919 SwDateTimeFieldType* pTyp =
920 (SwDateTimeFieldType*)pCurShell->GetFldType(0, RES_DATETIMEFLD);
921 pFld = new SwDateTimeField(pTyp, nSub, nFormatId);
922 pFld->SetPar2(rData.sPar2);
923 break;
925 case TYP_FILENAMEFLD:
927 SwFileNameFieldType* pTyp =
928 (SwFileNameFieldType*)pCurShell->GetFldType(0, RES_FILENAMEFLD);
929 pFld = new SwFileNameField(pTyp, nFormatId);
930 break;
932 case TYP_TEMPLNAMEFLD:
934 SwTemplNameFieldType* pTyp =
935 (SwTemplNameFieldType*)pCurShell->GetFldType(0, RES_TEMPLNAMEFLD);
936 pFld = new SwTemplNameField(pTyp, nFormatId);
937 break;
939 case TYP_CHAPTERFLD:
941 USHORT nByte = (USHORT)rData.sPar2.ToInt32();
942 SwChapterFieldType* pTyp =
943 (SwChapterFieldType*)pCurShell->GetFldType(0, RES_CHAPTERFLD);
944 pFld = new SwChapterField(pTyp, nFormatId);
945 nByte = Max(USHORT(1), nByte);
946 nByte = Min(nByte, USHORT(MAXLEVEL));
947 nByte -= 1;
948 ((SwChapterField*)pFld)->SetLevel((BYTE)nByte);
949 break;
951 case TYP_NEXTPAGEFLD:
952 case TYP_PREVPAGEFLD:
953 case TYP_PAGENUMBERFLD:
955 short nOff = (short)rData.sPar2.ToInt32();
957 if(rData.nTypeId == TYP_NEXTPAGEFLD)
959 if( SVX_NUM_CHAR_SPECIAL == nFormatId )
960 nOff = 1;
961 else
962 nOff += 1;
963 nSubType = PG_NEXT;
965 else if(rData.nTypeId == TYP_PREVPAGEFLD)
967 if( SVX_NUM_CHAR_SPECIAL == nFormatId )
968 nOff = -1;
969 else
970 nOff -= 1;
971 nSubType = PG_PREV;
973 else
974 nSubType = PG_RANDOM;
976 SwPageNumberFieldType* pTyp =
977 (SwPageNumberFieldType*)pCurShell->GetFldType(0, RES_PAGENUMBERFLD);
978 pFld = new SwPageNumberField(pTyp, nSubType, nFormatId, nOff);
980 if( SVX_NUM_CHAR_SPECIAL == nFormatId &&
981 ( PG_PREV == nSubType || PG_NEXT == nSubType ) )
982 ((SwPageNumberField*)pFld)->SetUserString( rData.sPar2 );
983 break;
985 case TYP_DOCSTATFLD:
986 { SwDocStatFieldType* pTyp =
987 (SwDocStatFieldType*)pCurShell->GetFldType(0, RES_DOCSTATFLD);
988 pFld = new SwDocStatField(pTyp, nSubType, nFormatId);
989 break;
991 case TYP_AUTHORFLD:
992 { SwAuthorFieldType* pTyp =
993 (SwAuthorFieldType*)pCurShell->GetFldType(0, RES_AUTHORFLD);
994 pFld = new SwAuthorField(pTyp, nFormatId);
995 break;
997 case TYP_CONDTXTFLD:
998 case TYP_HIDDENTXTFLD:
1000 SwHiddenTxtFieldType* pTyp =
1001 (SwHiddenTxtFieldType*)pCurShell->GetFldType(0, RES_HIDDENTXTFLD);
1002 pFld = new SwHiddenTxtField(pTyp, TRUE, rData.sPar1, rData.sPar2, FALSE, rData.nTypeId);
1003 bExp = TRUE;
1004 break;
1006 case TYP_HIDDENPARAFLD:
1008 SwHiddenParaFieldType* pTyp =
1009 (SwHiddenParaFieldType*)pCurShell->GetFldType(0, RES_HIDDENPARAFLD);
1010 pFld = new SwHiddenParaField(pTyp, rData.sPar1);
1011 bExp = TRUE;
1012 break;
1014 case TYP_SETREFFLD:
1016 if( rData.sPar1.Len() > 0 && CanInsertRefMark( rData.sPar1 ) )
1018 pCurShell->SetAttr( SwFmtRefMark( rData.sPar1 ) );
1019 return TRUE;
1021 return FALSE;
1023 case TYP_GETREFFLD:
1025 SwGetRefFieldType* pTyp =
1026 (SwGetRefFieldType*)pCurShell->GetFldType(0, RES_GETREFFLD);
1027 USHORT nSeqNo = (USHORT)rData.sPar2.ToInt32();
1028 pFld = new SwGetRefField(pTyp, rData.sPar1, nSubType, nSeqNo, nFormatId);
1029 bExp = TRUE;
1030 break;
1032 case TYP_DDEFLD:
1034 //JP 28.08.95: DDE-Topics/-Items koennen Blanks in ihren
1035 // Namen haben! Wird hier noch nicht beachtet.
1036 String sCmd( rData.sPar2 );
1037 USHORT nTmpPos = sCmd.SearchAndReplace( ' ', sfx2::cTokenSeperator );
1038 sCmd.SearchAndReplace( ' ', sfx2::cTokenSeperator, nTmpPos );
1040 SwDDEFieldType* pTyp = (SwDDEFieldType*)pCurShell->InsertFldType(
1041 SwDDEFieldType( rData.sPar1, sCmd, (USHORT)nFormatId ));
1042 pFld = new SwDDEField( pTyp );
1043 break;
1045 case TYP_MACROFLD:
1047 SwMacroFieldType* pTyp =
1048 (SwMacroFieldType*)pCurShell->GetFldType(0, RES_MACROFLD);
1050 pFld = new SwMacroField(pTyp, rData.sPar1, rData.sPar2);
1052 break;
1054 case TYP_INTERNETFLD:
1056 SwFmtINetFmt aFmt( rData.sPar1, sCurFrame );
1057 if( pMacroItem )
1058 aFmt.SetMacroTbl( &pMacroItem->GetMacroTable() );
1059 return pCurShell->InsertURL( aFmt, rData.sPar2 );
1061 case TYP_JUMPEDITFLD:
1063 SwJumpEditFieldType* pTyp =
1064 (SwJumpEditFieldType*)pCurShell->GetFldType(0, RES_JUMPEDITFLD);
1066 pFld = new SwJumpEditField(pTyp, nFormatId, rData.sPar1, rData.sPar2 );
1067 break;
1069 case TYP_DOCINFOFLD:
1071 SwDocInfoFieldType* pTyp = (SwDocInfoFieldType*)pCurShell->GetFldType(
1072 0, RES_DOCINFOFLD );
1073 pFld = new SwDocInfoField(pTyp, nSubType, rData.sPar1, nFormatId);
1074 break;
1076 case TYP_EXTUSERFLD:
1078 SwExtUserFieldType* pTyp = (SwExtUserFieldType*)pCurShell->GetFldType(
1079 0, RES_EXTUSERFLD);
1080 pFld = new SwExtUserField(pTyp, nSubType, nFormatId);
1081 break;
1083 case TYP_DBFLD:
1085 SwDBData aDBData;
1086 String sPar1;
1088 if (rData.sPar1.Search(DB_DELIM) == STRING_NOTFOUND)
1090 aDBData = pCurShell->GetDBData();
1091 sPar1 = rData.sPar1;
1093 else
1095 aDBData.sDataSource = rData.sPar1.GetToken(0, DB_DELIM);
1096 aDBData.sCommand = rData.sPar1.GetToken(1, DB_DELIM);
1097 aDBData.nCommandType = rData.sPar1.GetToken(2, DB_DELIM).ToInt32();
1098 sPar1 = rData.sPar1.GetToken(3, DB_DELIM);
1101 if(aDBData.sDataSource.getLength() && pCurShell->GetDBData() != aDBData)
1102 pCurShell->ChgDBData(aDBData);
1104 SwDBFieldType* pTyp = (SwDBFieldType*)pCurShell->InsertFldType(
1105 SwDBFieldType(pCurShell->GetDoc(), sPar1, aDBData) );
1106 pFld = new SwDBField(pTyp);
1107 pFld->SetSubType(nSubType);
1109 if( !(nSubType & nsSwExtendedSubType::SUB_OWN_FMT) ) // Datenbankformat ermitteln
1111 Reference< XDataSource> xSource;
1112 rData.aDBDataSource >>= xSource;
1113 Reference<XConnection> xConnection;
1114 rData.aDBConnection >>= xConnection;
1115 Reference<XPropertySet> xColumn;
1116 rData.aDBColumn >>= xColumn;
1117 if(xColumn.is())
1119 nFormatId = pCurShell->GetNewDBMgr()->GetColumnFmt(xSource, xConnection, xColumn,
1120 pCurShell->GetNumberFormatter(), GetCurrLanguage() );
1122 else
1123 nFormatId = pCurShell->GetNewDBMgr()->GetColumnFmt(
1124 aDBData.sDataSource, aDBData.sCommand, sPar1,
1125 pCurShell->GetNumberFormatter(), GetCurrLanguage() );
1127 pFld->ChangeFormat( nFormatId );
1129 bExp = TRUE;
1130 break;
1132 case TYP_DBSETNUMBERFLD:
1133 case TYP_DBNUMSETFLD:
1134 case TYP_DBNEXTSETFLD:
1135 case TYP_DBNAMEFLD:
1137 USHORT nPos, nTablePos, nCmdTypePos, nExpPos;
1138 String sPar1;
1139 SwDBData aDBData;
1141 // DBName aus rData.sPar1 extrahieren. Format: DBName.TableName.CommandType.ExpStrg
1142 if ((nTablePos = rData.sPar1.Search(DB_DELIM)) != STRING_NOTFOUND)
1143 aDBData.sDataSource = rData.sPar1.Copy(0, nTablePos++);
1144 if ((nCmdTypePos = rData.sPar1.Search(DB_DELIM, nTablePos)) != STRING_NOTFOUND)
1146 aDBData.sCommand = rData.sPar1.Copy(nTablePos, nCmdTypePos++ - nTablePos);
1148 if ((nExpPos = rData.sPar1.Search(DB_DELIM, nCmdTypePos)) != STRING_NOTFOUND)
1150 aDBData.nCommandType = rData.sPar1.Copy(nCmdTypePos, nExpPos++ - nCmdTypePos).ToInt32();
1152 if (nExpPos != STRING_NOTFOUND)
1153 nPos = nExpPos;
1154 else if (nTablePos != STRING_NOTFOUND)
1155 nPos = nTablePos;
1156 else
1157 nPos = 0;
1158 sPar1 = rData.sPar1.Copy(nPos);
1160 if (aDBData.sDataSource.getLength() && pCurShell->GetDBData() != aDBData)
1161 pCurShell->ChgDBData(aDBData);
1163 switch(rData.nTypeId)
1165 case TYP_DBNAMEFLD:
1167 SwDBNameFieldType* pTyp =
1168 (SwDBNameFieldType*)pCurShell->GetFldType(0, RES_DBNAMEFLD);
1169 pFld = new SwDBNameField(pTyp, aDBData);
1171 break;
1173 case TYP_DBNEXTSETFLD:
1175 SwDBNextSetFieldType* pTyp = (SwDBNextSetFieldType*)pCurShell->GetFldType(
1176 0, RES_DBNEXTSETFLD);
1177 pFld = new SwDBNextSetField(pTyp, sPar1, rData.sPar2, aDBData);
1178 bExp = TRUE;
1179 break;
1181 case TYP_DBNUMSETFLD:
1183 SwDBNumSetFieldType* pTyp = (SwDBNumSetFieldType*)pCurShell->GetFldType(
1184 0, RES_DBNUMSETFLD);
1185 pFld = new SwDBNumSetField( pTyp, sPar1, rData.sPar2, aDBData);
1186 bExp = TRUE;
1187 break;
1189 case TYP_DBSETNUMBERFLD:
1191 SwDBSetNumberFieldType* pTyp = (SwDBSetNumberFieldType*)
1192 pCurShell->GetFldType(0, RES_DBSETNUMBERFLD);
1193 pFld = new SwDBSetNumberField( pTyp, aDBData, nFormatId);
1194 bExp = TRUE;
1195 break;
1198 break;
1200 case TYP_USERFLD:
1202 SwUserFieldType* pTyp =
1203 (SwUserFieldType*)pCurShell->GetFldType(RES_USERFLD, rData.sPar1);
1205 // nur wenn vorhanden
1206 if(!pTyp)
1208 pTyp = (SwUserFieldType*)pCurShell->InsertFldType(
1209 SwUserFieldType(pCurShell->GetDoc(), rData.sPar1));
1211 if (pTyp->GetContent(nFormatId) != rData.sPar2)
1212 pTyp->SetContent(rData.sPar2, nFormatId);
1213 pFld = new SwUserField(pTyp, 0, nFormatId);
1214 if (pFld->GetSubType() != nSubType)
1215 pFld->SetSubType(nSubType);
1216 bTbl = TRUE;
1217 break;
1219 case TYP_INPUTFLD:
1221 if ((nSubType & 0x00ff) == INP_VAR)
1223 SwSetExpFieldType* pTyp = (SwSetExpFieldType*)
1224 pCurShell->GetFldType(RES_SETEXPFLD, rData.sPar1);
1226 // kein Experssion Type mit dem Namen vorhanden -> anlegen
1227 if(pTyp)
1229 SwSetExpField* pExpFld =
1230 new SwSetExpField(pTyp, aEmptyStr, nFormatId);
1232 // Typ vom SwSetExpFieldType nicht veraendern:
1233 USHORT nOldSubType = pExpFld->GetSubType();
1234 pExpFld->SetSubType(nOldSubType | (nSubType & 0xff00));
1236 pExpFld->SetPromptText(rData.sPar2);
1237 pExpFld->SetInputFlag(TRUE) ;
1238 bExp = TRUE;
1239 pFld = pExpFld;
1241 else
1242 return FALSE;
1244 else
1246 SwInputFieldType* pTyp =
1247 (SwInputFieldType*)pCurShell->GetFldType(0, RES_INPUTFLD);
1249 SwInputField* pInpFld =
1250 new SwInputField(pTyp, rData.sPar1, rData.sPar2, nSubType|nsSwExtendedSubType::SUB_INVISIBLE, nFormatId);
1251 pFld = pInpFld;
1254 // Dialog starten
1256 pCurShell->StartInputFldDlg(pFld, FALSE, rData.pParent);
1257 break;
1259 case TYP_SETFLD:
1261 if (!rData.sPar2.Len()) // Leere Variablen sind nicht erlaubt
1262 return FALSE;
1264 SwSetExpFieldType* pTyp = (SwSetExpFieldType*)pCurShell->InsertFldType(
1265 SwSetExpFieldType(pCurShell->GetDoc(), rData.sPar1) );
1267 SwSetExpField* pExpFld = new SwSetExpField( pTyp, rData.sPar2, nFormatId);
1268 pExpFld->SetSubType(nSubType);
1269 pExpFld->SetPar2(rData.sPar2);
1270 bExp = TRUE;
1271 pFld = pExpFld;
1272 break;
1274 case TYP_SEQFLD:
1276 SwSetExpFieldType* pTyp = (SwSetExpFieldType*)pCurShell->InsertFldType(
1277 SwSetExpFieldType(pCurShell->GetDoc(), rData.sPar1, nsSwGetSetExpType::GSE_SEQ));
1279 BYTE nLevel = static_cast< BYTE >(nSubType & 0xff);
1281 pTyp->SetOutlineLvl(nLevel);
1282 if (nLevel != 0x7f && cSeparator == 0)
1283 cSeparator = '.';
1285 pTyp->SetDelimiter(cSeparator);
1286 SwSetExpField* pExpFld = new SwSetExpField(pTyp, rData.sPar2, nFormatId);
1287 bExp = TRUE;
1288 pFld = pExpFld;
1289 nSubType = nsSwGetSetExpType::GSE_SEQ;
1290 break;
1292 case TYP_GETFLD:
1294 // gibt es ein entprechendes SetField
1295 SwSetExpFieldType* pSetTyp = (SwSetExpFieldType*)
1296 pCurShell->GetFldType(RES_SETEXPFLD, rData.sPar1);
1298 if(pSetTyp)
1300 SwGetExpFieldType* pTyp = (SwGetExpFieldType*)pCurShell->GetFldType(
1301 0, RES_GETEXPFLD);
1302 pFld = new SwGetExpField(pTyp, rData.sPar1, pSetTyp->GetType(), nFormatId);
1303 pFld->SetSubType(nSubType | pSetTyp->GetType());
1304 bExp = TRUE;
1306 else
1307 return FALSE;
1308 break;
1310 case TYP_FORMELFLD:
1312 if(pCurShell->GetFrmType(0,FALSE) & FRMTYPE_TABLE)
1314 pCurShell->StartAllAction();
1316 SvNumberFormatter* pFormatter = pCurShell->GetDoc()->GetNumberFormatter();
1317 const SvNumberformat* pEntry = pFormatter->GetEntry(nFormatId);
1319 if (pEntry)
1321 SfxStringItem aFormat(FN_NUMBER_FORMAT, pEntry->GetFormatstring());
1322 pCurShell->GetView().GetViewFrame()->GetDispatcher()->
1323 Execute(FN_NUMBER_FORMAT, SFX_CALLMODE_SYNCHRON, &aFormat, 0L);
1326 SfxItemSet aBoxSet( pCurShell->GetAttrPool(),
1327 RES_BOXATR_FORMULA, RES_BOXATR_FORMULA );
1329 String sFml( rData.sPar2 );
1330 if( sFml.EraseLeadingChars().Len() &&
1331 '=' == sFml.GetChar( 0 ) )
1332 sFml.Erase( 0, 1 );
1334 aBoxSet.Put( SwTblBoxFormula( sFml ));
1335 pCurShell->SetTblBoxFormulaAttrs( aBoxSet );
1336 pCurShell->UpdateTable();
1338 pCurShell->EndAllAction();
1339 return TRUE;
1341 /* // In der Tabelle Tabellenformeln einfuegen
1342 SwTblFieldType* pTyp = (SwTblFieldType*)pCurShell->GetFldType(
1343 0, RES_TABLEFLD);
1344 pFld = new SwTblField(pTyp, rData.sPar2, nsSwGetSetExpType::GSE_EXPR, nFormatId);
1345 bTbl = TRUE;*/
1347 else
1349 SwGetExpFieldType* pTyp = (SwGetExpFieldType*)
1350 pCurShell->GetFldType(0, RES_GETEXPFLD);
1351 pFld = new SwGetExpField(pTyp, rData.sPar2, nsSwGetSetExpType::GSE_FORMULA, nFormatId);
1352 pFld->SetSubType(nSubType);
1353 bExp = TRUE;
1355 break;
1357 case TYP_SETREFPAGEFLD:
1358 pFld = new SwRefPageSetField( (SwRefPageSetFieldType*)
1359 pCurShell->GetFldType( 0, RES_REFPAGESETFLD ),
1360 (short)rData.sPar2.ToInt32(), 0 != nSubType );
1361 bPageVar = TRUE;
1362 break;
1364 case TYP_GETREFPAGEFLD:
1365 pFld = new SwRefPageGetField( (SwRefPageGetFieldType*)
1366 pCurShell->GetFldType( 0, RES_REFPAGEGETFLD ), nFormatId );
1367 bPageVar = TRUE;
1368 break;
1369 case TYP_DROPDOWN :
1371 pFld = new SwDropDownField(pCurShell->GetFldType( 0, RES_DROPDOWN ));
1372 xub_StrLen nTokenCount = rData.sPar2.Len() ? rData.sPar2.GetTokenCount(DB_DELIM) : 0;
1373 Sequence<OUString> aEntries(nTokenCount);
1374 OUString* pArray = aEntries.getArray();
1375 for(xub_StrLen nToken = 0; nToken < nTokenCount; nToken++)
1376 pArray[nToken] = rData.sPar2.GetToken(nToken, DB_DELIM);
1377 ((SwDropDownField*)pFld)->SetItems(aEntries);
1378 ((SwDropDownField*)pFld)->SetName(rData.sPar1);
1380 break;
1381 default:
1382 { ASSERT(!this, "Falscher Feldtyp");
1383 return FALSE;
1386 ASSERT(pFld, "Feld nicht vorhanden");
1389 //the auto language flag has to be set prior to the language!
1390 pFld->SetAutomaticLanguage(rData.bIsAutomaticLanguage);
1391 USHORT nLang = GetCurrLanguage();
1392 pFld->SetLanguage(nLang);
1394 // Einfuegen
1395 pCurShell->StartAllAction();
1397 pCurShell->Insert(*pFld);
1399 if(bExp && bEvalExp)
1400 pCurShell->UpdateExpFlds(TRUE);
1402 if(bTbl)
1404 pCurShell->Left(CRSR_SKIP_CHARS, FALSE, 1, FALSE );
1405 pCurShell->UpdateFlds(*pFld);
1406 pCurShell->Right(CRSR_SKIP_CHARS, FALSE, 1, FALSE );
1408 else if( bPageVar )
1409 ((SwRefPageGetFieldType*)pCurShell->GetFldType( 0, RES_REFPAGEGETFLD ))->UpdateFlds();
1410 else if( TYP_GETREFFLD == rData.nTypeId )
1411 pFld->GetTyp()->Modify( 0, 0 );
1413 // temporaeres Feld loeschen
1414 delete pFld;
1416 pCurShell->EndAllAction();
1417 return TRUE;
1420 /*--------------------------------------------------------------------
1421 Beschreibung: Felder Update
1422 --------------------------------------------------------------------*/
1425 void SwFldMgr::UpdateCurFld(ULONG nFormat,
1426 const String& rPar1,
1427 const String& rPar2,
1428 SwField * _pTmpFld) // #111840#
1430 // Format aendern
1431 ASSERT(pCurFld, "kein Feld an der CursorPos");
1433 bool bDelete = false;
1434 SwField *pTmpFld; // mb: fixed memory leak
1435 if (NULL != _pTmpFld)
1437 pTmpFld = _pTmpFld;
1439 else
1441 pTmpFld = pCurFld->Copy();
1442 bDelete = true;
1445 SwFieldType* pType = pTmpFld->GetTyp();
1446 const USHORT nTypeId = pTmpFld->GetTypeId();
1448 SwWrtShell* pSh = pWrtShell ? pWrtShell : ::lcl_GetShell();
1449 DBG_ASSERT(pSh, "no SwWrtShell found");
1450 if(!pSh)
1451 return;
1452 pSh->StartAllAction();
1454 BOOL bSetPar2 = TRUE;
1455 BOOL bSetPar1 = TRUE;
1456 String sPar1( rPar1 );
1457 String sPar2( rPar2 );
1459 // Order to Format
1460 switch( nTypeId )
1462 case TYP_DDEFLD:
1464 //JP 28.08.95: DDE-Topics/-Items koennen Blanks in ihren
1465 // Namen haben! Wird hier noch nicht beachtet.
1466 USHORT nTmpPos = sPar2.SearchAndReplace( ' ', sfx2::cTokenSeperator );
1467 sPar2.SearchAndReplace( ' ', sfx2::cTokenSeperator, nTmpPos );
1468 break;
1471 case TYP_CHAPTERFLD:
1473 USHORT nByte = (USHORT)rPar2.ToInt32();
1474 nByte = Max(USHORT(1), nByte);
1475 nByte = Min(nByte, USHORT(MAXLEVEL));
1476 nByte -= 1;
1477 ((SwChapterField*)pTmpFld)->SetLevel((BYTE)nByte);
1478 bSetPar2 = FALSE;
1479 break;
1482 case TYP_SCRIPTFLD:
1483 ((SwScriptField*)pTmpFld)->SetCodeURL((BOOL)nFormat);
1484 break;
1486 case TYP_NEXTPAGEFLD:
1487 if( SVX_NUM_CHAR_SPECIAL == nFormat )
1489 ((SwPageNumberField*)pCurFld)->SetUserString( sPar2 );
1490 sPar2 = '1';
1492 else
1494 if( nFormat + 2 == SVX_NUM_PAGEDESC )
1495 nFormat = SVX_NUM_PAGEDESC;
1496 short nOff = (short)sPar2.ToInt32();
1497 nOff += 1;
1498 sPar2 = String::CreateFromInt32(nOff);
1500 break;
1502 case TYP_PREVPAGEFLD:
1503 if( SVX_NUM_CHAR_SPECIAL == nFormat )
1505 ((SwPageNumberField*)pCurFld)->SetUserString( sPar2 );
1506 sPar2 = String::CreateFromAscii(
1507 RTL_CONSTASCII_STRINGPARAM("-1"));
1509 else
1511 if( nFormat + 2 == SVX_NUM_PAGEDESC )
1512 nFormat = SVX_NUM_PAGEDESC;
1513 short nOff = (short)sPar2.ToInt32();
1514 nOff -= 1;
1515 sPar2 = String::CreateFromInt32(nOff);
1517 break;
1519 case TYP_PAGENUMBERFLD:
1520 case TYP_GETREFPAGEFLD:
1521 if( nFormat + 2 == SVX_NUM_PAGEDESC )
1522 nFormat = SVX_NUM_PAGEDESC;
1523 break;
1525 case TYP_GETREFFLD:
1527 bSetPar2 = FALSE;
1528 ((SwGetRefField*)pTmpFld)->SetSubType( (USHORT)rPar2.ToInt32() );
1529 USHORT nPos = rPar2.Search( '|' );
1530 if( STRING_NOTFOUND != nPos )
1531 ((SwGetRefField*)pTmpFld)->SetSeqNo( (USHORT)rPar2.Copy( nPos + 1 ).ToInt32());
1533 break;
1534 case TYP_DROPDOWN:
1536 xub_StrLen nTokenCount = sPar2.Len() ? sPar2.GetTokenCount(DB_DELIM) : 0;
1537 Sequence<OUString> aEntries(nTokenCount);
1538 OUString* pArray = aEntries.getArray();
1539 for(xub_StrLen nToken = 0; nToken < nTokenCount; nToken++)
1540 pArray[nToken] = sPar2.GetToken(nToken, DB_DELIM);
1541 ((SwDropDownField*)pTmpFld)->SetItems(aEntries);
1542 ((SwDropDownField*)pTmpFld)->SetName(sPar1);
1543 bSetPar1 = bSetPar2 = FALSE;
1545 break;
1546 case TYP_AUTHORITY :
1548 //#i99069# changes to a bibliography field should change the field type
1549 SwAuthorityField* pAuthorityField = static_cast<SwAuthorityField*>(pTmpFld);
1550 SwAuthorityFieldType* pAuthorityType = static_cast<SwAuthorityFieldType*>(pType);
1551 SwAuthEntry aTempEntry;
1552 for( USHORT i = 0; i < AUTH_FIELD_END; ++i )
1553 aTempEntry.SetAuthorField( (ToxAuthorityField)i,
1554 rPar1.GetToken( i, TOX_STYLE_DELIMITER ));
1555 if( pAuthorityType->ChangeEntryContent( &aTempEntry ) )
1557 pType->UpdateFlds();
1558 pSh->SetModified();
1561 if( aTempEntry.GetAuthorField( AUTH_FIELD_IDENTIFIER ) ==
1562 pAuthorityField->GetFieldText( AUTH_FIELD_IDENTIFIER ) )
1563 bSetPar1 = FALSE; //otherwise it's a new or changed entry, the field needs to be updated
1564 bSetPar2 = FALSE;
1566 break;
1569 // Format setzen
1570 // Format wegen NumberFormatter vor SetPar2 einstellen!
1571 pTmpFld->ChangeFormat(nFormat);
1573 if(bSetPar1)
1574 pTmpFld->SetPar1( sPar1 );
1575 if( bSetPar2 )
1576 pTmpFld->SetPar2( sPar2 );
1578 // Update anschmeissen
1579 if(nTypeId == TYP_DDEFLD ||
1580 nTypeId == TYP_USERFLD ||
1581 nTypeId == TYP_USRINPFLD)
1583 pType->UpdateFlds();
1584 pSh->SetModified();
1586 else {
1587 // mb: #32157
1588 pSh->SwEditShell::UpdateFlds(*pTmpFld);
1589 GetCurFld();
1592 if (bDelete)
1593 delete pTmpFld;
1595 pSh->EndAllAction();
1598 /*--------------------------------------------------------------------
1599 Beschreibung: ExpressionFields explizit evaluieren
1600 --------------------------------------------------------------------*/
1601 void SwFldMgr::EvalExpFlds(SwWrtShell* pSh)
1603 if (pSh == NULL)
1604 pSh = pWrtShell ? pWrtShell : ::lcl_GetShell();
1606 if(pSh)
1608 pSh->StartAllAction();
1609 pSh->UpdateExpFlds(TRUE);
1610 pSh->EndAllAction();
1613 USHORT SwFldMgr::GetCurrLanguage() const
1615 SwWrtShell* pSh = pWrtShell ? pWrtShell : ::lcl_GetShell();
1616 if( pSh )
1617 return pSh->GetCurLang();
1618 return SvxLocaleToLanguage( SvtSysLocale().GetLocaleData().getLocale() );
1621 void SwFieldType::_GetFldName()
1623 static const USHORT coFldCnt = STR_TYPE_END - STR_TYPE_BEGIN;
1625 static USHORT __READONLY_DATA coFldNms[ coFldCnt ] = {
1626 FLD_DATE_STD,
1627 FLD_TIME_STD,
1628 STR_FILENAMEFLD,
1629 STR_DBNAMEFLD,
1630 STR_CHAPTERFLD,
1631 STR_PAGENUMBERFLD,
1632 STR_DOCSTATFLD,
1633 STR_AUTHORFLD,
1634 STR_SETFLD,
1635 STR_GETFLD,
1636 STR_FORMELFLD,
1637 STR_HIDDENTXTFLD,
1638 STR_SETREFFLD,
1639 STR_GETREFFLD,
1640 STR_DDEFLD,
1641 STR_MACROFLD,
1642 STR_INPUTFLD,
1643 STR_HIDDENPARAFLD,
1644 STR_DOCINFOFLD,
1645 STR_DBFLD,
1646 STR_USERFLD,
1647 STR_POSTITFLD,
1648 STR_TEMPLNAMEFLD,
1649 STR_SEQFLD,
1650 STR_DBNEXTSETFLD,
1651 STR_DBNUMSETFLD,
1652 STR_DBSETNUMBERFLD,
1653 STR_CONDTXTFLD,
1654 STR_NEXTPAGEFLD,
1655 STR_PREVPAGEFLD,
1656 STR_EXTUSERFLD,
1657 FLD_DATE_FIX,
1658 FLD_TIME_FIX,
1659 STR_SETINPUTFLD,
1660 STR_USRINPUTFLD,
1661 STR_SETREFPAGEFLD,
1662 STR_GETREFPAGEFLD,
1663 STR_INTERNETFLD,
1664 STR_JUMPEDITFLD,
1665 STR_SCRIPTFLD,
1666 STR_AUTHORITY,
1667 STR_COMBINED_CHARS,
1668 STR_DROPDOWN
1671 // Infos fuer Felder einfuegen
1672 SwFieldType::pFldNames = new SvStringsDtor( (BYTE)coFldCnt, 2 );
1673 for( USHORT nIdx = 0; nIdx < coFldCnt; ++nIdx )
1675 String* pTmp = new SW_RESSTR( coFldNms[ nIdx ] );
1676 pTmp->Assign( MnemonicGenerator::EraseAllMnemonicChars( *pTmp ) );
1677 SwFieldType::pFldNames->Insert(pTmp, nIdx );
1681 /*--------------------------------------------------------------------
1682 Beschreibung:
1683 --------------------------------------------------------------------*/
1685 BOOL SwFldMgr::ChooseMacro(const String&)
1687 BOOL bRet = FALSE;
1689 // choose script dialog
1690 ::rtl::OUString aScriptURL = SfxApplication::ChooseScript();
1692 // the script selector dialog returns a valid script URL
1693 if ( aScriptURL.getLength() != 0 )
1695 SetMacroPath( aScriptURL );
1696 bRet = TRUE;
1699 return bRet;
1702 void SwFldMgr::SetMacroPath(const String& rPath)
1704 sMacroPath = rPath;
1705 sMacroName = rPath;
1707 // try to set sMacroName member variable by parsing the macro path
1708 // using the new URI parsing services
1710 Reference< XMultiServiceFactory > xSMgr =
1711 ::comphelper::getProcessServiceFactory();
1713 Reference< uri::XUriReferenceFactory >
1714 xFactory( xSMgr->createInstance(
1715 ::rtl::OUString::createFromAscii(
1716 "com.sun.star.uri.UriReferenceFactory" ) ), UNO_QUERY );
1718 if ( xFactory.is() )
1720 Reference< uri::XVndSunStarScriptUrl >
1721 xUrl( xFactory->parse( sMacroPath ), UNO_QUERY );
1723 if ( xUrl.is() )
1725 sMacroName = xUrl->getName();
1730 /*--------------------------------------------------------------------
1731 Beschreibung:
1732 --------------------------------------------------------------------*/
1734 ULONG SwFldMgr::GetDefaultFormat(USHORT nTypeId, BOOL bIsText, SvNumberFormatter* pFormatter, double* pVal)
1736 double fValue;
1737 short nDefFormat;
1739 switch (nTypeId)
1741 case TYP_TIMEFLD:
1742 case TYP_DATEFLD:
1744 Date aDate;
1745 Date* pNullDate = pFormatter->GetNullDate();
1747 fValue = aDate - *pNullDate;
1749 Time aTime;
1751 ULONG nNumFmtTime = (ULONG)aTime.GetSec() + (ULONG)aTime.GetMin() * 60L +
1752 (ULONG)aTime.GetHour() * 3600L;
1754 fValue += (double)nNumFmtTime / 86400.0;
1756 nDefFormat = (nTypeId == TYP_DATEFLD) ? NUMBERFORMAT_DATE : NUMBERFORMAT_TIME;
1758 break;
1760 default:
1761 if (bIsText)
1763 fValue = 0.0;
1764 nDefFormat = NUMBERFORMAT_TEXT;
1766 else
1768 fValue = 0.0;
1769 nDefFormat = NUMBERFORMAT_ALL;
1771 break;
1774 if (pVal)
1775 *pVal = fValue;
1777 return pFormatter->GetStandardFormat(nDefFormat, GetCurrLanguage());
1780 /* -----------------------------01.03.01 16:46--------------------------------
1782 ---------------------------------------------------------------------------*/
1783 Reference<XNumberingTypeInfo> SwFldMgr::GetNumberingInfo() const
1785 if(!xNumberingInfo.is())
1787 Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
1788 Reference < XInterface > xI = xMSF->createInstance(
1789 ::rtl::OUString::createFromAscii(
1790 "com.sun.star.text.DefaultNumberingProvider" ));
1791 Reference<XDefaultNumberingProvider> xDefNum(xI, UNO_QUERY);
1792 DBG_ASSERT(xDefNum.is(), "service missing: \"com.sun.star.text.DefaultNumberingProvider\"");
1793 ((SwFldMgr*)this)->xNumberingInfo = Reference<XNumberingTypeInfo>(xDefNum, UNO_QUERY);
1795 return xNumberingInfo;