Krita Source Code Documentation
Loading...
Searching...
No Matches
KisInputProfileManager Class Reference

A class to manage a list of profiles and actions. More...

#include <kis_input_profile_manager.h>

+ Inheritance diagram for KisInputProfileManager:

Signals

void currentProfileChanged ()
 
void profilesChanged ()
 

Public Member Functions

QList< KisAbstractInputAction * > actions ()
 
KisInputProfile * addProfile (const QString &name)
 
void createActions ()
 
KisInputProfile * currentProfile () const
 
void duplicateProfile (const QString &name, const QString &newName)
 
QList< KisShortcutConfiguration * > getConflictingShortcuts (KisInputProfile *profile)
 
 KisInputProfileManager (QObject *parent=0)
 
void loadProfiles ()
 
 Private ()
 
KisInputProfile * profile (const QString &name) const
 
QString profileFileName (const QString &profileName)
 
QStringList profileNames () const
 
QList< KisInputProfile * > profiles () const
 
void removeProfile (const QString &name)
 
bool renameProfile (const QString &oldName, const QString &newName)
 
void resetAll ()
 
void saveProfile (KisInputProfile *profile, QString storagePath)
 
void saveProfiles ()
 
void setCurrentProfile (KisInputProfile *profile)
 
 ~KisInputProfileManager () override
 

Static Public Member Functions

static KisInputProfileManager * instance ()
 

Public Attributes

QList< KisAbstractInputAction * > actions
 
KisInputProfile * currentProfile
 
QMap< QString, KisInputProfile * > profiles
 

Private Member Functions

KisInputProfile * loadProfileInternal (const QString &fullPath)
 
KisInputProfile * loadProfileWithMigration (const ProfileEntry &profileEntry)
 
- Private Member Functions inherited from Private
 Private (KisCanvas2 *c)
 

Private Attributes

Private *const d
 
- Private Attributes inherited from Private
KisCanvas2 * canvas
 
int displayedFrame
 
int intendedFrame
 

Friends

class KisInputProfileManagerTest
 

Detailed Description

A class to manage a list of profiles and actions.

Definition at line 40 of file kis_input_profile_manager.cpp.

Constructor & Destructor Documentation

◆ KisInputProfileManager()

KisInputProfileManager::KisInputProfileManager ( QObject * parent = 0)

Definition at line 458 of file kis_input_profile_manager.cpp.

459 : QObject(parent), d(new Private())
460{
461 d->createActions();
462}

References d.

◆ ~KisInputProfileManager()

KisInputProfileManager::~KisInputProfileManager ( )
override

Definition at line 464 of file kis_input_profile_manager.cpp.

465{
466 qDeleteAll(d->profiles);
467 qDeleteAll(d->actions);
468 delete d;
469}

References d.

Member Function Documentation

◆ actions()

QList< KisAbstractInputAction * > KisInputProfileManager::actions ( )
Returns
The list of all available actions.

◆ addProfile()

KisInputProfile * KisInputProfileManager::addProfile ( const QString & name)

Add a profile.

Parameters
nameThe name of the new profile.
Returns
The new, empty profile or the non-empty profile if it already exists.

Definition at line 94 of file kis_input_profile_manager.cpp.

95{
96 if (d->profiles.contains(name)) {
97 return d->profiles.value(name);
98 }
99
101 profile->setName(name);
102 d->profiles.insert(name, profile);
103
104 Q_EMIT profilesChanged();
105
106 return profile;
107}
KisInputProfile * profile(const QString &name) const
A container class for sets of shortcuts associated with an action.
void setName(const QString &name)

References d, profile(), profilesChanged(), and KisInputProfile::setName().

◆ createActions()

void KisInputProfileManager::createActions ( )

◆ currentProfile()

KisInputProfile * KisInputProfileManager::currentProfile ( ) const
Returns
The current active profile.

◆ currentProfileChanged

void KisInputProfileManager::currentProfileChanged ( )
signal

Emitted when the current active profile changes.

◆ duplicateProfile()

