File indexing completed on 2024-05-12 16:29:09

0001 #include "MsooXmlDrawingTableStyle.h"
0002 
0003 //#define MSOOXMLDRAWING_DEBUG_TABLES
0004 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0005 #include "MsooXmlDebug.h"
0006 #endif
0007 
0008 using namespace MSOOXML;
0009 
0010 DrawingTableStyleConverterProperties::DrawingTableStyleConverterProperties()
0011 : TableStyleConverterProperties()
0012 , m_role(DrawingTableStyle::WholeTbl)
0013 {
0014 }
0015 
0016 DrawingTableStyleConverterProperties::~DrawingTableStyleConverterProperties()
0017 {
0018 }
0019 
0020 DrawingTableStyleConverterProperties::Roles DrawingTableStyleConverterProperties::roles() const
0021 {
0022     return m_role;
0023 }
0024 
0025 void DrawingTableStyleConverterProperties::setRoles(DrawingTableStyleConverterProperties::Roles roles)
0026 {
0027     m_role = roles;
0028 }
0029 
0030 DrawingTableStyleConverter::DrawingTableStyleConverter(MSOOXML::DrawingTableStyleConverterProperties const& properties, DrawingTableStyle* style)
0031 : TableStyleConverter(properties.rowCount(), properties.columnCount())
0032 , m_style(style)
0033 , m_properties(properties)
0034 {
0035 }
0036 
0037 DrawingTableStyleConverter::~DrawingTableStyleConverter()
0038 {
0039 }
0040 
0041 void DrawingTableStyleConverter::applyStyle(MSOOXML::DrawingTableStyle::Type type, KoCellStyle::Ptr& style,
0042                                             int row, int column, const QPair<int, int> &spans)
0043 {
0044     if (!m_style) {
0045         return;
0046     }
0047 
0048     TableStyleProperties* styleProperties = m_style->properties(type);
0049 
0050 //     if (type == DrawingTableStyle::WholeTbl) {
0051 //         styleProperties->bordersToEdgesOnly = true;
0052 //     }
0053 
0054     TableStyleConverter::applyStyle(styleProperties, style, row, column, spans);
0055 }
0056 
0057 KoCellStyle::Ptr DrawingTableStyleConverter::style(int row, int column, const QPair<int, int> &spans)
0058 {
0059     Q_ASSERT(row >= 0);
0060     Q_ASSERT(row < m_properties.rowCount());
0061     Q_ASSERT(column >= 0);
0062     Q_ASSERT(column < m_properties.columnCount());
0063 
0064     //TODO: can we magically improve the creation of the styles?  For now I'll
0065     //take the naive approach and say no.  There are way, way too many things
0066     //to take into account so, reusing the styles doesn't seem feasible.
0067 
0068     KoCellStyle::Ptr cellStyle = KoCellStyle::create();
0069 
0070     // When specified, the conditional formats are applied in the following
0071     // order (therefore subsequent formats override properties on previous
0072     // formats):
0073     //
0074     // * Whole table
0075     // * Banded columns, even column banding
0076     // * Banded rows, even row banding
0077     // * First row, last row
0078     // * First column, last column
0079     // * Top left, top right, bottom left, bottom right
0080     //
0081     // NOTE: The standard doesn't say what happens to colliding properties in
0082     // the same hierarchy level (say, it's the first column and last column, or
0083     // it's first row and last row at once, I assume left to right priority on
0084     // the elements in the previous list.)
0085     //
0086     // See MSOOXML Table Styles ยง17.7.6 for details.
0087 
0088     const DrawingTableStyleConverterProperties::Roles& role = m_properties.roles();
0089     const int lastRow = m_properties.rowCount() - 1;
0090     const int lastColumn = m_properties.columnCount() - 1;
0091 
0092 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0093     debugMsooXml << "==> [styles.xml] TABLE-level:";
0094 #endif
0095     applyStyle(DrawingTableStyle::WholeTbl, cellStyle, row, column, spans);
0096 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0097     debugMsooXml << "<== [END] [styles.xml] TABLE-level:";
0098 #endif
0099 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0100     debugMsooXml << "==> [local] TABLE-level:";
0101 #endif
0102     TableStyleConverter::applyStyle(m_properties.localDefaultCellStyle(), cellStyle, row, column, spans);
0103 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0104     debugMsooXml << "<== [END] [local] TABLE-level:";
0105 #endif
0106 
0107     if (role & DrawingTableStyleConverterProperties::ColumnBanded) {
0108         // If last column is activated and it's last column, banding is not applied
0109         if (!(role & DrawingTableStyleConverterProperties::LastCol && column == lastColumn)) {
0110             // First column active means that the banding is shifted by one
0111             if (role & DrawingTableStyleConverterProperties::FirstCol) {
0112 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0113                 debugMsooXml << "====> [ColumnBanded] FirstCol:";
0114 #endif
0115                 // Banding not applied if it's the first column
0116                 if (column != 0) {
0117                     // Banding reversed
0118                     if ((column % (m_properties.columnBandSize() * 2)) < m_properties.columnBandSize()) {
0119                         applyStyle(DrawingTableStyle::Band2Vertical, cellStyle, row, column, spans);
0120                     }
0121                     else {
0122                         applyStyle(DrawingTableStyle::Band1Vertical, cellStyle, row, column, spans);
0123                     }
0124                 }
0125             }
0126             else {
0127 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0128                 debugMsooXml << "====> [ColumnBanded] Other:";
0129 #endif
0130                 //Is the column in the even band?
0131                 if ((column % (m_properties.columnBandSize() * 2)) < m_properties.columnBandSize()) {
0132                     applyStyle(DrawingTableStyle::Band1Vertical, cellStyle, row, column, spans);
0133                 }
0134                 else {
0135                     applyStyle(DrawingTableStyle::Band2Vertical, cellStyle, row, column, spans);
0136                 }
0137             }
0138         }
0139     }
0140 
0141     if (role & DrawingTableStyleConverterProperties::RowBanded) {
0142         // If last row is activated and it's last row, banding is not applied
0143         if (!(role & DrawingTableStyleConverterProperties::LastRow && row == lastRow)) {
0144             // First row active means that the banding is shifted by one
0145             if (role & DrawingTableStyleConverterProperties::FirstRow) {
0146 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0147                 debugMsooXml << "====> [RowBanded] FirstRow:";
0148 #endif
0149                 // Banding not applied if it's the first row
0150                 if (row != 0) {
0151                     // In case the first row is activated, the banding applying is reversed
0152                     if( (row % (m_properties.rowBandSize() * 2)) < m_properties.rowBandSize()) {
0153                         applyStyle(DrawingTableStyle::Band2Horizontal, cellStyle, row, column, spans);
0154                     }
0155                     else {
0156                         applyStyle(DrawingTableStyle::Band1Horizontal, cellStyle, row, column, spans);
0157                     }
0158                 }
0159             }
0160             else {
0161 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0162                 debugMsooXml << "====> [RowBanded] Other:";
0163 #endif
0164                 //Is the row in the even band?
0165                 if( (row % (m_properties.rowBandSize() * 2)) < m_properties.rowBandSize()) {
0166                     applyStyle(DrawingTableStyle::Band1Horizontal, cellStyle, row, column, spans);
0167                 }
0168                 else {
0169                     applyStyle(DrawingTableStyle::Band2Horizontal, cellStyle, row, column, spans);
0170                 }
0171             }
0172         }
0173     }
0174 
0175     //NOTE: According to test data, at least for the first table cell the
0176     //FirstCol format applies before the FirstRow format.  Also the previous
0177     //approach with RowBanded cells might be an option.
0178 
0179     if(role & DrawingTableStyleConverterProperties::FirstCol) {
0180         if(column == 0) {
0181 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0182             debugMsooXml << "====> FirstCol:";
0183 #endif
0184             applyStyle(DrawingTableStyle::FirstCol, cellStyle, row, column, spans);
0185         }
0186     }
0187 
0188     if (role & DrawingTableStyleConverterProperties::FirstRow) {
0189         if(row == 0) {
0190 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0191             debugMsooXml << "====> FirstRow:";
0192 #endif
0193             applyStyle(DrawingTableStyle::FirstRow, cellStyle, row, column, spans);
0194         }
0195     }
0196 
0197     if (role & DrawingTableStyleConverterProperties::LastRow) {
0198         if(row == lastRow) {
0199 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0200             debugMsooXml << "====> LastRow:";
0201 #endif
0202             applyStyle(DrawingTableStyle::LastRow, cellStyle, row, column, spans);
0203         }
0204     }
0205 
0206 
0207 
0208     if(role & DrawingTableStyleConverterProperties::LastCol) {
0209         if(column == lastColumn) {
0210 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0211             debugMsooXml << "====> LastCol:";
0212 #endif
0213             applyStyle(DrawingTableStyle::LastCol, cellStyle, row, column, spans);
0214         }
0215     }
0216 
0217     if(role & DrawingTableStyleConverterProperties::NeCell) {
0218         if(row == 0 && column == 0) {
0219 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0220             debugMsooXml << "====> NeCell:";
0221 #endif
0222             applyStyle(DrawingTableStyle::NeCell, cellStyle, row, column, spans);
0223         }
0224     }
0225 
0226     if(role & DrawingTableStyleConverterProperties::NwCell) {
0227         if(row == 0 && column == lastColumn) {
0228 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0229             debugMsooXml << "====> NwCell:";
0230 #endif
0231             applyStyle(DrawingTableStyle::NwCell, cellStyle, row, column, spans);
0232         }
0233     }
0234 
0235     if(role & DrawingTableStyleConverterProperties::SeCell) {
0236         if(row == lastRow && column == 0) {
0237 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0238             debugMsooXml << "====> SeCell:";
0239 #endif
0240             applyStyle(DrawingTableStyle::SeCell, cellStyle, row, column, spans);
0241         }
0242     }
0243 
0244     if(role & DrawingTableStyleConverterProperties::SwCell) {
0245         if(row == lastRow && column == lastColumn) {
0246 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0247             debugMsooXml << "====> SwCell:";
0248 #endif
0249             applyStyle(DrawingTableStyle::SwCell, cellStyle, row, column, spans);
0250         }
0251     }
0252 
0253     TableStyleProperties* localProperties = m_properties.localStyles().localStyle(row, -1);
0254     if (localProperties) {
0255 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0256         debugMsooXml << "==> ROW-level:";
0257 #endif
0258         TableStyleConverter::applyStyle(localProperties, cellStyle, row, column, spans);
0259         localProperties = 0;
0260 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0261         debugMsooXml << "<== [END] ROW-level:";
0262 #endif
0263     }
0264 
0265     localProperties = m_properties.localStyles().localStyle(row, column);
0266     if (localProperties) {
0267 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0268         debugMsooXml << "==> CELL-level:";
0269 #endif
0270         TableStyleConverter::applyStyle(localProperties, cellStyle, row, column, spans);
0271         localProperties = 0;
0272 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0273         debugMsooXml << "<== [END] CELL-level:";
0274 #endif
0275     }
0276 
0277     //RE-APPLY table-level border properties from tblBorders
0278 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0279     debugMsooXml << "==> [REAPPLY]: TABLE/ROW-level properties";
0280 #endif
0281     TableStyleProperties* tableProperties = 0;
0282     if (m_style) {
0283         tableProperties = m_style->properties(DrawingTableStyle::WholeTbl);
0284     }
0285     reapplyTableLevelBordersStyle(tableProperties,
0286                                   m_properties.localDefaultCellStyle(),
0287                                   m_properties.localStyles().localStyle(row, -1),
0288                                   cellStyle, row, column, spans);
0289 #ifdef MSOOXMLDRAWING_DEBUG_TABLES
0290     debugMsooXml << "<== [END] [REAPPLY]: TABLE/ROW-level properties";
0291 #endif
0292 
0293     return cellStyle;
0294 }
0295 
0296 DrawingTableStyle::DrawingTableStyle()
0297 : m_properties()
0298 {
0299 }
0300 
0301 DrawingTableStyle::~DrawingTableStyle()
0302 {
0303 //     FIXME: we crash because of this.
0304 //     qDeleteAll(m_properties.values());
0305 }
0306 
0307 void DrawingTableStyle::addProperties(DrawingTableStyle::Type type, TableStyleProperties* properties)
0308 {
0309     m_properties.insert(type, properties);
0310 }
0311 
0312 TableStyleProperties* DrawingTableStyle::properties(DrawingTableStyle::Type type) const
0313 {
0314     return m_properties.value(type);
0315 }