ScreenTranslator/src/substitutionstable.cpp

144 lines
3.8 KiB
C++
Raw Normal View History

2020-03-08 17:49:15 +07:00
#include "substitutionstable.h"
#include "debug.h"
#include "languagecodes.h"
#include <QComboBox>
#include <QPainter>
#include <QStringListModel>
#include <QStyledItemDelegate>
namespace
{
QStringList allSourceLanguages()
{
LanguageCodes langs;
const auto &allLangs = langs.all();
QStringList result;
result.reserve(allLangs.size());
for (const auto &i : allLangs) {
if (i.second.tesseract.isEmpty())
continue;
2020-03-18 02:15:28 +07:00
result.append(QObject::tr(i.second.name));
2020-03-08 17:49:15 +07:00
}
2020-03-18 02:15:28 +07:00
std::sort(result.begin(), result.end());
2020-03-08 17:49:15 +07:00
return result;
}
class SubstitutionDelegate : public QStyledItemDelegate
{
public:
explicit SubstitutionDelegate(QObject *parent = nullptr)
: QStyledItemDelegate(parent)
{
}
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override
{
painter->drawText(option.rect, Qt::AlignCenter, index.data().toString());
}
};
} // namespace
SubstitutionsTable::SubstitutionsTable(QWidget *parent)
: QTableWidget(parent)
, languagesModel_(new QStringListModel(allSourceLanguages(), this))
{
setItemDelegate(new SubstitutionDelegate(this));
setColumnCount(int(Column::Count));
setHorizontalHeaderLabels({tr("Language"), tr("Source"), tr("Changed")});
connect(this, &SubstitutionsTable::itemChanged, //
this, &SubstitutionsTable::handleItemChange);
}
void SubstitutionsTable::setSubstitutions(const Substitutions &substitutions)
{
for (const auto &i : substitutions) addRow(i.first, i.second);
addRow(); // for editing
resizeColumnsToContents();
}
Substitutions SubstitutionsTable::substitutions() const
{
Substitutions result;
for (auto row = 0, end = rowCount(); row < end; ++row) {
const auto pair = at(row);
SOFT_ASSERT(!pair.first.isEmpty(), continue);
if (pair.second.source.isEmpty())
continue;
result.emplace(pair.first, pair.second);
}
return result;
}
void SubstitutionsTable::addRow(const LanguageId &language,
const Substitution &substutution)
{
QSignalBlocker blocker(this);
auto row = rowCount();
insertRow(row);
auto combo = new QComboBox(this);
combo->setModel(languagesModel_);
using E = Column;
if (!language.isEmpty()) {
LanguageCodes langs;
if (auto lang = langs.findById(language))
2020-03-18 02:15:28 +07:00
combo->setCurrentText(QObject::tr(lang->name));
2020-03-08 17:49:15 +07:00
} else if (rowCount() > 1) {
const auto previousRow = rowCount() - 2;
auto previousCombo =
static_cast<QComboBox *>(cellWidget(previousRow, int(E::Language)));
SOFT_ASSERT(previousCombo, return );
combo->setCurrentText(previousCombo->currentText());
}
setCellWidget(row, int(E::Language), combo);
setItem(row, int(E::Source), new QTableWidgetItem(substutution.source));
setItem(row, int(E::Target), new QTableWidgetItem(substutution.target));
}
std::pair<LanguageId, Substitution> SubstitutionsTable::at(int row) const
{
SOFT_ASSERT(row >= 0 && row < rowCount(), return {});
using E = Column;
auto combo = static_cast<QComboBox *>(cellWidget(row, int(E::Language)));
SOFT_ASSERT(combo, return {});
LanguageCodes langs;
auto lang = langs.findByName(combo->currentText());
SOFT_ASSERT(lang, return {});
Substitution sub;
auto sourceItem = item(row, int(E::Source));
SOFT_ASSERT(sourceItem, return {});
sub.source = sourceItem->text();
auto targetItem = item(row, int(E::Target));
SOFT_ASSERT(targetItem, return {});
sub.target = targetItem->text();
return std::make_pair(lang->id, sub);
}
void SubstitutionsTable::handleItemChange(QTableWidgetItem *item)
{
if (item->column() != int(Column::Source))
return;
const auto lastRow = rowCount() - 1;
if (!item->text().isEmpty() && item->row() == lastRow) {
addRow();
return;
}
if (item->text().isEmpty() && item->row() != lastRow) {
removeRow(item->row());
return;
}
}