~ubuntu-branches/ubuntu/precise/koffice/precise

« back to all changes in this revision

Viewing changes to kspread/ui/CellView.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2010-10-27 17:52:57 UTC
  • mfrom: (0.12.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20101027175257-s04zqqk5bs8ckm9o
Tags: 1:2.2.83-0ubuntu1
* Merge with Debian git remaining changes:
 - Add build-deps on librcps-dev, opengtl-dev, libqtgtl-dev, freetds-dev,
   create-resources, libspnav-dev
 - Remove needless build-dep on libwv2-dev
 - koffice-libs recommends create-resources
 - krita recommends pstoedit
 - Keep our patches
* New upstream release 2.3 beta 3
  - Remove debian/patches fixed by upstream
  - Update install files

Show diffs side-by-side

added added

removed removed

Lines of Context:
52
52
#include <QTextCursor>
53
53
#include <QAbstractTextDocumentLayout>
54
54
 
 
55
// KDE
 
56
#include <KColorUtils>
 
57
 
55
58
// KOffice
56
59
#include <KoPostscriptPaintDevice.h>
57
60
#include <KoZoomHandler.h>
61
64
#include "CellStorage.h"
62
65
#include "Condition.h"
63
66
#include "Map.h"
 
67
#include "PrintSettings.h"
64
68
#include "RowColumnFormat.h"
65
69
#include "Selection.h"
66
70
#include "Sheet.h"
86
90
            , textWidth(0.0)
87
91
            , textHeight(0.0)
88
92
            , textLinesCount(0)
 
93
            , shrinkToFitFontSize(0.0)
89
94
            , hidden(false)
90
95
            , merged(false)
91
96
            , obscured(false)
110
115
    qreal  textHeight;
111
116
 
112
117
    int    textLinesCount;
 
118
    qreal shrinkToFitFontSize;
113
119
 
114
 
bool hidden         : 1;
115
 
bool merged         : 1;
116
 
bool obscured       : 1;
117
 
bool fittingHeight  : 1;
118
 
bool fittingWidth   : 1;
119
 
bool filterButton   : 1;
 
120
    bool hidden         : 1;
 
121
    bool merged         : 1;
 
122
    bool obscured       : 1;
 
123
    bool fittingHeight  : 1;
 
124
    bool fittingWidth   : 1;
 
125
    bool filterButton   : 1;
120
126
    // NOTE Stefan: A cell is either obscured by an other one or obscures others itself.
121
127
    //              But never both at the same time, so we can share the memory for this.
122
128
    union {
123
 
    int obscuringCellX : 16; // KS_colMax
124
 
    int obscuredCellsX : 16; // KS_colMax
 
129
        int obscuringCellX : 16; // KS_colMax
 
130
        int obscuredCellsX : 16; // KS_colMax
125
131
    };
126
132
    union {
127
 
    int obscuringCellY : 16; // KS_rowMax
128
 
    int obscuredCellsY : 16; // KS_rowMax
 
133
        int obscuringCellY : 16; // KS_rowMax
 
134
        int obscuredCellsY : 16; // KS_rowMax
129
135
    };
130
136
 
131
137
    // This is the text we want to display. Not necessarily the same
143
149
    void truncateHorizontalText(const QFont& font, const QFontMetricsF& fontMetrics);
144
150
    void truncateVerticalText(const QFont& font, const QFontMetricsF& fontMetrics);
145
151
    void truncateAngledText(const QFont& font, const QFontMetricsF& fontMetrics);
 
152
    QFont calculateFont() const;
146
153
    QTextOption textOptions() const;
147
154
};
148
155
 
 
156
QFont CellView::Private::calculateFont() const
 
157
{
 
158
    QFont f = style.font();
 
159
    if (shrinkToFitFontSize > 0.0)
 
160
        f.setPointSizeF(shrinkToFitFontSize);
 
161
    return f;
 
162
}
149
163
 
150
164
CellView::CellView(SheetView* sheetView)
151
165
        : d(new Private(sheetView->sheet()->map()->styleManager()->defaultStyle(),
176
190
 
177
191
        // use conditional formatting attributes
178
192
        Conditions conditions = cell.conditions();
179
 
        if (Style* style = conditions.testConditions(cell, sheetView->sheet()->map()->styleManager()))
180
 
            d->style.merge(*style);
 
193
        const Style conditionalStyle = conditions.testConditions(cell);
 
194
        if (!conditionalStyle.isEmpty()) {
 
195
            d->style.merge(conditionalStyle);
 
196
        }
181
197
    }
182
198
 
183
199
    if (cell.width() != sheetView->sheet()->map()->defaultColumnFormat()->width())
276
292
    return QRectF(d->textX, d->textY, d->textWidth, d->textWidth);
277
293
}
278
294
 
279
 
QString CellView::testAnchor(const Cell& cell, qreal x, qreal y) const
 
295
QString CellView::testAnchor(SheetView* sheetView, const Cell& cell, qreal x, qreal y) const
280
296
{
 
297
    if (isObscured()) {
 
298
        Sheet* sheet = cell.sheet();
 
299
        Cell otherCell = Cell(sheet, d->obscuringCellX, d->obscuringCellY);
 
300
        const CellView& otherView = sheetView->cellView(otherCell.column(), otherCell.row());
 
301
        if (cell.column() != otherCell.column()) x += sheet->columnPosition(cell.column()) - sheet->columnPosition(otherCell.column());
 
302
        if (cell.row() != otherCell.row()) y += sheet->rowPosition(cell.row()) - sheet->rowPosition(otherCell.row());
 
303
        return otherView.testAnchor(sheetView, otherCell, x, y);
 
304
    }
281
305
    if (cell.link().isEmpty())
282
306
        return QString();
283
307
 
317
341
//              coordinates.
318
342
//
319
343
void CellView::paintCellContents(const QRectF& paintRect, QPainter& painter,
320
 
                                 QPaintDevice* paintDevice, const QPointF& coordinate,
 
344
                                 const QPointF& coordinate,
321
345
                                 const Cell& cell, SheetView* sheetView)
322
346
{
323
347
    if (d->hidden)
358
382
    // 3. Paint possible indicator for clipped text.
359
383
    paintMoreTextIndicator(painter, coordinate);
360
384
 
361
 
    // 4. Paint cell highlight
362
 
#if 0
363
 
    if (highlightBorder != None)
364
 
        paintCellHighlight(painter, coordinate, cellRef, highlightBorder,
365
 
                           rightHighlightPen, bottomHighlightPen,
366
 
                           leftHighlightPen,  topHighlightPen);
367
 
#endif
368
 
 
369
385
    // 5. Paint the text in the cell unless:
370
386
    //  a) it is empty
371
387
    //  b) something indicates that the text should not be painted
374
390
            && (!dynamic_cast<QPrinter*>(painter.device()) || style().printText())
375
391
            && !(cell.sheet()->isProtected()
376
392
                 && style().hideAll())) {
377
 
        paintText(painter, coordinate, paintDevice, cell);
 
393
        paintText(painter, coordinate, cell);
378
394
    }
379
395
}
380
396
 
