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 }