File indexing completed on 2024-12-22 04:40:07
0001 #include "encodingdetectdialog.h" 0002 #include "ui_encodingdetectdialog.h" 0003 0004 #include <QPushButton> 0005 #include <QScrollBar> 0006 #include <QTextCodec> 0007 #include <QTextStream> 0008 0009 #include <KCharsets> 0010 0011 using namespace SubtitleComposer; 0012 0013 #define INVALID_PARENT_ROW quintptr(-1) 0014 0015 namespace SubtitleComposer { 0016 class TreeModel : public QAbstractItemModel 0017 { 0018 Q_OBJECT 0019 friend class EncodingDetectDialog; 0020 0021 public: 0022 explicit TreeModel(QObject *parent = nullptr); 0023 ~TreeModel(); 0024 0025 QVariant data(const QModelIndex &index, int role) const override; 0026 Qt::ItemFlags flags(const QModelIndex &index) const override; 0027 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; 0028 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; 0029 QModelIndex parent(const QModelIndex &index) const override; 0030 int rowCount(const QModelIndex &parent = QModelIndex()) const override; 0031 int columnCount(const QModelIndex &parent = QModelIndex()) const override { Q_UNUSED(parent); return 1; } 0032 const QString & encoding(const QModelIndex &index) const; 0033 0034 private: 0035 void setupModelData(); 0036 0037 QList<QStringList> m_encodings; 0038 QStringList m_detectedName; 0039 QStringList m_detected; 0040 }; 0041 } 0042 0043 EncodingDetectDialog::EncodingDetectDialog(const QByteArray &text, QWidget *parent) 0044 : QDialog(parent), 0045 ui(new Ui::EncodingDetectDialog), 0046 m_text(text) 0047 { 0048 ui->setupUi(this); 0049 TreeModel *model = new TreeModel(this); 0050 ui->encoding->setModel(model); 0051 0052 ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(true); 0053 connect(ui->encoding->selectionModel(), &QItemSelectionModel::selectionChanged, this, [&, model](const QItemSelection &sel, const QItemSelection &){ 0054 const bool hasSelection = !sel.isEmpty() && !sel.first().isEmpty(); 0055 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(hasSelection); 0056 0057 if(hasSelection) { 0058 const QModelIndex first = sel.first().indexes().first(); 0059 m_selectedEncoding = model->encoding(first); 0060 QTextCodec *codec = QTextCodec::codecForName(m_selectedEncoding.toUtf8()); 0061 const int val = ui->preview->verticalScrollBar()->value(); 0062 ui->preview->setPlainText(codec->toUnicode(m_text)); 0063 ui->preview->verticalScrollBar()->setValue(val); 0064 } else { 0065 ui->preview->clear(); 0066 m_selectedEncoding.clear(); 0067 } 0068 }); 0069 } 0070 0071 EncodingDetectDialog::~EncodingDetectDialog() 0072 { 0073 delete ui; 0074 } 0075 0076 void 0077 EncodingDetectDialog::addEncoding(const QString &name, int confidence) 0078 { 0079 TreeModel *model = reinterpret_cast<TreeModel *>(ui->encoding->model()); 0080 model->m_detectedName.append(name); 0081 model->m_detected.append(i18nc("Text encoding detected with n% confidence.", "%1 (%2% confidence)", 0082 name.toUpper(), confidence)); 0083 0084 if(ui->encoding->selectionModel()->selection().isEmpty()) { 0085 const QModelIndex &detected = model->index(0, 0); 0086 ui->encoding->expand(detected); 0087 const QModelIndex &selected = model->index(0, 0, detected); 0088 ui->encoding->selectionModel()->select(selected, QItemSelectionModel::ClearAndSelect); 0089 } 0090 } 0091 0092 /// Tree Model 0093 TreeModel::TreeModel(QObject *parent) 0094 : QAbstractItemModel(parent) 0095 { 0096 m_encodings = KCharsets::charsets()->encodingsByScript(); 0097 for(QStringList &encList : m_encodings) { 0098 bool first = true; 0099 for(QString &enc: encList) { 0100 if(first) 0101 first = false; 0102 else 0103 enc = enc.toUpper(); 0104 } 0105 } 0106 } 0107 0108 TreeModel::~TreeModel() {} 0109 0110 const QString & 0111 TreeModel::encoding(const QModelIndex &index) const 0112 { 0113 int p = index.parent().row(); 0114 const QStringList &parentList = p == 0 ? m_detectedName : m_encodings.at(p - 1); 0115 return parentList.at(p == 0 ? index.row() : index.row() + 1); 0116 } 0117 0118 Qt::ItemFlags 0119 TreeModel::flags(const QModelIndex &index) const 0120 { 0121 if(!index.isValid()) 0122 return Qt::NoItemFlags; 0123 if(index.internalId() != INVALID_PARENT_ROW) 0124 return Qt::ItemIsSelectable | Qt::ItemIsEnabled; 0125 return Qt::ItemIsEnabled; 0126 } 0127 0128 QVariant 0129 TreeModel::headerData(int section, Qt::Orientation orientation, int role) const 0130 { 0131 if(orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0) 0132 return QStringLiteral("Encoding"); 0133 0134 return QVariant(); 0135 } 0136 0137 QModelIndex 0138 TreeModel::index(int row, int column, const QModelIndex &parent) const 0139 { 0140 Q_ASSERT(column == 0); 0141 0142 if(!parent.isValid()) { 0143 if(row <= m_encodings.size()) 0144 return createIndex(row, 0, INVALID_PARENT_ROW); 0145 return QModelIndex(); 0146 } 0147 0148 Q_ASSERT(parent.internalId() == INVALID_PARENT_ROW); 0149 0150 if(row < rowCount(parent)) 0151 return createIndex(row, 0, parent.row()); 0152 0153 return QModelIndex(); 0154 } 0155 0156 QModelIndex 0157 TreeModel::parent(const QModelIndex &index) const 0158 { 0159 if(!index.isValid()) 0160 return QModelIndex(); 0161 0162 if(index.internalId() == INVALID_PARENT_ROW) 0163 return QModelIndex(); 0164 0165 return createIndex(index.internalId(), 0, INVALID_PARENT_ROW); 0166 } 0167 0168 int 0169 TreeModel::rowCount(const QModelIndex &parent) const 0170 { 0171 if(parent.column() > 0) 0172 return 0; 0173 0174 if(!parent.isValid()) 0175 return m_encodings.size() + 1; 0176 0177 if(parent.internalId() != INVALID_PARENT_ROW) 0178 return 0; 0179 0180 return parent.row() == 0 ? m_detected.size() : m_encodings.at(parent.row() - 1).size() - 1; 0181 } 0182 0183 QVariant 0184 TreeModel::data(const QModelIndex &index, int role) const 0185 { 0186 if(!index.isValid() || role != Qt::DisplayRole) 0187 return QVariant(); 0188 0189 const QModelIndex &parentIndex = index.parent(); 0190 if(!parentIndex.isValid()) 0191 return index.row() == 0 ? i18n("Detected") : m_encodings.at(index.row() - 1).at(0); 0192 0193 const QStringList &parentList = parentIndex.row() == 0 ? m_detected : m_encodings.at(parentIndex.row() - 1); 0194 return parentList.at(parentIndex.row() == 0 ? index.row() : index.row() + 1); 0195 } 0196 0197 #include "encodingdetectdialog.moc"