#include "tablebottombox.hpp" #include #include #include #include #include #include #include #include #include "creator.hpp" #include "infocreator.hpp" namespace { constexpr const char* statusBarStyle = "QStatusBar::item { border: 0px }"; } void CSVWorld::TableBottomBox::updateSize() { // Make sure that the size of the bottom box is determined by the currently visible widget for (int i = 0; i < mLayout->count(); ++i) { QSizePolicy::Policy verPolicy = QSizePolicy::Ignored; if (mLayout->widget(i) == mLayout->currentWidget()) { verPolicy = QSizePolicy::Expanding; } mLayout->widget(i)->setSizePolicy(QSizePolicy::Expanding, verPolicy); } } void CSVWorld::TableBottomBox::updateStatus() { if (mShowStatusBar) { if (!mStatusMessage.isEmpty()) { mStatus->setText(mStatusMessage); return; } static const char* sLabels[4] = { "record", "deleted", "touched", "selected" }; static const char* sLabelsPlural[4] = { "records", "deleted", "touched", "selected" }; std::ostringstream stream; bool first = true; for (int i = 0; i < 4; ++i) { if (mStatusCount[i] > 0) { if (first) first = false; else stream << ", "; stream << mStatusCount[i] << ' ' << (mStatusCount[i] == 1 ? sLabels[i] : sLabelsPlural[i]); } } if (mHasPosition) { if (!first) stream << " -- "; stream << "(" << mRow << ", " << mColumn << ")"; } mStatus->setText(QString::fromUtf8(stream.str().c_str())); } } void CSVWorld::TableBottomBox::extendedConfigRequest( CSVWorld::ExtendedCommandConfigurator::Mode mode, const std::vector& selectedIds) { mExtendedConfigurator->configure(mode, selectedIds); mLayout->setCurrentWidget(mExtendedConfigurator); mEditMode = EditMode_ExtendedConfig; setVisible(true); mExtendedConfigurator->setFocus(); } CSVWorld::TableBottomBox::TableBottomBox(const CreatorFactoryBase& creatorFactory, CSMDoc::Document& document, const CSMWorld::UniversalId& id, QWidget* parent) : QWidget(parent) , mShowStatusBar(false) , mEditMode(EditMode_None) , mHasPosition(false) , mRow(0) , mColumn(0) { for (int i = 0; i < 4; ++i) mStatusCount[i] = 0; setVisible(false); mLayout = new QStackedLayout; mLayout->setContentsMargins(0, 0, 0, 0); connect(mLayout, &QStackedLayout::currentChanged, this, &TableBottomBox::currentWidgetChanged); mStatus = new QLabel; mStatusBar = new QStatusBar(this); mStatusBar->addWidget(mStatus); mStatusBar->setStyleSheet(statusBarStyle); mLayout->addWidget(mStatusBar); setLayout(mLayout); mCreator = creatorFactory.makeCreator(document, id); if (mCreator) { mCreator->installEventFilter(this); mLayout->addWidget(mCreator); connect(mCreator, &Creator::done, this, &TableBottomBox::requestDone); connect(mCreator, &Creator::requestFocus, this, &TableBottomBox::requestFocus); } mExtendedConfigurator = new ExtendedCommandConfigurator(document, id, this); mExtendedConfigurator->installEventFilter(this); mLayout->addWidget(mExtendedConfigurator); connect(mExtendedConfigurator, &ExtendedCommandConfigurator::done, this, &TableBottomBox::requestDone); updateSize(); } bool CSVWorld::TableBottomBox::event(QEvent* event) { // Apply style sheet again if style was changed if (event->type() == QEvent::PaletteChange) { if (mStatusBar != nullptr) mStatusBar->setStyleSheet(statusBarStyle); } return QWidget::event(event); } void CSVWorld::TableBottomBox::setEditLock(bool locked) { if (mCreator) mCreator->setEditLock(locked); mExtendedConfigurator->setEditLock(locked); } CSVWorld::TableBottomBox::~TableBottomBox() { delete mCreator; } bool CSVWorld::TableBottomBox::eventFilter(QObject* object, QEvent* event) { if (event->type() == QEvent::KeyPress) { QKeyEvent* keyEvent = static_cast(event); if (keyEvent->key() == Qt::Key_Escape) { requestDone(); return true; } } return QWidget::eventFilter(object, event); } void CSVWorld::TableBottomBox::setStatusBar(bool show) { if (show != mShowStatusBar) { setVisible(show || (mEditMode != EditMode_None)); mShowStatusBar = show; if (show) updateStatus(); } } bool CSVWorld::TableBottomBox::canCreateAndDelete() const { return mCreator; } void CSVWorld::TableBottomBox::requestDone() { if (!mShowStatusBar) setVisible(false); else updateStatus(); mLayout->setCurrentWidget(mStatusBar); mEditMode = EditMode_None; } void CSVWorld::TableBottomBox::currentWidgetChanged(int /*index*/) { updateSize(); } void CSVWorld::TableBottomBox::setStatusMessage(const QString& message) { mStatusMessage = message; updateStatus(); } void CSVWorld::TableBottomBox::selectionSizeChanged(int size) { if (mStatusCount[3] != size) { mStatusMessage = ""; mStatusCount[3] = size; updateStatus(); } } void CSVWorld::TableBottomBox::tableSizeChanged(int size, int deleted, int modified) { bool changed = false; if (mStatusCount[0] != size) { mStatusCount[0] = size; changed = true; } if (mStatusCount[1] != deleted) { mStatusCount[1] = deleted; changed = true; } if (mStatusCount[2] != modified) { mStatusCount[2] = modified; changed = true; } if (changed) { mStatusMessage = ""; updateStatus(); } } void CSVWorld::TableBottomBox::positionChanged(int row, int column) { mRow = row; mColumn = column; mHasPosition = true; updateStatus(); } void CSVWorld::TableBottomBox::noMorePosition() { mHasPosition = false; updateStatus(); } void CSVWorld::TableBottomBox::createRequest() { mCreator->reset(); mCreator->toggleWidgets(true); mLayout->setCurrentWidget(mCreator); setVisible(true); mEditMode = EditMode_Creation; mCreator->focus(); } void CSVWorld::TableBottomBox::createRecordsDirectlyRequest(const std::string& id) { if (InfoCreator* creator = dynamic_cast(mCreator)) { creator->reset(); creator->setText(id); creator->callReturnPressed(); } else { Log(Debug::Warning) << "Creating a record directly failed."; } } void CSVWorld::TableBottomBox::cloneRequest(const std::string& id, const CSMWorld::UniversalId::Type type) { mCreator->reset(); mCreator->cloneMode(id, type); mLayout->setCurrentWidget(mCreator); mCreator->toggleWidgets(false); setVisible(true); mEditMode = EditMode_Creation; mCreator->focus(); } void CSVWorld::TableBottomBox::touchRequest(const std::vector& ids) { mCreator->touch(ids); } void CSVWorld::TableBottomBox::extendedDeleteConfigRequest(const std::vector& selectedIds) { extendedConfigRequest(ExtendedCommandConfigurator::Mode_Delete, selectedIds); } void CSVWorld::TableBottomBox::extendedRevertConfigRequest(const std::vector& selectedIds) { extendedConfigRequest(ExtendedCommandConfigurator::Mode_Revert, selectedIds); }