446
462
 
447
463
    // ----------------  Start the actual painting.  ----------------
448
464
 
449
 
#if 0
450
 
    // 1. Paint the default borders if we are on screen or if we are printing
451
 
    //    and the checkbox to do this is checked.
452
 
    if (painter.device()->devType() != QInternal::Printer ||
453
 
            sheet->printSettings()->printGrid())
454
 
        paintDefaultBorders(painter, paintRegion, cellRect, paintBorder, cell);
455
 
#endif
456
 
 
457
465
    // 2. Paint the borders of the cell if no other cell is forcing this
458
466
    // one, i.e. this cell is not part of a merged cell.
459
467
    //
477
485
    paintPageBorders(painter, coordinate, paintBorder, cell);
478
486
}
479
487
 
480
 
 
481
 
// The following code was commented out in the above function.  I'll
482
 
// leave it here in case this functionality is ever re-implemented and
483
 
// someone wants some code to start from.
484
 
//
485
 
#if 0
486
 
 
487
 
/**
488
 
* Modification for drawing the button
489
 
 */
490
 
if (d->style == Cell::ST_Button)
491
 
{
492
 
    QBrush fill(Qt::lightGray);
493
 
    QApplication::style().drawControl(QStyle::CE_PushButton, &_painter, this,
494
 
                                      QRect(_tx + 1, _ty + 1, w2 - 1, h2 - 1),
495
 
                                      defaultColorGroup);  //, selected, &fill );
496
 
}
497
 
 
498
 
/**
499
 
* Modification for drawing the combo box
500
 
 */
501
 
else if (d->style == Cell::ST_Select)
502
 
{
503
 
    QApplication::style().drawComboButton(&_painter, _tx + 1, _ty + 1,
504
 
                                          w2 - 1, h2 - 1,
505
 
                                          defaultColorGroup, selected);
506
 
}
507
 
#endif
508
 
 
509
 
 
510
 
#if 0
511
 
void CellView::paintCellHighlight(QPainter& painter,
512
 
                                  const QPointF& coordinate,
513
 
                                  const QPoint& cellRef,
514
 
                                  const int highlightBorder,
515
 
                                  const QPen& rightPen,
516
 
                                  const QPen& bottomPen,
517
 
                                  const QPen& leftPen,
518
 
                                  const QPen& topPen
519
 
                                 )
520
 
{
521
 
    //painter.drawLine(coordinate.x(),coordinate.y(),coordinate.x() + d->width,coordinate.y() + d->height);
522
 
    //QPen pen(cell.d->extra()->highlight);
523
 
    //painter.setPen(highlightPen);
524
 
 
525
 
    QBrush nullBrush;
526
 
    painter.setBrush(nullBrush);
527
 
 
528
 
    QRect zoomedCellRect = cell.doc()->zoomRect(cellRect);
529
 
 
530
 
    //The highlight rect is just inside the main cell rect
531
 
    //This saves the hassle of repainting nearby cells when the highlight is changed as the highlight areas
532
 
    //do not overlap
533
 
    zoomedCellRect.setLeft(zoomedCellRect.left() + 1);
534
 
    //zoomedCellRect.setRight(zoomedCellRect.right()-1);
535
 
    zoomedCellRect.setTop(zoomedCellRect.top() + 1);
536
 
    //zoomedCellRect.setBottom(zoomedCellRect.bottom()-1);
537
 
 
538
 
    if (cellRef.x() != KS_colMax)
539
 
        zoomedCellRect.setWidth(zoomedCellRect.width() - 1);
540
 
    if (cellRef.y() != KS_rowMax)
541
 
        zoomedCellRect.setHeight(zoomedCellRect.height() - 1);
542
 
 
543
 
    if (highlightBorder & Top) {
544
 
        painter.setPen(topPen);
545
 
        painter.drawLine(zoomedCellRect.left(), zoomedCellRect.top(), zoomedCellRect.right(), zoomedCellRect.top());
546
 
    }
547
 
    if (highlightBorder & Left) {
548
 
        painter.setPen(leftPen);
549
 
        painter.drawLine(zoomedCellRect.left(), zoomedCellRect.top(), zoomedCellRect.left(), zoomedCellRect.bottom());
550
 
    }
551
 
    if (highlightBorder & RightBorder) {
552
 
        painter.setPen(rightPen);
553
 
        painter.drawLine(zoomedCellRect.right(), zoomedCellRect.top(), zoomedCellRect.right(), zoomedCellRect.bottom());
554
 
    }
555
 
    if (highlightBorder & Bottom) {
556
 
        painter.setPen(bottomPen);
557
 
        painter.drawLine(zoomedCellRect.left(), zoomedCellRect.bottom(), zoomedCellRect.right(), zoomedCellRect.bottom());
558
 
    }
559
 
 
560
 
    if (highlightBorder & SizeGrip) {
561
 
        QBrush brush(rightPen.color());
562
 
        painter.setBrush(brush);
563
 
        painter.setPen(rightPen);
564
 
        painter.drawRect(zoomedCellRect.right() - 3, zoomedCellRect.bottom() - 3, 4, 4);
565
 
    }
566
 
 
567
 
    //painter.drawRect(zoomedCellRect.left(),zoomedCellRect.top(),zoomedCellRect.width(),zoomedCellRect.height());
568
 
}
569
 
#endif
570
 
 
571
488
//
572
489
// Paint the background of this cell.
573
490
//
682
599
        d->style.setBottomBorderPen(sheetView->cellView(col, row + cell.mergedYCells()).style().topBorderPen());
683
600
    else if (d->style.bottomPenValue() >= sheetView->cellView(col, row + cell.mergedYCells()).style().topPenValue())
684
601
        paintBorder |= BottomBorder;
685
 
    
 
602
 
686
603
    // Check merging...
