1 /* This file is part of the KDE project
2 Copyright 2007,2009 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
3 Copyright 1999-2007 The KSpread Team <calligra-devel@kde.org>
4 Copyright 1998,1999 Torben Weis <weis@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20 */
21
22 #include "CopyCommand.h"
23
24 #include "CellStorage.h"
25 #include "Map.h"
26 #include "Region.h"
27 #include "RowColumnFormat.h"
28 #include "RowFormatStorage.h"
29 #include "Sheet.h"
30
31 using namespace Calligra::Sheets;
32
33 // era: encode references absolutely
saveAsXml(const Region & region,bool era)34 QDomDocument CopyCommand::saveAsXml(const Region& region, bool era)
35 {
36 QDomDocument xmlDoc("spreadsheet-snippet");
37 xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\""));
38 QDomElement root = xmlDoc.createElement("spreadsheet-snippet");
39 xmlDoc.appendChild(root);
40
41 // find the upper left corner of the selection
42 const QRect boundingRect = region.boundingRect();
43 int left = boundingRect.left();
44 int top = boundingRect.top();
45
46 // for tiling the clipboard content in the selection
47 root.setAttribute("rows", QString::number(boundingRect.height()));
48 root.setAttribute("columns", QString::number(boundingRect.width()));
49
50 const Region::ConstIterator end(region.constEnd());
51 for (Region::ConstIterator it = region.constBegin(); it != end; ++it) {
52 Sheet *const sheet = (*it)->sheet();
53 const QRect range = (*it)->rect();
54 CellStorage *const storage = sheet->cellStorage();
55
56 //
57 // Entire rows selected?
58 //
59 if ((*it)->isRow()) {
60 QDomElement rows = xmlDoc.createElement("rows");
61 rows.setAttribute("count", QString::number(range.height()));
62 rows.setAttribute("row", QString::number(range.top() - top + 1));
63 root.appendChild(rows);
64
65 // Save all cells.
66 for (int row = range.top(); row <= range.bottom(); ++row) {
67 Cell cell = storage->firstInRow(row);
68 for (; !cell.isNull(); cell = storage->nextInRow(cell.column(), cell.row())) {
69 if (!cell.isPartOfMerged()) {
70 root.appendChild(cell.save(xmlDoc, 0, top - 1, era));
71 }
72 }
73 }
74
75 // TODO Stefan: Inefficient, use cluster functionality
76 // Save the row formats if there are any
77 //const RowFormat* format;
78 for (int row = range.top(); row <= range.bottom(); ++row) {
79 if (!sheet->rowFormats()->isDefaultRow(row)) {
80 QDomElement e = RowFormat(sheet->rowFormats(), row).save(xmlDoc, top - 1);
81 if (!e.isNull()) {
82 rows.appendChild(e);
83 }
84 }
85 }
86 continue;
87 }
88
89 //
90 // Entire columns selected?
91 //
92 if ((*it)->isColumn()) {
93 QDomElement columns = xmlDoc.createElement("columns");
94 columns.setAttribute("count", QString::number(range.width()));
95 columns.setAttribute("column", QString::number(range.left() - left + 1));
96 root.appendChild(columns);
97
98 // Save all cells.
99 for (int col = range.left(); col <= range.right(); ++col) {
100 Cell cell = storage->firstInColumn(col);
101 for (; !cell.isNull(); cell = storage->nextInColumn(cell.column(), cell.row())) {
102 if (!cell.isPartOfMerged()) {
103 root.appendChild(cell.save(xmlDoc, left - 1, 0, era));
104 }
105 }
106 }
107
108 // TODO Stefan: Inefficient, use the cluster functionality
109 // Save the column formats if there are any
110 const ColumnFormat* format;
111 for (int col = range.left(); col <= range.right(); ++col) {
112 format = sheet->columnFormat(col);
113 if (format && !format->isDefault()) {
114 QDomElement e = format->save(xmlDoc, left - 1);
115 if (!e.isNull()) {
116 columns.appendChild(e);
117 }
118 }
119 }
120 continue;
121 }
122
123 // Save all cells.
124 Cell cell;
125 for (int row = range.top(); row <= range.bottom(); ++row) {
126 if (range.left() == 1) {
127 cell = storage->firstInRow(row);
128 } else {
129 cell = storage->nextInRow(range.left() - 1, row);
130 }
131 while (!cell.isNull() && cell.column() >= range.left() && cell.column() <= range.right()) {
132 if (!cell.isPartOfMerged()) {
133 root.appendChild(cell.save(xmlDoc, left - 1, top - 1, era));
134 }
135 cell = storage->nextInRow(cell.column(), cell.row());
136 }
137 }
138 }
139 return xmlDoc;
140 }
141
cellAsText(const Cell & cell,bool addTab)142 static QString cellAsText(const Cell& cell, bool addTab)
143 {
144 QString result;
145 if (!cell.isDefault()) {
146 result += cell.displayText();
147 }
148 if (addTab) {
149 result += '\t';
150 }
151 return result;
152 }
153
saveAsPlainText(const Region & region)154 QString CopyCommand::saveAsPlainText(const Region ®ion)
155 {
156 // Only one cell selected? => copy active cell
157 if (region.isSingular()) {
158 const Cell cell(region.firstSheet(), region.firstRange().topLeft());
159 return cell.displayText();
160 }
161
162 QString result;
163 Region::ConstIterator end(region.constEnd());
164 for (Region::ConstIterator it(region.constBegin()); it != end; ++it) {
165 if (result.length()) result += QLatin1Char('\n');
166 Region::Element *el = *it;
167 QRect used = el->sheet()->usedArea (true);
168 QRect rect = el->rect().intersected (used);
169 for (int row = rect.top(); row <= rect.bottom(); ++row) {
170 for (int col = rect.left(); col <= rect.right(); ++col) {
171 Cell cell (el->sheet(), col, row);
172 result += cellAsText (cell, col != rect.right());
173 }
174 result += QLatin1Char('\n');
175 }
176 }
177 return result;
178 }
179
saveAsHtml(const Region & region)180 QDomDocument CopyCommand::saveAsHtml(const Region ®ion)
181 {
182 QDomDocument doc("spreadsheet-html");
183 QDomElement html = doc.createElement("html");
184 doc.appendChild(html);
185 QDomElement body = doc.createElement("body");
186 html.appendChild(body);
187 QDomElement table = doc.createElement("table");
188 body.appendChild(table);
189
190 const Region::ConstIterator end(region.constEnd());
191 for (Region::ConstIterator it(region.constBegin()); it != end; ++it) {
192 Sheet *const sheet = (*it)->sheet();
193 const QRect range = (*it)->rect();
194
195 // TODO
196 Q_UNUSED(sheet);
197 Q_UNUSED(range);
198 }
199 return doc;
200 }
201
saveAsCSV(const Region & region)202 QString CopyCommand::saveAsCSV(const Region ®ion)
203 {
204 // TODO
205 Q_UNUSED(region);
206 return QString();
207 }
208