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 :
10 : #include <document.hxx>
11 : #include <clipcontext.hxx>
12 : #include <formulacell.hxx>
13 : #include <clipparam.hxx>
14 : #include <table.hxx>
15 : #include <tokenarray.hxx>
16 : #include <editutil.hxx>
17 : #include <listenercontext.hxx>
18 : #include <tokenstringcontext.hxx>
19 :
20 : // Add totally brand-new methods to this source file.
21 :
22 0 : bool ScDocument::IsMerged( const ScAddress& rPos ) const
23 : {
24 0 : const ScTable* pTab = FetchTable(rPos.Tab());
25 0 : if (!pTab)
26 0 : return false;
27 :
28 0 : return pTab->IsMerged(rPos.Col(), rPos.Row());
29 : }
30 :
31 0 : void ScDocument::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScMarkData& rMark )
32 : {
33 0 : SCTAB nClipTab = 0;
34 0 : const TableContainer& rClipTabs = rCxt.getClipDoc()->maTabs;
35 0 : SCTAB nClipTabCount = rClipTabs.size();
36 :
37 0 : for (SCTAB nTab = rCxt.getTabStart(); nTab <= rCxt.getTabEnd(); ++nTab)
38 : {
39 0 : ScTable* pTab = FetchTable(nTab);
40 0 : if (!pTab)
41 0 : continue;
42 :
43 0 : if (!rMark.GetTableSelect(nTab))
44 0 : continue;
45 :
46 0 : while (!rClipTabs[nClipTab])
47 0 : nClipTab = (nClipTab+1) % nClipTabCount;
48 :
49 0 : pTab->DeleteBeforeCopyFromClip(rCxt, *rClipTabs[nClipTab]);
50 :
51 0 : nClipTab = (nClipTab+1) % nClipTabCount;
52 : }
53 0 : }
54 :
55 0 : bool ScDocument::CopyOneCellFromClip(
56 : sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
57 : {
58 0 : ScDocument* pClipDoc = rCxt.getClipDoc();
59 0 : ScRange aClipRange = pClipDoc->GetClipParam().getWholeRange();
60 0 : if (aClipRange.aStart != aClipRange.aEnd)
61 : // The source is not really a single cell. Bail out.
62 0 : return false;
63 :
64 0 : ScAddress aSrcPos = aClipRange.aStart;
65 0 : if (pClipDoc->IsMerged(aSrcPos))
66 : // We don't handle merged source cell for this.
67 0 : return false;
68 :
69 0 : ScTable* pSrcTab = pClipDoc->FetchTable(aSrcPos.Tab());
70 0 : if (!pSrcTab)
71 0 : return false;
72 :
73 0 : ScCellValue& rSrcCell = rCxt.getSingleCell();
74 0 : if (rCxt.isAsLink())
75 : {
76 : ScSingleRefData aRef;
77 0 : aRef.InitAddress(aSrcPos);
78 0 : aRef.SetFlag3D(true);
79 :
80 0 : ScTokenArray aArr;
81 0 : aArr.AddSingleReference(aRef);
82 0 : rSrcCell.set(new ScFormulaCell(pClipDoc, aSrcPos, aArr));
83 : }
84 : else
85 : {
86 0 : rSrcCell.set(pClipDoc->GetRefCellValue(aSrcPos));
87 0 : const ScPatternAttr* pAttr = pClipDoc->GetPattern(aSrcPos);
88 0 : rCxt.setSingleCellPattern(pAttr);
89 :
90 : // Check the paste flag to see whether we want to paste this cell. If the
91 : // flag says we don't want to paste this cell, we'll return with true.
92 0 : sal_uInt16 nFlags = rCxt.getInsertFlag();
93 0 : bool bNumeric = (nFlags & IDF_VALUE) != 0;
94 0 : bool bDateTime = (nFlags & IDF_DATETIME) != 0;
95 0 : bool bString = (nFlags & IDF_STRING) != 0;
96 0 : bool bBoolean = (nFlags & IDF_SPECIAL_BOOLEAN) != 0;
97 0 : bool bFormula = (nFlags & IDF_FORMULA) != 0;
98 :
99 0 : switch (rSrcCell.meType)
100 : {
101 : case CELLTYPE_VALUE:
102 : {
103 0 : bool bPaste = rCxt.isDateCell(pSrcTab->aCol[aSrcPos.Col()], aSrcPos.Row()) ? bDateTime : bNumeric;
104 0 : if (!bPaste)
105 : // Don't paste this.
106 0 : rSrcCell.clear();
107 : }
108 0 : break;
109 : case CELLTYPE_STRING:
110 : case CELLTYPE_EDIT:
111 : {
112 0 : if (!bString)
113 : // Skip pasting.
114 0 : rSrcCell.clear();
115 : }
116 0 : break;
117 : case CELLTYPE_FORMULA:
118 : {
119 0 : if (bBoolean)
120 : {
121 : // Check if this formula cell is a boolean cell, and if so, go ahead and paste it.
122 0 : ScTokenArray* pCode = rSrcCell.mpFormula->GetCode();
123 0 : if (pCode && pCode->GetLen() == 1)
124 : {
125 0 : const formula::FormulaToken* p = pCode->First();
126 0 : if (p->GetOpCode() == ocTrue || p->GetOpCode() == ocFalse)
127 : // This is a boolean formula. Good.
128 0 : break;
129 : }
130 : }
131 :
132 0 : if (bFormula)
133 : // Good.
134 0 : break;
135 :
136 0 : sal_uInt16 nErr = rSrcCell.mpFormula->GetErrCode();
137 0 : if (nErr)
138 : {
139 : // error codes are cloned with values
140 0 : if (!bNumeric)
141 : // Error code is treated as numeric value. Don't paste it.
142 0 : rSrcCell.clear();
143 : }
144 0 : else if (rSrcCell.mpFormula->IsValue())
145 : {
146 0 : bool bPaste = rCxt.isDateCell(pSrcTab->aCol[aSrcPos.Col()], aSrcPos.Row()) ? bDateTime : bNumeric;
147 0 : if (!bPaste)
148 : {
149 : // Don't paste this.
150 0 : rSrcCell.clear();
151 0 : break;
152 : }
153 :
154 : // Turn this into a numeric cell.
155 0 : rSrcCell.set(rSrcCell.mpFormula->GetValue());
156 : }
157 0 : else if (bString)
158 : {
159 0 : svl::SharedString aStr = rSrcCell.mpFormula->GetString();
160 0 : if (aStr.isEmpty())
161 : {
162 : // do not clone empty string
163 0 : rSrcCell.clear();
164 0 : break;
165 : }
166 :
167 : // Turn this into a string or edit cell.
168 0 : if (rSrcCell.mpFormula->IsMultilineResult())
169 : {
170 : // TODO : Add shared string support to the edit engine to
171 : // make this process simpler.
172 0 : ScFieldEditEngine& rEngine = GetEditEngine();
173 0 : rEngine.SetText(rSrcCell.mpFormula->GetString().getString());
174 0 : boost::scoped_ptr<EditTextObject> pObj(rEngine.CreateTextObject());
175 0 : pObj->NormalizeString(GetSharedStringPool());
176 0 : rSrcCell.set(*pObj);
177 : }
178 : else
179 0 : rSrcCell.set(rSrcCell.mpFormula->GetString());
180 : }
181 : else
182 : // We don't want to paste this.
183 0 : rSrcCell.clear();
184 : }
185 0 : break;
186 : case CELLTYPE_NONE:
187 : default:
188 : // There is nothing to paste.
189 0 : rSrcCell.clear();
190 : }
191 : }
192 :
193 0 : if ((rCxt.getInsertFlag() & (IDF_NOTE | IDF_ADDNOTES)) != 0)
194 0 : rCxt.setSingleCellNote(pClipDoc->GetNote(aSrcPos));
195 :
196 : // All good. Proceed with the pasting.
197 :
198 0 : SCTAB nTabEnd = rCxt.getTabEnd();
199 0 : for (SCTAB i = rCxt.getTabStart(); i <= nTabEnd && i < static_cast<SCTAB>(maTabs.size()); ++i)
200 0 : maTabs[i]->CopyOneCellFromClip(rCxt, nCol1, nRow1, nCol2, nRow2);
201 :
202 0 : return true;
203 : }
204 :
205 0 : void ScDocument::SetValues( const ScAddress& rPos, const std::vector<double>& rVals )
206 : {
207 0 : ScTable* pTab = FetchTable(rPos.Tab());
208 0 : if (!pTab)
209 0 : return;
210 :
211 0 : pTab->SetValues(rPos.Col(), rPos.Row(), rVals);
212 : }
213 :
214 0 : void ScDocument::TransferCellValuesTo( const ScAddress& rTopPos, size_t nLen, sc::CellValues& rDest )
215 : {
216 0 : ScTable* pTab = FetchTable(rTopPos.Tab());
217 0 : if (!pTab)
218 0 : return;
219 :
220 0 : pTab->TransferCellValuesTo(rTopPos.Col(), rTopPos.Row(), nLen, rDest);
221 : }
222 :
223 0 : void ScDocument::CopyCellValuesFrom( const ScAddress& rTopPos, const sc::CellValues& rSrc )
224 : {
225 0 : ScTable* pTab = FetchTable(rTopPos.Tab());
226 0 : if (!pTab)
227 0 : return;
228 :
229 0 : pTab->CopyCellValuesFrom(rTopPos.Col(), rTopPos.Row(), rSrc);
230 : }
231 :
232 0 : void ScDocument::SetCalcConfig( const ScCalcConfig& rConfig )
233 : {
234 0 : maCalcConfig = rConfig;
235 0 : }
236 :
237 0 : const ScCalcConfig& ScDocument::GetCalcConfig() const
238 : {
239 0 : return maCalcConfig;
240 : }
241 :
242 0 : void ScDocument::PreprocessRangeNameUpdate()
243 : {
244 0 : sc::EndListeningContext aEndListenCxt(*this);
245 0 : sc::CompileFormulaContext aCompileCxt(this);
246 :
247 0 : TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
248 0 : for (; it != itEnd; ++it)
249 : {
250 0 : ScTable* p = *it;
251 0 : p->PreprocessRangeNameUpdate(aEndListenCxt, aCompileCxt);
252 0 : }
253 0 : }
254 :
255 0 : void ScDocument::PostprocessRangeNameUpdate()
256 : {
257 0 : sc::CompileFormulaContext aCompileCxt(this);
258 0 : TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
259 0 : for (; it != itEnd; ++it)
260 : {
261 0 : ScTable* p = *it;
262 0 : p->PostprocessRangeNameUpdate(aCompileCxt);
263 0 : }
264 0 : }
265 :
266 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|