Split Insert triplet button, and add mode menus

The "insert before" and "insert after" buttons will drop a menu to
select the new triplet mode, allowing triplets with different modes to
be inserted with one less mouse click.

The "insert copy" button still does the old behaviour of inserting a
copy of the currently selected triplet.
This commit is contained in:
G.K.MacGregor
2022-03-06 12:00:53 +00:00
parent cda458b5bf
commit 74ebc91ee6
5 changed files with 154 additions and 87 deletions

View File

@@ -72,8 +72,8 @@ void InsertTripletCommand::redo()
if (m_firstDo) if (m_firstDo)
m_firstDo = false; m_firstDo = false;
else
m_teletextDocument->emit tripletCommandHighlight(m_row+1); m_teletextDocument->emit tripletCommandHighlight(m_row);
} }
void InsertTripletCommand::undo() void InsertTripletCommand::undo()

View File

@@ -133,73 +133,93 @@ X26DockWidget::X26DockWidget(TeletextWidget *parent): QDockWidget(parent)
m_cookedModePushButton = new QPushButton; m_cookedModePushButton = new QPushButton;
cookedTripletLayout->addWidget(m_cookedModePushButton); cookedTripletLayout->addWidget(m_cookedModePushButton);
auto newModeMenuAction=[&](QMenu *menu, int mode)
{
QAction *action = menu->addAction(m_x26Model->modeTripletName(mode));
connect(action, &QAction::triggered, [=]() { cookedModeMenuSelected(mode); });
};
// Cooked triplet menu // Cooked triplet menu
// We build the menus for both "Insert" buttons at the same time
m_cookedModeMenu = new QMenu(this); m_cookedModeMenu = new QMenu(this);
newModeMenuAction(m_cookedModeMenu, 0x04); m_insertBeforeMenu = new QMenu(this);
QMenu *rowTripletSubMenu = m_cookedModeMenu->addMenu(tr("Row triplet")); m_insertAfterMenu = new QMenu(this);
newModeMenuAction(rowTripletSubMenu, 0x00);
newModeMenuAction(rowTripletSubMenu, 0x01); for (int m=0; m<3; m++) {
newModeMenuAction(rowTripletSubMenu, 0x07); QMenu *menuToBuild;
newModeMenuAction(rowTripletSubMenu, 0x18);
QMenu *columnTripletSubMenu = m_cookedModeMenu->addMenu(tr("Column triplet")); if (m == 0)
newModeMenuAction(columnTripletSubMenu, 0x20); menuToBuild = m_cookedModeMenu;
newModeMenuAction(columnTripletSubMenu, 0x23); else if (m == 1)
newModeMenuAction(columnTripletSubMenu, 0x27); menuToBuild = m_insertBeforeMenu;
newModeMenuAction(columnTripletSubMenu, 0x2c); else // if (m == 2)
newModeMenuAction(columnTripletSubMenu, 0x2e); menuToBuild = m_insertAfterMenu;
newModeMenuAction(columnTripletSubMenu, 0x28);
columnTripletSubMenu->addSeparator(); auto newModeMenuAction=[&](QMenu *menu, int mode)
newModeMenuAction(columnTripletSubMenu, 0x29); {
newModeMenuAction(columnTripletSubMenu, 0x2f); QAction *action = menu->addAction(m_x26Model->modeTripletName(mode));
newModeMenuAction(columnTripletSubMenu, 0x21); if (m == 0)
newModeMenuAction(columnTripletSubMenu, 0x22); connect(action, &QAction::triggered, [=]() { cookedModeMenuSelected(mode); });
newModeMenuAction(columnTripletSubMenu, 0x2b); else if (m == 1)
newModeMenuAction(columnTripletSubMenu, 0x2d); connect(action, &QAction::triggered, [=]() { insertTriplet(mode, false); });
QMenu *diacriticalSubMenu = columnTripletSubMenu->addMenu(tr("G0 diacritical")); else // if (m == 2)
for (int i=0; i<16; i++) connect(action, &QAction::triggered, [=]() { insertTriplet(mode, true); });
newModeMenuAction(diacriticalSubMenu, 0x30 + i); };
QMenu *objectSubMenu = m_cookedModeMenu->addMenu(tr("Object"));
newModeMenuAction(objectSubMenu, 0x10); newModeMenuAction(menuToBuild, 0x04);
newModeMenuAction(objectSubMenu, 0x11); QMenu *rowTripletSubMenu = menuToBuild->addMenu(tr("Row triplet"));
newModeMenuAction(objectSubMenu, 0x12); newModeMenuAction(rowTripletSubMenu, 0x00);
newModeMenuAction(objectSubMenu, 0x13); newModeMenuAction(rowTripletSubMenu, 0x01);
newModeMenuAction(objectSubMenu, 0x15); newModeMenuAction(rowTripletSubMenu, 0x07);
newModeMenuAction(objectSubMenu, 0x16); newModeMenuAction(rowTripletSubMenu, 0x18);
newModeMenuAction(objectSubMenu, 0x17); QMenu *columnTripletSubMenu = menuToBuild->addMenu(tr("Column triplet"));
newModeMenuAction(m_cookedModeMenu, 0x1f); newModeMenuAction(columnTripletSubMenu, 0x20);
m_cookedModeMenu->addSeparator(); newModeMenuAction(columnTripletSubMenu, 0x23);
QMenu *pdcSubMenu = m_cookedModeMenu->addMenu(tr("PDC/reserved")); newModeMenuAction(columnTripletSubMenu, 0x27);
newModeMenuAction(pdcSubMenu, 0x08); newModeMenuAction(columnTripletSubMenu, 0x2c);
newModeMenuAction(pdcSubMenu, 0x09); newModeMenuAction(columnTripletSubMenu, 0x2e);
newModeMenuAction(pdcSubMenu, 0x0a); newModeMenuAction(columnTripletSubMenu, 0x28);
newModeMenuAction(pdcSubMenu, 0x0b); columnTripletSubMenu->addSeparator();
newModeMenuAction(pdcSubMenu, 0x0c); newModeMenuAction(columnTripletSubMenu, 0x29);
newModeMenuAction(pdcSubMenu, 0x0d); newModeMenuAction(columnTripletSubMenu, 0x2f);
newModeMenuAction(pdcSubMenu, 0x26); newModeMenuAction(columnTripletSubMenu, 0x21);
QMenu *reservedRowSubMenu = pdcSubMenu->addMenu(tr("Reserved row")); newModeMenuAction(columnTripletSubMenu, 0x22);
newModeMenuAction(reservedRowSubMenu, 0x02); newModeMenuAction(columnTripletSubMenu, 0x2b);
newModeMenuAction(reservedRowSubMenu, 0x03); newModeMenuAction(columnTripletSubMenu, 0x2d);
newModeMenuAction(reservedRowSubMenu, 0x05); QMenu *diacriticalSubMenu = columnTripletSubMenu->addMenu(tr("G0 diacritical"));
newModeMenuAction(reservedRowSubMenu, 0x06); for (int i=0; i<16; i++)
newModeMenuAction(reservedRowSubMenu, 0x0e); newModeMenuAction(diacriticalSubMenu, 0x30 + i);
newModeMenuAction(reservedRowSubMenu, 0x0f); QMenu *objectSubMenu = menuToBuild->addMenu(tr("Object"));
newModeMenuAction(reservedRowSubMenu, 0x14); newModeMenuAction(objectSubMenu, 0x10);
newModeMenuAction(reservedRowSubMenu, 0x19); newModeMenuAction(objectSubMenu, 0x11);
newModeMenuAction(reservedRowSubMenu, 0x1a); newModeMenuAction(objectSubMenu, 0x12);
newModeMenuAction(reservedRowSubMenu, 0x1b); newModeMenuAction(objectSubMenu, 0x13);
newModeMenuAction(reservedRowSubMenu, 0x1c); newModeMenuAction(objectSubMenu, 0x15);
newModeMenuAction(reservedRowSubMenu, 0x1d); newModeMenuAction(objectSubMenu, 0x16);
newModeMenuAction(reservedRowSubMenu, 0x1e); newModeMenuAction(objectSubMenu, 0x17);
QMenu *reservedColumnSubMenu = pdcSubMenu->addMenu(tr("Reserved column")); newModeMenuAction(menuToBuild, 0x1f);
newModeMenuAction(reservedColumnSubMenu, 0x24); menuToBuild->addSeparator();
newModeMenuAction(reservedColumnSubMenu, 0x25); QMenu *pdcSubMenu = menuToBuild->addMenu(tr("PDC/reserved"));
newModeMenuAction(reservedColumnSubMenu, 0x26); newModeMenuAction(pdcSubMenu, 0x08);
newModeMenuAction(pdcSubMenu, 0x09);
newModeMenuAction(pdcSubMenu, 0x0a);
newModeMenuAction(pdcSubMenu, 0x0b);
newModeMenuAction(pdcSubMenu, 0x0c);
newModeMenuAction(pdcSubMenu, 0x0d);
newModeMenuAction(pdcSubMenu, 0x26);
QMenu *reservedRowSubMenu = pdcSubMenu->addMenu(tr("Reserved row"));
newModeMenuAction(reservedRowSubMenu, 0x02);
newModeMenuAction(reservedRowSubMenu, 0x03);
newModeMenuAction(reservedRowSubMenu, 0x05);
newModeMenuAction(reservedRowSubMenu, 0x06);
newModeMenuAction(reservedRowSubMenu, 0x0e);
newModeMenuAction(reservedRowSubMenu, 0x0f);
newModeMenuAction(reservedRowSubMenu, 0x14);
newModeMenuAction(reservedRowSubMenu, 0x19);
newModeMenuAction(reservedRowSubMenu, 0x1a);
newModeMenuAction(reservedRowSubMenu, 0x1b);
newModeMenuAction(reservedRowSubMenu, 0x1c);
newModeMenuAction(reservedRowSubMenu, 0x1d);
newModeMenuAction(reservedRowSubMenu, 0x1e);
QMenu *reservedColumnSubMenu = pdcSubMenu->addMenu(tr("Reserved column"));
newModeMenuAction(reservedColumnSubMenu, 0x24);
newModeMenuAction(reservedColumnSubMenu, 0x25);
newModeMenuAction(reservedColumnSubMenu, 0x26);
}
m_cookedModePushButton->setMenu(m_cookedModeMenu); m_cookedModePushButton->setMenu(m_cookedModeMenu);
@@ -584,12 +604,21 @@ X26DockWidget::X26DockWidget(TeletextWidget *parent): QDockWidget(parent)
// Insert and delete widgets // Insert and delete widgets
QHBoxLayout *insertDeleteLayout = new QHBoxLayout; QHBoxLayout *insertDeleteLayout = new QHBoxLayout;
m_insertPushButton = new QPushButton(tr("Insert triplet")); m_insertBeforePushButton = new QPushButton(tr("Insert above"));
insertDeleteLayout->addWidget(m_insertPushButton); insertDeleteLayout->addWidget(m_insertBeforePushButton);
m_deletePushButton = new QPushButton(tr("Delete triplet")); m_insertBeforePushButton->setMenu(m_insertBeforeMenu);
m_insertAfterPushButton = new QPushButton(tr("Insert below"));
insertDeleteLayout->addWidget(m_insertAfterPushButton);
m_insertAfterPushButton->setMenu(m_insertAfterMenu);
m_insertCopyPushButton = new QPushButton(tr("Insert copy"));
insertDeleteLayout->addWidget(m_insertCopyPushButton);
m_deletePushButton = new QPushButton(tr("Delete"));
insertDeleteLayout->addWidget(m_deletePushButton); insertDeleteLayout->addWidget(m_deletePushButton);
connect(m_insertPushButton, &QPushButton::clicked, this, &X26DockWidget::insertTriplet); connect(m_insertCopyPushButton, &QPushButton::clicked, this, &X26DockWidget::insertTripletCopy);
connect(m_deletePushButton, &QPushButton::clicked, this, &X26DockWidget::deleteTriplet); connect(m_deletePushButton, &QPushButton::clicked, this, &X26DockWidget::deleteTriplet);
x26Layout->addLayout(insertDeleteLayout); x26Layout->addLayout(insertDeleteLayout);
@@ -607,7 +636,7 @@ void X26DockWidget::keyPressEvent(QKeyEvent *event)
{ {
switch (event->key()) { switch (event->key()) {
case Qt::Key_Insert: case Qt::Key_Insert:
insertTriplet(); insertTripletCopy();
break; break;
case Qt::Key_Delete: case Qt::Key_Delete:
deleteTriplet(); deleteTriplet();
@@ -965,14 +994,47 @@ void X26DockWidget::updateModelFromCookedWidget(const int value, const int role)
updateAllRawTripletSpinBoxes(m_x26View->currentIndex()); updateAllRawTripletSpinBoxes(m_x26View->currentIndex());
} }
void X26DockWidget::insertTriplet() void X26DockWidget::insertTriplet(int modeExt, bool after)
{
QModelIndex index = m_x26View->currentIndex();
X26Triplet newTriplet(modeExt < 0x20 ? 41 : 0, modeExt & 0x1f, 0);
int row;
if (index.isValid()) {
// If we're inserting a column triplet next to another column triplet,
// duplicate the column number
// Avoid the PDC and reserved mode triplets
if (modeExt >= 0x20 && modeExt != 0x24 && modeExt != 0x25 && modeExt != 0x26 && modeExt != 0x2a) {
const int existingTripletModeExt = index.model()->data(index.model()->index(index.row(), 2), Qt::EditRole).toInt();
if (existingTripletModeExt >= 0x20 && existingTripletModeExt != 0x24 && existingTripletModeExt != 0x25 && existingTripletModeExt != 0x26 && existingTripletModeExt != 0x2a)
newTriplet.setAddress(index.model()->data(index.model()->index(index.row(), 0), Qt::UserRole).toInt());
}
row = index.row()+after;
} else
row = 0;
// For character triplets, ensure Data is not reserved
if (modeExt == 0x21 || modeExt == 0x22 || modeExt == 0x29 || modeExt == 0x2b || modeExt >= 0x2f)
newTriplet.setData(0x20);
// For Termination Marker, set Address and Mode
if (modeExt == 0x1f) {
newTriplet.setAddress(63);
newTriplet.setData(7);
}
m_x26Model->insertRows(row, 1, QModelIndex(), newTriplet);
}
void X26DockWidget::insertTripletCopy()
{ {
QModelIndex index = m_x26View->currentIndex(); QModelIndex index = m_x26View->currentIndex();
if (index.isValid()) if (index.isValid())
m_x26Model->insertRow(index.row(), QModelIndex()); m_x26Model->insertRow(index.row(), QModelIndex());
else else
m_x26Model->insertFirstRow(); // No existing triplet to copy, so insert a Termination Marker
m_x26Model->insertRows(0, 1, QModelIndex(), X26Triplet(63, 31, 7));
} }
void X26DockWidget::deleteTriplet() void X26DockWidget::deleteTriplet()
@@ -988,9 +1050,9 @@ void X26DockWidget::customMenuRequested(QPoint pos)
QMenu *menu = new QMenu(this); QMenu *menu = new QMenu(this);
QAction *insertAct = new QAction("Insert triplet", this); QAction *insertAct = new QAction("Insert triplet copy", this);
menu->addAction(insertAct); menu->addAction(insertAct);
connect(insertAct, &QAction::triggered, this, &X26DockWidget::insertTriplet); connect(insertAct, &QAction::triggered, this, &X26DockWidget::insertTripletCopy);
if (index.isValid()) { if (index.isValid()) {
QAction *deleteAct = new QAction("Delete triplet", this); QAction *deleteAct = new QAction("Delete triplet", this);
menu->addAction(deleteAct); menu->addAction(deleteAct);

View File

@@ -61,7 +61,8 @@ public:
X26DockWidget(TeletextWidget *parent); X26DockWidget(TeletextWidget *parent);
public slots: public slots:
void insertTriplet(); void insertTriplet(int, bool);
void insertTripletCopy();
void deleteTriplet(); void deleteTriplet();
void customMenuRequested(QPoint pos); void customMenuRequested(QPoint pos);
void loadX26List(); void loadX26List();
@@ -87,7 +88,7 @@ private:
QTableView *m_x26View; QTableView *m_x26View;
X26Model *m_x26Model; X26Model *m_x26Model;
QSpinBox *m_cookedRowSpinBox, *m_cookedColumnSpinBox; QSpinBox *m_cookedRowSpinBox, *m_cookedColumnSpinBox;
QMenu *m_cookedModeMenu; QMenu *m_cookedModeMenu, *m_insertBeforeMenu, *m_insertAfterMenu;
QPushButton *m_cookedModePushButton; QPushButton *m_cookedModePushButton;
QSpinBox *m_rawTripletAddressSpinBox, *m_rawTripletModeSpinBox, *m_rawTripletDataSpinBox; QSpinBox *m_rawTripletAddressSpinBox, *m_rawTripletModeSpinBox, *m_rawTripletDataSpinBox;
QStackedLayout *m_rawOrCookedStackedLayout; QStackedLayout *m_rawOrCookedStackedLayout;
@@ -113,7 +114,7 @@ private:
QSpinBox *m_reservedPDCSpinBox; QSpinBox *m_reservedPDCSpinBox;
QComboBox *m_terminationMarkerPageTypeComboBox; QComboBox *m_terminationMarkerPageTypeComboBox;
QCheckBox *m_terminationMarkerMoreFollowsCheckBox; QCheckBox *m_terminationMarkerMoreFollowsCheckBox;
QPushButton *m_insertPushButton, *m_deletePushButton; QPushButton *m_insertBeforePushButton, *m_insertAfterPushButton, *m_insertCopyPushButton, *m_deletePushButton;
TeletextWidget *m_parentMainWidget; TeletextWidget *m_parentMainWidget;
}; };

View File

@@ -797,13 +797,6 @@ QVariant X26Model::headerData(int section, Qt::Orientation orientation, int role
return QVariant(); return QVariant();
} }
bool X26Model::insertFirstRow()
{
m_parentMainWidget->document()->undoStack()->push(new InsertTripletCommand(m_parentMainWidget->document(), this, 0, 1, X26Triplet(63, 31, 7)));
return true;
}
bool X26Model::insertRows(int row, int count, const QModelIndex &parent) bool X26Model::insertRows(int row, int count, const QModelIndex &parent)
{ {
Q_UNUSED(parent); Q_UNUSED(parent);
@@ -815,6 +808,17 @@ bool X26Model::insertRows(int row, int count, const QModelIndex &parent)
return true; return true;
} }
bool X26Model::insertRows(int row, int count, const QModelIndex &parent, X26Triplet triplet)
{
Q_UNUSED(parent);
if (m_parentMainWidget->document()->currentSubPage()->enhancements()->size() + count > m_parentMainWidget->document()->currentSubPage()->maxEnhancements())
return false;
m_parentMainWidget->document()->undoStack()->push(new InsertTripletCommand(m_parentMainWidget->document(), this, row, count, triplet));
return true;
}
bool X26Model::removeRows(int row, int count, const QModelIndex &index) bool X26Model::removeRows(int row, int count, const QModelIndex &index)
{ {
Q_UNUSED(index); Q_UNUSED(index);

View File

@@ -36,8 +36,8 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role); bool setData(const QModelIndex &index, const QVariant &value, int role);
QVariant headerData(int section, Qt::Orientation orientation, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const;
bool insertFirstRow();
bool insertRows(int position, int rows, const QModelIndex &parent); bool insertRows(int position, int rows, const QModelIndex &parent);
bool insertRows(int position, int rows, const QModelIndex &parent, X26Triplet triplet);
bool removeRows(int position, int rows, const QModelIndex &index); bool removeRows(int position, int rows, const QModelIndex &index);
// Qt::ItemFlags flags(const QModelIndex &index) const; // Qt::ItemFlags flags(const QModelIndex &index) const;