#include "textviewerwidget.h" #include #include TextViewerWidget::TextViewerWidget(QWidget *parent) : QWidget(parent) { auto *mainLayout = new QVBoxLayout(this); mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->setSpacing(0); // Info label at top mInfoLabel = new QLabel(this); mInfoLabel->setContentsMargins(8, 4, 8, 4); mainLayout->addWidget(mInfoLabel); // Splitter for text view and metadata mSplitter = new QSplitter(Qt::Horizontal, this); mainLayout->addWidget(mSplitter, 1); // Text editor (read-only) mTextEdit = new QPlainTextEdit(this); mTextEdit->setReadOnly(true); mTextEdit->setLineWrapMode(QPlainTextEdit::NoWrap); // Use monospace font QFont monoFont("Consolas", 10); monoFont.setStyleHint(QFont::Monospace); mTextEdit->setFont(monoFont); mSplitter->addWidget(mTextEdit); // Metadata tree on the right mMetadataTree = new QTreeWidget(this); mMetadataTree->setHeaderLabels({"Property", "Value"}); mMetadataTree->setColumnCount(2); mMetadataTree->header()->setStretchLastSection(true); mMetadataTree->setMinimumWidth(200); mSplitter->addWidget(mMetadataTree); // Set initial splitter sizes (80% text, 20% metadata) mSplitter->setSizes({800, 200}); // Connect to theme changes connect(&Settings::instance(), &Settings::themeChanged, this, &TextViewerWidget::applyTheme); applyTheme(Settings::instance().theme()); } void TextViewerWidget::setData(const QByteArray &data, const QString &filename) { mData = data; mFilename = filename; // Set text content QString text = QString::fromUtf8(data); mTextEdit->setPlainText(text); // Update info label QFileInfo fi(filename); int lineCount = text.count('\n') + 1; mInfoLabel->setText(QString("%1 | %2 bytes | %3 lines") .arg(filename) .arg(data.size()) .arg(lineCount)); // Setup syntax highlighting based on extension setupSyntaxHighlighting(fi.suffix().toLower()); } void TextViewerWidget::setMetadata(const QVariantMap &metadata) { mMetadataTree->clear(); for (auto it = metadata.constBegin(); it != metadata.constEnd(); ++it) { const QString &key = it.key(); const QVariant &val = it.value(); // Skip internal fields and large binary data if (key.startsWith('_') && key != "_name" && key != "_type") continue; if (val.typeId() == QMetaType::QByteArray) continue; auto *item = new QTreeWidgetItem(mMetadataTree); item->setText(0, key); if (val.typeId() == QMetaType::QVariantMap) { item->setText(1, QString("{%1 fields}").arg(val.toMap().size())); } else if (val.typeId() == QMetaType::QVariantList) { item->setText(1, QString("[%1 items]").arg(val.toList().size())); } else { item->setText(1, val.toString()); } } mMetadataTree->resizeColumnToContents(0); } void TextViewerWidget::applyTheme(const Theme &theme) { mCurrentTheme = theme; // Style the text editor QString textStyle = QString( "QPlainTextEdit {" " background-color: %1;" " color: %2;" " border: 1px solid %3;" " selection-background-color: %4;" "}" ).arg(theme.panelColor, theme.textColor, theme.borderColor, theme.accentColor); mTextEdit->setStyleSheet(textStyle); // Style info label mInfoLabel->setStyleSheet(QString( "QLabel {" " background-color: %1;" " color: %2;" " border-bottom: 1px solid %3;" "}" ).arg(theme.panelColor, theme.textColorMuted, theme.borderColor)); // Style metadata tree mMetadataTree->setStyleSheet(QString( "QTreeWidget {" " background-color: %1;" " color: %2;" " border: 1px solid %3;" "}" "QTreeWidget::item:selected {" " background-color: %4;" "}" "QHeaderView::section {" " background-color: %1;" " color: %2;" " border: 1px solid %3;" " padding: 4px;" "}" ).arg(theme.panelColor, theme.textColor, theme.borderColor, theme.accentColor)); } void TextViewerWidget::setupSyntaxHighlighting(const QString &extension) { // Basic syntax highlighting could be added here in the future // For now, just adjust display based on file type Q_UNUSED(extension) }