void KisInputProfileManager::duplicateProfile ( const QString & name,
const QString & newName )

Duplicate a profile.

This creates a new profile with the given name and copies all data from the old profile to the new profile.

Parameters
nameThe name of the profile to duplicate.
newNameThe name of the new profile.

Definition at line 154 of file kis_input_profile_manager.cpp.

155{
156 if (!d->profiles.contains(name) || d->profiles.contains(newName)) {
157 return;
158 }
159
160 KisInputProfile *newProfile = new KisInputProfile(this);
161 newProfile->setName(newName);
162 d->profiles.insert(newName, newProfile);
163
164 KisInputProfile *profile = d->profiles.value(name);
166 Q_FOREACH(KisShortcutConfiguration * shortcut, shortcuts) {
167 newProfile->addShortcut(new KisShortcutConfiguration(*shortcut));
168 }
169
170 Q_EMIT profilesChanged();
171}
QList< KisShortcutConfiguration * > allShortcuts() const
void addShortcut(KisShortcutConfiguration *shortcut)
A class encapsulating all settings for a single shortcut.

References KisInputProfile::addShortcut(), KisInputProfile::allShortcuts(), d, profile(), profilesChanged(), and KisInputProfile::setName().

◆ getConflictingShortcuts()

QList< KisShortcutConfiguration * > KisInputProfileManager::getConflictingShortcuts ( KisInputProfile * profile)

Return the configurations that have conflicts.

Definition at line 421 of file kis_input_profile_manager.cpp.

422{
423 QSet<KisShortcutConfiguration *> conflictedShortcuts;
425 for (auto startIt = shortcuts.constBegin(); startIt != shortcuts.constEnd(); ++startIt) {
426 KisShortcutConfiguration *first = *startIt;
427 for (auto index = startIt + 1; index != shortcuts.constEnd(); ++index) {
428 KisShortcutConfiguration *second = *index;
429 // since there can be multiple no-ops in the config and because no-ops are something a user can't
430 // perform, there should be no conflicts.
431 if (*first == *second && !first->isNoOp()) {
432 conflictedShortcuts.insert(first);
433 conflictedShortcuts.insert(second);
434 }
435 }
436 }
437 return conflictedShortcuts.values();
438}

References KisInputProfile::allShortcuts(), KisShortcutConfiguration::isNoOp(), and profile().

◆ instance()

KisInputProfileManager * KisInputProfileManager::instance ( )
static
Returns
The singleton instance of this class.

Definition at line 57 of file kis_input_profile_manager.cpp.

58{
59 return inputProfileManager;
60}

◆ loadProfileInternal()

KisInputProfile * KisInputProfileManager::loadProfileInternal ( const QString & fullPath)
private

Loads a single profile from a file without applying any migrations

Definition at line 299 of file kis_input_profile_manager.cpp.

300{
301 KConfig config(fullPath, KConfig::SimpleConfig);
302
303 QList<KisShortcutConfiguration*> loadedShortcuts;
304
305 // Only entries of exactly the right version can be considered
306 const int version = config.group("General").readEntry("version", 0);
307 const QString name = config.group("General").readEntry("name");
308
309 // the profile must be already converted by this point
311
312 Q_FOREACH (KisAbstractInputAction *action, d->actions) {
313 if (!config.hasGroup(action->id())) {
314 continue;
315 }
316
317 KConfigGroup grp = config.group(action->id());
318 // Read the settings for the action and create the appropriate shortcuts.
319 Q_FOREACH (const QString &entry, grp.entryMap()) {
321 shortcut->setAction(action);
322
323 if (shortcut->unserialize(entry)) {
324 loadedShortcuts.append(shortcut);
325 } else {
326 delete shortcut;
327 }
328 }
329 }
330
331 KisInputProfile *newProfile = addProfile(name);
332 Q_FOREACH(KisShortcutConfiguration *shortcut, loadedShortcuts) {
333 newProfile->addShortcut(shortcut);
334 }
335 return newProfile;
336}
Abstract base class for input actions.
KisInputProfile * addProfile(const QString &name)
bool unserialize(const QString &serialized)
void setAction(KisAbstractInputAction *newAction)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
#define PROFILE_VERSION
const char * name(StandardAction id)

