File indexing completed on 2024-04-28 05:50:45

0001 /*
0002     SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "ProfileModel.h"
0008 #include "Profile.h"
0009 #include "ProfileManager.h"
0010 
0011 #include <KLocalizedString>
0012 
0013 #include <QIcon>
0014 
0015 using namespace Konsole;
0016 
0017 ProfileModel *ProfileModel::instance()
0018 {
0019     static ProfileModel self;
0020     return &self;
0021 }
0022 
0023 ProfileModel::ProfileModel()
0024 {
0025     connect(ProfileManager::instance(), &ProfileManager::profileAdded, this, &ProfileModel::add);
0026     connect(ProfileManager::instance(), &ProfileManager::profileRemoved, this, &ProfileModel::remove);
0027     connect(ProfileManager::instance(), &ProfileManager::profileChanged, this, &ProfileModel::update);
0028     populate();
0029 }
0030 int ProfileModel::rowCount(const QModelIndex &unused) const
0031 {
0032     Q_UNUSED(unused)
0033 
0034     // All profiles plus the built-in profile that's always on top
0035     return m_profiles.count();
0036 }
0037 
0038 int ProfileModel::columnCount(const QModelIndex &unused) const
0039 {
0040     Q_UNUSED(unused)
0041     return COLUMNS;
0042 }
0043 
0044 QVariant ProfileModel::headerData(int section, Qt::Orientation orientation, int role) const
0045 {
0046     if (orientation == Qt::Vertical) {
0047         return {};
0048     }
0049     if (role != Qt::DisplayRole) {
0050         return {};
0051     }
0052 
0053     switch (section) {
0054     case NAME:
0055         return i18nc("@title:column Profile name", "Name");
0056     case SHORTCUT:
0057         return i18nc("@title:column Profile keyboard shortcut", "Shortcut");
0058     }
0059     return {};
0060 }
0061 
0062 QVariant ProfileModel::data(const QModelIndex &idx, int role) const
0063 {
0064     if (!idx.isValid()) {
0065         return {};
0066     }
0067 
0068     if (idx.row() > m_profiles.count()) {
0069         return {};
0070     }
0071 
0072     auto profile = m_profiles.at(idx.row());
0073 
0074     switch (idx.column()) {
0075     case NAME: {
0076         switch (role) {
0077         case Qt::DisplayRole: {
0078             QString txt = profile->name();
0079             if (profile->isBuiltin()) {
0080                 txt += i18nc("@label:textbox added to the name of the built-in profile, to point out it's read-only", " [Read-only]");
0081             }
0082 
0083             if (ProfileManager::instance()->defaultProfile() == profile) {
0084                 txt += i18nc("@label:textbox added to the name of the current default profile", " [Default]");
0085             }
0086 
0087             return txt;
0088         }
0089         case Qt::DecorationRole:
0090             return QIcon::fromTheme(profile->icon());
0091         case Qt::FontRole:
0092             if (ProfileManager::instance()->defaultProfile() == profile) {
0093                 QFont font;
0094                 font.setBold(true);
0095                 return font;
0096             }
0097             break;
0098         case Qt::ToolTipRole:
0099             return profile->isBuiltin() ? i18nc("@info:tooltip", "Built-in profile is always available") : profile->path();
0100         }
0101     } break;
0102 
0103     case SHORTCUT: {
0104         auto shortcut = ProfileManager::instance()->shortcut(profile);
0105         switch (role) {
0106         case Qt::DisplayRole:
0107             return shortcut;
0108         case Qt::EditRole:
0109             return shortcut;
0110         case Qt::ToolTipRole:
0111             return i18nc("@info:tooltip", "Double click to change shortcut");
0112         }
0113         break;
0114     }
0115 
0116     case PROFILE: {
0117         switch (role) {
0118         case ProfilePtrRole:
0119             return QVariant::fromValue(profile);
0120         case Qt::DisplayRole:
0121             return profile->name();
0122         case Qt::DecorationRole:
0123             return QIcon::fromTheme(profile->icon());
0124         }
0125     }
0126     }
0127 
0128     return {};
0129 }
0130 
0131 Qt::ItemFlags ProfileModel::flags(const QModelIndex &idx) const
0132 {
0133     auto currentFlags = QAbstractTableModel::flags(idx);
0134 
0135     switch (idx.column()) {
0136     case NAME:
0137         return currentFlags & (~Qt::ItemIsEditable);
0138     case SHORTCUT:
0139         return currentFlags | Qt::ItemIsEditable;
0140     default:;
0141     }
0142     return currentFlags;
0143 }
0144 
0145 bool ProfileModel::setData(const QModelIndex &idx, const QVariant &value, int role)
0146 {
0147     if (!idx.isValid()) {
0148         return false;
0149     }
0150 
0151     if (idx.column() != SHORTCUT) {
0152         return false;
0153     }
0154 
0155     if (role != Qt::EditRole && role != Qt::DisplayRole) {
0156         return false;
0157     }
0158 
0159     auto profile = m_profiles.at(idx.row());
0160     if (idx.column() == SHORTCUT) {
0161         auto sequence = QKeySequence::fromString(value.toString());
0162         ProfileManager::instance()->setShortcut(profile, sequence);
0163         Q_EMIT dataChanged(idx, idx, {Qt::DisplayRole});
0164         return true;
0165     }
0166 
0167     return false;
0168 }
0169 
0170 void ProfileModel::populate()
0171 {
0172     beginResetModel();
0173     m_profiles = ProfileManager::instance()->allProfiles();
0174     endResetModel();
0175 }
0176 
0177 void ProfileModel::add(QExplicitlySharedDataPointer<Profile> profile)
0178 {
0179     // The model is too small for this to matter.
0180     Q_UNUSED(profile)
0181     populate();
0182 }
0183 
0184 void ProfileModel::remove(QExplicitlySharedDataPointer<Profile> profile)
0185 {
0186     // The model is too small for this to matter.
0187     Q_UNUSED(profile)
0188     populate();
0189 }
0190 
0191 void ProfileModel::setDefault(QExplicitlySharedDataPointer<Profile> profile)
0192 {
0193     Q_UNUSED(profile)
0194     Q_EMIT dataChanged(index(0, 0), index(0, COLUMNS - 1), {Qt::DisplayRole});
0195 }
0196 
0197 void ProfileModel::update(QExplicitlySharedDataPointer<Profile> profile)
0198 {
0199     int row = m_profiles.indexOf(profile);
0200     dataChanged(index(row, 0), index(row, COLUMNS - 1));
0201     // Resort as the profile name could have changed
0202     populate();
0203 }
0204 
0205 #include "moc_ProfileModel.cpp"