Project

General

Profile

Bug #14065 ยป main.cpp

Michael Seibt, 02/06/2026 02:36 PM

 
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <Wt/WAbstractTableModel.h>
#pragma GCC diagnostic pop
#include <Wt/WApplication.h>
#include <Wt/WBootstrap5Theme.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WGridLayout.h>
#include <Wt/WHBoxLayout.h>
#include <Wt/WMenuItem.h>
#include <Wt/WPanel.h>
#include <Wt/WPushButton.h>
#include <Wt/WServer.h>
#include <Wt/WTableView.h>
#include <Wt/WTabWidget.h>
#include <Wt/WText.h>
#include <Wt/WVBoxLayout.h>

using namespace std;
using namespace Wt;
using namespace Wt::cpp17;

#define SET_BS5THEME 1

// Always apply theme before creating widgets!
class CThemedApplication : public WApplication
{
public:
CThemedApplication(const WEnvironment& rcEnv)
: WApplication{rcEnv}
{
#if SET_BS5THEME
setTheme(make_shared<WBootstrap5Theme>());
#endif
}
};

class CFixedTableModel : public WAbstractTableModel
{
public:
CFixedTableModel(const int rowCount, const int colCount)
: _rowCount{rowCount}
, _colCount{colCount}
{ }

any headerData(const int section, const Orientation orientation, const ItemDataRole role) const
{
if (orientation != Orientation::Horizontal) throw invalid_argument("orientation");
switch (role.value())
{
default: return {};
case ItemDataRole::Display: return format("C{}", section);
}
}

any data(const WModelIndex& index, const ItemDataRole role) const override
{
if (!index.isValid()) return {};
switch (role.value())
{
default: return {};
case ItemDataRole::Display: return format("{}, {}", index.row(), index.column());
}
}

//! Returns the WModelIndex moved by delta.
[[nodiscard]]
WModelIndex move(const WModelIndex& index, int rowDelta, int colDelta)
{
const int row{clamp(index.row() + rowDelta, 0, _rowCount - 1)};
const int col{clamp(index.column() + colDelta, 0, _colCount - 1)};
return createIndex(row, col, nullptr);
}

int columnCount(const WModelIndex& index) const override { return index.isValid() ? 0 : _colCount; }
int rowCount (const WModelIndex& index) const override { return index.isValid() ? 0 : _rowCount; }

const int _rowCount;
const int _colCount;
};

class CApplication final : public CThemedApplication
{
public:
CApplication(const WEnvironment& rcEnv);

private:
WServer& _Server; //!< The associated WServer instance, needed for async operations.

WContainerWidget& _cntRoot{*root()};
WBoxLayout& _lytRoot{*_cntRoot.setLayout(make_unique<WVBoxLayout>())};

WTableView& _tvA{*_lytRoot.addWidget(make_unique<WTableView>())};

shared_ptr<CFixedTableModel> _mdlAPtr{make_shared<CFixedTableModel>(100, 50)};
};

CApplication::CApplication(const WEnvironment& rcEnv)
: CThemedApplication{rcEnv}
, _Server{*environment().server()}
{
setTitle("bug repro");

const auto initTable = [](WTableView& tv, const shared_ptr<CFixedTableModel>& mdlPtr)
{
tv.setSelectionBehavior(SelectionBehavior::Items);
tv.setSelectionMode(SelectionMode::Single);
tv.setSortingEnabled(false);
tv.setCanReceiveFocus(true);
tv.setEditTriggers(EditTrigger::None);
tv.setAlternatingRowColors(true);
tv.setModel(mdlPtr);

tv.select(mdlPtr->move(WModelIndex{}, 0, 1));
};
initTable(_tvA, _mdlAPtr);
}

int main(int argc, char* argv[])
{
return WRun(argc, argv, [](const WEnvironment& rcEnv)
{
try
{
return make_unique<CApplication>(rcEnv);
}
catch (const std::exception& rcException)
{
cerr << "exception " << typeid(remove_cvref<decltype(rcException)>::type).name() << ": " << rcException.what() << endl;

#if DEBUG
exit(-1);
#endif
throw;
}
});
}
    (1-1/1)