References addProfile(), KisInputProfile::addShortcut(), d, KisAbstractInputAction::id, KIS_SAFE_ASSERT_RECOVER_NOOP, PROFILE_VERSION, KisShortcutConfiguration::setAction(), and KisShortcutConfiguration::unserialize().

◆ loadProfiles()

void KisInputProfileManager::loadProfiles ( )

Load all profiles from the configuration stored on disk.

Definition at line 178 of file kis_input_profile_manager.cpp.

179{
180 //Remove any profiles that already exist
181 d->currentProfile = nullptr;
182 qDeleteAll(d->profiles);
183 d->profiles.clear();
184
185 //Look up all profiles (this includes those installed to $prefix as well as the user's local data dir)
187
188 dbgKrita << "profiles" << profiles;
189
190 // We don't use list here, because we're assuming we are only going to be changing the user directory and
191 // there can only be one of a profile name.
192 QMap<QString, ProfileEntry> profileEntriesToMigrate;
193 QMap<QString, QList<ProfileEntry>> profileEntries;
194
195 KisConfig cfg(true);
196
197 // Get only valid entries...
198 Q_FOREACH(const QString & p, profiles) {
199
200 ProfileEntry entry;
201 entry.fullpath = p;
202
203 KConfig config(p, KConfig::SimpleConfig);
204 if (!config.hasGroup("General") || !config.group("General").hasKey("name") || !config.group("General").hasKey("version")) {
205 //Skip if we don't have the proper settings.
206 continue;
207 }
208
209 // Only entries of exactly the right version can be considered
210 entry.version = config.group("General").readEntry("version", 0);
211 entry.name = config.group("General").readEntry("name");
212
213 // NOTE: Migrating profiles doesn't just mean porting them to new version. Migrating a profile
214 // may override the existing newer profile file.
215 if (entry.version < PROFILE_VERSION) {
216 // we only utilize the first entry, because it is the most local one and the one which has to be
217 // migrated.
218 profileEntriesToMigrate[entry.name] = entry;
219
220 } else if (entry.version == PROFILE_VERSION) {
221 if (!profileEntries.contains(entry.name)) {
222 profileEntries[entry.name] = QList<ProfileEntry>();
223 }
224
225 // let all the current version entries pile up in the list, it is only later where we check if it
226 // is something we will use or a migrated entry.
227 profileEntries[entry.name].append(entry);
228 }
229 }
230
231 {
232 const QString userLocalSaveLocation = KoResourcePaths::saveLocation("data", "input/");
233 auto entriesIt = profileEntriesToMigrate.begin();
234 while (entriesIt != profileEntriesToMigrate.end()) {
235 ProfileEntry entry = *entriesIt;
236 // if entry doesn't exist in profileEntries, means there is no corresponding new version of the
237 // entry in user directory. Meaning, it is a certain candidate for migration.
238
239 if (profileEntries.contains(entry.name)) {
240
241 // we only need first() because if a user-local entry exists, it will be the first.
242 ProfileEntry existingEntry = profileEntries[entry.name].first();
243
244 // check if the entry's fullpath is a saveLocation, if so, we remove it from migration list.
245 if (existingEntry.fullpath.startsWith(userLocalSaveLocation)) {
246 entriesIt = profileEntriesToMigrate.erase(entriesIt);
247 } else {
248 // if the entry's fullpath is not a saveLocation, we will migrate it. Because (user's
249 // previous configuration + current default touch shortcuts) are better than. (All default
250 // shortcuts).
251 entriesIt++;
252
253 // Because this entry is supposed to be migrated, it will clash with an already existing
254 // default entry. So remove it.
255 profileEntries.remove(existingEntry.name);
256 }
257 } else {
258 entriesIt++;
259 }
260 }
261 }
262
263 for (const auto &profileEntry : profileEntriesToMigrate) {
264 loadProfileWithMigration(profileEntry);
265 }
266
267 Q_FOREACH(const QString & profileName, profileEntries.keys()) {
268
269 if (profileEntries[profileName].isEmpty()) {
270 continue;
271 }
272
273 // we have one or more entries for this profile name. We'll take the first,
274 // because that's the most local one.
275 ProfileEntry entry = profileEntries[profileName].first();
276
278 }
279
280 QString currentProfile = cfg.currentInputProfile();
281 if (d->profiles.size() > 0) {
282 if (currentProfile.isEmpty() || !d->profiles.contains(currentProfile)) {
283 QString kritaDefault = QStringLiteral("Krita Default");
284 if (d->profiles.contains(kritaDefault)) {
285 d->currentProfile = d->profiles.value(kritaDefault);
286 } else {
287 d->currentProfile = d->profiles.begin().value();
288 }
289 }
290 else {
291 d->currentProfile = d->profiles.value(currentProfile);
292 }
293 }
294 if (d->currentProfile) {
295 Q_EMIT currentProfileChanged();
296 }
297}
const Params2D p
KisInputProfile * loadProfileInternal(const QString &fullPath)
KisInputProfile * loadProfileWithMigration(const ProfileEntry &profileEntry)
QMap< QString, KisInputProfile * > profiles
static QStringList findAllAssets(const QString &type, const QString &filter=QString(), SearchOptions options=NoSearchOptions)
static QString saveLocation(const QString &type, const QString &suffix=QString(), bool create=true)
#define dbgKrita
Definition kis_debug.h:49

