#include "CollapsibleSection.h" #include #include #include #include #include #include #include CollapsibleSection::CollapsibleSection( const QString &title, const QString &markdownContent, QWidget *parent, const bool expanded ): QWidget(parent) { QColor bg = qApp->palette().color(QPalette::Window); bool dark = bg.lightness() < 128; // Кнопка заголовка с стрелкой m_toggleButton = new QToolButton(this); m_toggleButton->setText(title); m_toggleButton->setCheckable(true); m_toggleButton->setChecked(expanded); m_toggleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); m_toggleButton->setArrowType(expanded ? Qt::DownArrow : Qt::RightArrow); connect(m_toggleButton, &QToolButton::toggled, this, &CollapsibleSection::onToggled); // Контент без собственного скрола, займёт доступное пространство m_contentBrowser = new QTextBrowser(this); m_contentBrowser->setSearchPaths({QCoreApplication::applicationDirPath() + "/tutorials"}); if (markdownContent.contains(" html.replace(QRegularExpression(R"(^## (.+)$)", QRegularExpression::MultilineOption), R"(

\1

)"); // --- →
html.replace(QRegularExpression(R"(^---$)", QRegularExpression::MultilineOption), "
"); // **text** → text html.replace(QRegularExpression(R"(\*\*([^*]+)\*\*)"), R"(\1)"); m_contentBrowser->setHtml(html); } else { m_contentBrowser->setMarkdown(markdownContent); } m_contentBrowser->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_contentBrowser->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_contentBrowser->setFrameShape(QFrame::NoFrame); m_contentBrowser->setVisible(expanded); m_contentBrowser->document()->adjustSize(); m_contentBrowser->setReadOnly(true); m_contentBrowser->setOpenLinks(false); // 2) Подключаемся к клику по ссылке connect(m_contentBrowser, &QTextBrowser::anchorClicked, this, [](const QUrl &url) { QDesktopServices::openUrl(url); }); if (dark) { m_contentBrowser->setStyleSheet(R"( QTextBrowser { background-color: #2b2b2b; border: 1px solid #ccc; color: #dddddd; border-radius:3px; } )"); } else { m_contentBrowser->setStyleSheet(R"( QTextBrowser { background-color: white; border: 1px solid #ccc; color: black; border-radius: 3px; } )"); } updateContentHeight(); m_contentBrowser->viewport()->installEventFilter(this); auto *layout = new QVBoxLayout(this); layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(m_toggleButton); layout->addSpacing(5); layout->addWidget(m_contentBrowser); } bool CollapsibleSection::eventFilter(QObject *watched, QEvent *event) { if (watched == m_contentBrowser->viewport() && event->type() == QEvent::Resize) { updateContentHeight(); } return QWidget::eventFilter(watched, event); } void CollapsibleSection::updateContentHeight() const { const qreal w = m_contentBrowser->viewport()->width(); m_contentBrowser->document()->setTextWidth(w); const qreal h = m_contentBrowser->document()->size().height(); // Можно добавить +1 пиксел на погрешность: m_contentBrowser->setFixedHeight(static_cast(h) + 5); } void CollapsibleSection::onToggled(const bool checked) const { m_toggleButton->setArrowType(checked ? Qt::DownArrow : Qt::RightArrow); m_contentBrowser->setVisible(checked); if (checked) { updateContentHeight(); } }