Ejemplo n.º 1
0
void Document::loadTheme(const Theme& theme)
{
	m_text->document()->blockSignals(true);

        m_block_default_format.clear();
        for(int i=0;i<theme.definedDefaultFormatsForBlocks().length();i++)
            m_block_default_format.insert(theme.definedDefaultFormatsForBlocks()[i],theme.defaultFormatForBlock(theme.definedDefaultFormatsForBlocks()[i]));

	// Update colors
	QString contrast = (qGray(theme.textColor().rgb()) > 127) ? "black" : "white";
	QColor color = theme.foregroundColor();
	color.setAlpha(theme.foregroundOpacity() * 2.55f);
        m_text->setStyleSheet(
                QString("Editor { background: rgba(%1, %2, %3, %4); color: %5; selection-background-color: %6; selection-color: %7; padding: %8px; border-radius: %9px; }")
			.arg(color.red())
			.arg(color.green())
			.arg(color.blue())
			.arg(color.alpha())
			.arg(theme.textColor().name())
			.arg(theme.textColor().name())
			.arg(contrast)
			.arg(theme.foregroundPadding())
			.arg(theme.foregroundRounding())
	);
	if (m_highlighter->misspelledColor() != theme.misspelledColor()) {
		m_highlighter->setMisspelledColor(theme.misspelledColor());
	}

	// Update text
	QFont font = theme.textFont();
	font.setStyleStrategy(m_text->font().styleStrategy());
	if (m_text->font() != font) {
		m_text->setFont(font);
	}
	m_text->setCursorWidth(!m_block_cursor ? 1 : m_text->fontMetrics().averageCharWidth());

	int margin = theme.foregroundMargin();
	m_layout->setColumnMinimumWidth(0, margin);
	m_layout->setColumnMinimumWidth(2, margin);
	if (theme.foregroundPosition() < 3) {
		m_text->setFixedWidth(theme.foregroundWidth());

		switch (theme.foregroundPosition()) {
		case 0:
			m_layout->setColumnStretch(0, 0);
			m_layout->setColumnStretch(2, 1);
			break;

		case 2:
			m_layout->setColumnStretch(0, 1);
			m_layout->setColumnStretch(2, 0);
			break;

		case 1:
		default:
			m_layout->setColumnStretch(0, 1);
			m_layout->setColumnStretch(2, 1);
			break;
		};
	} else {
		m_text->setMinimumWidth(theme.foregroundWidth());
		m_text->setMaximumWidth(maximumSize().height());

		m_layout->setColumnStretch(0, 0);
		m_layout->setColumnStretch(2, 0);
	}
        cleanUpDocument(false);
	centerCursor(true);
	m_text->document()->blockSignals(false);
        m_highlighter->rehighlight();
}
Ejemplo n.º 2
0
ThemeDialog::ThemeDialog(Theme& theme, QWidget* parent)
	: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint),
	m_theme(theme)
{
	setWindowTitle(tr("Edit Theme"));
	setWindowModality(Qt::WindowModal);

	// Create name edit
	m_name = new QLineEdit(this);
	m_name->setText(m_theme.name());
	connect(m_name, SIGNAL(textChanged(QString)), this, SLOT(checkNameAvailable()));

	QHBoxLayout* name_layout = new QHBoxLayout;
	name_layout->setMargin(0);
	name_layout->addWidget(new QLabel(tr("Name:"), this));
	name_layout->addWidget(m_name);


	// Create scrollarea
	QWidget* contents = new QWidget(this);

	QScrollArea* scroll = new QScrollArea(this);
	scroll->setWidget(contents);
	scroll->setWidgetResizable(true);


	// Create text group
	QGroupBox* text_group = new QGroupBox(tr("Text"), contents);

	m_text_color = new ColorButton(text_group);
	m_text_color->setColor(m_theme.textColor());
	connect(m_text_color, SIGNAL(changed(QColor)), this, SLOT(renderPreview()));

	m_font_names = new FontComboBox(text_group);
	m_font_names->setEditable(false);
	m_font_names->setCurrentFont(m_theme.textFont());
	connect(m_font_names, SIGNAL(activated(int)), this, SLOT(fontChanged()));
	connect(m_font_names, SIGNAL(activated(int)), this, SLOT(renderPreview()));

	m_font_sizes = new QComboBox(text_group);
	m_font_sizes->setEditable(true);
	m_font_sizes->setMinimumContentsLength(3);
	connect(m_font_sizes, SIGNAL(editTextChanged(QString)), this, SLOT(renderPreview()));
	fontChanged();

	m_misspelled_color = new ColorButton(text_group);
	m_misspelled_color->setColor(m_theme.misspelledColor());
	connect(m_misspelled_color, SIGNAL(changed(QColor)), this, SLOT(renderPreview()));

	QHBoxLayout* font_layout = new QHBoxLayout;
	font_layout->addWidget(m_font_names);
	font_layout->addWidget(m_font_sizes);

	QFormLayout* text_layout = new QFormLayout(text_group);
	text_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
	text_layout->addRow(tr("Color:"), m_text_color);
	text_layout->addRow(tr("Font:"), font_layout);
	text_layout->addRow(tr("Misspelled:"), m_misspelled_color);


	// Create background group
	QGroupBox* background_group = new QGroupBox(tr("Window Background"), contents);

	m_background_color = new ColorButton(background_group);
	m_background_color->setColor(m_theme.backgroundColor());
	connect(m_background_color, SIGNAL(changed(QColor)), this, SLOT(renderPreview()));

	m_background_image = new ImageButton(background_group);
	m_background_image->setImage(m_theme.backgroundImage(), m_theme.backgroundPath());
	connect(m_background_image, SIGNAL(changed(QString)), this, SLOT(imageChanged()));

	m_clear_image = new QPushButton(tr("Remove"), background_group);
	connect(m_clear_image, SIGNAL(clicked()), m_background_image, SLOT(unsetImage()));

	m_background_type = new QComboBox(background_group);
	m_background_type->addItems(QStringList() << tr("No Image") << tr("Tiled") << tr("Centered") << tr("Stretched") << tr("Scaled") << tr("Zoomed"));
	m_background_type->setCurrentIndex(m_theme.backgroundType());
	connect(m_background_type, SIGNAL(activated(int)), this, SLOT(renderPreview()));

	QVBoxLayout* image_layout = new QVBoxLayout;
	image_layout->setSpacing(0);
	image_layout->setMargin(0);
	image_layout->addWidget(m_background_image);
	image_layout->addWidget(m_clear_image);

	QFormLayout* background_layout = new QFormLayout(background_group);
	background_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
	background_layout->addRow(tr("Color:"), m_background_color);
	background_layout->addRow(tr("Image:"), image_layout);
	background_layout->addRow(tr("Type:"), m_background_type);


	// Create foreground group
	QGroupBox* foreground_group = new QGroupBox(tr("Text Background"), contents);

	m_foreground_color = new ColorButton(foreground_group);
	m_foreground_color->setColor(m_theme.foregroundColor());
	connect(m_foreground_color, SIGNAL(changed(QColor)), this, SLOT(renderPreview()));

	m_foreground_opacity = new QSpinBox(foreground_group);
	m_foreground_opacity->setCorrectionMode(QSpinBox::CorrectToNearestValue);
	m_foreground_opacity->setSuffix(QLocale().percent());
	m_foreground_opacity->setRange(theme.foregroundOpacity().minimumValue(), theme.foregroundOpacity().maximumValue());
	m_foreground_opacity->setValue(m_theme.foregroundOpacity());
	connect(m_foreground_opacity, SIGNAL(valueChanged(int)), this, SLOT(renderPreview()));

	m_foreground_position = new QComboBox(foreground_group);
	m_foreground_position->addItems(QStringList() << tr("Left") << tr("Centered") << tr("Right") << tr("Stretched"));
	m_foreground_position->setCurrentIndex(m_theme.foregroundPosition());
	connect(m_foreground_position, SIGNAL(currentIndexChanged(int)), this, SLOT(positionChanged(int)));

	m_foreground_width = new QSpinBox(foreground_group);
	m_foreground_width->setCorrectionMode(QSpinBox::CorrectToNearestValue);
	m_foreground_width->setSuffix(tr(" pixels"));
	m_foreground_width->setRange(theme.foregroundWidth().minimumValue(), theme.foregroundWidth().maximumValue());
	m_foreground_width->setValue(m_theme.foregroundWidth());
	m_foreground_width->setEnabled(m_theme.foregroundPosition() != 3);
	connect(m_foreground_width, SIGNAL(valueChanged(int)), this, SLOT(renderPreview()));

	QFormLayout* foreground_layout = new QFormLayout(foreground_group);
	foreground_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
	foreground_layout->addRow(tr("Color:"), m_foreground_color);
	foreground_layout->addRow(tr("Opacity:"), m_foreground_opacity);
	foreground_layout->addRow(tr("Position:"), m_foreground_position);
	foreground_layout->addRow(tr("Width:"), m_foreground_width);


	// Create rounding group
	m_round_corners = new QGroupBox(tr("Round Text Background Corners"), contents);
	m_round_corners->setCheckable(true);
	m_round_corners->setChecked(m_theme.roundCornersEnabled());
	connect(m_round_corners, SIGNAL(clicked()), this, SLOT(renderPreview()));

	m_corner_radius = new QSpinBox(m_round_corners);
	m_corner_radius->setCorrectionMode(QSpinBox::CorrectToNearestValue);
	m_corner_radius->setSuffix(tr(" pixels"));
	m_corner_radius->setRange(theme.cornerRadius().minimumValue(), theme.cornerRadius().maximumValue());
	m_corner_radius->setValue(m_theme.cornerRadius());
	connect(m_corner_radius, SIGNAL(valueChanged(int)), this, SLOT(renderPreview()));

	QFormLayout* corner_layout = new QFormLayout(m_round_corners);
	corner_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
	corner_layout->addRow(tr("Radius:"), m_corner_radius);


	// Create blur group
	m_blur = new QGroupBox(tr("Blur Text Background"), contents);
	m_blur->setCheckable(true);
	m_blur->setChecked(m_theme.blurEnabled());
	connect(m_blur, SIGNAL(clicked()), this, SLOT(renderPreview()));

	m_blur_radius = new QSpinBox(m_blur);
	m_blur_radius->setCorrectionMode(QSpinBox::CorrectToNearestValue);
	m_blur_radius->setSuffix(tr(" pixels"));
	m_blur_radius->setRange(theme.blurRadius().minimumValue(), theme.blurRadius().maximumValue());
	m_blur_radius->setValue(m_theme.blurRadius());
	connect(m_blur_radius, SIGNAL(valueChanged(int)), this, SLOT(renderPreview()));

	QFormLayout* blur_layout = new QFormLayout(m_blur);
	blur_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
	blur_layout->addRow(tr("Radius:"), m_blur_radius);


	// Create shadow group
	m_shadow = new QGroupBox(tr("Text Background Drop Shadow"), contents);
	m_shadow->setCheckable(true);
	m_shadow->setChecked(m_theme.shadowEnabled());
	connect(m_shadow, SIGNAL(clicked()), this, SLOT(renderPreview()));

	m_shadow_color = new ColorButton(m_shadow);
	m_shadow_color->setColor(m_theme.shadowColor());
	connect(m_shadow_color, SIGNAL(changed(QColor)), this, SLOT(renderPreview()));

	m_shadow_radius = new QSpinBox(m_shadow);
	m_shadow_radius->setCorrectionMode(QSpinBox::CorrectToNearestValue);
	m_shadow_radius->setSuffix(tr(" pixels"));
	m_shadow_radius->setRange(theme.shadowRadius().minimumValue(), theme.shadowRadius().maximumValue());
	m_shadow_radius->setValue(m_theme.shadowRadius());
	connect(m_shadow_radius, SIGNAL(valueChanged(int)), this, SLOT(renderPreview()));

	m_shadow_offset = new QSpinBox(m_shadow);
	m_shadow_offset->setCorrectionMode(QSpinBox::CorrectToNearestValue);
	m_shadow_offset->setSuffix(tr(" pixels"));
	m_shadow_offset->setRange(theme.shadowOffset().minimumValue(), theme.shadowOffset().maximumValue());
	m_shadow_offset->setValue(m_theme.shadowOffset());
	connect(m_shadow_offset, SIGNAL(valueChanged(int)), this, SLOT(renderPreview()));

	QFormLayout* shadow_layout = new QFormLayout(m_shadow);
	shadow_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
	shadow_layout->addRow(tr("Color:"), m_shadow_color);
	shadow_layout->addRow(tr("Radius:"), m_shadow_radius);
	shadow_layout->addRow(tr("Vertical Offset:"), m_shadow_offset);


	// Create margins group
	QGroupBox* margins_group = new QGroupBox(tr("Margins"), contents);

	m_foreground_margin = new QSpinBox(margins_group);
	m_foreground_margin->setCorrectionMode(QSpinBox::CorrectToNearestValue);
	m_foreground_margin->setSuffix(tr(" pixels"));
	m_foreground_margin->setRange(theme.foregroundMargin().minimumValue(), theme.foregroundMargin().maximumValue());
	m_foreground_margin->setValue(m_theme.foregroundMargin());
	connect(m_foreground_margin, SIGNAL(valueChanged(int)), this, SLOT(renderPreview()));

	m_foreground_padding = new QSpinBox(margins_group);
	m_foreground_padding->setCorrectionMode(QSpinBox::CorrectToNearestValue);
	m_foreground_padding->setSuffix(tr(" pixels"));
	m_foreground_padding->setRange(theme.foregroundPadding().minimumValue(), theme.foregroundPadding().maximumValue());
	m_foreground_padding->setValue(m_theme.foregroundPadding());
	connect(m_foreground_padding, SIGNAL(valueChanged(int)), this, SLOT(renderPreview()));

	QFormLayout* margins_layout = new QFormLayout(margins_group);
	margins_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
	margins_layout->addRow(tr("Window:"), m_foreground_margin);
	margins_layout->addRow(tr("Page:"), m_foreground_padding);


	// Create line spacing group
	QGroupBox* line_spacing = new QGroupBox(tr("Line Spacing"), contents);

	m_line_spacing_type = new QComboBox(line_spacing);
	m_line_spacing_type->setEditable(false);
	m_line_spacing_type->addItems(QStringList() << tr("Single") << tr("1.5 Lines") << tr("Double") << tr("Proportional"));
	m_line_spacing_type->setCurrentIndex(3);

	m_line_spacing = new QSpinBox(line_spacing);
	m_line_spacing->setSuffix(QLocale().percent());
	m_line_spacing->setRange(theme.lineSpacing().minimumValue(), theme.lineSpacing().maximumValue());
	m_line_spacing->setValue(m_theme.lineSpacing());
	m_line_spacing->setEnabled(false);

	switch (m_theme.lineSpacing()) {
	case 100: m_line_spacing_type->setCurrentIndex(0); break;
	case 150: m_line_spacing_type->setCurrentIndex(1); break;
	case 200: m_line_spacing_type->setCurrentIndex(2); break;
	default: m_line_spacing->setEnabled(true); break;
	}
	connect(m_line_spacing_type, SIGNAL(currentIndexChanged(int)), this, SLOT(lineSpacingChanged(int)));
	connect(m_line_spacing_type, SIGNAL(currentIndexChanged(int)), this, SLOT(renderPreview()));
	connect(m_line_spacing, SIGNAL(valueChanged(int)), this, SLOT(renderPreview()));

	QFormLayout* line_spacing_layout = new QFormLayout(line_spacing);
	line_spacing_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
	line_spacing_layout->addRow(tr("Type:"), m_line_spacing_type);
	line_spacing_layout->addRow(tr("Height:"), m_line_spacing);


	// Create paragraph spacing group
	QGroupBox* paragraph_spacing = new QGroupBox(tr("Paragraph Spacing"), contents);

	m_tab_width = new QSpinBox(paragraph_spacing);
	m_tab_width->setSuffix(tr(" pixels"));
	m_tab_width->setRange(theme.tabWidth().minimumValue(), theme.tabWidth().maximumValue());
	m_tab_width->setValue(m_theme.tabWidth());
	connect(m_tab_width, SIGNAL(valueChanged(int)), this, SLOT(renderPreview()));

	m_spacing_above_paragraph = new QSpinBox(paragraph_spacing);
	m_spacing_above_paragraph->setSuffix(tr(" pixels"));
	m_spacing_above_paragraph->setRange(theme.spacingAboveParagraph().minimumValue(), theme.spacingAboveParagraph().maximumValue());
	m_spacing_above_paragraph->setValue(m_theme.spacingAboveParagraph());
	connect(m_spacing_above_paragraph, SIGNAL(valueChanged(int)), this, SLOT(renderPreview()));

	m_spacing_below_paragraph = new QSpinBox(paragraph_spacing);
	m_spacing_below_paragraph->setSuffix(tr(" pixels"));
	m_spacing_below_paragraph->setRange(theme.spacingBelowParagraph().minimumValue(), theme.spacingBelowParagraph().maximumValue());
	m_spacing_below_paragraph->setValue(m_theme.spacingBelowParagraph());
	connect(m_spacing_below_paragraph, SIGNAL(valueChanged(int)), this, SLOT(renderPreview()));

	m_indent_first_line = new QCheckBox(tr("Indent first line"), paragraph_spacing);
	m_indent_first_line->setChecked(m_theme.indentFirstLine());
	connect(m_indent_first_line, SIGNAL(toggled(bool)), this, SLOT(renderPreview()));

	QFormLayout* paragraph_spacing_layout = new QFormLayout(paragraph_spacing);
	paragraph_spacing_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);
	paragraph_spacing_layout->addRow(tr("Tab Width:"), m_tab_width);
	paragraph_spacing_layout->addRow(tr("Above:"), m_spacing_above_paragraph);
	paragraph_spacing_layout->addRow(tr("Below:"), m_spacing_below_paragraph);
	paragraph_spacing_layout->addRow("", m_indent_first_line);


	// Create preview
	m_preview_text = new QTextEdit;
	m_preview_text->setFrameStyle(QFrame::NoFrame);
	m_preview_text->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
	m_preview_text->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
	QFile file(":/lorem.txt");
	if (file.open(QFile::ReadOnly)) {
		m_preview_text->setPlainText(QString::fromLatin1(file.readAll()));
		file.close();
	}

	m_preview = new QLabel(this);
	m_preview->setAlignment(Qt::AlignCenter);
	m_preview->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);

	QPixmap pixmap(480, 270);
	pixmap.fill(palette().window().color());
	m_preview->setPixmap(pixmap);

	m_theme_renderer = new ThemeRenderer(this);
	connect(m_theme_renderer, SIGNAL(rendered(QImage,QRect,Theme)), this, SLOT(renderPreview(QImage,QRect,Theme)));
	renderPreview();


	// Lay out dialog
	QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
	m_ok = buttons->button(QDialogButtonBox::Ok);
	connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
	connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));

	QVBoxLayout* groups_layout = new QVBoxLayout(contents);
	groups_layout->addWidget(text_group);
	groups_layout->addWidget(background_group);
	groups_layout->addWidget(foreground_group);
	groups_layout->addWidget(m_round_corners);
	groups_layout->addWidget(m_blur);
	groups_layout->addWidget(m_shadow);
	groups_layout->addWidget(margins_group);
	groups_layout->addWidget(line_spacing);
	groups_layout->addWidget(paragraph_spacing);

	QGridLayout* layout = new QGridLayout(this);
	layout->setColumnStretch(0, 1);
	layout->setRowStretch(1, 1);
	layout->setRowMinimumHeight(2, layout->margin());
	layout->addLayout(name_layout, 0, 0, 1, 2);
	layout->addWidget(scroll, 1, 0, 1, 1);
	layout->addWidget(m_preview, 1, 1, 1, 1, Qt::AlignCenter);
	layout->addWidget(buttons, 3, 0, 1, 2);

	resize(QSettings().value("ThemeDialog/Size", sizeHint()).toSize());
}
Ejemplo n.º 3
0
void Document::loadTheme(const Theme& theme)
{
	m_text->document()->blockSignals(true);

	// Update colors
	QColor color = theme.foregroundColor();
	color.setAlpha(theme.foregroundOpacity() * 2.55f);
	m_text->setStyleSheet(
		QString("QTextEdit { background: rgba(%1, %2, %3, %4); color: %5; selection-background-color: %6; selection-color: %7; padding: %8px; }")
			.arg(color.red())
			.arg(color.green())
			.arg(color.blue())
			.arg(color.alpha())
			.arg(theme.textColor().name())
			.arg(theme.textColor().name())
			.arg(theme.foregroundColor().name())
			.arg(theme.foregroundPadding())
	);
	if (m_highlighter->misspelledColor() != theme.misspelledColor()) {
		m_highlighter->setMisspelledColor(theme.misspelledColor());
	}

	// Update text
	QFont font = theme.textFont();
	font.setStyleStrategy(m_text->font().styleStrategy());
	if (m_text->font() != font) {
		m_text->setFont(font);
	}
	m_text->setCursorWidth(!m_block_cursor ? 1 : m_text->fontMetrics().averageCharWidth());

	int margin = theme.foregroundMargin();
	m_layout->setColumnMinimumWidth(0, margin);
	m_layout->setColumnMinimumWidth(2, margin);
	if (theme.foregroundPosition() < 3) {
		m_text->setFixedWidth(theme.foregroundWidth());

		switch (theme.foregroundPosition()) {
		case 0:
			m_layout->setColumnStretch(0, 0);
			m_layout->setColumnStretch(2, 1);
			break;

		case 2:
			m_layout->setColumnStretch(0, 1);
			m_layout->setColumnStretch(2, 0);
			break;

		case 1:
		default:
			m_layout->setColumnStretch(0, 1);
			m_layout->setColumnStretch(2, 1);
			break;
		};
	} else {
		m_text->setMinimumWidth(theme.foregroundWidth());
		m_text->setMaximumWidth(maximumSize().height());

		m_layout->setColumnStretch(0, 0);
		m_layout->setColumnStretch(2, 0);
	}

	centerCursor(true);
	m_text->document()->blockSignals(false);
}
Ejemplo n.º 4
0
void ThemeDialog::renderPreview(QImage preview, const QRect& foreground, const Theme& theme)
{
	m_load_color = QtConcurrent::run(averageImage, theme.backgroundImage(), theme.backgroundColor());

	// Position preview text
	int padding = theme.foregroundPadding();
	int x = foreground.x() + padding;
	int y = foreground.y() + padding + theme.spacingAboveParagraph();
	int width = foreground.width() - (padding * 2);
	int height = foreground.height() - (padding * 2) - theme.spacingAboveParagraph();
	m_preview_text->setGeometry(x, y, width, height);

	// Set colors
	QColor text_color = theme.textColor();
	text_color.setAlpha(255);

	QPalette p = m_preview_text->palette();
	p.setBrush(QPalette::Base, preview.copy(x, y, width, height));
	p.setColor(QPalette::Text, text_color);
	p.setColor(QPalette::Highlight, text_color);
	p.setColor(QPalette::HighlightedText, (qGray(text_color.rgb()) > 127) ? Qt::black : Qt::white);
	m_preview_text->setPalette(p);

	// Set spacings
	int tab_width = theme.tabWidth();
	QTextBlockFormat block_format;
	block_format.setLineHeight(theme.lineSpacing(), (theme.lineSpacing() == 100) ? QTextBlockFormat::SingleHeight : QTextBlockFormat::ProportionalHeight);
	block_format.setTextIndent(tab_width * theme.indentFirstLine());
	block_format.setTopMargin(theme.spacingAboveParagraph());
	block_format.setBottomMargin(theme.spacingBelowParagraph());
	m_preview_text->textCursor().mergeBlockFormat(block_format);
	for (int i = 0, count = m_preview_text->document()->allFormats().count(); i < count; ++i) {
		QTextFormat& f = m_preview_text->document()->allFormats()[i];
		if (f.isBlockFormat()) {
			f.merge(block_format);
		}
	}
	m_preview_text->setTabStopWidth(tab_width);
	m_preview_text->document()->setIndentWidth(tab_width);

	// Set font
	m_preview_text->setFont(theme.textFont());

	// Render text
	m_preview_text->render(&preview, m_preview_text->pos());

	// Create zoomed text cutout
	int x2 = (x >= 24) ? (x - 24) : 0;
	int y2 = (y >= 24) ? (y - 24) : 0;
	QImage text_cutout = preview.copy(x2, y2, 162, 110);

	// Create preview icon
	m_preview_icon = QImage(":/shadow.png").convertToFormat(QImage::Format_ARGB32_Premultiplied);
	{
		QPainter painter(&m_preview_icon);
		painter.drawImage(9, 9, preview.scaled(240, 135, Qt::KeepAspectRatio, Qt::SmoothTransformation));
		painter.fillRect(20, 32, 85, 59, QColor(0, 0, 0, 32));
		painter.fillRect(21, 33, 83, 57, Qt::white);
		int x3 = (x >= 24) ? (x - 12 + theme.tabWidth()) : 12 + theme.tabWidth();
		int y3 = (y >= 24) ? (y - 6) : 0;
		painter.drawImage(22, 34, preview, x3, y3, 81, 55);
	}

	// Create preview pixmap
	preview = preview.scaled(480, 270, Qt::KeepAspectRatio, Qt::SmoothTransformation);
	{
		QPainter painter(&preview);
		painter.setPen(Qt::NoPen);
		painter.fillRect(22, 46, 170, 118, QColor(0, 0, 0, 32));
		painter.fillRect(24, 48, 166, 114, Qt::white);
		painter.drawImage(26, 50, text_cutout);
	}
	m_preview->setPixmap(QPixmap::fromImage(preview));
}