References KisConfig::currentInputProfile(), currentProfile, currentProfileChanged(), d, dbgKrita, KoResourcePaths::findAllAssets(), ProfileEntry::fullpath, loadProfileInternal(), loadProfileWithMigration(), ProfileEntry::name, p, PROFILE_VERSION, profiles, KoResourcePaths::Recursive, KoResourcePaths::saveLocation(), and ProfileEntry::version.

◆ loadProfileWithMigration()

KisInputProfile * KisInputProfileManager::loadProfileWithMigration ( const ProfileEntry & profileEntry)
private

Loads a single profile from a file performing all the migrations necessary. The old profile will be saved into KoResourcePaths::saveLocation with a version suffix, and the new version will be written with the profile name.

Definition at line 338 of file kis_input_profile_manager.cpp.

339{
340 QList<KisShortcutConfiguration> parsedShortcuts;
341
342 if (profileEntry.version == 5) {
343 KisInputProfileMigratorFrom5 migratorFromV5(this);
344 parsedShortcuts = migratorFromV5.migrate(profileEntry);
345 } else if (profileEntry.version == 6) {
346 KisInputProfileMigratorFrom6 migratorFromV6(this);
347 parsedShortcuts = migratorFromV6.migrate(profileEntry);
348 } else {
349 warnKrita << "Unable to migrate input profile: unknown version:" << profileEntry.version << "("
350 << profileEntry.fullpath << ")";
351 return nullptr;
352 }
353
354 dbgKrita << "Migrating a profile " << profileEntry.name << "(" << profileEntry.fullpath << ")" << "from version" << profileEntry.version;
355
356 const QString storagePath = KoResourcePaths::saveLocation("data", "input/", true);
357
358 {
359 // the profile we have here uses the previous config, the only thing we need to make sure is
360 // it doesn't overwrite the existing profile to preserve backwards compatibility.
361 const QString profilePath = profileEntry.fullpath;
362 QString oldProfileName = QFileInfo(profilePath).fileName();
363 oldProfileName.replace(".profile", QString::number(PROFILE_VERSION - 1) + ".profile");
364
365 QString oldProfilePath = storagePath + oldProfileName;
366 // copy the profile to a new file but add version number to the name
367 QFile::copy(profilePath, oldProfilePath);
368
369 KConfig config(oldProfilePath, KConfig::SimpleConfig);
370 config.group("General").writeEntry("migrated", PROFILE_VERSION);
371 }
372
373 KisInputProfile *newProfile = addProfile(profileEntry.name);
374 for (const auto &shortcut : parsedShortcuts) {
375 newProfile->addShortcut(new KisShortcutConfiguration(shortcut));
376 }
377
378 // save the new profile with migrated shortcuts. We overwrite the previous version of file (which
379 // previously has been moved for backward compatibility).
380 saveProfile(newProfile, storagePath);
381
382 return newProfile;
383}
void saveProfile(KisInputProfile *profile, QString storagePath)
#define warnKrita
Definition kis_debug.h:94

