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 : #include "scitems.hxx"
21 :
22 : #include <svl/slstitm.hxx>
23 : #include <svl/stritem.hxx>
24 : #include <svl/whiter.hxx>
25 : #include <unotools/moduleoptions.hxx>
26 : #include <svtools/cliplistener.hxx>
27 : #include <svtools/insdlg.hxx>
28 : #include <sot/formats.hxx>
29 : #include <svx/hlnkitem.hxx>
30 : #include <sfx2/app.hxx>
31 : #include <sfx2/bindings.hxx>
32 : #include <sfx2/childwin.hxx>
33 : #include <sfx2/objface.hxx>
34 : #include <sfx2/request.hxx>
35 : #include <sfx2/viewfrm.hxx>
36 : #include <svx/clipfmtitem.hxx>
37 : #include <editeng/langitem.hxx>
38 :
39 : #include "cellsh.hxx"
40 : #include "sc.hrc"
41 : #include "docsh.hxx"
42 : #include "attrib.hxx"
43 : #include "scresid.hxx"
44 : #include "tabvwsh.hxx"
45 : #include "impex.hxx"
46 : #include "cell.hxx"
47 : #include "scmod.hxx"
48 : #include "globstr.hrc"
49 : #include "transobj.hxx"
50 : #include "drwtrans.hxx"
51 : #include "scabstdlg.hxx"
52 : #include "dociter.hxx"
53 : #include "postit.hxx"
54 : #include "cliputil.hxx"
55 : #include "clipparam.hxx"
56 : #include "markdata.hxx"
57 :
58 : //------------------------------------------------------------------
59 :
60 : #define ScCellShell
61 : #define CellMovement
62 : #include "scslots.hxx"
63 :
64 0 : TYPEINIT1( ScCellShell, ScFormatShell );
65 :
66 25 : SFX_IMPL_INTERFACE(ScCellShell, ScFormatShell , ScResId(SCSTR_CELLSHELL) )
67 : {
68 10 : SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT | SFX_VISIBILITY_STANDARD |
69 : SFX_VISIBILITY_SERVER,
70 5 : ScResId(RID_OBJECTBAR_FORMAT));
71 5 : SFX_POPUPMENU_REGISTRATION(ScResId(RID_POPUP_CELLS));
72 5 : }
73 :
74 :
75 0 : ScCellShell::ScCellShell(ScViewData* pData) :
76 : ScFormatShell(pData),
77 : pImpl( new CellShell_Impl() ),
78 0 : bPastePossible(false)
79 : {
80 0 : SetHelpId(HID_SCSHELL_CELLSH);
81 0 : SetName(rtl::OUString("Cell"));
82 0 : }
83 :
84 0 : ScCellShell::~ScCellShell()
85 : {
86 0 : if ( pImpl->m_pClipEvtLstnr )
87 : {
88 0 : pImpl->m_pClipEvtLstnr->AddRemoveListener( GetViewData()->GetActiveWin(), false );
89 :
90 : // The listener may just now be waiting for the SolarMutex and call the link
91 : // afterwards, in spite of RemoveListener. So the link has to be reset, too.
92 0 : pImpl->m_pClipEvtLstnr->ClearCallbackLink();
93 :
94 0 : pImpl->m_pClipEvtLstnr->release();
95 : }
96 :
97 0 : delete pImpl->m_pLinkedDlg;
98 0 : delete pImpl->m_pRequest;
99 0 : delete pImpl;
100 0 : }
101 :
102 : //------------------------------------------------------------------
103 :
104 0 : void ScCellShell::GetBlockState( SfxItemSet& rSet )
105 : {
106 0 : ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
107 0 : ScRange aMarkRange;
108 0 : ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange );
109 0 : bool bSimpleArea = (eMarkType == SC_MARK_SIMPLE);
110 : bool bOnlyNotBecauseOfMatrix;
111 0 : bool bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix );
112 0 : ScDocument* pDoc = GetViewData()->GetDocument();
113 0 : ScDocShell* pDocShell = GetViewData()->GetDocShell();
114 0 : ScMarkData& rMark = GetViewData()->GetMarkData();
115 : SCCOL nCol1, nCol2;
116 : SCROW nRow1, nRow2;
117 0 : nCol1 = aMarkRange.aStart.Col();
118 0 : nRow1 = aMarkRange.aStart.Row();
119 0 : nCol2 = aMarkRange.aEnd.Col();
120 0 : nRow2 = aMarkRange.aEnd.Row();
121 :
122 0 : SfxWhichIter aIter(rSet);
123 0 : sal_uInt16 nWhich = aIter.FirstWhich();
124 0 : while ( nWhich )
125 : {
126 0 : bool bDisable = false;
127 0 : bool bNeedEdit = true; // need selection be editable?
128 0 : switch ( nWhich )
129 : {
130 : case FID_FILL_TO_BOTTOM: // fill to top / bottom
131 : {
132 0 : bDisable = !bSimpleArea || (nRow1 == 0 && nRow2 == 0);
133 0 : if ( !bDisable && bEditable )
134 : { // do not damage matrix
135 : bDisable = pDoc->HasSelectedBlockMatrixFragment(
136 0 : nCol1, nRow1, nCol2, nRow1, rMark ); // first row
137 : }
138 : }
139 0 : break;
140 : case FID_FILL_TO_TOP:
141 : {
142 0 : bDisable = (!bSimpleArea) || (nRow1 == MAXROW && nRow2 == MAXROW);
143 0 : if ( !bDisable && bEditable )
144 : { // do not damage matrix
145 : bDisable = pDoc->HasSelectedBlockMatrixFragment(
146 0 : nCol1, nRow2, nCol2, nRow2, rMark ); // last row
147 : }
148 : }
149 0 : break;
150 : case FID_FILL_TO_RIGHT: // fill to left / right
151 : {
152 0 : bDisable = !bSimpleArea || (nCol1 == 0 && nCol2 == 0);
153 0 : if ( !bDisable && bEditable )
154 : { // do not damage matrix
155 : bDisable = pDoc->HasSelectedBlockMatrixFragment(
156 0 : nCol1, nRow1, nCol1, nRow2, rMark ); // first column
157 : }
158 : }
159 0 : break;
160 : case FID_FILL_TO_LEFT:
161 : {
162 0 : bDisable = (!bSimpleArea) || (nCol1 == MAXCOL && nCol2 == MAXCOL);
163 0 : if ( !bDisable && bEditable )
164 : { // do not damage matrix
165 : bDisable = pDoc->HasSelectedBlockMatrixFragment(
166 0 : nCol2, nRow1, nCol2, nRow2, rMark ); // last column
167 : }
168 : }
169 0 : break;
170 : case FID_FILL_SERIES: // fill block
171 : case SID_OPENDLG_TABOP: // multiple-cell operations, are at least 2 cells marked?
172 0 : if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP)
173 0 : bDisable = sal_True;
174 : else
175 0 : bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2);
176 :
177 0 : if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES )
178 : { // do not damage matrix
179 : bDisable = pDoc->HasSelectedBlockMatrixFragment(
180 0 : nCol1, nRow1, nCol2, nRow1, rMark ) // first row
181 : || pDoc->HasSelectedBlockMatrixFragment(
182 0 : nCol1, nRow2, nCol2, nRow2, rMark ) // last row
183 : || pDoc->HasSelectedBlockMatrixFragment(
184 0 : nCol1, nRow1, nCol1, nRow2, rMark ) // first column
185 : || pDoc->HasSelectedBlockMatrixFragment(
186 0 : nCol2, nRow1, nCol2, nRow2, rMark ); // last column
187 : }
188 0 : break;
189 :
190 : case SID_CUT: // cut
191 : case FID_INS_CELL: // insert cells, just simple selection
192 0 : bDisable = (!bSimpleArea);
193 0 : break;
194 :
195 : case FID_INS_ROW: // insert rows
196 : case FID_INS_CELLSDOWN:
197 0 : bDisable = (!bSimpleArea) || GetViewData()->SimpleColMarked();
198 0 : break;
199 :
200 : case FID_INS_COLUMN: // insert columns
201 : case FID_INS_CELLSRIGHT:
202 0 : bDisable = (!bSimpleArea) || GetViewData()->SimpleRowMarked();
203 0 : break;
204 :
205 : case SID_COPY: // copy
206 : // not editable because of matrix only? Do not damage matrix
207 : //! is not called, when protected AND matrix, we will have
208 : //! to live with this... is caught in Copy-Routine, otherwise
209 : //! work is to be done once more
210 0 : if ( !(!bEditable && bOnlyNotBecauseOfMatrix) )
211 0 : bNeedEdit = false; // allowed when protected/ReadOnly
212 0 : break;
213 :
214 : case SID_AUTOFORMAT: // Autoformat, at least 3x3 selected
215 0 : bDisable = (!bSimpleArea)
216 0 : || ((nCol2 - nCol1) < 2) || ((nRow2 - nRow1) < 2);
217 0 : break;
218 :
219 : case SID_CELL_FORMAT_RESET :
220 : case FID_CELL_FORMAT :
221 : case SID_ENABLE_HYPHENATION :
222 : // not editable because of matrix only? Attribute ok nonetheless
223 0 : if ( !bEditable && bOnlyNotBecauseOfMatrix )
224 0 : bNeedEdit = false;
225 0 : break;
226 :
227 : case FID_VALIDATION:
228 : {
229 0 : if ( pDocShell && pDocShell->IsDocShared() )
230 : {
231 0 : bDisable = sal_True;
232 : }
233 : }
234 0 : break;
235 :
236 : case SID_TRANSLITERATE_HALFWIDTH:
237 : case SID_TRANSLITERATE_FULLWIDTH:
238 : case SID_TRANSLITERATE_HIRAGANA:
239 : case SID_TRANSLITERATE_KATAGANA:
240 0 : ScViewUtil::HideDisabledSlot( rSet, GetViewData()->GetBindings(), nWhich );
241 0 : break;
242 : }
243 0 : if (!bDisable && bNeedEdit && !bEditable)
244 0 : bDisable = sal_True;
245 :
246 0 : if (bDisable)
247 0 : rSet.DisableItem(nWhich);
248 0 : else if (nWhich == SID_ENABLE_HYPHENATION)
249 : {
250 : // toggle slots need a bool item
251 0 : rSet.Put( SfxBoolItem( nWhich, false ) );
252 : }
253 0 : nWhich = aIter.NextWhich();
254 0 : }
255 0 : }
256 :
257 : // functionen, disabled depending on cursor position
258 : // Default:
259 : // SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION
260 :
261 0 : void ScCellShell::GetCellState( SfxItemSet& rSet )
262 : {
263 0 : ScDocShell* pDocShell = GetViewData()->GetDocShell();
264 0 : ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
265 0 : ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
266 0 : GetViewData()->GetTabNo() );
267 :
268 0 : SfxWhichIter aIter(rSet);
269 0 : sal_uInt16 nWhich = aIter.FirstWhich();
270 0 : while ( nWhich )
271 : {
272 0 : sal_Bool bDisable = false;
273 0 : sal_Bool bNeedEdit = sal_True; // need cursor position be editable?
274 0 : switch ( nWhich )
275 : {
276 : case SID_THESAURUS:
277 : {
278 0 : CellType eType = pDoc->GetCellType( aCursor );
279 0 : bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT);
280 0 : if (!bDisable)
281 : {
282 : // test for available languages
283 0 : sal_uInt16 nLang = ScViewUtil::GetEffLanguage( pDoc, aCursor );
284 0 : bDisable = !ScModule::HasThesaurusLanguage( nLang );
285 : }
286 : }
287 0 : break;
288 : case SID_OPENDLG_FUNCTION:
289 : {
290 0 : ScMarkData aMarkData=GetViewData()->GetMarkData();
291 0 : aMarkData.MarkToSimple();
292 0 : ScRange aRange;
293 0 : aMarkData.GetMarkArea(aRange);
294 0 : if(aMarkData.IsMarked())
295 : {
296 0 : if (!pDoc->IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(),
297 0 : aRange.aEnd.Col(),aRange.aEnd.Row() ))
298 : {
299 0 : bDisable = sal_True;
300 : }
301 0 : bNeedEdit=false;
302 0 : }
303 :
304 : }
305 0 : break;
306 : case SID_INSERT_POSTIT:
307 : {
308 0 : if ( pDocShell && pDocShell->IsDocShared() )
309 : {
310 0 : bDisable = sal_True;
311 : }
312 : }
313 0 : break;
314 : }
315 0 : if (!bDisable && bNeedEdit)
316 0 : if (!pDoc->IsBlockEditable( aCursor.Tab(), aCursor.Col(),aCursor.Row(),
317 0 : aCursor.Col(),aCursor.Row() ))
318 0 : bDisable = sal_True;
319 0 : if (bDisable)
320 0 : rSet.DisableItem(nWhich);
321 0 : nWhich = aIter.NextWhich();
322 0 : }
323 0 : }
324 :
325 0 : static sal_Bool lcl_TestFormat( SvxClipboardFmtItem& rFormats, const TransferableDataHelper& rDataHelper,
326 : SotFormatStringId nFormatId )
327 : {
328 0 : if ( rDataHelper.HasFormat( nFormatId ) )
329 : {
330 : // translated format name strings are no longer inserted here,
331 : // handled by "paste special" dialog / toolbox controller instead.
332 : // Only the object type name has to be set here:
333 0 : String aStrVal;
334 0 : if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE )
335 : {
336 0 : TransferableObjectDescriptor aDesc;
337 0 : if ( ((TransferableDataHelper&)rDataHelper).GetTransferableObjectDescriptor(
338 0 : SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aDesc ) )
339 0 : aStrVal = aDesc.maTypeName;
340 : }
341 0 : else if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
342 : || nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
343 : {
344 0 : String aSource;
345 0 : SvPasteObjectHelper::GetEmbeddedName( rDataHelper, aStrVal, aSource, nFormatId );
346 : }
347 :
348 0 : if ( aStrVal.Len() )
349 0 : rFormats.AddClipbrdFormat( nFormatId, aStrVal );
350 : else
351 0 : rFormats.AddClipbrdFormat( nFormatId );
352 :
353 0 : return sal_True;
354 : }
355 :
356 0 : return false;
357 : }
358 :
359 0 : void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFmtItem& rFormats )
360 : {
361 0 : Window* pWin = GetViewData()->GetActiveWin();
362 0 : sal_Bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
363 :
364 0 : TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
365 :
366 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DRAWING );
367 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_SVXB );
368 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_GDIMETAFILE );
369 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_BITMAP );
370 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE );
371 :
372 0 : if ( !bDraw )
373 : {
374 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_LINK );
375 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_STRING );
376 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DIF );
377 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_RTF );
378 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML );
379 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML_SIMPLE );
380 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_8 );
381 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_5 );
382 : }
383 :
384 0 : if ( !lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
385 0 : lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
386 0 : }
387 :
388 : // insert, insert contents
389 :
390 0 : static sal_Bool lcl_IsCellPastePossible( const TransferableDataHelper& rData )
391 : {
392 0 : sal_Bool bPossible = false;
393 0 : if ( ScTransferObj::GetOwnClipboard( NULL ) || ScDrawTransferObj::GetOwnClipboard( NULL ) )
394 0 : bPossible = sal_True;
395 : else
396 : {
397 0 : if ( rData.HasFormat( SOT_FORMAT_BITMAP ) ||
398 0 : rData.HasFormat( SOT_FORMAT_GDIMETAFILE ) ||
399 0 : rData.HasFormat( SOT_FORMATSTR_ID_SVXB ) ||
400 0 : rData.HasFormat( FORMAT_PRIVATE ) ||
401 0 : rData.HasFormat( SOT_FORMAT_RTF ) ||
402 0 : rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
403 0 : rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
404 0 : rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
405 0 : rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
406 0 : rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
407 0 : rData.HasFormat( SOT_FORMAT_STRING ) ||
408 0 : rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) ||
409 0 : rData.HasFormat( SOT_FORMATSTR_ID_LINK ) ||
410 0 : rData.HasFormat( SOT_FORMATSTR_ID_HTML ) ||
411 0 : rData.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
412 0 : rData.HasFormat( SOT_FORMATSTR_ID_DIF ) )
413 : {
414 0 : bPossible = sal_True;
415 : }
416 : }
417 0 : return bPossible;
418 : }
419 :
420 0 : IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
421 : {
422 0 : if ( pDataHelper )
423 : {
424 0 : bPastePossible = lcl_IsCellPastePossible( *pDataHelper );
425 :
426 0 : SfxBindings& rBindings = GetViewData()->GetBindings();
427 0 : rBindings.Invalidate( SID_PASTE );
428 0 : rBindings.Invalidate( SID_PASTE_SPECIAL );
429 0 : rBindings.Invalidate( SID_PASTE_ONLY_VALUE );
430 0 : rBindings.Invalidate( SID_PASTE_ONLY_TEXT );
431 0 : rBindings.Invalidate( SID_PASTE_ONLY_FORMULA );
432 0 : rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
433 : }
434 0 : return 0;
435 : }
436 :
437 : namespace {
438 :
439 0 : bool checkDestRanges(ScViewData& rViewData)
440 : {
441 0 : ScRange aDummy;
442 0 : ScMarkType eMarkType = rViewData.GetSimpleArea( aDummy);
443 0 : if (eMarkType != SC_MARK_MULTI)
444 : {
445 : // Single destination range.
446 0 : if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
447 0 : return false;
448 : }
449 :
450 : // Multiple destination ranges.
451 :
452 0 : ScDocument* pDoc = rViewData.GetDocument();
453 0 : Window* pWin = rViewData.GetActiveWin();
454 0 : if (!pWin)
455 0 : return false;
456 :
457 0 : ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(pWin);
458 0 : if (!pOwnClip)
459 : // If it's not a Calc document, we won't be picky.
460 0 : return true;
461 :
462 0 : ScDocument* pClipDoc = pOwnClip->GetDocument();
463 0 : if (!pClipDoc)
464 0 : return false;
465 :
466 0 : ScRange aSrcRange = pClipDoc->GetClipParam().getWholeRange();
467 0 : SCROW nRowSize = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1;
468 0 : SCCOL nColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
469 :
470 0 : ScMarkData aMark = rViewData.GetMarkData();
471 0 : ScRangeList aRanges;
472 0 : aMark.MarkToSimple();
473 0 : aMark.FillRangeListWithMarks(&aRanges, false);
474 :
475 0 : return ScClipUtil::CheckDestRanges(pDoc, nColSize, nRowSize, aMark, aRanges);
476 : }
477 :
478 : }
479 :
480 0 : void ScCellShell::GetClipState( SfxItemSet& rSet )
481 : {
482 : // SID_PASTE
483 : // SID_PASTE_SPECIAL
484 : // SID_CLIPBOARD_FORMAT_ITEMS
485 :
486 0 : if ( !pImpl->m_pClipEvtLstnr )
487 : {
488 : // create listener
489 0 : pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) );
490 0 : pImpl->m_pClipEvtLstnr->acquire();
491 0 : Window* pWin = GetViewData()->GetActiveWin();
492 0 : pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, sal_True );
493 :
494 : // get initial state
495 0 : TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
496 0 : bPastePossible = lcl_IsCellPastePossible( aDataHelper );
497 : }
498 :
499 0 : bool bDisable = !bPastePossible;
500 :
501 : // cell protection / multiple selection
502 :
503 0 : if (!bDisable)
504 : {
505 0 : SCCOL nCol = GetViewData()->GetCurX();
506 0 : SCROW nRow = GetViewData()->GetCurY();
507 0 : SCTAB nTab = GetViewData()->GetTabNo();
508 0 : ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
509 0 : if (!pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow ))
510 0 : bDisable = true;
511 :
512 0 : if (!checkDestRanges(*GetViewData()))
513 0 : bDisable = true;
514 : }
515 :
516 0 : if (bDisable)
517 : {
518 0 : rSet.DisableItem( SID_PASTE );
519 0 : rSet.DisableItem( SID_PASTE_SPECIAL );
520 0 : rSet.DisableItem( SID_PASTE_ONLY_VALUE );
521 0 : rSet.DisableItem( SID_PASTE_ONLY_TEXT );
522 0 : rSet.DisableItem( SID_PASTE_ONLY_FORMULA );
523 0 : rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS );
524 : }
525 0 : else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SFX_ITEM_UNKNOWN )
526 : {
527 0 : SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
528 0 : GetPossibleClipboardFormats( aFormats );
529 0 : rSet.Put( aFormats );
530 : }
531 0 : }
532 :
533 : // only SID_HYPERLINK_GETLINK:
534 :
535 0 : void ScCellShell::GetHLinkState( SfxItemSet& rSet )
536 : {
537 : // always return an item (or inserting will be disabled)
538 : // if the cell at the cursor contains only a link, return that link
539 :
540 0 : SvxHyperlinkItem aHLinkItem;
541 0 : if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) )
542 : {
543 : //! put selected text into item?
544 : }
545 :
546 0 : rSet.Put(aHLinkItem);
547 0 : }
548 :
549 0 : void ScCellShell::GetState(SfxItemSet &rSet)
550 : {
551 0 : ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
552 0 : ScDocShell* pDocSh = GetViewData()->GetDocShell();
553 0 : ScViewData* pData = GetViewData();
554 0 : ScDocument* pDoc = pData->GetDocument();
555 0 : ScMarkData& rMark = pData->GetMarkData();
556 0 : SCCOL nPosX = pData->GetCurX();
557 0 : SCROW nPosY = pData->GetCurY();
558 0 : SCTAB nTab = pData->GetTabNo();
559 :
560 0 : SCTAB nTabCount = pDoc->GetTableCount();
561 0 : SCTAB nTabSelCount = rMark.GetSelectCount();
562 :
563 0 : SfxWhichIter aIter(rSet);
564 0 : sal_uInt16 nWhich = aIter.FirstWhich();
565 0 : while ( nWhich )
566 : {
567 0 : switch ( nWhich )
568 : {
569 : case SID_DETECTIVE_REFRESH:
570 0 : if (!pDoc->HasDetectiveOperations())
571 0 : rSet.DisableItem( nWhich );
572 0 : break;
573 :
574 : case SID_RANGE_ADDRESS:
575 : {
576 0 : ScRange aRange;
577 0 : if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
578 : {
579 0 : String aStr;
580 0 : sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D;
581 0 : aRange.Format(aStr,nFlags,pDoc);
582 0 : rSet.Put( SfxStringItem( nWhich, aStr ) );
583 : }
584 : }
585 0 : break;
586 :
587 : case SID_RANGE_NOTETEXT:
588 : {
589 : // always take cursor position, do not use top-left cell of selection
590 0 : String aNoteText;
591 0 : if ( const ScPostIt* pNote = pDoc->GetNotes(nTab)->findByAddress(nPosX, nPosY) )
592 0 : aNoteText = pNote->GetText();
593 0 : rSet.Put( SfxStringItem( nWhich, aNoteText ) );
594 : }
595 0 : break;
596 :
597 : case SID_RANGE_ROW:
598 0 : rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) );
599 0 : break;
600 :
601 : case SID_RANGE_COL:
602 0 : rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) );
603 0 : break;
604 :
605 : case SID_RANGE_TABLE:
606 0 : rSet.Put( SfxInt16Item( nWhich, nTab+1 ) );
607 0 : break;
608 :
609 : case SID_RANGE_VALUE:
610 : {
611 : double nValue;
612 0 : pDoc->GetValue( nPosX, nPosY, nTab, nValue );
613 0 : rSet.Put( ScDoubleItem( nWhich, nValue ) );
614 : }
615 0 : break;
616 :
617 : case SID_RANGE_FORMULA:
618 : {
619 0 : String aString;
620 0 : pDoc->GetFormula( nPosX, nPosY, nTab, aString );
621 0 : if( aString.Len() == 0 )
622 : {
623 0 : pDoc->GetInputString( nPosX, nPosY, nTab, aString );
624 : }
625 0 : rSet.Put( SfxStringItem( nWhich, aString ) );
626 : }
627 0 : break;
628 :
629 : case SID_RANGE_TEXTVALUE:
630 : {
631 0 : String aString;
632 0 : pDoc->GetString( nPosX, nPosY, nTab, aString );
633 0 : rSet.Put( SfxStringItem( nWhich, aString ) );
634 : }
635 0 : break;
636 :
637 : case SID_STATUS_SELMODE:
638 : {
639 : /* 0: STD Click cancels Sel
640 : * 1: ER Click extends selection
641 : * 2: ERG Click defines further selection
642 : */
643 0 : sal_uInt16 nMode = pTabViewShell->GetLockedModifiers();
644 :
645 0 : switch ( nMode )
646 : {
647 0 : case KEY_SHIFT: nMode = 1; break;
648 0 : case KEY_MOD1: nMode = 2; break; // Control-key
649 : case 0:
650 : default:
651 0 : nMode = 0;
652 : }
653 :
654 0 : rSet.Put( SfxUInt16Item( nWhich, nMode ) );
655 : }
656 0 : break;
657 :
658 : case SID_STATUS_DOCPOS:
659 : {
660 0 : String aStr( ScGlobal::GetRscString( STR_TABLE ) );
661 :
662 0 : aStr += ' ';
663 0 : aStr += String::CreateFromInt32( nTab + 1 );
664 0 : aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
665 0 : aStr += String::CreateFromInt32( nTabCount );
666 0 : rSet.Put( SfxStringItem( nWhich, aStr ) );
667 : }
668 0 : break;
669 :
670 : // calculations etc. with date/time/Fail/position&size together
671 :
672 : // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be
673 : // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl.
674 : case SID_TABLE_CELL:
675 : {
676 : // Test, if error under cursor
677 : // (not pDoc->GetErrCode, to avoid erasing circular references)
678 :
679 : // In interpreter may happen via rescheduled Basic
680 0 : if ( pDoc->IsInInterpreter() )
681 0 : rSet.Put( SfxStringItem( nWhich, rtl::OUString("...") ) );
682 : else
683 : {
684 0 : sal_uInt16 nErrCode = 0;
685 : ScBaseCell* pCell;
686 0 : pDoc->GetCell( nPosX, nPosY, nTab, pCell );
687 0 : if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
688 : {
689 0 : ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
690 0 : if (!pFCell->IsRunning())
691 0 : nErrCode = pFCell->GetErrCode();
692 : }
693 :
694 0 : String aFuncStr;
695 0 : if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
696 0 : rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
697 : }
698 : }
699 0 : break;
700 :
701 : case SID_DATA_SELECT:
702 : // HasSelectionData includes column content and validity,
703 : // page fields have to be checked separately.
704 0 : if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) &&
705 0 : !pTabViewShell->HasPageFieldDataAtCursor() )
706 0 : rSet.DisableItem( nWhich );
707 0 : break;
708 :
709 : case SID_STATUS_SUM:
710 : {
711 0 : String aFuncStr;
712 0 : if ( pTabViewShell->GetFunction( aFuncStr ) )
713 0 : rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
714 : }
715 0 : break;
716 :
717 : case FID_MERGE_ON:
718 0 : if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() )
719 0 : rSet.DisableItem( nWhich );
720 0 : break;
721 :
722 : case FID_MERGE_OFF:
723 0 : if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
724 0 : rSet.DisableItem( nWhich );
725 0 : break;
726 :
727 : case FID_MERGE_TOGGLE:
728 0 : if ( pDoc->GetChangeTrack() )
729 0 : rSet.DisableItem( nWhich );
730 : else
731 : {
732 0 : bool bCanMerge = pTabViewShell->TestMergeCells();
733 0 : bool bCanSplit = pTabViewShell->TestRemoveMerge();
734 0 : if( !bCanMerge && !bCanSplit )
735 0 : rSet.DisableItem( nWhich );
736 : else
737 0 : rSet.Put( SfxBoolItem( nWhich, bCanSplit ) );
738 : }
739 0 : break;
740 :
741 : case FID_INS_ROWBRK:
742 0 : if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) )
743 0 : rSet.DisableItem( nWhich );
744 0 : break;
745 :
746 : case FID_INS_COLBRK:
747 0 : if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) )
748 0 : rSet.DisableItem( nWhich );
749 0 : break;
750 :
751 : case FID_DEL_ROWBRK:
752 0 : if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 )
753 0 : rSet.DisableItem( nWhich );
754 0 : break;
755 :
756 : case FID_DEL_COLBRK:
757 0 : if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 )
758 0 : rSet.DisableItem( nWhich );
759 0 : break;
760 :
761 : case FID_FILL_TAB:
762 0 : if ( nTabSelCount < 2 )
763 0 : rSet.DisableItem( nWhich );
764 0 : break;
765 :
766 : case SID_SELECT_SCENARIO:
767 : {
768 0 : std::vector<String> aList;
769 0 : Color aDummyCol;
770 :
771 0 : if ( !pDoc->IsScenario(nTab) )
772 : {
773 0 : rtl::OUString aStr;
774 : sal_uInt16 nFlags;
775 0 : SCTAB nScTab = nTab + 1;
776 0 : String aProtect;
777 0 : bool bSheetProtected = pDoc->IsTabProtected(nTab);
778 :
779 0 : while ( pDoc->IsScenario(nScTab) )
780 : {
781 0 : pDoc->GetName( nScTab, aStr );
782 0 : aList.push_back(aStr);
783 0 : pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags );
784 0 : aList.push_back(aStr);
785 : // Protection is sal_True if both Sheet and Scenario are protected
786 0 : aProtect = (bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? '1' : '0';
787 0 : aList.push_back(aProtect);
788 0 : ++nScTab;
789 0 : }
790 : }
791 : else
792 : {
793 0 : rtl::OUString aComment;
794 : sal_uInt16 nDummyFlags;
795 0 : pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags );
796 : OSL_ENSURE( aList.empty(), "List not empty!" );
797 0 : aList.push_back(aComment);
798 : }
799 :
800 0 : rSet.Put( SfxStringListItem( nWhich, &aList ) );
801 : }
802 0 : break;
803 :
804 : case FID_ROW_HIDE:
805 : case FID_ROW_SHOW:
806 : case FID_COL_HIDE:
807 : case FID_COL_SHOW:
808 : case FID_COL_OPT_WIDTH:
809 : case FID_ROW_OPT_HEIGHT:
810 : case FID_DELETE_CELL:
811 0 : if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly())
812 0 : rSet.DisableItem( nWhich );
813 0 : break;
814 :
815 : case SID_OUTLINE_MAKE:
816 : {
817 0 : if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
818 0 : GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
819 : {
820 : //! test for data pilot operation
821 : }
822 0 : else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
823 : {
824 0 : rSet.DisableItem( nWhich );
825 : }
826 : }
827 0 : break;
828 : case SID_OUTLINE_SHOW:
829 0 : if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
830 0 : GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
831 : {
832 : //! test for data pilot operation
833 : }
834 0 : else if (!pTabViewShell->OutlinePossible(false))
835 0 : rSet.DisableItem( nWhich );
836 0 : break;
837 :
838 : case SID_OUTLINE_HIDE:
839 0 : if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
840 0 : GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
841 : {
842 : //! test for data pilot operation
843 : }
844 0 : else if (!pTabViewShell->OutlinePossible(sal_True))
845 0 : rSet.DisableItem( nWhich );
846 0 : break;
847 :
848 : case SID_OUTLINE_REMOVE:
849 : {
850 0 : if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
851 0 : GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
852 : {
853 : //! test for data pilot operation
854 : }
855 : else
856 : {
857 : sal_Bool bCol, bRow;
858 0 : pTabViewShell->TestRemoveOutline( bCol, bRow );
859 0 : if ( !bCol && !bRow )
860 0 : rSet.DisableItem( nWhich );
861 : }
862 : }
863 0 : break;
864 :
865 : case FID_COL_WIDTH:
866 : {
867 : //GetViewData()->GetCurX();
868 0 : SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) );
869 0 : rSet.Put( aWidthItem );
870 0 : if ( pDocSh->IsReadOnly())
871 0 : rSet.DisableItem( nWhich );
872 :
873 : //XXX disable if not conclusive
874 : }
875 0 : break;
876 :
877 : case FID_ROW_HEIGHT:
878 : {
879 : //GetViewData()->GetCurY();
880 0 : SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) );
881 0 : rSet.Put( aHeightItem );
882 : //XXX disable if not conclusive
883 0 : if ( pDocSh->IsReadOnly())
884 0 : rSet.DisableItem( nWhich );
885 : }
886 0 : break;
887 :
888 : case SID_DETECTIVE_FILLMODE:
889 0 : rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() ));
890 0 : break;
891 :
892 : case FID_INPUTLINE_STATUS:
893 : OSL_FAIL( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
894 0 : break;
895 :
896 : case SID_SCENARIOS: // scenarios:
897 0 : if (!(rMark.IsMarked() || rMark.IsMultiMarked())) // only, if something selected
898 0 : rSet.DisableItem( nWhich );
899 0 : break;
900 :
901 : case FID_NOTE_VISIBLE:
902 : {
903 0 : const ScPostIt* pNote = pDoc->GetNotes(nTab)->findByAddress(nPosX, nPosY);
904 0 : if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
905 0 : rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) );
906 : else
907 0 : rSet.DisableItem( nWhich );
908 : }
909 0 : break;
910 :
911 : case FID_HIDE_NOTE:
912 : case FID_SHOW_NOTE:
913 : {
914 0 : bool bEnable = false;
915 0 : bool bSearchForHidden = nWhich == FID_SHOW_NOTE;
916 0 : if (!rMark.IsMarked() && !rMark.IsMultiMarked())
917 : {
918 : // Check current cell
919 0 : const ScPostIt* pNote = pDoc->GetNotes(nTab)->findByAddress(nPosX, nPosY);
920 0 : if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
921 0 : if ( pNote->IsCaptionShown() != bSearchForHidden)
922 0 : bEnable = true;
923 : }
924 : else
925 : {
926 : // Check selection range
927 0 : ScRangeListRef aRangesRef;
928 0 : pData->GetMultiArea(aRangesRef);
929 0 : ScRangeList aRanges = *aRangesRef;
930 0 : size_t nRangeSize = aRanges.size();
931 :
932 0 : for ( size_t i = 0; i < nRangeSize && !bEnable; ++i )
933 : {
934 0 : const ScRange * pRange = aRanges[i];
935 0 : const SCROW nRow0 = pRange->aStart.Row();
936 0 : const SCROW nRow1 = pRange->aEnd.Row();
937 0 : const SCCOL nCol0 = pRange->aStart.Col();
938 0 : const SCCOL nCol1 = pRange->aEnd.Col();
939 0 : const SCTAB nRangeTab = pRange->aStart.Tab();
940 0 : const size_t nCellNumber = ( nRow1 - nRow0 ) * ( nCol1 - nCol0 );
941 0 : const ScNotes *pNotes = pDoc->GetNotes(nRangeTab);
942 :
943 0 : if ( nCellNumber < pNotes->size() )
944 : {
945 : // Check by each cell
946 0 : for ( SCROW nRow = nRow0; nRow <= nRow1 && !bEnable; ++nRow )
947 : {
948 0 : for ( SCCOL nCol = nCol0; nCol <= nCol1; ++nCol )
949 : {
950 0 : const ScPostIt* pNote = pNotes->findByAddress(nCol, nRow);
951 0 : if ( pNote && pDoc->IsBlockEditable( nRangeTab, nCol,nRow, nCol,nRow ) )
952 : {
953 0 : if ( pNote->IsCaptionShown() != bSearchForHidden)
954 : {
955 0 : bEnable = true;
956 0 : break;
957 : }
958 : }
959 : }
960 : }
961 : }
962 : else
963 : {
964 : // Check by each document note
965 0 : for (ScNotes::const_iterator itr = pNotes->begin(); itr != pNotes->end(); ++itr)
966 : {
967 0 : SCCOL nCol = itr->first.first;
968 0 : SCROW nRow = itr->first.second;
969 :
970 0 : if ( nCol <= nCol1 && nRow <= nRow1 && nCol >= nCol0 && nRow >= nRow0 )
971 : {
972 0 : if ( itr->second->IsCaptionShown() != bSearchForHidden)
973 : {
974 0 : bEnable = true; //note found
975 0 : break;
976 : }
977 : }
978 : }
979 : }
980 0 : }
981 : }
982 0 : if ( !bEnable )
983 0 : rSet.DisableItem( nWhich );
984 : }
985 0 : break;
986 :
987 : case SID_DELETE_NOTE:
988 : {
989 0 : bool bEnable = false;
990 0 : if ( rMark.IsMarked() || rMark.IsMultiMarked() )
991 : {
992 0 : if ( pDoc->IsSelectionEditable( rMark ) )
993 : {
994 : // look for at least one note in selection
995 0 : ScRangeList aRanges;
996 0 : rMark.FillRangeListWithMarks( &aRanges, false );
997 0 : size_t nCount = aRanges.size();
998 0 : for (size_t nPos = 0; nPos < nCount && !bEnable; ++nPos)
999 : {
1000 0 : ScNotes* pNotes = pDoc->GetNotes( aRanges[nPos]->aStart.Tab() );
1001 0 : for (ScNotes::const_iterator itr = pNotes->begin(); itr != pNotes->end(); ++itr)
1002 : {
1003 0 : SCCOL nCol = itr->first.first;
1004 0 : SCROW nRow = itr->first.second;
1005 :
1006 0 : if ( nCol <= aRanges[nPos]->aEnd.Col() && nRow <= aRanges[nPos]->aEnd.Row()
1007 0 : && nCol >= aRanges[nPos]->aStart.Col() && nRow >= aRanges[nPos]->aStart.Row() )
1008 : {
1009 0 : bEnable = true; //note found
1010 0 : break;
1011 : }
1012 : }
1013 0 : }
1014 : }
1015 : }
1016 : else
1017 : {
1018 0 : bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
1019 0 : pDoc->GetNotes(nTab)->findByAddress( nPosX, nPosY );
1020 : }
1021 0 : if ( !bEnable )
1022 0 : rSet.DisableItem( nWhich );
1023 : }
1024 0 : break;
1025 :
1026 : case SID_OPENDLG_CONSOLIDATE:
1027 : case SCITEM_CONSOLIDATEDATA:
1028 : {
1029 0 : if(pDoc->GetChangeTrack()!=NULL)
1030 0 : rSet.DisableItem( nWhich);
1031 : }
1032 0 : break;
1033 :
1034 : case SID_CHINESE_CONVERSION:
1035 : case SID_HANGUL_HANJA_CONVERSION:
1036 0 : ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich );
1037 0 : break;
1038 :
1039 : case FID_USE_NAME:
1040 : {
1041 0 : if ( pDocSh && pDocSh->IsDocShared() )
1042 0 : rSet.DisableItem( nWhich );
1043 : else
1044 : {
1045 0 : ScRange aRange;
1046 0 : if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
1047 0 : rSet.DisableItem( nWhich );
1048 : }
1049 : }
1050 0 : break;
1051 :
1052 : case FID_DEFINE_NAME:
1053 : case FID_INSERT_NAME:
1054 : case FID_ADD_NAME:
1055 : case SID_DEFINE_COLROWNAMERANGES:
1056 : {
1057 0 : if ( pDocSh && pDocSh->IsDocShared() )
1058 : {
1059 0 : rSet.DisableItem( nWhich );
1060 : }
1061 : }
1062 0 : break;
1063 :
1064 : case SID_SPELL_DIALOG:
1065 : {
1066 0 : if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) )
1067 : {
1068 0 : bool bVisible = false;
1069 0 : SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL );
1070 0 : if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) )
1071 : {
1072 0 : SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich );
1073 0 : Window* pWin = ( pChild ? pChild->GetWindow() : NULL );
1074 0 : if ( pWin && pWin->IsVisible() )
1075 : {
1076 0 : bVisible = true;
1077 : }
1078 : }
1079 0 : if ( !bVisible )
1080 : {
1081 0 : rSet.DisableItem( nWhich );
1082 : }
1083 : }
1084 : }
1085 0 : break;
1086 :
1087 : } // switch ( nWitch )
1088 0 : nWhich = aIter.NextWhich();
1089 0 : } // while ( nWitch )
1090 15 : }
1091 :
1092 : //------------------------------------------------------------------
1093 :
1094 :
1095 :
1096 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|