File indexing completed on 2024-03-24 04:59:57

0001 /***************************************************************************
0002  *   Copyright (C) 2010 Matthias Fuchs <mat69@gmx.net>                     *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or modify  *
0005  *   it under the terms of the GNU General Public License as published by  *
0006  *   the Free Software Foundation; either version 2 of the License, or     *
0007  *   (at your option) any later version.                                   *
0008  *                                                                         *
0009  *   This program is distributed in the hope that it will be useful,       *
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0012  *   GNU General Public License for more details.                          *
0013  *                                                                         *
0014  *   You should have received a copy of the GNU General Public License     *
0015  *   along with this program; if not, write to the                         *
0016  *   Free Software Foundation, Inc.,                                       *
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
0018  ***************************************************************************/
0019 
0020 #include "autopastemodel.h"
0021 #include "settings.h"
0022 
0023 #include <KComboBox>
0024 #include <KLineEdit>
0025 #include <KLocalizedString>
0026 #include <QIcon>
0027 
0028 AutoPasteDelegate::AutoPasteDelegate(QAbstractItemModel *types, QAbstractItemModel *syntaxes, QObject *parent)
0029     : QStyledItemDelegate(parent)
0030     , m_types(types)
0031     , m_syntaxes(syntaxes)
0032 {
0033 }
0034 
0035 QWidget *AutoPasteDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
0036 {
0037     Q_UNUSED(option)
0038 
0039     if (!index.isValid()) {
0040         return nullptr;
0041     }
0042 
0043     switch (index.column()) {
0044     case AutoPasteModel::Type: {
0045         auto *types = new KComboBox(parent);
0046         types->setModel(m_types);
0047         return types;
0048     }
0049     case AutoPasteModel::Pattern: {
0050         auto *pattern = new KLineEdit(parent);
0051         return pattern;
0052     }
0053     case AutoPasteModel::PatternSyntax: {
0054         auto *syntaxes = new KComboBox(parent);
0055         syntaxes->setModel(m_syntaxes);
0056         return syntaxes;
0057     }
0058     default:
0059         return nullptr;
0060     }
0061 }
0062 
0063 void AutoPasteDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
0064 {
0065     if (!index.isValid() || !editor) {
0066         return;
0067     }
0068 
0069     switch (index.column()) {
0070     case AutoPasteModel::Type: {
0071         auto *type = static_cast<KComboBox *>(editor);
0072         const int row = type->findData(index.data(Qt::EditRole));
0073         type->setCurrentIndex(row);
0074         break;
0075     }
0076     case AutoPasteModel::Pattern: {
0077         auto *line = static_cast<KLineEdit *>(editor);
0078         line->setText(index.data(Qt::EditRole).toString());
0079         break;
0080     }
0081     case AutoPasteModel::PatternSyntax: {
0082         auto *syntax = static_cast<KComboBox *>(editor);
0083         const int row = syntax->findData(index.data(Qt::EditRole));
0084         syntax->setCurrentIndex(row);
0085         break;
0086     }
0087     default:
0088         break;
0089     }
0090 }
0091 
0092 void AutoPasteDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
0093 {
0094     if (!index.isValid() || !editor || !model) {
0095         return;
0096     }
0097 
0098     switch (index.column()) {
0099     case AutoPasteModel::Type: {
0100         auto *typeBox = static_cast<KComboBox *>(editor);
0101         const int type = typeBox->itemData(typeBox->currentIndex()).toInt();
0102         model->setData(index, type);
0103         break;
0104     }
0105     case AutoPasteModel::Pattern: {
0106         auto *line = static_cast<KLineEdit *>(editor);
0107         const QString text = line->text();
0108         if (!text.isEmpty()) {
0109             model->setData(index, text);
0110         }
0111         break;
0112     }
0113     case AutoPasteModel::PatternSyntax: {
0114         auto *syntaxBox = static_cast<KComboBox *>(editor);
0115         const int syntax = syntaxBox->itemData(syntaxBox->currentIndex()).toInt();
0116         model->setData(index, syntax);
0117         break;
0118     }
0119     default:
0120         break;
0121     }
0122 }
0123 
0124 void AutoPasteDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
0125 {
0126     Q_UNUSED(index)
0127     editor->setGeometry(option.rect);
0128 }
0129 
0130 QSize AutoPasteDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
0131 {
0132     // make the sizeHint a little bit nicer to have more beautiful editors
0133     QSize hint;
0134     hint.setWidth(QStyledItemDelegate::sizeHint(option, index).width());
0135     hint.setHeight(option.fontMetrics.height() + 7);
0136     return hint;
0137 }
0138 
0139 AutoPasteModel::AutoPasteModel(QObject *parent)
0140     : QAbstractTableModel(parent)
0141 {
0142 }
0143 
0144 AutoPasteModel::~AutoPasteModel()
0145 {
0146 }
0147 
0148 int AutoPasteModel::rowCount(const QModelIndex &index) const
0149 {
0150     if (!index.isValid()) {
0151         return m_data.count();
0152     }
0153 
0154     return 0;
0155 }
0156 
0157 int AutoPasteModel::columnCount(const QModelIndex &index) const
0158 {
0159     if (!index.isValid()) {
0160         return 3;
0161     }
0162 
0163     return 0;
0164 }
0165 
0166 QVariant AutoPasteModel::headerData(int section, Qt::Orientation orientation, int role) const
0167 {
0168     if (orientation == Qt::Vertical) {
0169         return QVariant();
0170     }
0171 
0172     if (role == Qt::DisplayRole) {
0173         if (section == Pattern) {
0174             return i18n("Pattern");
0175         } else if (section == PatternSyntax) {
0176             return i18n("Syntax");
0177         }
0178     }
0179 
0180     return QVariant();
0181 }
0182 
0183 QVariant AutoPasteModel::data(const QModelIndex &index, int role) const
0184 {
0185     if (!index.isValid()) {
0186         return QVariant();
0187     }
0188 
0189     const int column = index.column();
0190     const int row = index.row();
0191 
0192     switch (column) {
0193     case Type: {
0194         if (role == Qt::DecorationRole) {
0195             return (m_data[row].type == Include ? QIcon::fromTheme("list-add") : QIcon::fromTheme("list-remove"));
0196         } else if ((role == Qt::UserRole) || (role == Qt::EditRole)) {
0197             return m_data[row].type;
0198         }
0199         break;
0200     }
0201     case Pattern: {
0202         if ((role == Qt::DisplayRole) || (role == Qt::EditRole) || (role == Qt::UserRole)) {
0203             return m_data[row].pattern;
0204         }
0205         break;
0206     }
0207     case PatternSyntax: {
0208         if (role == Qt::DisplayRole) {
0209             return (m_data[row].syntax == Wildcard ? i18n("Escape sequences") : i18n("Regular expression"));
0210         } else if ((role == Qt::UserRole) || (role == Qt::EditRole)) {
0211             return m_data[row].syntax;
0212         }
0213         break;
0214     }
0215     default:
0216         return QVariant();
0217     }
0218 
0219     return QVariant();
0220 }
0221 
0222 Qt::ItemFlags AutoPasteModel::flags(const QModelIndex &index) const
0223 {
0224     Q_UNUSED(index)
0225 
0226     return (Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable);
0227 }
0228 
0229 bool AutoPasteModel::setData(const QModelIndex &index, const QVariant &value, int role)
0230 {
0231     if (role != Qt::EditRole) {
0232         return false;
0233     }
0234 
0235     const int row = index.row();
0236     const int column = index.column();
0237 
0238     switch (column) {
0239     case Type: {
0240         m_data[row].type = static_cast<TypeData>(value.toInt());
0241         break;
0242     }
0243     case Pattern: {
0244         m_data[row].pattern = value.toString();
0245         break;
0246     }
0247     case PatternSyntax: {
0248         m_data[row].syntax = static_cast<PatternSyntaxData>(value.toInt());
0249         break;
0250     }
0251     default:
0252         return false;
0253     }
0254 
0255     Q_EMIT dataChanged(index, index);
0256     return true;
0257 }
0258 
0259 bool AutoPasteModel::removeRows(int row, int count, const QModelIndex &parent)
0260 {
0261     if (parent.isValid() || (row < 0) || (count < 1) || (row + count > rowCount())) {
0262         return false;
0263     }
0264 
0265     beginRemoveRows(parent, row, row + count - 1);
0266     while (count) {
0267         m_data.removeAt(row);
0268         --count;
0269     }
0270     endRemoveRows();
0271 
0272     return true;
0273 }
0274 
0275 void AutoPasteModel::addItem(TypeData dataType, PatternSyntaxData patternSyntax, const QString &pattern)
0276 {
0277     addItems(QList<int>() << dataType, QList<int>() << patternSyntax, QStringList() << pattern);
0278 }
0279 
0280 void AutoPasteModel::addItems(const QList<int> &dataTypes, const QList<int> patternSyntaxes, const QStringList &patterns)
0281 {
0282     const int row = rowCount();
0283     const int numItems = patterns.count();
0284     beginInsertRows(QModelIndex(), row, row + numItems - 1);
0285 
0286     for (int i = 0; i < numItems; ++i) {
0287         Data data;
0288         data.type = static_cast<TypeData>(dataTypes[i]);
0289         data.pattern = patterns[i];
0290         data.syntax = static_cast<PatternSyntaxData>(patternSyntaxes[i]);
0291         m_data.append(data);
0292     }
0293 
0294     endInsertRows();
0295 }
0296 
0297 bool AutoPasteModel::moveItem(int sourceRow, int destinationRow)
0298 {
0299     if (!beginMoveRows(QModelIndex(), sourceRow, sourceRow, QModelIndex(), destinationRow)) {
0300         return false;
0301     }
0302 
0303     // beginMoveRows asks for different data, than QList::move does, see the 4.7 docs
0304     if (sourceRow + 2 == destinationRow) {
0305         --destinationRow;
0306     }
0307     m_data.move(sourceRow, destinationRow);
0308     endMoveRows();
0309 
0310     return true;
0311 }
0312 
0313 void AutoPasteModel::load()
0314 {
0315     // remove all old items if there are any
0316     if (rowCount()) {
0317         beginRemoveRows(QModelIndex(), 0, rowCount() - 1);
0318         m_data.clear();
0319         endRemoveRows();
0320     }
0321     addItems(Settings::autoPasteTypes(), Settings::autoPastePatternSyntaxes(), Settings::autoPastePatterns());
0322 }
0323 
0324 void AutoPasteModel::save()
0325 {
0326     QList<int> types;
0327     QList<int> syntaxes;
0328     QStringList patterns;
0329     foreach (const Data &data, m_data) {
0330         types << data.type;
0331         syntaxes << data.syntax;
0332         patterns << data.pattern;
0333     }
0334 
0335     Settings::self()->setAutoPasteTypes(types);
0336     Settings::self()->setAutoPastePatternSyntaxes(syntaxes);
0337     Settings::self()->setAutoPastePatterns(patterns);
0338     Settings::self()->save();
0339 }
0340 
0341 void AutoPasteModel::resetDefaults()
0342 {
0343     QStringList names = QStringList() << "AutoPastePatterns"
0344                                       << "AutoPasteTypes"
0345                                       << "AutoPastePatternSyntaxes";
0346     foreach (const QString &name, names) {
0347         KConfigSkeletonItem *item = Settings::self()->findItem(name);
0348         if (item) {
0349             item->readDefault(Settings::self()->config());
0350         }
0351     }
0352 
0353     load();
0354 }
0355 
0356 #include "moc_autopastemodel.cpp"