379{
381 const QString imageFileName = fileInfo.baseName();
385
386 if (dlg.exec() == QDialog::Accepted) {
387 dlg.hide();
388 KisCursorOverrideLock cursorLock(Qt::WaitCursor);
389
390 ExportPage layoutPage;
391 QPrinter printer(QPrinter::HighResolution);
392
393
394 QPainter painter;
395 QSvgGenerator generator;
396
397 QFont font = painter.font();
398 font.setPointSize(dlg.fontSize());
399
401
402
403 bool layoutSpecifiedBySvg = dlg.layoutSpecifiedBySvgFile();
404 if (layoutSpecifiedBySvg) {
405 QString svgFileName = dlg.layoutSvgFile();
407 }
408 else {
409 int rows = dlg.rows();
410 int columns = dlg.columns();
411 printer.setOutputFileName(dlg.saveFileName());
412 printer.setPageSize(dlg.pageSize());
413 printer.setPageOrientation(dlg.pageOrientation());
414 painter.begin(&printer);
415 painter.setFont(font);
417 columns,
419 printer.pageLayout().paintRectPixels(printer.resolution()),
420 painter.fontMetrics());
421 painter.end();
422 }
423
425
426
429
430 if (!firstIndex.isValid() || !lastIndex.isValid()) {
431 QMessageBox::warning((QWidget*)(&dlg), i18nc("@title:window", "Krita"), i18n("Please enter correct range. There are no panels in the range of frames provided."));
432 return;
433 }
434
435 int firstItemRow = firstIndex.row();
436 int lastItemRow = lastIndex.row();
437
438 int numBoards = lastItemRow - firstItemRow + 1;
439 if (numBoards <= 0) {
440 QMessageBox::warning((QWidget*)(&dlg), i18nc("@title:window", "Krita"), i18n("Please enter correct range. There are no panels in the range of frames provided."));
441 return;
442 }
443
445 generator.setFileName(dlg.saveFileName() + "/" + imageFileName + "0.svg");
446 QSize sz = printer.pageLayout().paintRectPixels(printer.resolution()).size();
447 generator.setSize(sz);
448 generator.setViewBox(QRect(0, 0, sz.width(), sz.height()));
449 generator.setResolution(printer.resolution());
450 painter.begin(&generator);
451 painter.setBrush(QBrush(QColor(255,255,255)));
452 painter.drawRect(QRect(0,0, sz.width(), sz.height()));
453 }
454 else {
455 printer.setOutputFileName(dlg.saveFileName());
456 printer.setOutputFormat(QPrinter::PdfFormat);
457 painter.begin(&printer);
458 painter.setFont(font);
459 painter.setBackgroundMode(Qt::BGMode::OpaqueMode);
460 }
461
462
463 int pageNumber = 1;
464 int pageDurationInFrames = 0;
465
466 for (int currentBoard = 0; currentBoard < numBoards; currentBoard++) {
467 if (currentBoard % layoutPage.elements.length() == 0) {
469 if (currentBoard != 0) {
470 painter.end();
471 painter.eraseRect(printer.pageLayout().paintRectPixels(printer.resolution()));
472 generator.setFileName(dlg.saveFileName() + "/" + imageFileName + QString::number(currentBoard / layoutPage.elements.length()) + ".svg");
473 QSize sz = printer.pageLayout().paintRectPixels(printer.resolution()).size();
474 generator.setSize(sz);
475 generator.setViewBox(QRect(0, 0, sz.width(), sz.height()));
476 generator.setResolution(printer.resolution());
477 painter.begin(&generator);
478 }
479 }
480 else {
481 if (currentBoard != 0 ) {
482 printer.newPage();
483
484 pageNumber++;
485 pageDurationInFrames = 0;
486 }
487
488 if(layoutPage.svg) {
489 QMap<QString, QDomNode> groups =
rootItemsInSvg(layoutPage.svg.value());
490 if (groups.contains("overlay")) {
491 QMapIterator<QString, QDomNode> iter(groups);
492 while(iter.hasNext()) {
493 iter.next();
494 if (iter.key() == "overlay" || iter.key() == "layout") {
495 iter.value().toElement().setAttribute("display","none");
496 } else {
497 iter.value().toElement().setAttribute("display","inline");
498 }
499 }
500 }
501 QSvgRenderer renderer(layoutPage.svg->toByteArray());
502 renderer.render(&painter);
503 }
504 }
505 }
506
508 QPixmap pxmp = qvariant_cast<QPixmap>(data.
pixmap);
510 const int numComments = comments.size();
511
512 const ExportPageShot* const layoutShot = &layoutPage.elements[currentBoard % layoutPage.elements.length()];
513
514 QPen pen(QColor(1, 0, 0));
515 pen.setWidth(5);
516 painter.setPen(pen);
517
518
519 if (layoutShot->cutImageRect.has_value()) {
520 QRectF imgRect = layoutShot->cutImageRect.value();
521 QSizeF resizedImage = QSizeF(pxmp.size()).scaled(layoutShot->cutImageRect->size(), Qt::KeepAspectRatio);
523 resizedImage = QSize(resizedImage.width() +
MARGIN * 2, resizedImage.height() +
MARGIN * 2);
524 imgRect.setSize(resizedImage);
525 imgRect.translate((layoutShot->cutImageRect.value().width() - imgRect.size().width()) / 2 -
MARGIN,
526 (layoutShot->cutImageRect->height() - imgRect.size().height()) / 2 -
MARGIN);
527 painter.drawPixmap(imgRect, pxmp, pxmp.rect());
528 painter.drawRect(layoutShot->cutImageRect.value());
529 }
530
531 {
532 painter.save();
533 painter.setBackgroundMode(Qt::TransparentMode);
534
535
536 if (layoutShot->cutNameRect.has_value()) {
538 painter.drawText(layoutShot->cutNameRect.value().translated(painter.fontMetrics().averageCharWidth() / 2, 0), Qt::AlignLeft | Qt::AlignVCenter, str);
539
540 if (!layoutPage.svg) {
541 painter.drawRect(layoutShot->cutNameRect.value());
542 }
543 }
544
545
546 if (layoutShot->cutNumberRect.has_value()) {
547 painter.drawText(layoutShot->cutNumberRect.value(), Qt::AlignCenter, QString::number(currentBoard + firstItemRow));
548
549 if (!layoutPage.svg) {
550 painter.drawRect(layoutShot->cutNumberRect.value());
551 }
552 }
553
554 QModelIndex boardIndex =
m_storyboardModel->index(currentBoard + firstItemRow, 0);
555
557 pageDurationInFrames += boardDurationFrames;
558
559
560 if (layoutShot->cutDurationRect.has_value()) {
561
562 int durationSecondsPart = boardDurationFrames /
m_storyboardModel->getFramesPerSecond();
563 int durationFramesPart = boardDurationFrames %
m_storyboardModel->getFramesPerSecond();
564
565 painter.drawText(layoutShot->cutDurationRect.value(), Qt::AlignCenter,
567
568 if (!layoutPage.svg) {
569 painter.drawRect(layoutShot->cutDurationRect.value());
570 }
571 }
572
573 painter.restore();
574 }
575
576
577
578 for (int commentIndex = 0; commentIndex < numComments; commentIndex++) {
579 if (!layoutShot->commentRects.contains(comments[commentIndex].name))
580 continue;
581
582 const QString& commentName = comments[commentIndex].name;
583
584 QTextDocument doc;
585 doc.setDocumentMargin(0);
586 doc.setDefaultFont(painter.font());
587 QString comment;
588 comment += "<p><b>" + commentName + "</b></p>";
589 QString originalCommentText = qvariant_cast<CommentBox>(storyboardList.at(currentBoard + firstItemRow)->child(
StoryboardItem::Comments + commentIndex)->data()).content.toString();
590 originalCommentText = originalCommentText.replace('\n', "</p><p>");
591 comment += "<p> " + originalCommentText + "</p>";
592 const int MARGIN = painter.fontMetrics().averageCharWidth() / 2;
593
594 doc.setHtml(comment);
595 doc.setTextWidth(layoutShot->commentRects[commentName].width() -
MARGIN * 2);
596
597 QAbstractTextDocumentLayout::PaintContext ctx;
598 ctx.palette.setColor(QPalette::Text, painter.pen().color());
599
600
601 painter.save();
602 painter.translate(layoutShot->commentRects[commentName].topLeft() + QPoint(
MARGIN,
MARGIN));
603 painter.setClipRegion(QRegion(0,0,layoutShot->commentRects[commentName].width(), layoutShot->commentRects[commentName].height() - painter.fontMetrics().height()));
604 painter.setBackgroundMode(Qt::TransparentMode);
605 doc.documentLayout()->draw(&painter, ctx);
606 painter.restore();
607
608 painter.drawRect(layoutShot->commentRects[commentName]);
609 }
610
611
612 if ((currentBoard % layoutPage.elements.length()) == (layoutPage.elements.length() - 1) || (currentBoard == numBoards - 1)) {
613
614 painter.save();
615 painter.setBackgroundMode(Qt::TransparentMode);
616
617 if (layoutPage.pageNumberRect) {
618 painter.drawText(layoutPage.pageNumberRect.value(), Qt::AlignCenter, QString::number(pageNumber));
619 }
620
621 if (layoutPage.pageTimeRect) {
622 int pageDurationSecondsPart = pageDurationInFrames /
m_storyboardModel->getFramesPerSecond();
623 int pageDurationFramesPart = pageDurationInFrames %
m_storyboardModel->getFramesPerSecond();
624
625 painter.drawText(layoutPage.pageTimeRect.value(), Qt::AlignCenter,
buildDurationString(pageDurationSecondsPart, pageDurationFramesPart));
626 }
627
628 if (layoutPage.svg) {
629 QMap<QString, QDomNode> groups =
rootItemsInSvg(layoutPage.svg.value());
630 if (groups.contains("overlay")) {
631 QMapIterator<QString, QDomNode> iter(groups);
632 while(iter.hasNext()) {
633 iter.next();
634 if (iter.key() == "overlay") {
635 iter.value().toElement().setAttribute("display","inline");
636 } else {
637 iter.value().toElement().setAttribute("display","none");
638 }
639 }
640 }
641 QSvgRenderer renderer(layoutPage.svg->toByteArray());
642 renderer.render(&painter);
643 }
644
645 painter.restore();
646 }
647 }
648 painter.end();
649 }
650}
QString buildDurationString(int seconds, int frames)
ExportPage getPageLayout(int rows, int columns, const QRect &imageSize, const QRect &pageRect, const QFontMetrics &painter)
@ FrameNumber
Store the frame number at index 0. Data type stored here should be ThumbnailData.
@ ItemName
Store the item name at index 1. Data type stored here should be string.
@ Comments
Store the comments at indices greater_than_or_equal_to to index 4. Data type stored here should be Co...
@ TotalSceneDurationInFrames
This class is a simple combination of two QVariants. It can be converted to and from QVariant type an...
QVariant pixmap
a scaled down thumbnail version of the frame
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)