References addProfile(), KisInputProfile::addShortcut(), dbgKrita, ProfileEntry::fullpath, KisInputProfileMigratorFrom5::migrate(), KisInputProfileMigratorFrom6::migrate(), ProfileEntry::name, PROFILE_VERSION, KoResourcePaths::saveLocation(), saveProfile(), ProfileEntry::version, and warnKrita.

◆ Private()

KisInputProfileManager::Private ( )
inline

Definition at line 43 of file kis_input_profile_manager.cpp.

43: currentProfile(0) { }

◆ profile()

KisInputProfile * KisInputProfileManager::profile ( const QString & name) const

Retrieve a profile by name.

Parameters
nameThe name of the profile to retrieve.
Returns
The profile with the given name, or 0 if not found.

Definition at line 72 of file kis_input_profile_manager.cpp.

73{
74 if (d->profiles.contains(name)) {
75 return d->profiles.value(name);
76 }
77
78 return 0;
79}

References d.

◆ profileFileName()

QString KisInputProfileManager::profileFileName ( const QString & profileName)

◆ profileNames()

QStringList KisInputProfileManager::profileNames ( ) const
Returns
A list of the names of all profiles.

Definition at line 67 of file kis_input_profile_manager.cpp.

68{
69 return d->profiles.keys();
70}

References d.

◆ profiles()

QList< KisInputProfile * > KisInputProfileManager::profiles ( ) const
Returns
A list of all profiles.

◆ profilesChanged

void KisInputProfileManager::profilesChanged ( )
signal

Emitted when the list of profiles changes.

◆ removeProfile()

void KisInputProfileManager::removeProfile ( const QString & name)

Remove a profile.

This will remove the given profile from the list of profiles and delete it.

Parameters
nameThe profile to remove.

Definition at line 109 of file kis_input_profile_manager.cpp.

110{
111 if (d->profiles.contains(name)) {
112 QString currentProfileName = d->currentProfile->name();
113
114 delete d->profiles.value(name);
115 d->profiles.remove(name);
116
117 //Delete the settings file for the removed profile, if it exists
118 QDir userDir(KoResourcePaths::saveLocation("data", "input/"));
119
120 if (userDir.exists(d->profileFileName(name))) {
121 userDir.remove(d->profileFileName(name));
122 }
123
124 if (currentProfileName == name) {
125 d->currentProfile = d->profiles.begin().value();
126 Q_EMIT currentProfileChanged();
127 }
128
129 Q_EMIT profilesChanged();
130 }
131}

References currentProfileChanged(), d, profilesChanged(), and KoResourcePaths::saveLocation().

◆ renameProfile()

bool KisInputProfileManager::renameProfile ( const QString & oldName,
const QString & newName )

Rename a profile.

Parameters
oldNameThe current name of the profile.
newNameThe new name of the profile.
Returns
true if successful, false if not.

Definition at line 133 of file kis_input_profile_manager.cpp.

134{
135 if (!d->profiles.contains(oldName)) {
136 return false;
137 }
138
139 KisInputProfile *profile = d->profiles.value(oldName);
140 if (profile) {
141 d->profiles.remove(oldName);
142 profile->setName(newName);
143 d->profiles.insert(newName, profile);
144
145 Q_EMIT profilesChanged();
146
147
148 return true;
149 }
150
151 return false;
152}

References d, profile(), profilesChanged(), and KisInputProfile::setName().

◆ resetAll()

void KisInputProfileManager::resetAll ( )

Reset all profiles to the default state.

This will remove all custom profiles the user created and reset any changed profiles.

