File indexing completed on 2024-05-12 16:35:13

0001 /* This file is part of the KDE project
0002    Copyright 2005-2006 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 */
0019 
0020 // Local
0021 #include "StyleCommand.h"
0022 
0023 #include <QBrush>
0024 
0025 #include <KLocalizedString>
0026 
0027 #include "Cell.h"
0028 #include "CellStorage.h"
0029 #include "Damages.h"
0030 #include "Map.h"
0031 #include "Sheet.h"
0032 #include "Style.h"
0033 #include "StyleStorage.h"
0034 
0035 using namespace Calligra::Sheets;
0036 
0037 StyleCommand::StyleCommand(KUndo2Command* parent)
0038         : AbstractRegionCommand(parent)
0039         , m_horizontalPen(QPen(QColor(), 0, Qt::NoPen))
0040         , m_verticalPen(QPen(QColor(), 0, Qt::NoPen))
0041         , m_horizontalPenChanged(false)
0042         , m_verticalPenChanged(false)
0043         , m_style(new Style())
0044 {
0045 }
0046 
0047 StyleCommand::~StyleCommand()
0048 {
0049     delete m_style;
0050 }
0051 
0052 bool StyleCommand::process(Element* element)
0053 {
0054     const QRect range = element->rect();
0055     if (!m_reverse) { // (re)do
0056         if (m_firstrun) {
0057             const QRect rect = range.adjusted(m_style->hasAttribute(Style::LeftPen) ? -1 : 0,
0058                                               m_style->hasAttribute(Style::TopPen) ? -1 : 0,
0059                                               m_style->hasAttribute(Style::RightPen) ? 1 : 0,
0060                                               m_style->hasAttribute(Style::BottomPen) ? 1 : 0);
0061             const QList< QPair<QRectF, SharedSubStyle> > rawUndoData
0062             = m_sheet->styleStorage()->undoData(Region(rect));
0063             for (int i = 0; i < rawUndoData.count(); ++i) {
0064 //                 if ( m_style->hasAttribute( rawUndoData[i].second->type() ) ||
0065 //                      rawUndoData[i].second->type() == Style::DefaultStyleKey ||
0066 //                      rawUndoData[i].second->type() == Style::NamedStyleKey )
0067                 m_undoData << rawUndoData[i];
0068             }
0069         }
0070         // special handling for the border
0071         bool hasLeftPen = m_style->hasAttribute(Style::LeftPen);
0072         bool hasRightPen = m_style->hasAttribute(Style::RightPen);
0073         bool hasTopPen = m_style->hasAttribute(Style::TopPen);
0074         bool hasBottomPen = m_style->hasAttribute(Style::BottomPen);
0075         const QPen leftPen = m_style->leftBorderPen();
0076         const QPen rightPen = m_style->rightBorderPen();
0077         const QPen topPen = m_style->topBorderPen();
0078         const QPen bottomPen = m_style->bottomBorderPen();
0079         m_style->clearAttribute(Style::LeftPen);
0080         m_style->clearAttribute(Style::RightPen);
0081         m_style->clearAttribute(Style::TopPen);
0082         m_style->clearAttribute(Style::BottomPen);
0083 
0084         // use the horizontal/vertical pens
0085         if (m_horizontalPenChanged) {
0086             m_style->setTopBorderPen(m_horizontalPen);
0087             m_style->setBottomBorderPen(m_horizontalPen);
0088             hasTopPen = hasBottomPen = true;
0089         }
0090         if (m_verticalPenChanged) {
0091             m_style->setLeftBorderPen(m_verticalPen);
0092             m_style->setRightBorderPen(m_verticalPen);
0093             hasLeftPen = hasRightPen = true;
0094         }
0095 
0096         // special handling for indentation: reset the indentation first
0097         if (m_style->hasAttribute(Style::Indentation)) {
0098             Style style;
0099             style.setIndentation(0);
0100             m_sheet->cellStorage()->setStyle(Region(range), style);
0101         }
0102 
0103         // special handling for precision: reset the precision first
0104         if (m_style->hasAttribute(Style::Precision)) {
0105             Style style;
0106             style.setPrecision(0);   // insert storage default
0107             m_sheet->cellStorage()->setStyle(Region(range), style);
0108         }
0109 
0110         // set the actual style
0111         m_sheet->cellStorage()->setStyle(Region(range), *m_style);
0112 
0113         // prepare to restore pens
0114         m_style->clearAttribute(Style::LeftPen);
0115         m_style->clearAttribute(Style::RightPen);
0116         m_style->clearAttribute(Style::TopPen);
0117         m_style->clearAttribute(Style::BottomPen);
0118 
0119         // set the outer border styles
0120         Style style;
0121         if (hasLeftPen) {
0122             style.setLeftBorderPen(leftPen);
0123             m_sheet->cellStorage()->setStyle(Region(QRect(range.left(), range.top(), 1, range.height())), style);
0124             m_style->setLeftBorderPen(leftPen); // restore pen
0125             // reset the border of the adjacent cell
0126             if (range.left() > 1) {
0127                 Style tmpStyle;
0128                 tmpStyle.setRightBorderPen(QPen(Qt::NoPen));
0129                 const Region region(QRect(range.left() - 1, range.top(), 1, range.height()));
0130                 m_sheet->cellStorage()->setStyle(region, tmpStyle);
0131                 m_sheet->map()->addDamage(new CellDamage(m_sheet, region, CellDamage::Appearance));
0132             }
0133         }
0134         if (hasRightPen) {
0135             style.clear();
0136             style.setRightBorderPen(rightPen);
0137             m_sheet->cellStorage()->setStyle(Region(QRect(range.right(), range.top(), 1, range.height())), style);
0138             m_style->setRightBorderPen(rightPen); // restore pen
0139             // reset the border of the adjacent cell
0140             if (range.right() < KS_colMax) {
0141                 Style tmpStyle;
0142                 tmpStyle.setLeftBorderPen(QPen(Qt::NoPen));
0143                 const Region region(QRect(range.right() + 1, range.top(), 1, range.height()));
0144                 m_sheet->cellStorage()->setStyle(region, tmpStyle);
0145                 m_sheet->map()->addDamage(new CellDamage(m_sheet, region, CellDamage::Appearance));
0146             }
0147         }
0148         if (hasTopPen) {
0149             style.clear();
0150             style.setTopBorderPen(topPen);
0151             m_sheet->cellStorage()->setStyle(Region(QRect(range.left(), range.top(), range.width(), 1)), style);
0152             m_style->setTopBorderPen(topPen); // restore pen
0153             // reset the border of the adjacent cell
0154             if (range.top() > 1) {
0155                 Style tmpStyle;
0156                 tmpStyle.setBottomBorderPen(QPen(Qt::NoPen));
0157                 const Region region(QRect(range.left(), range.top() - 1, range.width(), 1));
0158                 m_sheet->cellStorage()->setStyle(region, tmpStyle);
0159                 m_sheet->map()->addDamage(new CellDamage(m_sheet, region, CellDamage::Appearance));
0160             }
0161         }
0162         if (hasBottomPen) {
0163             style.clear();
0164             style.setBottomBorderPen(bottomPen);
0165             m_sheet->cellStorage()->setStyle(Region(QRect(range.left(), range.bottom(), range.width(), 1)), style);
0166             m_style->setBottomBorderPen(bottomPen); // restore pen
0167             // reset the border of the adjacent cell
0168             if (range.bottom() < KS_rowMax) {
0169                 Style tmpStyle;
0170                 tmpStyle.setTopBorderPen(QPen(Qt::NoPen));
0171                 const Region region(QRect(range.left(), range.bottom() + 1, range.width(), 1));
0172                 m_sheet->cellStorage()->setStyle(region, tmpStyle);
0173                 m_sheet->map()->addDamage(new CellDamage(m_sheet, region, CellDamage::Appearance));
0174             }
0175         }
0176     }
0177     return true;
0178 }
0179 
0180 bool StyleCommand::preProcessing()
0181 {
0182     if (m_firstrun) {
0183         if (m_style->isDefault())
0184             setText(kundo2_i18n("Reset Style"));
0185         else
0186             setText(kundo2_i18n("Change Style"));
0187 
0188         // special handling for precision
0189         if (m_style->hasAttribute(Style::Precision)) {
0190             if (m_style->precision() == -1)   // Style default
0191                 m_style->setPrecision(0);   // storage default
0192             else if (m_style->precision() == 0)
0193                 m_style->setPrecision(-1);   // anything resulting in zero, but not storage default
0194         }
0195     }
0196     return AbstractRegionCommand::preProcessing();
0197 }
0198 
0199 bool StyleCommand::mainProcessing()
0200 {
0201     if (!m_reverse) {
0202     } else { // m_reverse
0203         Style style;
0204         style.setDefault();
0205         // special handling for indentation
0206         style.setIndentation(0);   // reset to zero
0207         // special handling for precision
0208         style.setPrecision(0);   // reset to storage default
0209         m_sheet->cellStorage()->setStyle(*this, style);
0210         for (int i = 0; i < m_undoData.count(); ++i) {
0211             m_sheet->cellStorage()->insertSubStyle(m_undoData[i].first.toRect(), m_undoData[i].second);
0212         }
0213     }
0214     return AbstractRegionCommand::mainProcessing();
0215 }
0216 
0217 bool StyleCommand::postProcessing()
0218 {
0219     return true;
0220 }