Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,525 @@
/**
* @RDE_HEADER@
* Topic Editor for the Situation Topic in the Script Editor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Mike Wille, SLSE, 2017-04-04
*/
#include "topic_editor.h"
#include "ui_topic_editor.h"
#include <LtsWidgets/lts_text_edit_dialog.h>
#include <LtsUtilsCore/dds_vector.h>
#include <LtsUtilsCore/dds_vector_to_pixmap.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
#include <Plugins/PresentationManagement/Gui/Script/Common/topic_designer.h>
#include <PluginInterfaces/gui_plugin_interface.h>
#include <TopicEditorBase/topic_previewer.h>
#include <QInputDialog>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
namespace FileManagement
{
FileTopicEditor::FileTopicEditor(
LtsSession::LtsSession *session, FileContentPreviewPlaybackWidget *previewWidget, const std::shared_ptr<Interface::Ftc> &ftc,
QWidget *parent
)
: TopicEditorBase::TopicEditor(parent)
, m_session(session)
, m_getContent(new FileManagement::GetFileContent(ftc, this))
, m_previewPlaybackWidget(previewWidget)
, m_ui(new Ui::FileTopicEditor)
, m_logger(getLogger("FileManagementTopicEditor"))
{
// init UI
m_ui->setupUi(this);
init(m_ui->widget);
m_ftc = ftc;
m_ui->scrollArea->setWidget(m_previewPlaybackWidget);
connect(m_previewPlaybackWidget, &FileContentPreviewPlaybackWidget::currentPageChanged,
this, &FileTopicEditor::onPageNoChanged);
connect(m_previewPlaybackWidget, &FileContentPreviewPlaybackWidget::rotationChanged,
this, &FileTopicEditor::onRotationChanged);
if (m_ui->pbSetTopicPosition->isEnabled())
m_ui->pbSetTopicPosition->setToolTip(tr("Starts a replay at the time that the topic was positioned.%1").arg(QString())); // same tr as below to save HJL some hassle with the linguist
else
m_ui->pbSetTopicPosition->setToolTip(tr("Starts a replay at the time that the topic was positioned.%1").arg(QStringLiteral(" <b>%1</b>").arg(tr("You need to position the topic on a screen track first to start a preview.", "Sie müssen das Topic auf eine Screen-Spur ziehen, bevor Sie eine Vorschau starten können."))));
connect(m_ui->pbBrowse, &QPushButton::clicked,
this, &FileTopicEditor::onSelectFile);
connect(m_ui->pbEnterText, &QPushButton::clicked,
this, &FileTopicEditor::onEnterText);
connect(m_ui->zoomSlider, &QSlider::valueChanged,
this, &FileTopicEditor::onZoomSliderChanged);
connect(m_ui->sbPageNo, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &FileTopicEditor::onPageNoChanged);
connect(m_ui->sbRotation, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &FileTopicEditor::onRotationChanged);
// connect(m_ui->scrollArea, &QObject::destroyed,
// this, [this]()
// {
// WARNING_LOG(m_logger)<<"==> FileTopicEditor: !!! deleted !!! ScrollArea: "<<m_ui->scrollArea;
// });
// connect(m_previewPlaybackWidget, &QObject::destroyed,
// this, [this]()
// {
// WARNING_LOG(m_logger)<<"==> FileTopicEditor: !!! deleted !!! PreviewPlaybackWidget: "<<m_previewPlaybackWidget;
// });
m_ui->pbSetTopicPosition->setEnabled(false);
#if 0
connect(m_ui->pbSetTopicPosition, &QPushButton::clicked, this, [this]()
{
m_ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
emit signalSetTopicPosition(m_ui->scrollArea, m_topicData.id);
});
#else
{
connect(m_ui->pbSetTopicPosition, &QPushButton::clicked, this, &FileTopicEditor::onPreview);
}
#endif
}
FileTopicEditor::~FileTopicEditor()
{
delete m_ui;
}
///////////////////////////////////////////////////////////////////////////////
// PUBLIC
void FileTopicEditor::updatePreview()
{
setUnchangeable(true);
if (m_userText.isEmpty()) // no user text specified (either not a text topic or a file was selected for text) - use file
{
DEBUG_LOG(m_logger) << "file id = " << m_fileId;
m_fileContent = m_dtc->fileContent(m_fileId);
m_fileName = QString::fromStdString(m_fileContent.name());
m_ui->leFileName->setText(m_fileName);
DEBUG_LOG(m_logger) << "file name = " << m_fileName;
if (m_topicData.topicType == TopicEditorBase::TopicType::Pdf)
{
DEBUG_LOG(m_logger) << "zoom level = " << m_zoomLevel;
m_ui->zoomSlider->setValue(m_zoomLevel);
DEBUG_LOG(m_logger) << "rotation = " << m_rotation;
m_ui->sbRotation->setValue(m_rotation);
const int pageNo = m_pageNo; // QSlider::setRange() emits sliderChanged
m_ui->sbPageNo->setRange(1, m_previewPlaybackWidget->getNumPages());
m_pageNo = pageNo;
DEBUG_LOG(m_logger) << "page no = " << m_pageNo;
m_ui->sbPageNo->setValue(m_pageNo);
m_ui->sbPageNo->setEnabled(true);
m_ui->zoomSlider->setEnabled(true);
m_ui->sbRotation->setEnabled(true);
}
}
else // user text specified
{
m_fileId = 0;
m_ui->leFileName->setText(tr("Custom text"));
}
m_previewPlaybackWidget->setVisible(true);
m_previewPlaybackWidget->init(m_fileContent, m_pageNo, m_zoomLevel / 100., m_rotation, 0, m_userText);
setUnchangeable(false);
}
bool FileTopicEditor::fetchInterfaces()
{
if (!m_session->getForeignGuiInterface<FileManagement::ForeignGuiInterface>(m_guiIfc))
{
ERROR_LOG(m_logger) << "Failed to retrieve Flm ForeignGuiInterface";
return false;
}
if (!m_session->getDtc<FileManagement::DataInterface>(m_dtc))
{
ERROR_LOG(m_logger) << "Failed to retrieve Flm Dtc";
return false;
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
// PRIVATE
void FileTopicEditor::updateInternalData()
{
enaDisa();
if (m_topicData.topicType != TopicEditorBase::TopicType::Text)
m_ui->pbEnterText->hide();
if (m_topicData.topicType == TopicEditorBase::TopicType::TacticalPlan)
{
m_ui->pbSetTopicPosition->hide();
m_ui->scrollArea->hide();
}
if (m_topicData.topicType == TopicEditorBase::TopicType::Text ||
m_topicData.topicType == TopicEditorBase::TopicType::Image ||
m_topicData.topicType == TopicEditorBase::TopicType::Pdf)
{
// prepare topic with full size (+ margin) if all are zero
if (m_topicData.x <= 0 && m_topicData.y <= 0 && m_topicData.w <= 0 && m_topicData.h <= 0)
{
m_topicData.x = 0;
m_topicData.y = 0;
m_topicData.h = 0.8;
m_topicData.w = 0.8;
}
}
// init file dialog filter
m_fileTypes.clear();
switch (m_topicData.topicType)
{
case TopicEditorBase::TopicType::Image:
m_fileTypes << FileManagement::FileType_def::Jpg << FileManagement::FileType_def::Png;
break;
case TopicEditorBase::TopicType::Pdf:
m_fileTypes << FileManagement::FileType_def::Pdf;
break;
case TopicEditorBase::TopicType::Text:
m_fileTypes << FileManagement::FileType_def::Text << FileManagement::FileType_def::EvaluationSchema;
break;
case TopicEditorBase::TopicType::Xml:
m_fileTypes << FileManagement::FileType_def::Xml;
break;
case TopicEditorBase::TopicType::TacticalPlan:
m_fileTypes << FileManagement::FileType_def::TacticalPlan;
break;
case TopicEditorBase::TopicType::MSOffice:
m_fileTypes << FileManagement::FileType_def::MSOfficeDocument
<< FileManagement::FileType_def::MSOfficeDocument97
<< FileManagement::FileType_def::MSOfficePresentation
<< FileManagement::FileType_def::MSOfficePresentation97
<< FileManagement::FileType_def::MSOfficeSpreadsheet
<< FileManagement::FileType_def::MSOfficeSpreadsheet97;
break;
case TopicEditorBase::TopicType::OpenOffice:
m_fileTypes << FileManagement::FileType_def::OpenOfficeDocument
<< FileManagement::FileType_def::OpenOfficePresentation
<< FileManagement::FileType_def::OpenOfficeSpreadsheet;
break;
default:
break;
}
switch (m_topicData.topicType)
{
case TopicEditorBase::TopicType::Image:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_Image_Topic"));
break;
case TopicEditorBase::TopicType::Pdf:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_PDF_Topic"));
break;
case TopicEditorBase::TopicType::Text:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_Text_Topic"));
break;
case TopicEditorBase::TopicType::Xml:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_XML_Topic"));
break;
case TopicEditorBase::TopicType::TacticalPlan:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_Tactical_Plan_Topic"));
break;
case TopicEditorBase::TopicType::MSOffice:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_MS_Office_Topic"));
break;
case TopicEditorBase::TopicType::OpenOffice:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_Open_Office_Topic"));
break;
default:
translate(m_ui, tr("Unknown File Topic Editor"));
break;
}
m_ui->pbSetTopicPosition->setEnabled(!m_topicData.channel.isEmpty() || !m_topicData.parentChannel.isEmpty()); // preview only available if topic is at a screen
// only get ONCE (initially) from SAVED topic data !
m_userText = getTopicDataValue(QStringLiteral("UserText")).toString();
m_fileId = getTopicDataValue(QStringLiteral("FileId")).toInt();
m_pageNo = getTopicDataValue(QStringLiteral("PageNo")).toInt();
m_zoomLevel = getTopicDataValue(QStringLiteral("ZoomLevel")).toInt();
m_rotation = getTopicDataValue(QStringLiteral("Rotation")).toInt();
if (hasTopicDataProperties())
updatePreview();
}
void FileTopicEditor::retranslate()
{
switch (m_topicData.topicType)
{
case TopicEditorBase::TopicType::Image:
translate(m_ui, tr("Image Topic Editor"));
break;
case TopicEditorBase::TopicType::Pdf:
translate(m_ui, tr("Pdf Topic Editor"));
break;
case TopicEditorBase::TopicType::Text:
translate(m_ui, tr("Text Topic Editor"));
break;
case TopicEditorBase::TopicType::Xml:
translate(m_ui, tr("Xml Topic Editor"));
break;
case TopicEditorBase::TopicType::TacticalPlan:
translate(m_ui, tr("Tactical Plan Topic Editor"));
break;
case TopicEditorBase::TopicType::MSOffice:
translate(m_ui, tr("MS Office Topic Editor"));
break;
case TopicEditorBase::TopicType::OpenOffice:
translate(m_ui, tr("Open Office Topic Editor"));
break;
default:
translate(m_ui, tr("Unknown File Topic Editor"));
break;
}
if (hasTopicDataProperties())
updatePreview();
}
void FileTopicEditor::enaDisa()
{
if (m_previewPlaybackWidget)
m_previewPlaybackWidget->setVisible(false);
m_ui->lblPageNo->setVisible(false);
m_ui->sbPageNo->setVisible(false);
m_ui->lblZoom->setVisible(false);
m_ui->zoomSlider->setVisible(false);
m_ui->lblZoomValue->setVisible(false);
m_ui->sbRotation->setVisible(false);
m_ui->lblRotation->setVisible(false);
if (m_topicData.topicType == TopicEditorBase::TopicType::Pdf)
{
m_ui->lblPageNo->setVisible(true);
m_ui->sbPageNo->setVisible(true);
m_ui->lblZoom->setVisible(true);
m_ui->zoomSlider->setVisible(true);
m_ui->lblZoomValue->setVisible(true);
m_ui->sbRotation->setVisible(true);
m_ui->lblRotation->setVisible(true);
m_ui->sbPageNo->setEnabled(false);
m_ui->zoomSlider->setEnabled(false);
m_ui->sbRotation->setEnabled(false);
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->hide();
}
}
///////////////////////////////////////////////////////////////////////////////
// PRIVATE SLOTS
bool FileTopicEditor::apply2()
{
setTopicDataProperty(QStringLiteral("FileId"), m_fileId);
if (m_topicData.topicType == TopicEditorBase::TopicType::Pdf)
{
setTopicDataProperty(QStringLiteral("PageNo"), m_pageNo);
setTopicDataProperty(QStringLiteral("ZoomLevel"), m_zoomLevel);
setTopicDataProperty(QStringLiteral("Rotation"), m_rotation);
}
setTopicDataProperty(QStringLiteral("UserText"), m_userText);
setDescription(m_ui->widget->description());
m_ui->widget->previewer()->setTopicData(m_topicData);
if (m_fileId == 0)
{
if (m_topicData.topicType == TopicEditorBase::TopicType::Text && !m_userText.isEmpty())
{
emit changesSaved(m_topicData);
return true;
}
new LtsWidgets::LtsMessageDialogNew(this, tr("No content was selected for this topic."), tr("Applying changes failed"));
return false;
}
emit changesSaved(m_topicData); // used to reset flag if on Preview widget was modified.
return true;
}
void FileTopicEditor::onSelectFile()
{
QByteArray content;
int folderId = 0;
if (m_topicData.topicType == TopicEditorBase::TopicType::TacticalPlan)
folderId = m_dtc->findFolder(0, QStringLiteral("Tactical Plans"));
int fileId = m_guiIfc->loadFileContent(this, content, m_fileTypes, 0, QString(), folderId);
if (fileId > 0)
{
m_fileId = fileId;
m_userText.clear(); // if we selected a valid file, user text has no use
updatePreview();
slotChangesMade();
}
else
{
ERROR_LOG(m_logger) << "Cannot load file from library";
}
}
void FileTopicEditor::onZoomSliderChanged()
{
DEBUG_LOG(m_logger) << LOGFUNCTION;
m_zoomLevel = m_ui->zoomSlider->value();
m_ui->zoomSlider->setToolTip(tr("Zoom %1 %").arg(m_zoomLevel));
m_ui->lblZoomValue->setText(QString::number(m_zoomLevel) + QStringLiteral(" %"));
m_previewPlaybackWidget->setZoomFactor(m_zoomLevel / 100.);
}
void FileTopicEditor::onPageNoChanged(int pageNo)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << "page no = " << pageNo;
m_pageNo = pageNo;
m_ui->sbPageNo->setValue(m_pageNo);
m_previewPlaybackWidget->setPage(m_pageNo);
}
void FileTopicEditor::onEnterText()
{
if (m_textEditDialog)
{
focusDialog(menuGroup(), QStringLiteral("FileTopicTextEditDialog"), LtsWidgets::LayoutArea::eDialogTab);
return;
}
m_textEditDialog = new LtsWidgets::LtsTextEditDialog(this); // QPointer
m_textEditDialog->enableBackgroundColor(true);
QString html;
if (m_userText.isEmpty() && m_fileContent.id() != 0)
{
std::vector<uint8_t> content;
m_getContent->getContent(m_fileContent.id(), content);
html = QString::fromUtf8(LtsUtils::toQByteArray(content));
}
else
html = m_userText;
// we have to remove the background color from the html but to add it to the exteditors color picker
const int backGroundColorIndex = html.indexOf(QLatin1String("background-color"));
if (backGroundColorIndex != -1)
{
const int rgbIndex = html.indexOf(QLatin1Char('#'), backGroundColorIndex);
const QColor backGroundColor(html.mid(rgbIndex, 7));
const int backGroundColorIndexEnd = html.indexOf(QLatin1Char(';'), backGroundColorIndex);
m_textEditDialog->setInitialBackgroundColor(backGroundColor);
html.remove(backGroundColorIndex, backGroundColorIndexEnd - backGroundColorIndex + 2);
}
m_textEditDialog->setHtml(html);
connect(m_textEditDialog.data(), &LtsWidgets::LtsTextEditDialog::signalTextAppliedWithBackGroundColor,
this, &FileTopicEditor::onCustomTextChanged);
addDialog(m_textEditDialog, menuGroup(), QStringLiteral("FileTopicTextEditDialog"), LtsWidgets::LayoutArea::eDialogTab);
}
void FileTopicEditor::onRotationChanged(int rotation)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " rotation = " << rotation;
m_rotation = rotation;
m_ui->sbRotation->setValue(m_rotation);
m_previewPlaybackWidget->setRotation(m_rotation);
}
void FileTopicEditor::onCustomTextChanged(const QString &htmlText)
{
m_userText = htmlText;
m_ui->leFileName->setText(tr("Custom text"));
m_fileId = 0;
m_fileContent = FileContent();
updatePreview();
slotChangesMade();
}
/*!
* \brief FileTopicEditor::onPreview
* in this Method the scroll area and the widget will be used as parent
* A new Object will be created and used instead of the parent. to avoid sofware crashed on preview
* setWidget in topic designer: ownership of created scrollArea will be changed there => on delete will be
* automatically deleted.
*/
void FileTopicEditor::onPreview()
{
if(m_ui->scrollArea == nullptr || m_ftc == nullptr)
return;
updatePreview();
QScrollArea *scrollArea = new QScrollArea(m_ui->scrollArea);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea->setWidgetResizable(true);
FileContentPreviewPlaybackWidget *prevWidget = new FileContentPreviewPlaybackWidget(m_ftc, m_previewPlaybackWidget);
prevWidget->setGeometry(QRect(0, 0, 566, 69));
QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Expanding);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
sizePolicy1.setHeightForWidth(prevWidget->sizePolicy().hasHeightForWidth());
prevWidget->setSizePolicy(sizePolicy1);
prevWidget->setVisible(true);
prevWidget->init(m_fileContent, m_pageNo, m_zoomLevel / 100., m_rotation, 0, m_userText);
scrollArea->setWidget(prevWidget);
connect(prevWidget, &FileContentPreviewPlaybackWidget::currentPageChanged,
this, &FileTopicEditor::onPageNoChanged);
connect(prevWidget, &FileContentPreviewPlaybackWidget::rotationChanged,
this, [this, prevWidget](int rotation)
{
if(m_ui->sbRotation == nullptr)
return;
m_rotation = rotation;
m_ui->sbRotation->setValue(m_rotation);
prevWidget->setRotation(m_rotation);
});
emit signalSetTopicPosition(scrollArea, m_topicData.id);
}
} // namespace FileManagement
@@ -0,0 +1,87 @@
/**
* @RDE_HEADER@
* Topic Editor for the Situation Topic in the Script Editor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Mike Wille, SLSE, 2017-04-04
*/
#pragma once
#include <FileManagement/logger.h>
#include <LtsSession/lts_session.h>
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/FileManagement/Gui/Explorer/flm_preview_playback.h>
#include <TopicEditorBase/topic_editor_base.h>
#include <QPointer>
namespace Ui { class FileTopicEditor; }
namespace PresentationManagement { class TopicDesigner; }
namespace LtsWidgets { class LtsTextEditDialog; }
namespace FileManagement
{
class FileTopicEditor : public TopicEditorBase::TopicEditor
{
Q_OBJECT
public:
explicit FileTopicEditor(
LtsSession::LtsSession *session, FileContentPreviewPlaybackWidget *previewWidget,
const std::shared_ptr<FileManagement::Interface::Ftc> &ftc, QWidget *parent = nullptr
);
~FileTopicEditor();
void updatePreview();
bool fetchInterfaces();
private:
void updateInternalData() override final;
void retranslate() override final;
void enaDisa();
private slots:
bool apply2() override final;
void onSelectFile();
void onZoomSliderChanged();
void onPageNoChanged(int pageNo);
void onRotationChanged(int rotation);
void onEnterText();
void onCustomTextChanged(const QString &htmlText);
void onPreview();
private:
LtsSession::LtsSession *m_session{nullptr};
std::shared_ptr<FileManagement::Interface::Dtc> m_dtc{nullptr};
std::shared_ptr<FileManagement::ForeignGuiInterface> m_guiIfc{nullptr};
std::shared_ptr<FileManagement::Interface::Ftc> m_ftc{nullptr};
QVector<FileManagement::FileType> m_fileTypes;
FileManagement::GetFileContent *m_getContent{nullptr};
FileContentPreviewPlaybackWidget *m_previewPlaybackWidget{nullptr};
FileContent m_fileContent;
QString m_fileName;
int m_fileId{0};
int m_pageNo{1};
int m_zoomLevel{100};
int m_rotation{0};
QString m_userText;
//bool m_firstTimeSelected;
QPointer<LtsWidgets::LtsTextEditDialog> m_textEditDialog;
Ui::FileTopicEditor *m_ui{nullptr};
NGL::INGLLogger &m_logger;
};
} // namespace FileManagement
@@ -0,0 +1,226 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FileTopicEditor</class>
<widget class="QWidget" name="FileTopicEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>589</width>
<height>179</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">File Topic Editor</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="lblSelectedFile">
<property name="text">
<string>Selected File:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="leFileName">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbBrowse">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbEnterText">
<property name="text">
<string>... or enter Text</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbSetTopicPosition">
<property name="text">
<string>Preview Positioning</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblPageNo">
<property name="text">
<string>Scroll to Page No:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="sbPageNo"/>
</item>
<item>
<widget class="QLabel" name="lblRotation">
<property name="text">
<string>Rotation:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="sbRotation">
<property name="maximum">
<number>270</number>
</property>
<property name="singleStep">
<number>90</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblZoom">
<property name="text">
<string>Zoom Level:</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="zoomSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string notr="true"/>
</property>
<property name="minimum">
<number>50</number>
</property>
<property name="maximum">
<number>200</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblZoomValue">
<property name="text">
<string notr="true">100</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="TopicEditorBase::TopicPreviewWidget" name="widget" native="true"/>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>100</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" colspan="2">
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>563</width>
<height>64</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>TopicEditorBase::TopicPreviewWidget</class>
<extends>QWidget</extends>
<header>TopicEditorBase/topic_preview_widget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>leFileName</tabstop>
<tabstop>sbPageNo</tabstop>
<tabstop>sbRotation</tabstop>
<tabstop>zoomSlider</tabstop>
<tabstop>scrollArea</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>