File indexing completed on 2024-05-12 16:35:36
0001 /* This file is part of the KDE project 0002 0003 Copyright 2006 Fredrik Edemar <f_edemar@linux.se> 0004 Copyright 2003 Lukas Tinkl <lukas@kde.org> 0005 Copyright 2000, 2002-2003 Laurent Montel <montel@kde.org> 0006 Copyright 2001-2003 Philipp Mueller <philipp.mueller@gmx.de> 0007 Copyright 2003 Joseph Wenninger <jowenn@kde.org> 0008 Copyright 2002 Ariya Hidayat <ariya@kde.org> 0009 Copyright 2002 Harri Porten <porten@kde.org> 0010 Copyright 2002 John Dailey <dailey@vt.edu> 0011 Copyright 2001 Simon Hausmann <hausmann@kde.org> 0012 Copyright 2000 Werner Trobin <trobin@kde.org> 0013 Copyright 1999 Torben Weis <weis@kde.org> 0014 0015 This library is free software; you can redistribute it and/or 0016 modify it under the terms of the GNU Library General Public 0017 License as published by the Free Software Foundation; either 0018 version 2 of the License, or (at your option) any later version. 0019 0020 This library is distributed in the hope that it will be useful, 0021 but WITHOUT ANY WARRANTY; without even the implied warranty of 0022 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0023 Library General Public License for more details. 0024 0025 You should have received a copy of the GNU Library General Public License 0026 along with this library; see the file COPYING.LIB. If not, write to 0027 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0028 Boston, MA 02110-1301, USA. 0029 */ 0030 0031 // Local 0032 #include "SheetAdaptor.h" 0033 0034 #include "SheetsDebug.h" 0035 #include "Damages.h" 0036 #include "Map.h" 0037 #include "PrintSettings.h" 0038 #include "Sheet.h" 0039 #include "SheetPrint.h" 0040 #include "Region.h" 0041 #include "ValueConverter.h" 0042 0043 // commands 0044 #include "commands/DataManipulators.h" 0045 #include "commands/RowColumnManipulators.h" 0046 0047 #include <KoUnit.h> 0048 0049 using namespace Calligra::Sheets; 0050 0051 SheetAdaptor::SheetAdaptor(Sheet* t) 0052 : QDBusAbstractAdaptor(t) 0053 { 0054 setAutoRelaySignals(false); 0055 m_sheet = t; 0056 connect(m_sheet->map(), SIGNAL(damagesFlushed(QList<Damage*>)), 0057 this, SLOT(handleDamages(QList<Damage*>))); 0058 } 0059 0060 SheetAdaptor::~SheetAdaptor() 0061 { 0062 } 0063 0064 QString SheetAdaptor::cellName(int x, int y) 0065 { 0066 /* sebsauer 20061206: commented out cause if someone starts to believe that 0067 counting starts by 0,0 then they may very surprised why the first col/row 0068 got returned twice. That happened to me and I was believing that's a Calligra Sheets 0069 bug too :-( 0070 // if someone calls us with either x or y 0 they _most_ most likely don't 0071 // know that the cell counting starts with 1 (Simon) 0072 // P.S.: I made that mistake for weeks and already started looking for the 0073 // "bug" in Calligra Sheets ;-) 0074 if ( x == 0 ) x = 1; 0075 if ( y == 0 ) y = 1; 0076 */ 0077 return Cell::name(x, y); 0078 } 0079 0080 int SheetAdaptor::cellRow(const QString& cellname) 0081 { 0082 return cellLocation(cellname).x(); 0083 } 0084 0085 int SheetAdaptor::cellColumn(const QString& cellname) 0086 { 0087 return cellLocation(cellname).y(); 0088 } 0089 0090 QPoint SheetAdaptor::cellLocation(const QString& cellname) 0091 { 0092 const Region region(cellname, m_sheet->map(), m_sheet); 0093 if (region.firstRange().isNull()) 0094 return QPoint(); 0095 return region.firstRange().topLeft(); 0096 } 0097 0098 QString SheetAdaptor::text(int x, int y) 0099 { 0100 Cell cell = Cell(m_sheet, x, y); 0101 return cell.userInput(); 0102 } 0103 0104 QString SheetAdaptor::text(const QString& cellname) 0105 { 0106 const QPoint location = cellLocation(cellname); 0107 return text(location.x(), location.y()); 0108 } 0109 0110 bool SheetAdaptor::setText(int x, int y, const QString& text, bool parse) 0111 { 0112 //FIXME: there is some problem with asString parameter, when it's set 0113 //to true Calligra Sheets says: ASSERT: "f" in Dependencies.cpp (621) 0114 //kspread: Cell at row 6, col 1 marked as formula, but formula is NULL 0115 0116 Calligra::Sheets::DataManipulator *dm = new Calligra::Sheets::DataManipulator(); 0117 dm->setSheet(m_sheet); 0118 dm->setValue(Value(text)); 0119 dm->setParsing(parse); 0120 dm->add(QPoint(x, y)); 0121 return dm->execute(); 0122 } 0123 0124 bool SheetAdaptor::setText(const QString& cellname, const QString& text, bool parse) 0125 { 0126 const QPoint location = cellLocation(cellname); 0127 return setText(location.x(), location.y(), text, parse); 0128 } 0129 0130 QVariant valueToVariant(const Calligra::Sheets::Value& value, Sheet* sheet) 0131 { 0132 //Should we use following value-format enums here? 0133 //fmt_None, fmt_Boolean, fmt_Number, fmt_Percent, fmt_Money, fmt_DateTime, fmt_Date, fmt_Time, fmt_String 0134 switch (value.type()) { 0135 case Calligra::Sheets::Value::Empty: 0136 return QVariant(); 0137 case Calligra::Sheets::Value::Boolean: 0138 return QVariant(value.asBoolean()); 0139 case Calligra::Sheets::Value::Integer: 0140 return static_cast<qint64>(value.asInteger()); 0141 case Calligra::Sheets::Value::Float: 0142 return (double) numToDouble(value.asFloat()); 0143 case Calligra::Sheets::Value::Complex: 0144 return sheet->map()->converter()->asString(value).asString(); 0145 case Calligra::Sheets::Value::String: 0146 return value.asString(); 0147 case Calligra::Sheets::Value::Array: { 0148 QVariantList colarray; 0149 for (uint j = 0; j < value.rows(); j++) { 0150 QVariantList rowarray; 0151 for (uint i = 0; i < value.columns(); i++) { 0152 Calligra::Sheets::Value v = value.element(i, j); 0153 rowarray.append(valueToVariant(v, sheet)); 0154 } 0155 colarray.append(rowarray); 0156 } 0157 return colarray; 0158 } 0159 break; 0160 case Calligra::Sheets::Value::CellRange: 0161 //FIXME: not yet used 0162 return QVariant(); 0163 case Calligra::Sheets::Value::Error: 0164 return QVariant(); 0165 } 0166 return QVariant(); 0167 } 0168 0169 QVariant SheetAdaptor::value(int x, int y) 0170 { 0171 Cell cell = Cell(m_sheet, x, y); 0172 return valueToVariant(cell.value(), m_sheet); 0173 } 0174 0175 QVariant SheetAdaptor::value(const QString& cellname) 0176 { 0177 const QPoint location = cellLocation(cellname); 0178 return value(location.x(), location.y()); 0179 } 0180 0181 bool SheetAdaptor::setValue(int x, int y, const QVariant& value) 0182 { 0183 Cell cell = Cell(m_sheet, x, y); 0184 if (! cell) return false; 0185 Calligra::Sheets::Value v = cell.value(); 0186 switch (value.type()) { 0187 case QVariant::Bool: v = Value(value.toBool()); break; 0188 case QVariant::ULongLong: v = Value(value.toLongLong()); break; 0189 case QVariant::Int: v = Value(value.toInt()); break; 0190 case QVariant::Double: v = Value(value.toDouble()); break; 0191 case QVariant::String: v = Value(value.toString()); break; 0192 //case QVariant::Date: v = Value( value.toDate() ); break; 0193 //case QVariant::Time: v = Value( value.toTime() ); break; 0194 //case QVariant::DateTime: v = Value( value.toDateTime() ); break; 0195 default: return false; 0196 } 0197 return true; 0198 } 0199 0200 bool SheetAdaptor::setValue(const QString& cellname, const QVariant& value) 0201 { 0202 const QPoint location = cellLocation(cellname); 0203 return setValue(location.x(), location.y(), value); 0204 } 0205 0206 #if 0 0207 QString SheetAdaptor::column(int _col) 0208 { 0209 //First col number = 1 0210 if (_col < 1) 0211 return QString(); 0212 return "";//m_sheet->nonDefaultColumnFormat( _col )->getName/*objectName*/();/*dcopObject()->objId()*/ 0213 0214 } 0215 0216 QString SheetAdaptor::row(int _row) 0217 { 0218 //First row number = 1 0219 if (_row < 1) 0220 return QString(); 0221 return "";//m_sheet->nonDefaultRowFormat( _row )->/*dcopObject()->*/getName/*objectName*/(); 0222 } 0223 #endif 0224 0225 QString SheetAdaptor::sheetName() const 0226 { 0227 return m_sheet->sheetName(); 0228 } 0229 0230 bool SheetAdaptor::setSheetName(const QString & name) 0231 { 0232 return m_sheet->setSheetName(name); 0233 } 0234 0235 int SheetAdaptor::lastColumn() const 0236 { 0237 return m_sheet->usedArea().width(); 0238 } 0239 0240 int SheetAdaptor::lastRow() const 0241 { 0242 return m_sheet->usedArea().height(); 0243 } 0244 0245 // bool SheetAdaptor::processDynamic( const DCOPCString& fun, const QByteArray&/*data*/, 0246 // DCOPCString& replyType, QByteArray &replyData ) 0247 // { 0248 // debugSheets <<"Calling '" << fun.data() << '\''; 0249 // // Does the name follow the pattern "foobar()" ? 0250 // uint len = fun.length(); 0251 // if ( len < 3 ) 0252 // return false; 0253 // 0254 // if ( fun[ len - 1 ] != ')' || fun[ len - 2 ] != '(' ) 0255 // return false; 0256 // 0257 // // Is the function name a valid cell like "B5" ? 0258 // Point p( fun.left( len - 2 ).data() ); 0259 // if ( !p.isValid() ) 0260 // return false; 0261 // 0262 // DCOPCString str = objId() + '/' + fun.left( len - 2 ); 0263 // 0264 // replyType = "DCOPRef"; 0265 // QDataStream out( &replyData,QIODevice::WriteOnly ); 0266 // out.setVersion(QDataStream::Qt_3_1); 0267 // out << DCOPRef( kapp->dcopClient()->appId(), str ); 0268 // return true; 0269 // } 0270 0271 void SheetAdaptor::insertColumn(int col, int nbCol) 0272 { 0273 InsertDeleteColumnManipulator* manipulator = new InsertDeleteColumnManipulator(); 0274 manipulator->setSheet(m_sheet); 0275 manipulator->add(Region(QRect(col, 1, nbCol, 1))); 0276 manipulator->execute(); 0277 } 0278 0279 void SheetAdaptor::insertRow(int row, int nbRow) 0280 { 0281 InsertDeleteRowManipulator* manipulator = new InsertDeleteRowManipulator(); 0282 manipulator->setSheet(m_sheet); 0283 manipulator->add(Region(QRect(1, row, 1, nbRow))); 0284 manipulator->execute(); 0285 } 0286 0287 void SheetAdaptor::removeColumn(int col, int nbCol) 0288 { 0289 InsertDeleteColumnManipulator* manipulator = new InsertDeleteColumnManipulator(); 0290 manipulator->setSheet(m_sheet); 0291 manipulator->setReverse(true); 0292 manipulator->add(Region(QRect(col, 1, nbCol, 1))); 0293 manipulator->execute(); 0294 } 0295 0296 void SheetAdaptor::removeRow(int row, int nbRow) 0297 { 0298 InsertDeleteRowManipulator* manipulator = new InsertDeleteRowManipulator(); 0299 manipulator->setSheet(m_sheet); 0300 manipulator->setReverse(true); 0301 manipulator->add(Region(QRect(1, row, 1, nbRow))); 0302 manipulator->execute(); 0303 } 0304 0305 bool SheetAdaptor::isHidden() const 0306 { 0307 return m_sheet->isHidden(); 0308 } 0309 0310 void SheetAdaptor::setHidden(bool hidden) 0311 { 0312 m_sheet->setHidden(hidden); 0313 } 0314 0315 #if 0 0316 bool SheetAdaptor::showGrid() const 0317 { 0318 return m_sheet->getShowGrid(); 0319 } 0320 0321 bool SheetAdaptor::showFormula() const 0322 { 0323 return m_sheet->getShowFormula(); 0324 } 0325 0326 bool SheetAdaptor::lcMode() const 0327 { 0328 return m_sheet->getLcMode(); 0329 } 0330 0331 bool SheetAdaptor::autoCalc() const 0332 { 0333 return m_sheet->isAutoCalculationEnabled(); 0334 } 0335 0336 bool SheetAdaptor::showColumnNumber() const 0337 { 0338 return m_sheet->getShowColumnNumber(); 0339 } 0340 0341 bool SheetAdaptor::hideZero() const 0342 { 0343 return m_sheet->getHideZero(); 0344 } 0345 0346 bool SheetAdaptor::firstLetterUpper() const 0347 { 0348 return m_sheet->getFirstLetterUpper(); 0349 } 0350 0351 void SheetAdaptor::setShowPageOutline(bool b) 0352 { 0353 m_sheet->setShowPageOutline(b); 0354 m_sheet->doc()->updateBorderButton(); 0355 } 0356 #endif 0357 0358 float SheetAdaptor::paperHeight()const 0359 { 0360 return m_sheet->print()->settings()->pageLayout().height; 0361 } 0362 0363 void SheetAdaptor::setPrinterHeight(float height) 0364 { 0365 KoPageLayout pageLayout = m_sheet->print()->settings()->pageLayout(); 0366 pageLayout.format = KoPageFormat::CustomSize; 0367 pageLayout.height = MM_TO_POINT(height); 0368 m_sheet->print()->settings()->setPageLayout(pageLayout); 0369 } 0370 0371 float SheetAdaptor::paperWidth()const 0372 { 0373 return m_sheet->print()->settings()->pageLayout().width; 0374 } 0375 0376 void SheetAdaptor::setPaperWidth(float width) 0377 { 0378 KoPageLayout pageLayout = m_sheet->print()->settings()->pageLayout(); 0379 pageLayout.format = KoPageFormat::CustomSize; 0380 pageLayout.width = MM_TO_POINT(width); 0381 m_sheet->print()->settings()->setPageLayout(pageLayout); 0382 } 0383 0384 float SheetAdaptor::paperLeftBorder()const 0385 { 0386 return m_sheet->print()->settings()->pageLayout().leftMargin; 0387 } 0388 0389 float SheetAdaptor::paperRightBorder()const 0390 { 0391 return m_sheet->print()->settings()->pageLayout().rightMargin; 0392 } 0393 0394 float SheetAdaptor::paperTopBorder()const 0395 { 0396 return m_sheet->print()->settings()->pageLayout().topMargin; 0397 } 0398 0399 float SheetAdaptor::paperBottomBorder()const 0400 { 0401 return m_sheet->print()->settings()->pageLayout().bottomMargin; 0402 } 0403 0404 QString SheetAdaptor::paperFormat() const 0405 { 0406 return m_sheet->printSettings()->paperFormatString(); 0407 } 0408 0409 QString SheetAdaptor::paperOrientation() const 0410 { 0411 return m_sheet->printSettings()->orientationString(); 0412 } 0413 0414 void SheetAdaptor::setPaperLayout(float leftBorder, float topBorder, 0415 float rightBorder, float bottomBoder, 0416 const QString& format, const QString& orientation) 0417 { 0418 KoPageLayout pageLayout; 0419 pageLayout.format = KoPageFormat::formatFromString(format); 0420 pageLayout.orientation = (orientation == "Portrait") 0421 ? KoPageFormat::Portrait : KoPageFormat::Landscape; 0422 pageLayout.leftMargin = leftBorder; 0423 pageLayout.rightMargin = rightBorder; 0424 pageLayout.topMargin = topBorder; 0425 pageLayout.bottomMargin = bottomBoder; 0426 m_sheet->print()->settings()->setPageLayout(pageLayout); 0427 } 0428 0429 #if 0 0430 QString SheetAdaptor::printHeadLeft()const 0431 { 0432 return m_sheet->print()->headLeft(); 0433 } 0434 0435 QString SheetAdaptor::printHeadMid()const 0436 { 0437 return m_sheet->print()->headMid(); 0438 } 0439 0440 QString SheetAdaptor::printHeadRight()const 0441 { 0442 return m_sheet->print()->headRight(); 0443 } 0444 0445 QString SheetAdaptor::printFootLeft()const 0446 { 0447 return m_sheet->print()->footLeft(); 0448 } 0449 0450 QString SheetAdaptor::printFootMid()const 0451 { 0452 return m_sheet->print()->footMid(); 0453 } 0454 0455 QString SheetAdaptor::printFootRight()const 0456 { 0457 return m_sheet->print()->footRight(); 0458 } 0459 0460 void SheetAdaptor::setPrintHeaderLeft(const QString & text) 0461 { 0462 m_sheet->print()->setHeadFootLine(text, headMid(), headRight(), 0463 footLeft(), footMid(), footRight()); 0464 } 0465 0466 void SheetAdaptor::setPrintHeaderMiddle(const QString & text) 0467 { 0468 m_sheet->print()->setHeadFootLine(headLeft(), text, headRight(), 0469 footLeft(), footMid(), footRight()); 0470 0471 } 0472 0473 void SheetAdaptor::setPrintHeaderRight(const QString & text) 0474 { 0475 m_sheet->print()->setHeadFootLine(headLeft(), headMid(), text, 0476 footLeft(), footMid(), footRight()); 0477 } 0478 0479 void SheetAdaptor::setPrintFooterLeft(const QString & text) 0480 { 0481 m_sheet->print()->setHeadFootLine(headLeft(), headMid(), headRight(), 0482 text, footMid(), footRight()); 0483 } 0484 0485 void SheetAdaptor::setPrintFooterMiddle(const QString & text) 0486 { 0487 m_sheet->print()->setHeadFootLine(headLeft(), headMid(), headRight(), 0488 footLeft(), text, footRight()); 0489 } 0490 0491 void SheetAdaptor::setPrintFooterRight(const QString & text) 0492 { 0493 m_sheet->print()->setHeadFootLine(headLeft(), headMid(), headRight(), 0494 footLeft(), footMid(), text); 0495 } 0496 #endif 0497 0498 bool SheetAdaptor::checkPassword(const QByteArray& passwd) const 0499 { 0500 return m_sheet->checkPassword(passwd); 0501 } 0502 0503 bool SheetAdaptor::isProtected() const 0504 { 0505 return m_sheet->isProtected(); 0506 } 0507 0508 void SheetAdaptor::setProtected(const QByteArray& passwd) 0509 { 0510 m_sheet->setProtected(passwd); 0511 } 0512 0513 void SheetAdaptor::handleDamages(const QList<Damage*>& damages) 0514 { 0515 const QList<Damage*>::ConstIterator end(damages.end()); 0516 for (QList<Damage*>::ConstIterator it = damages.begin(); it != end; ++it) { 0517 const Damage *const damage = *it; 0518 if (!damage) { 0519 continue; 0520 } 0521 if (damage->type() == Damage::Sheet) { 0522 const SheetDamage *const sheetDamage = static_cast<const SheetDamage *>(damage); 0523 // Only process the sheet this adaptor works for. 0524 if (sheetDamage->sheet() != m_sheet) { 0525 continue; 0526 } 0527 debugSheetsDamage << *sheetDamage; 0528 const SheetDamage::Changes changes = sheetDamage->changes(); 0529 if (changes & SheetDamage::Name) { 0530 emit nameChanged(); 0531 } 0532 if (changes & SheetDamage::Shown) { 0533 emit showChanged(); 0534 } 0535 if (changes & SheetDamage::Hidden) { 0536 emit hideChanged(); 0537 } 0538 continue; 0539 } 0540 } 0541 }