687
604
    if (d->merged) {
688
605
        // by default: none ...
751
668
        int dt = 0;
752
669
        int db = 0;
753
670
 
754
 
#if 0
 
671
#if 0 // KSPREAD_WIP_STYLE_BORDER
755
672
        if (cellRef.x() > 1) {
756
673
            Cell  *cell_west = Cell(cell.sheet(), cellRef.x() - 1,
757
674
                                    cellRef.y());
787
704
        int dl = 0;
788
705
        int dr = 0;
789
706
 
790
 
#if 0
 
707
#if 0 // KSPREAD_WIP_STYLE_BORDER
791
708
        if (cellRef.y() > 1) {
792
709
            Cell  *cell_north = Cell(cell.sheet(), cellRef.x(),
793
710
                                     cellRef.y() - 1);
824
741
        int dt = 0;
825
742
        int db = 0;
826
743
 
827
 
#if 0
 
744
#if 0 // KSPREAD_WIP_STYLE_BORDER
828
745
        if (cellRef.x() < KS_colMax) {
829
746
            Cell  *cell_east = Cell(cell.sheet(), cellRef.x() + 1,
830
747
                                    cellRef.y());
861
778
    if (paintBorder & BottomBorder) {
862
779
        int dl = 0;
863
780
        int dr = 0;
864
 
#if 0
 
781
#if 0 // KSPREAD_WIP_STYLE_BORDER
865
782
        if (cellRef.y() < KS_rowMax) {
866
783
            Cell  *cell_south = Cell(cell.sheet(), cellRef.x(),
867
784
                                     cellRef.y() + 1);
1022
939
//
1023
940
void CellView::paintMoreTextIndicator(QPainter& painter, const QPointF& coordinate)
1024
941
{
 
942
    if (d->style.shrinkToFit())
 
943
        return;
1025
944
    // Show a red triangle when it's not possible to write all text in cell.
1026
945
    // Don't print the red triangle if we're printing.
1027
946
    if (!d->fittingWidth &&
1056
975
    }
1057
976
}
1058
977
 
 
978
static int fixAngle(int angle) {
 
979
    angle = ((angle % 360) + 360) % 360;
 
980
    // now angle is between 0 and 359, but 181-359 should be -179 - -1
 
981
    if (angle > 180) angle = angle - 360;
 
982
    return angle;
 
983
}
1059
984
 
1060
985
// Paint the real contents of a cell - the text.
1061
986
//
1062
987
void CellView::paintText(QPainter& painter,
1063
988
                         const QPointF& coordinate,
1064
 
                         QPaintDevice* paintDevice, const Cell& cell)
 
989
                         const Cell& cell)
1065
990
{
1066
 
    Q_UNUSED(paintDevice);
1067
991
    QColor textColorPrint = d->style.fontColor();
1068
 
 
1069
 
    // set a clipping region
1070
 
    painter.save();
1071
 
    painter.setClipRect(QRectF(coordinate, QSizeF(d->width, d->height)));
1072
 
 
1073
992
    // Resolve the text color if invalid (=default).
1074
993
    if (!textColorPrint.isValid()) {
1075
994
        if (dynamic_cast<QPrinter*>(painter.device()))
1076
995
            textColorPrint = Qt::black;
1077
996
        else
1078
997
            textColorPrint = QApplication::palette().text().color();
 
998
 
 
999
        QColor bgColor = d->style.backgroundColor();
 
1000
        if (bgColor.isValid()) {
 
1001
            qreal contrast = KColorUtils::contrastRatio(bgColor, textColorPrint);
 
1002
            if (contrast < 3)
 
1003
                textColorPrint = QColor(255 - textColorPrint.red(), 255 - textColorPrint.green(), 255 - textColorPrint.blue());
 
1004
        }
1079
1005
    }
1080
1006
 
1081
1007
    QPen tmpPen(textColorPrint);
1082
 
    QFont font = d->style.font();
 
1008
    QFont font = d->calculateFont();
1083
1009
 
1084
1010
    // Check for red font color for negative values.
1085
1011
    if (cell.value().isNumber()
1095
1021
        tmpPen.setColor(QApplication::palette().link().color());
1096
1022
        font.setUnderline(true);
1097
1023
    }
1098
 
 
1099
 
#if 0
1100
 
    /****
1101
 
 
1102
 
     For now I am commenting this out -- with the default color display you
1103
 
     can read normal text through a highlighted background.  Maybe this isn't
1104
 
     always the case, though, and we can put the highlighted text color back in.
1105
 
     In that case, we need to somewhere in here figure out if the text overlaps
1106
 
     another cell outside of the selection, otherwise that portion of the text
1107
 
     will be printed white on white.  So just that portion would need to be
1108
 
     painted again in the normal color.
1109
 
 
1110
 
     This should probably be done eventually, anyway, because I like using the
1111
 
     reverse text color for highlighted cells.  I just don't like extending the
1112
 
     cell 'highlight' background outside of the selection rectangle because it
1113
 
     looks REALLY ugly.
1114
 
    */
1115
 
 
1116
 
    if (selected && (cellRef.x() != marker.x() || cellRef.y() != marker.y())) {
1117
 
        QPen p(tmpPen);
1118
 
        p.setColor(defaultColorGroup.highlightedText());
1119
 
        painter.setPen(p);
1120
 
    } else {
1121
 
        painter.setPen(tmpPen);
1122
 
    }
1123
 
#endif
1124
1024
    painter.setPen(tmpPen);
1125
1025
 
1126
1026
    qreal indent = 0.0;
1152
1052
        fontOffset = qMax(fontMetrics.underlinePos() + 1, fontMetrics.descent());
1153
1053
    }
1154
1054
 
1155
 
    const int tmpAngle = d->style.angle();
 
1055
    const int tmpAngle = fixAngle(d->style.angle());
1156
1056
    const bool tmpVerticalText = d->style.verticalText();
1157
1057
    // force multiple rows on explicitly set line breaks
1158
1058
    const bool tmpMultiRow = d->style.wrapText() || d->displayText.contains('\n');
1159
1059
    const bool tmpVDistributed = vAlign == Style::VJustified || vAlign == Style::VDistributed;
1160
1060
    const bool tmpRichText = !d->richText.isNull();
1161
1061
 
 
1062
 
 
1063
    // set a clipping region for non-rotated text
 
1064
    painter.save();
 
1065
    if (tmpAngle == 0)
 
1066
        painter.setClipRect(QRectF(coordinate, QSizeF(d->width, d->height)));
 
1067
 
 
1068
 
1162
1069
    // Actually paint the text.
1163
1070
    //    There are 5 possible cases:
1164
1071
    //        - One line of plain text , horizontal
1175
1082
    } else if (tmpAngle != 0) {
1176
1083
        // Case 2: an angle.
1177
1084
 
1178
 
        int angle = ((tmpAngle % 360) + 360) % 360;
1179
 
        // now angle is between 0 and 359, but 181-359 should be -179 - -1
1180
 
        if (angle > 180) angle = angle - 360;
1181
 
 
1182
 
        painter.rotate(angle);
 
1085
        painter.rotate(tmpAngle);
1183
1086
        qreal x;
1184
 
        if (angle > 0)
1185
 
            x = indent + coordinate.x();
 
1087
        if (tmpAngle > 0)
 
1088
            x = indent + d->textX + coordinate.x();
1186
1089
        else
1187
 
            x = indent + coordinate.x()
1188
 
                - (fontMetrics.descent() + fontMetrics.ascent()) * ::sin(angle * M_PI / 180);
 
1090
            x = indent + d->textX + coordinate.x()
 
1091
                - (fontMetrics.descent() + fontMetrics.ascent()) * ::sin(tmpAngle * M_PI / 180);
1189
1092
        qreal y;
1190
 
        if (angle > 0)
 
1093
        if (tmpAngle > 0)
1191
1094
            y = coordinate.y() + d->textY;
1192
1095
        else
1193
1096
            y = coordinate.y() + d->textY + d->textHeight;
1194
 
        const QPointF position(x * ::cos(angle * M_PI / 180) + y * ::sin(angle * M_PI / 180),
1195
 
                               -x * ::sin(angle * M_PI / 180) + y * ::cos(angle * M_PI / 180));
 
1097
        if (tmpAngle < -90 || tmpAngle > 90) {
 
1098
            x += d->textWidth;
 
1099
        }
 
1100
        const QPointF position(x * ::cos(tmpAngle * M_PI / 180) + y * ::sin(tmpAngle * M_PI / 180),
 
1101
                               -x * ::sin(tmpAngle * M_PI / 180) + y * ::cos(tmpAngle * M_PI / 180));
1196
1102
        drawText(painter, position, d->displayText.split('\n'), cell);
1197
 
        painter.rotate(-angle);
 
1103
        painter.rotate(-tmpAngle);
1198
1104
    } else if (tmpMultiRow && !tmpVerticalText && !tmpRichText) {
1199
1105
        // Case 3: Multiple rows, but horizontal.
1200
1106
        const QPointF position(indent + coordinate.x(), coordinate.y() + d->textY);
1209
1115
        qreal space = d->width - d->textWidth;
1210
1116
        if (space > 0) {
1211
1117
            switch (hAlign) {
1212
 
                case Style::Center:
1213
 
                case Style::HAlignUndefined:
1214
 
                    dx += space/2;
1215
 
                    break;
1216
 
                case Style::Right:
1217
 
                    dx += space;
1218
 
                    break;
1219
 
                default:
1220
 
                    break;
 
1118
            case Style::Center:
 
1119
            case Style::HAlignUndefined:
 
1120
                dx += space / 2;
 
1121
                break;
 
1122
            case Style::Right:
 
1123
                dx += space;
 
1124
                break;
 
1125
            default:
 
1126
                break;
1221
1127
            }
1222
1128
        }
1223
1129
        for (int i = 0; i < textLines.count(); ++i) {
1234
1140
        QSharedPointer<QTextDocument> doc = d->richText;
1235
1141
        doc->setDefaultTextOption(d->textOptions());
1236
1142
        const QPointF position(coordinate.x() + indent,
1237
 
                               coordinate.y() + d->textY);
 
1143
                               coordinate.y() + d->textY - d->textHeight);
1238
1144
        painter.translate(position);
1239
1145
 
1240
1146
        QAbstractTextDocumentLayout::PaintContext ctx;
1261
1167
        return;
1262
1168
 
1263
1169
    SheetPrint* const print = cell.sheet()->print();
 
1170
    const PrintSettings *const settings = cell.sheet()->printSettings();
 
1171
    const QRect printRange = settings->printRegion().lastRange();
1264
1172
 
1265
1173
    // Draw page borders
1266
1174
    QLineF line;
1267
1175
 
1268
 
    if (cell.column() >= print->printRange().left()
1269
 
            && cell.column() <= print->printRange().right() + 1
1270
 
            && cell.row() >= print->printRange().top()
1271
 
            && cell.row() <= print->printRange().bottom() + 1) {
 
1176
    if (cell.column() >= printRange.left()
 
1177
            && cell.column() <= printRange.right() + 1
 
1178
            && cell.row() >= printRange.top()
 
1179
            && cell.row() <= printRange.bottom() + 1) {
1272
1180
        if (print->isColumnOnNewPage(cell.column())
1273
 
                && cell.row() <= print->printRange().bottom()) {
 
1181
                && cell.row() <= printRange.bottom()) {
1274
1182
            painter.setPen(cell.sheet()->map()->settings()->pageBorderColor());
1275
1183
 
1276
1184
            if (cell.sheet()->layoutDirection() == Qt::RightToLeft)
1283
1191
        }
1284
1192
 
1285
1193
        if (print->isRowOnNewPage(cell.row()) &&
1286
 
                (cell.column() <= print->printRange().right())) {
 
1194
                (cell.column() <= printRange.right())) {
1287
1195
            painter.setPen(cell.sheet()->map()->settings()->pageBorderColor());
1288
1196
            line = QLineF(coordinate.x(),  coordinate.y(),
1289
1197
                          coordinate.x() + d->width, coordinate.y());
1292
1200
 
1293
1201
        if (paintBorder & RightBorder) {
1294
1202
            if (print->isColumnOnNewPage(cell.column() + 1)
1295
 
                    && cell.row() <= print->printRange().bottom()) {
 
1203
                    && cell.row() <= printRange.bottom()) {
1296
1204
                painter.setPen(cell.sheet()->map()->settings()->pageBorderColor());
1297
1205
 
1298
1206
                if (cell.sheet()->layoutDirection() == Qt::RightToLeft)
1307
1215
 
1308
1216
        if (paintBorder & BottomBorder) {
1309
1217
            if (print->isRowOnNewPage(cell.row() + 1)
1310
 
                    && cell.column() <= print->printRange().right()) {
 
1218
                    && cell.column() <= printRange.right()) {
1311
1219
                painter.setPen(cell.sheet()->map()->settings()->pageBorderColor());
1312
1220
                line = QLineF(coordinate.x(),  coordinate.y() + d->height,
1313
1221
                              coordinate.x() + d->width, coordinate.y() + d->height);
1430
1338
        }
1431
1339
        painter.drawLine(line);
1432
1340
    }
1433
 
 
1434
 
    // FIXME: Look very closely at when the following code is really needed.
1435
 
    //        I can't really see any case, but I might be wrong.
1436
 
    //        Since the code below is buggy, and incredibly complex,
1437
 
    //        I am currently disabling it.  If somebody wants to enable
1438
 
    //        it again, then please also solve bug 68977: "Embedded KSpread
1439
 
    //        document printing problem" at the same time.
1440
 
    return;
1441
 
 
1442
 
#if 0
1443
 
    // Look at the cells on our corners. It may happen that we
1444
 
    // just erased parts of their borders corner, so we might need
1445
 
    // to repaint these corners.
1446
 
    //
1447
 
    QPen  vert_pen, horz_pen;
1448
 
    int   vert_penWidth, horz_penWidth;
1449
 
 
1450
 
    // Some useful referenses.
1451
 
    Cell  *cell_north     = Cell(cell.sheet(), cellRef.x(),     cellRef.y() - 1);
1452
 
    Cell  *cell_northwest = Cell(cell.sheet(), cellRef.x() - 1, cellRef.y() - 1);
1453
 
    Cell  *cell_west      = Cell(cell.sheet(), cellRef.x() - 1, cellRef.y());
1454
 
    Cell  *cell_northeast = Cell(cell.sheet(), cellRef.x() + 1, cellRef.y() - 1);
1455
 
    Cell  *cell_east      = Cell(cell.sheet(), cellRef.x() + 1, cellRef.y());
1456
 
    Cell  *cell_south     = Cell(cell.sheet(), cellRef.x(),     cellRef.y() + 1);
1457
 
    Cell  *cell_southwest = Cell(cell.sheet(), cellRef.x() - 1, cellRef.y() + 1);
1458
 
    Cell  *cell_southeast = Cell(cell.sheet(), cellRef.x() + 1, cellRef.y() + 1);
1459
 
 
1460
 
    // Fix the borders which meet at the top left corner
1461
 
    if (cell_north->effLeftBorderValue(cellRef.x(), cellRef.y() - 1)
1462
 
            >= cell_northwest->effRightBorderValue(cellRef.x() - 1, cellRef.y() - 1))
1463
 
        vert_pen = cell_north->effLeftBorderPen(cellRef.x(), cellRef.y() - 1);
1464
 
    else
1465
 
        vert_pen = cell_northwest->effRightBorderPen(cellRef.x() - 1, cellRef.y() - 1);
1466
 
 
1467
 
    vert_penWidth = qMax(1, doc->zoomItXOld(vert_pen.width()));
1468
 
    vert_pen.setWidth(vert_penWidth);
1469
 
 
1470
 
    if (vert_pen.style() != Qt::NoPen) {
1471
 
        if (cell_west->effTopBorderValue(cellRef.x() - 1, cellRef.y())
1472
 
                >= cell_northwest->effBottomBorderValue(cellRef.x() - 1, cellRef.y() - 1))
1473
 
            horz_pen = cell_west->effTopBorderPen(cellRef.x() - 1, cellRef.y());
1474
 
        else
1475
 
            horz_pen = cell_northwest->effBottomBorderPen(cellRef.x() - 1, cellRef.y() - 1);
1476
 
 
1477
 
        horz_penWidth = qMax(1, doc->zoomItYOld(horz_pen.width()));
1478
 
        int bottom = (qMax(0, -1 + horz_penWidth)) / 2 + 1;
1479
 
 
1480
 
        painter.setPen(vert_pen);
1481
 
        // If we are on paper printout, we limit the length of the lines.
1482
 
        // On paper, we always have full cells, on screen not.
1483
 
        if (dynamic_cast<QPrinter*>(painter.device())) {
1484
 
            if (cell.sheet()->layoutDirection() == Qt::RightToLeft)
1485
 
                painter.drawLine(qMax(rect.left(), coordinate.x() + d->width),
1486
 
                                 qMax(rect.top(), coordinate.y()),
1487
 
                                 qMin(rect.right(), coordinate.x() + d->width),
1488
 
                                 qMin(rect.bottom(), coordinate.y() + bottom));
1489
 
            else
1490
 
                painter.drawLine(qMax(rect.left(), coordinate.x()),
1491
 
                                 qMax(rect.top(), coordinate.y()),
1492
 
                                 qMin(rect.right(), coordinate.x()),
1493
 
                                 qMin(rect.bottom(), coordinate.y() + bottom));
1494
 
        } else {
1495
 
            if (cell.sheet()->layoutDirection() == Qt::RightToLeft)
1496
 
                painter.drawLine(coordinate.x() + d->width, coordinate.y(),
1497
 
                                 coordinate.x() + d->width, coordinate.y() + bottom);
1498
 
            else
1499
 
                painter.drawLine(coordinate.x(), coordinate.y(),
1500
 
                                 coordinate.x(), coordinate.y() + bottom);
1501
 
        }
1502
 
    }
1503
 
 
1504
 
    // Fix the borders which meet at the top right corner
1505
 
    if (cell_north->effRightBorderValue(cellRef.x(), cellRef.y() - 1)
1506
 
            >= cell_northeast->effLeftBorderValue(cellRef.x() + 1,
1507
 
                                                  cellRef.y() - 1))
1508
 
        vert_pen = cell_north->effRightBorderPen(cellRef.x(), cellRef.y() - 1);
1509
 
    else
1510
 
        vert_pen = cell_northeast->effLeftBorderPen(cellRef.x() + 1,
1511
 
                   cellRef.y() - 1);
1512
 
 
1513
 
    // vert_pen = effRightBorderPen( cellRef.x(), cellRef.y() - 1 );
1514
 
    vert_penWidth = qMax(1, doc->zoomItXOld(vert_pen.width()));
1515
 
    vert_pen.setWidth(vert_penWidth);
1516
 
    if ((vert_pen.style() != Qt::NoPen) && (cellRef.x() < KS_colMax)) {
1517
 
        if (cell_east->effTopBorderValue(cellRef.x() + 1, cellRef.y())
1518
 
                >= cell_northeast->effBottomBorderValue(cellRef.x() + 1,
1519
 
                                                        cellRef.y() - 1))
1520
 
            horz_pen = cell_east->effTopBorderPen(cellRef.x() + 1, cellRef.y());
1521
 
        else
1522
 
            horz_pen = cell_northeast->effBottomBorderPen(cellRef.x() + 1,
1523
 
                       cellRef.y() - 1);
1524
 
 
1525
 
        // horz_pen = cell.effTopBorderPen( cellRef.x() + 1, cellRef.y() );
1526
 
        horz_penWidth = qMax(1, doc->zoomItYOld(horz_pen.width()));
1527
 
        int bottom = (qMax(0, -1 + horz_penWidth)) / 2 + 1;
1528
 
 
1529
 
        painter.setPen(vert_pen);
1530
 
        //If we are on paper printout, we limit the length of the lines
1531
 
        //On paper, we always have full cells, on screen not
1532
 
        if (dynamic_cast<QPrinter*>(painter.device())) {
1533
 
            if (cell.sheet()->layoutDirection() == Qt::RightToLeft)
1534
 
                painter.drawLine(qMax(rect.left(), coordinate.x()),
1535
 
                                 qMax(rect.top(), coordinate.y()),
1536
 
                                 qMin(rect.right(), coordinate.x()),
1537
 
                                 qMin(rect.bottom(), coordinate.y() + bottom));
1538
 
            else
1539
 
                painter.drawLine(qMax(rect.left(), coordinate.x() + d->width),
1540
 
                                 qMax(rect.top(), coordinate.y()),
1541
 
                                 qMin(rect.right(), coordinate.x() + d->width),
1542
 
                                 qMin(rect.bottom(), coordinate.y() + bottom));
1543
 
        } else {
1544
 
            if (cell.sheet()->layoutDirection() == Qt::RightToLeft)
1545
 
                painter.drawLine(coordinate.x(), coordinate.y(),
1546
 
                                 coordinate.x(), coordinate.y() + bottom);
1547
 
            else
1548
 
                painter.drawLine(coordinate.x() + d->width, coordinate.y(),
1549
 
                                 coordinate.x() + d->width, coordinate.y() + bottom);
1550
 
        }
1551
 
    }
1552
 
 
1553
 
    // Bottom
1554
 
    if (cellRef.y() < KS_rowMax) {
1555
 
        // Fix the borders which meet at the bottom left corner
1556
 
        if (cell_south->effLeftBorderValue(cellRef.x(), cellRef.y() + 1)
1557
 
                >= cell_southwest->effRightBorderValue(cellRef.x() - 1,
1558
 
                                                       cellRef.y() + 1))
1559
 
            vert_pen = cell_south->effLeftBorderPen(cellRef.x(), cellRef.y() + 1);
1560
 
        else
1561
 
            vert_pen = cell_southwest->effRightBorderPen(cellRef.x() - 1,
1562
 
                       cellRef.y() + 1);
1563
 
 
1564
 
        // vert_pen = effLeftBorderPen( cellRef.x(), cellRef.y() + 1 );
1565
 
        vert_penWidth = qMax(1, doc->zoomItYOld(vert_pen.width()));
1566
 
        vert_pen.setWidth(vert_penWidth);
1567
 
        if (vert_pen.style() != Qt::NoPen) {
1568
 
            if (cell_west->effBottomBorderValue(cellRef.x() - 1, cellRef.y())
1569
 
                    >= cell_southwest->effTopBorderValue(cellRef.x() - 1,
1570
 
                                                         cellRef.y() + 1))
1571
 
                horz_pen = cell_west->effBottomBorderPen(cellRef.x() - 1,
1572
 
                           cellRef.y());
1573
 
            else
1574
 
                horz_pen = cell_southwest->effTopBorderPen(cellRef.x() - 1,
1575
 
                           cellRef.y() + 1);
1576
 
 
1577
 
            // horz_pen = cell.effBottomBorderPen( cellRef.x() - 1, cellRef.y() );
1578
 
            horz_penWidth = qMax(1, doc->zoomItXOld(horz_pen.width()));
1579
 
            int bottom = (qMax(0, -1 + horz_penWidth)) / 2;
1580
 
 
1581
 
            painter.setPen(vert_pen);
1582
 
            // If we are on paper printout, we limit the length of the lines.
1583
 
            // On paper, we always have full cells, on screen not.
1584
 
            if (dynamic_cast<QPrinter*>(painter.device())) {
1585
 
                if (cell.sheet()->layoutDirection() == Qt::RightToLeft)
1586
 
                    painter.drawLine(qMax(rect.left(), coordinate.x() + d->width),
1587
 
                                     qMax(rect.top(), coordinate.y() + d->height - bottom),
1588
 
                                     qMin(rect.right(), coordinate.x() + d->width),
1589
 
                                     qMin(rect.bottom(), coordinate.y() + d->height));
1590
 
                else
1591
 
                    painter.drawLine(qMax(rect.left(), coordinate.x()),
1592
 
                                     qMax(rect.top(), coordinate.y() + d->height - bottom),
1593
 
                                     qMin(rect.right(), coordinate.x()),
1594
 
                                     qMin(rect.bottom(), coordinate.y() + d->height));
1595
 
            } else {
1596
 
                if (cell.sheet()->layoutDirection() == Qt::RightToLeft)
1597
 
                    painter.drawLine(coordinate.x() + d->width, coordinate.y() + d->height - bottom,
1598
 
                                     coordinate.x() + d->width, coordinate.y() + d->height);
1599
 
                else
1600
 
                    painter.drawLine(coordinate.x(), coordinate.y() + d->height - bottom,
1601
 
                                     coordinate.x(), coordinate.y() + d->height);
1602
 
            }
1603
 
        }
1604
 
 
1605
 
        // Fix the borders which meet at the bottom right corner
1606
 
        if (cell_south->effRightBorderValue(cellRef.x(), cellRef.y() + 1)
1607
 
                >= cell_southeast->effLeftBorderValue(cellRef.x() + 1, cellRef.y() + 1))
1608
 
            vert_pen = cell_south->effRightBorderPen(cellRef.x(), cellRef.y() + 1);
1609
 
        else
1610
 
            vert_pen = cell_southeast->effLeftBorderPen(cellRef.x() + 1, cellRef.y() + 1);
1611
 
 
1612
 
        // vert_pen = effRightBorderPen( cellRef.x(), cellRef.y() + 1 );
1613
 
        vert_penWidth = qMax(1, doc->zoomItYOld(vert_pen.width()));
1614
 
        vert_pen.setWidth(vert_penWidth);
1615
 
        if ((vert_pen.style() != Qt::NoPen) && (cellRef.x() < KS_colMax)) {
1616
 
            if (cell_east ->effBottomBorderValue(cellRef.x() + 1, cellRef.y())
1617
 
                    >= cell_southeast->effTopBorderValue(cellRef.x() + 1,
1618
 
                                                         cellRef.y() + 1))
1619
 
 
1620
 
                horz_pen = Cell(cell.sheet(), cellRef.x() + 1, cellRef.y())
1621
 
                           ->effBottomBorderPen(cellRef.x() + 1, cellRef.y());
1622
 
            else
1623
 
                horz_pen = Cell(cell.sheet(), cellRef.x() + 1, cellRef.y() + 1)
1624
 
                           ->effTopBorderPen(cellRef.x() + 1, cellRef.y() + 1);
1625
 
 
1626
 
            // horz_pen = cell.effBottomBorderPen( cellRef.x() + 1, cellRef.y() );
1627
 
            horz_penWidth = qMax(1, doc->zoomItXOld(horz_pen.width()));
1628
 
            int bottom = (qMax(0, -1 + horz_penWidth)) / 2;
1629
 
 
1630
 
            painter.setPen(vert_pen);
1631
 
            // If we are on paper printout, we limit the length of the lines.
1632
 
            // On paper, we always have full cells, on screen not.
1633
 
            if (dynamic_cast<QPrinter*>(painter.device()))      {
1634
 
                if (cell.sheet()->layoutDirection() == Qt::RightToLeft)
1635
 
                    painter.drawLine(qMax(rect.left(), coordinate.x()),
1636
 
                                     qMax(rect.top(), coordinate.y() + d->height - bottom),
1637
 
                                     qMin(rect.right(), coordinate.x()),
1638
 
                                     qMin(rect.bottom(), coordinate.y() + d->height));
1639
 
                else
1640
 
                    painter.drawLine(qMax(rect.left(), coordinate.x() + d->width),
1641
 
                                     qMax(rect.top(), coordinate.y() + d->height - bottom),
1642
 
                                     qMin(rect.right(), coordinate.x() + d->width),
1643
 
                                     qMin(rect.bottom(), coordinate.y() + d->height));
1644
 
            } else {
1645
 
                if (cell.sheet()->layoutDirection() == Qt::RightToLeft)
1646
 
                    painter.drawLine(coordinate.x(), coordinate.y() + d->height - bottom,
1647
 
                                     coordinate.x(), coordinate.y() + d->height);
1648
 
                else
1649
 
                    painter.drawLine(coordinate.x() + d->width, coordinate.y() + d->height - bottom,
1650
 
                                     coordinate.x() + d->width, coordinate.y() + d->height);
1651
 
            }
1652
 
        }
1653
 
    }
1654
 
#endif
1655
1341
}
1656
1342
 
1657
1343
 
1711
1397
    if (style().wrapText() || d->richText) {
1712
1398
        // For wrapping text and richtext always draw all text
1713
1399
        return d->displayText;
 
1400
    } else if (style().angle() != 0) {
 
1401
        // Rotated text, return all text
 
1402
        return d->displayText;
1714
1403
    } else if (!style().verticalText()) {
1715
1404
        // Non-vertical text: the ordinary case.
1716
1405
 
1735
1424
        start = qMin(d->displayText.length(), start);
1736
1425
        // Start out with the whole text, cut one character at a time, and
1737
1426
        // when the text finally fits, return it.
1738
 
        for (int i = start; i != 0; i--) {
 
1427
        for (int i = start; i >= 0; i--) {
1739
1428
            //Note that numbers are always treated as left-aligned since if we have to cut digits off, they should
1740
1429
            //always be the least significant ones at the end of the string
1741
1430
            if (hAlign == Style::Left || hAlign == Style::HAlignUndefined || isNumeric)
1848
1537
 
1849
1538
    // First, create a device independent font and its metrics.
1850
1539
    KoPostscriptPaintDevice device;
1851
 
    const QFont font(d->style.font(), &device);
1852
 
    const QFontMetricsF fontMetrics(font, &device);
 
1540
    QFont font(d->style.font(), &device);
 
1541
    QFontMetricsF fontMetrics(font, &device);
1853
1542
 
1854
1543
    // Then calculate text dimensions, i.e. d->textWidth and d->textHeight,
1855
1544
    // and check whether the text fits into the cell dimension by the way.
 
1545
 
1856
1546
    d->calculateTextSize(font, fontMetrics);
 
1547
    d->shrinkToFitFontSize = 0.0;
 
1548
 
 
1549
    //if shrink-to-fit is enabled, try to find a font size so that the string fits into the cell
 
1550
    if (d->style.shrinkToFit()) {
 
1551
        int lower = 1;
 
1552
        int upper = font.pointSize() * 2;
 
1553
        int siz = 0;
 
1554
        while (lower != upper) {
 
1555
            siz = static_cast<int>( std::ceil( lower + ( upper - lower ) / 2. ) );
 
1556
            font.setPointSizeF(siz / 2.);
 
1557
            fontMetrics = QFontMetricsF(font, &device);
 
1558
            d->calculateTextSize(font, fontMetrics);
 
1559
            if (d->fittingWidth)
 
1560
                lower = siz;
 
1561
            else
 
1562
                upper = siz - 1;
 
1563
        }
 
1564
        d->shrinkToFitFontSize = upper / 2.0;
 
1565
        font.setPointSizeF(upper / 2.0);
 
1566
        fontMetrics = QFontMetricsF(font, &device);
 
1567
        d->calculateTextSize(font, fontMetrics); // update fittingWidth et al
 
1568
        d->fittingWidth = true;
 
1569
    }
1857
1570
 
1858
1571
    // Obscure horizontal cells, if necessary.
1859
1572
    if (!d->fittingWidth) {
1877
1590
//         // Recalculate the text dimensions and check whether the text fits.
1878
1591
//         d->calculateTextSize(font, fontMetrics);
1879
1592
    }
1880
 
 
1881
1593
    // Recalculate the text offset.
1882
1594
    textOffset(fontMetrics, cell);
1883
1595
}
1923
1635
    const qreal ascent = fontMetrics.ascent();
1924
1636
    const Style::HAlign hAlign = d->style.halign();
1925
1637
    const Style::VAlign vAlign = d->style.valign();
1926
 
    const int tmpAngle = d->style.angle();
 
1638
    const int tmpAngle = fixAngle(d->style.angle());
1927
1639
    const bool tmpVerticalText = d->style.verticalText();
1928
1640
    const bool tmpMultiRow = d->style.wrapText() || d->displayText.contains('\n');
1929
1641
    const bool tmpRichText = !d->richText.isNull();
1941
1653
    case Style::VJustified:
1942
1654
    case Style::Top: {
1943
1655
        if (tmpAngle == 0 && tmpRichText) {
1944
 
            d->textY = effTop;
 
1656
            d->textY = effTop + d->textHeight;
1945
1657
        } else if (tmpAngle == 0) {
1946
1658
            d->textY = effTop + ascent;
1947
1659
        } else if (tmpAngle < 0) {
1956
1668
        if (!tmpVerticalText && !tmpMultiRow && !tmpAngle && !tmpRichText) {
1957
1669
            d->textY = effBottom;
1958
1670
        } else if (tmpAngle != 0) {
1959
 
            // Is enough place available?
1960
 
            if (effBottom - effTop - d->textHeight > 0) {
1961
 
                if (tmpAngle < 0) {
1962
 
                    d->textY = effBottom - d->textHeight;
1963
 
                } else {
1964
 
                    d->textY = effBottom - d->textHeight + ascent * ::cos(tmpAngle * M_PI / 180);
1965
 
                }
 
1671
            if (tmpAngle < 0) {
 
1672
                d->textY = effBottom - d->textHeight;
1966
1673
            } else {
1967
 
                if (tmpAngle < 0) {
1968
 
                    d->textY = effTop;
1969
 
                } else {
1970
 
                    d->textY = effTop + ascent * ::cos(tmpAngle * M_PI / 180);
1971
 
                }
 
1674
                d->textY = effBottom - d->textHeight + ascent * ::cos(tmpAngle * M_PI / 180);
 
1675
            }
 
1676
            if (tmpAngle < -90 || tmpAngle > 90) {
 
1677
                d->textY += ascent * ::cos(tmpAngle * M_PI / 180);
1972
1678
            }
1973
1679
        } else if (tmpRichText) {
1974
 
            d->textY = effBottom - d->textHeight;
 
1680
            d->textY = effBottom;
1975
1681
        } else if (tmpMultiRow && !tmpVerticalText) {
1976
 
            // Is enough place available?
1977
 
            if (effBottom - effTop - d->textHeight > 0) {
1978
 
                d->textY = effBottom - d->textHeight + ascent;
1979
 
            } else {
1980
 
                d->textY = effTop + ascent;
1981
 
            }
1982
 
        } else {
 
1682
            d->textY = effBottom - d->textHeight + ascent;
 
1683
        } else { // vertical text
1983
1684
            // Is enough place available?
1984
1685
            if (effBottom - effTop - d->textHeight > 0) {
1985
1686
                d->textY = effBottom - d->textHeight + ascent;
2014
1715
                }
2015
1716
            }
2016
1717
        } else if (tmpRichText && !tmpVerticalText) {
2017
 
            d->textY = (h - d->textHeight) / 2;
 
1718
            d->textY = (h - d->textHeight) / 2 + d->textHeight;
2018
1719
        } else if (tmpMultiRow && !tmpVerticalText) {
2019
1720
            // Is enough place available?
2020
1721
            if (effBottom - effTop - d->textHeight > 0) {
2152
1853
        while (status == Undefined) {
2153
1854
            Cell nextCell = Cell(masterCell.sheet(), masterCell.column(), row + 1).masterCell();
2154
1855
 
2155
 
            if (nextCell.isEmpty()) {
 
1856
            bool isEmpty = true;
 
1857
            
 
1858
            for (int col = 0; col < masterCell.mergedXCells() + d->obscuredCellsX+1; col++) {
 
1859
                Cell cellNext = Cell(masterCell.sheet(), masterCell.column() + col, row + 1).masterCell();
 
1860
                if (!cellNext.isEmpty()) {
 
1861
                    isEmpty = false;
 
1862
                    break;
 
1863
                }
 
1864
            }
 
1865
            if (isEmpty) {
2156
1866
                extraHeight += nextCell.height();
2157
1867
                row += 1 + nextCell.mergedYCells();
2158
1868
 
2187
1897
    Q_UNUSED(cell)
2188
1898
 
2189
1899
    KoPostscriptPaintDevice device;
2190
 
    const QFont font(d->style.font(), &device);
 
1900
    const QFont font(d->calculateFont(), &device);
2191
1901
    const QFontMetricsF fontMetrics(font, &device);
2192
1902
 
2193
1903
    const qreal leading = fontMetrics.leading();
2195
1905
    const QTextOption options = d->textOptions();
2196
1906
 
2197
1907
    const bool tmpVerticalText = d->style.verticalText();
2198
 
    const qreal lineWidth = tmpVerticalText ? fontMetrics.maxWidth() :
2199
 
                                        (d->width - 2 * s_borderSpace
2200
 
                                        - 0.5 * d->style.leftBorderPen().width()
2201
 
                                        - 0.5 * d->style.rightBorderPen().width());
 
1908
    const bool tmpAngled = fixAngle(d->style.angle()) != 0;
 
1909
    const qreal tmpIndent = cell.isEmpty() || d->style.halign() != Style::Left ? 0.0 : style().indentation();
 
1910
    const qreal lineWidth = tmpAngled ? 1e9 : tmpVerticalText ? fontMetrics.maxWidth() :
 
1911
                            (d->width - 2 * s_borderSpace
 
1912
                             - 0.5 * d->style.leftBorderPen().width()
 
1913
                             - 0.5 * d->style.rightBorderPen().width())
 
1914
                             - tmpIndent;
2202
1915
 
2203
1916
    qreal offset = 1.0 - fontMetrics.ascent();
2204
1917
    for (int i = 0; i < textLines.count(); ++i) {
2216
1929
            line.setLineWidth(lineWidth);
2217
1930
            height += leading;
2218
1931
            line.setPosition(QPointF((s_borderSpace + 0.5 * d->style.leftBorderPen().widthF()),
2219
 
                                    height));
 
1932
                                     height));
2220
1933
 
2221
1934
            height += line.height() + lineSpacing;
2222
1935
        }
2307
2020
    const qreal leading = fontMetrics.leading();
2308
2021
    const QTextOption options = textOptions();
2309
2022
 
 
2023
    const qreal tmpIndent = style.halign() != Style::Left ? 0.0 : style.indentation();
 
2024
    const qreal lineWidth = (width - 2 * s_borderSpace
 
2025
                             - 0.5 * style.leftBorderPen().width()
 
2026
                             - 0.5 * style.rightBorderPen().width())
 
2027
                             - tmpIndent;
 
2028
 
2310
2029
    textHeight = 0.0;
2311
2030
    textWidth = 0.0;
2312
2031
    textLinesCount = 0;
2321
2040
            QTextLine line = textLayout.createLine();
2322
2041
            if (!line.isValid())
2323
2042
                break; // forever
2324
 
            line.setLineWidth(width);
 
2043
            line.setLineWidth(lineWidth);
2325
2044
            textHeight += leading + line.height();
2326
2045
            if ((textHeight - fontMetrics.descent()) > (height - 2 * s_borderSpace
2327
2046
                    - 0.5 * style.topBorderPen().width()
2335
2054
    }
2336
2055
    // The width fits, if the text is wrapped or all lines are smaller than the cell width.
2337
2056
    fittingWidth = style.wrapText() ||
2338
 
                   textWidth <= (width - 2 * s_borderSpace
2339
 
                                 - 0.5 * style.leftBorderPen().width()
2340
 
                                 - 0.5 * style.rightBorderPen().width());
 
2057
                   textWidth <= lineWidth;
2341
2058
}
2342
2059
 
2343
2060
void CellView::Private::calculateVerticalTextSize(const QFont& font, const QFontMetricsF& fontMetrics)
2356
2073
void CellView::Private::calculateAngledTextSize(const QFont& font, const QFontMetricsF& fontMetrics)
2357
2074
{
2358
2075
    Q_UNUSED(font)
2359
 
    const qreal angle = style.angle();
 
2076
    const qreal angle = fixAngle(style.angle());
2360
2077
    const qreal height = fontMetrics.ascent() + fontMetrics.descent();
2361
2078
    const qreal width  = fontMetrics.width(displayText);
2362
 
    textHeight = height * ::cos(angle * M_PI / 180) + qAbs(width * ::sin(angle * M_PI / 180));
2363
 
    textWidth = qAbs(height * ::sin(angle * M_PI / 180)) + width * ::cos(angle * M_PI / 180);
 
2079
    textHeight = qAbs(height * ::cos(angle * M_PI / 180)) + qAbs(width * ::sin(angle * M_PI / 180));
 
2080
    textWidth = qAbs(height * ::sin(angle * M_PI / 180)) + qAbs(width * ::cos(angle * M_PI / 180));
2364
2081
    fittingHeight = textHeight <= this->width;
2365
2082
    fittingWidth = textWidth <= this->height;
2366
2083
}
2448
2165
        break;
2449
2166
    case Style::Center:
2450
2167
        options.setAlignment(Qt::AlignHCenter);
 
2168
        break;
 
2169
    case Style::Justified:
 
2170
        options.setAlignment(Qt::AlignJustify);
 
2171
        break;
2451
2172
    }
2452
2173
    // The text consists of a single character, if it's vertical. Always center it.
2453
2174
    if (style.verticalText())