File indexing completed on 2024-05-12 16:35:39
0001 /* This file is part of the KDE project 0002 Copyright 1998-2016 The Calligra Team <calligra-devel@kde.org> 0003 Copyright 2016 Tomas Mecir <mecirt@gmail.com> 0004 Copyright 2010 Marijn Kruisselbrink <mkruisselbrink@kde.org> 0005 Copyright 2007 Stefan Nikolaus <stefan.nikolaus@kdemail.net> 0006 Copyright 2007 Thorsten Zachmann <zachmann@kde.org> 0007 Copyright 2005-2006 Inge Wallin <inge@lysator.liu.se> 0008 Copyright 2004 Ariya Hidayat <ariya@kde.org> 0009 Copyright 2002-2003 Norbert Andres <nandres@web.de> 0010 Copyright 2000-2002 Laurent Montel <montel@kde.org> 0011 Copyright 2002 John Dailey <dailey@vt.edu> 0012 Copyright 2002 Phillip Mueller <philipp.mueller@gmx.de> 0013 Copyright 2000 Werner Trobin <trobin@kde.org> 0014 Copyright 1999-2000 Simon Hausmann <hausmann@kde.org> 0015 Copyright 1999 David Faure <faure@kde.org> 0016 Copyright 1998-2000 Torben Weis <weis@kde.org> 0017 0018 This library is free software; you can redistribute it and/or 0019 modify it under the terms of the GNU Library General Public 0020 License as published by the Free Software Foundation; either 0021 version 2 of the License, or (at your option) any later version. 0022 0023 This library is distributed in the hope that it will be useful, 0024 but WITHOUT ANY WARRANTY; without even the implied warranty of 0025 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0026 Library General Public License for more details. 0027 0028 You should have received a copy of the GNU Library General Public License 0029 along with this library; see the file COPYING.LIB. If not, write to 0030 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0031 Boston, MA 02110-1301, USA. 0032 */ 0033 0034 #include "SheetsOdf.h" 0035 #include "SheetsOdfPrivate.h" 0036 #include "Region.h" 0037 0038 // This file contains functionality to load/save regions 0039 0040 namespace Calligra { 0041 namespace Sheets { 0042 0043 static void append(const QChar *from, const QChar *to, QChar **dest) 0044 { 0045 while (from < to) { 0046 **dest = *from; 0047 ++from; 0048 ++*dest; 0049 } 0050 } 0051 0052 void Odf::loadRegion(const QChar *&data, const QChar *&end, QChar *&out) 0053 { 0054 enum { Start, InQuotes } state = Start; 0055 0056 if (*data == QChar('$', 0)) { 0057 ++data; 0058 } 0059 0060 bool isRange = false; 0061 0062 const QChar *pos = data; 0063 while (data < end) { 0064 switch (state) { 0065 case Start: 0066 switch (data->unicode()) { 0067 case '\'': // quoted sheet name or named area 0068 state = InQuotes; 0069 break; 0070 case '.': // sheet name separator 0071 if (pos != data && !isRange) { 0072 append(pos, data, &out); 0073 *out = QChar('!', 0); 0074 ++out; 0075 } 0076 pos = data; 0077 ++pos; 0078 break; 0079 case ':': { // cell separator 0080 isRange = true; 0081 append(pos, data, &out); 0082 *out = *data; // append : 0083 ++out; 0084 const QChar * next = data + 1; 0085 if (!next->isNull()) { 0086 const QChar * nextnext = next + 1; 0087 if (!nextnext->isNull() && *next == QChar('$', 0) && *nextnext != QChar('.', 0)) { 0088 ++data; 0089 } 0090 } 0091 pos = data + 1; 0092 } break; 0093 case ' ': // range separator 0094 append(pos, data, &out); 0095 *out = QChar(';', 0); 0096 ++out; 0097 pos = data; 0098 break; 0099 default: 0100 break; 0101 } 0102 break; 0103 case InQuotes: 0104 if (data->unicode() == '\'') { 0105 // an escaped apostrophe? 0106 // As long as Calligra Sheets does not support fixed sheets eat the dollar sign. 0107 const QChar * next = data + 1; 0108 if (!next->isNull() && *next == QChar('\'', 0)) { 0109 ++data; 0110 } 0111 else { // the end 0112 state = Start; 0113 } 0114 } 0115 break; 0116 } 0117 ++data; 0118 } 0119 append(pos, data, &out); 0120 } 0121 0122 QString Odf::loadRegion(const QString& expression) 0123 { 0124 QString result; 0125 QString temp; 0126 bool isRange = false; 0127 enum { Start, InQuotes } state = Start; 0128 int i = 0; 0129 // NOTE Stefan: As long as Calligra Sheets does not support fixed sheets eat the dollar sign. 0130 if (expression[i] == '$') 0131 ++i; 0132 while (i < expression.count()) { 0133 switch (state) { 0134 case Start: { 0135 if (expression[i] == '\'') { // quoted sheet name or named area 0136 temp.append(expression[i]); 0137 state = InQuotes; 0138 } else if (expression[i] == '.') { // sheet name separator 0139 // was there already a sheet name? 0140 if (!temp.isEmpty() && !isRange) { 0141 result.append(temp); 0142 result.append('!'); 0143 } 0144 temp.clear(); 0145 } else if (expression[i] == ':') { // cell separator 0146 isRange = true; 0147 result.append(temp); 0148 result.append(':'); 0149 temp.clear(); 0150 // NOTE Stefan: As long as Calligra Sheets does not support fixed sheets eat the dollar sign. 0151 if (i + 2 < expression.count() && expression[i+1] == '$' && expression[i+2] != '.') 0152 ++i; 0153 } else if (expression[i] == ' ') { // range separator 0154 result.append(temp); 0155 result.append(';'); 0156 temp.clear(); 0157 } else 0158 temp.append(expression[i]); 0159 ++i; 0160 break; 0161 } 0162 case InQuotes: { 0163 temp.append(expression[i]); 0164 if (expression[i] == '\'') { 0165 // an escaped apostrophe? 0166 if (i + 1 < expression.count() && expression[i+1] == '\'') 0167 ++i; // eat it 0168 else // the end 0169 state = Start; 0170 } 0171 ++i; 0172 break; 0173 } 0174 } 0175 } 0176 return result + temp; 0177 } 0178 0179 QString Odf::saveRegion(const QString& expression) 0180 { 0181 QString result; 0182 QString sheetName; 0183 QString temp; 0184 enum { Start, InQuotes } state = Start; 0185 int i = 0; 0186 while (i < expression.count()) { 0187 switch (state) { 0188 case Start: { 0189 if (expression[i] == '\'') { 0190 temp.append(expression[i]); 0191 state = InQuotes; 0192 } else if (expression[i] == '!') { // sheet name separator 0193 // There has to be a sheet name. 0194 if (temp.isEmpty()) 0195 return expression; // error 0196 if (temp.count() > 2 && (temp[0] != '\'' && temp[temp.count()-1] != '\'')) { 0197 temp.replace('\'', "''"); 0198 if (temp.contains(' ') || temp.contains('.') || 0199 temp.contains(';') || temp.contains('!') || 0200 temp.contains('$') || temp.contains(']')) 0201 temp = '\'' + temp + '\''; 0202 } 0203 sheetName = temp; 0204 result.append(temp); 0205 result.append('.'); 0206 temp.clear(); 0207 } else if (expression[i] == ':') { // cell separator 0208 if (result.isEmpty()) 0209 result = '.'; 0210 result.append(temp); 0211 result.append(':'); 0212 result.append(sheetName); 0213 result.append('.'); 0214 temp.clear(); 0215 } else if (expression[i] == ';') { // range separator 0216 result.append(temp); 0217 result.append(' '); 0218 temp.clear(); 0219 } else 0220 temp.append(expression[i]); 0221 ++i; 0222 break; 0223 } 0224 case InQuotes: { 0225 temp.append(expression[i]); 0226 if (expression[i] == '\'') { 0227 // an escaped apostrophe? 0228 if (i + 1 < expression.count() && expression[i+1] == '\'') 0229 ++i; // eat it 0230 else // the end 0231 state = Start; 0232 } 0233 ++i; 0234 break; 0235 } 0236 } 0237 } 0238 if (result.isEmpty()) 0239 result = '.'; 0240 return result + temp; 0241 } 0242 0243 QString Odf::saveRegion(Region *region) 0244 { 0245 return saveRegion(region->name()); 0246 } 0247 0248 0249 } // Sheets 0250 } // Calligra 0251