Definition at line 440 of file kis_input_profile_manager.cpp.

441{
442 QString kdeHome = KoResourcePaths::getAppDataLocation();
444
445 Q_FOREACH (const QString &profile, profiles) {
446 if(profile.contains(kdeHome)) {
447 //This is a local file, remove it.
448 QFile::remove(profile);
449 }
450 }
451
452 //Load the profiles again, this should now only load those shipped with Krita.
453 loadProfiles();
454
455 Q_EMIT profilesChanged();
456}
static QString getAppDataLocation()

References KoResourcePaths::findAllAssets(), KoResourcePaths::getAppDataLocation(), loadProfiles(), profile(), profiles, profilesChanged(), and KoResourcePaths::Recursive.

◆ saveProfile()

void KisInputProfileManager::saveProfile ( KisInputProfile * profile,
QString storagePath )

Save profile to storagePath

Definition at line 399 of file kis_input_profile_manager.cpp.

400{
401 const QString profilePath = storagePath + d->profileFileName(profile->name());
402 KConfig config(profilePath, KConfig::SimpleConfig);
403
404 config.group("General").writeEntry("name", profile->name());
405 config.group("General").writeEntry("version", PROFILE_VERSION);
406
407 Q_FOREACH(KisAbstractInputAction * action, d->actions) {
408 KConfigGroup grp = config.group(action->id());
409 grp.deleteGroup(); //Clear the group of any existing shortcuts.
410
411 int index = 0;
413 Q_FOREACH(KisShortcutConfiguration * shortcut, shortcuts) {
414 grp.writeEntry(QString("%1").arg(index++), shortcut->serialize());
415 }
416 }
417
418 config.sync();
419}
QList< KisShortcutConfiguration * > shortcutsForAction(KisAbstractInputAction *action) const
QString name() const

References d, KisAbstractInputAction::id, KisInputProfile::name(), profile(), PROFILE_VERSION, KisShortcutConfiguration::serialize(), and KisInputProfile::shortcutsForAction().

◆ saveProfiles()

void KisInputProfileManager::saveProfiles ( )

Save all profiles to configuration on disk.

Definition at line 385 of file kis_input_profile_manager.cpp.

386{
387 QString storagePath = KoResourcePaths::saveLocation("data", "input/", true);
388 Q_FOREACH(KisInputProfile * p, d->profiles) {
389 saveProfile(p, storagePath);
390 }
391
392 KisConfig config(false);
393 config.setCurrentInputProfile(d->currentProfile->name());
394
395 //Force a reload of the current profile in input manager and whatever else uses the profile.
396 Q_EMIT currentProfileChanged();
397}

References currentProfileChanged(), d, p, KoResourcePaths::saveLocation(), saveProfile(), and KisConfig::setCurrentInputProfile().

◆ setCurrentProfile()

void KisInputProfileManager::setCurrentProfile ( KisInputProfile * profile)

Set the current active profile.

Parameters
profileThe profile to set as current.

Definition at line 86 of file kis_input_profile_manager.cpp.

87{
88 if (profile && profile != d->currentProfile) {
89 d->currentProfile = profile;
90 Q_EMIT currentProfileChanged();
91 }
92}

References currentProfileChanged(), d, and profile().

Friends And Related Symbol Documentation

◆ KisInputProfileManagerTest

friend class KisInputProfileManagerTest
friend

Definition at line 146 of file kis_input_profile_manager.h.

Member Data Documentation

◆ actions

QList< KisAbstractInputAction * > KisInputProfileManager::actions

Definition at line 52 of file kis_input_profile_manager.cpp.

◆ currentProfile

KisInputProfile * KisInputProfileManager::currentProfile

Definition at line 48 of file kis_input_profile_manager.cpp.

◆ d

Private* const KisInputProfileManager::d
private

Definition at line 163 of file kis_input_profile_manager.h.

◆ profiles

QList< KisInputProfile * > KisInputProfileManager::profiles

Definition at line 50 of file kis_input_profile_manager.cpp.


The documentation for this class was generated from the following files: