LibreCAD / librecad /src /ui /actions /lc_shortcuts_manager.cpp
AbdulElahGwaith's picture
Upload folder using huggingface_hub
a5ffdcd verified
/*******************************************************************************
*
This file is part of the LibreCAD project, a 2D CAD program
Copyright (C) 2024 LibreCAD.org
Copyright (C) 2024 sand1024
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
******************************************************************************/
#include <QApplication>
#include "lc_shortcuts_manager.h"
#include <QDir>
#include <QFile>
#include "lc_shortcutsstorage.h"
#include "rs_debug.h"
#include "rs_settings.h"
#include "rs_system.h"
const char* LC_ShortcutsManager::PROPERTY_SHORTCUT_BACKUP = "tooltip.original";
LC_ShortcutsManager::LC_ShortcutsManager() {}
int LC_ShortcutsManager::saveShortcuts(
QMap<QString, LC_ShortcutInfo *> &shortcuts, QMap<QString, QAction *> &actionsMap) const {
applyShortcutsMapToActionsMap(shortcuts, actionsMap);
updateActionTooltips(actionsMap);
QString defaultShortcutsFileName = getDefaultShortcutsFileName();
int saveResult = LC_ShortcutsStorage::saveShortcuts(defaultShortcutsFileName, shortcuts.values(), false);
return saveResult;
}
int LC_ShortcutsManager::loadShortcuts(QMap<QString, QAction *> &actionsMap) const {
QString defaultFileName = getDefaultShortcutsFileName();
QMap<QString, QKeySequence> shortcuts = QMap<QString, QKeySequence>();
int loadResult = loadShortcuts(defaultFileName, &shortcuts);
if (loadResult == LC_ShortcutsStorage::OK){
applyKeySequencesMapToActionsMap(shortcuts, actionsMap);
}
updateActionTooltips(actionsMap);
return loadResult;
}
int LC_ShortcutsManager::saveShortcuts(const QString &fileName, const QList<LC_ShortcutInfo *> &shortcutsList) const {
int result = LC_ShortcutsStorage::saveShortcuts(fileName, shortcutsList);
return result;
}
int LC_ShortcutsManager::loadShortcuts(const QString &filename, QMap<QString, QKeySequence> *result) const{
return LC_ShortcutsStorage::loadShortcuts(filename, result);
}
void LC_ShortcutsManager::updateActionTooltips(const QMap<QString, QAction *> &actionsMap) const {
bool showShortcutsInActionsTooltips = LC_GET_ONE_BOOL("Appearance","ShowKeyboardShortcutsInTooltips", true);
updateActionShortcutTooltips(actionsMap, showShortcutsInActionsTooltips);
}
void LC_ShortcutsManager::init() {
QString defaultFileName = getDefaultShortcutsFileName();
if (!defaultFileName.isEmpty()) {
QFile defaultFile(defaultFileName);
if (defaultFile.exists()) {
QString backupFileName = defaultFileName + ".bak";
QFile::copy(defaultFileName, backupFileName);
}
}
}
void LC_ShortcutsManager::applyShortcutsMapToActionsMap(QMap<QString, LC_ShortcutInfo*> &shortcuts, QMap<QString, QAction *> &actionsMap) const{
for (auto [key, shortcut] : shortcuts.asKeyValueRange()){
QAction* action = actionsMap[key];
if (action != nullptr){
action->setShortcut(shortcut->getKey());
}
}
}
void LC_ShortcutsManager::applyKeySequencesMapToActionsMap(QMap<QString, QKeySequence> &shortcuts, QMap<QString, QAction *> &actionsMap) const{
for (auto [name, shortcut] : shortcuts.asKeyValueRange()){
QAction* action = actionsMap[name];
if (action != nullptr){
action->setShortcut(shortcut);
action->setShortcutContext(Qt::ApplicationShortcut);
}
}
}
void LC_ShortcutsManager::assignShortcutsToActions(const QMap<QString, QAction *> &map,
std::vector<LC_ShortcutInfo> &shortcutsList) const {
for (const LC_ShortcutInfo &a: shortcutsList){
QAction* createdAction = map[a.getName()];
if (createdAction != nullptr){
const QList<QKeySequence> &list = a.getKeysList();
if (list.isEmpty()) {
const QKeySequence &sequence = a.getKey();
if (sequence != QKeySequence::UnknownKey) {
createdAction->setShortcut(sequence);
}
} else { // todo - support for future
createdAction->setShortcuts(list);
}
}
}
}
QString LC_ShortcutsManager::getPlainActionToolTip(QAction* action){
if (action != nullptr) {
if (!action->shortcut().isEmpty()) {
QString tooltip = action->property(PROPERTY_SHORTCUT_BACKUP).toString();
if (tooltip.isEmpty()) {
tooltip = action->toolTip();
}
return tooltip;
}
return action->toolTip();
}
return "";
}
void LC_ShortcutsManager::updateActionShortcutTooltips(const QMap<QString, QAction *> &map, bool enable) const {
if (enable){
for (auto [key, action]: map.asKeyValueRange()) {
if (action != nullptr) {
if (!action->shortcut().isEmpty()) {
// action uses a custom tooltip. Backup so that we can restore it later.
QString tooltip = action->property(PROPERTY_SHORTCUT_BACKUP).toString();
if (tooltip.isEmpty()) {
tooltip = action->toolTip();
action->setProperty(PROPERTY_SHORTCUT_BACKUP, action->toolTip());
}
QColor shortcutTextColor = QApplication::palette().color(QPalette::ToolTipText);
QString shortCutTextColorName;
if (shortcutTextColor.value() == 0) {
shortCutTextColorName = "gray"; // special handling for black because lighter() does not work there [QTBUG-9343].
} else {
int factor = (shortcutTextColor.value() < 128) ? 150 : 50;
shortCutTextColorName = shortcutTextColor.lighter(factor).name();
}
action->setToolTip(QString(
"<p style='white-space:pre'>%1&nbsp;&nbsp;<code style='color:%2; font-size:small'>%3</code></p>")
.arg(tooltip, shortCutTextColorName,
action->shortcut().toString(QKeySequence::NativeText)));
}
}
else{
// if we are here, it means that there is a key for which no action was registered in actions map.
// it might be either due to incorrect data in settings file, or if the action was created somewhere in
// code that is outside actions factory.
// in any case, just ignore that key
LC_ERR << "LC_ShortcutsManager::updateActionShortcutTooltips - Action is null in the map, ignored. Key " << key;
}
}
}
else{
for (QAction* action: map){
action->setToolTip(action->property(PROPERTY_SHORTCUT_BACKUP).toString());
action->setProperty(PROPERTY_SHORTCUT_BACKUP, QVariant()); // todo - is it really necessary to remove it?
}
}
}
/* guesses a descriptive text from a text suited for a menu entry
This is equivalent to QActions internal qt_strippedText()
*/
QString LC_ShortcutsManager::strippedActionText(QString s) const{
s.remove( QString::fromLatin1("..."));
for (int i = 0; i < s.size(); ++i) {
if (s.at(i) == QLatin1Char('&'))
s.remove(i, 1);
}
return s.trimmed();
}
QString LC_ShortcutsManager::getShortcutsMappingsFolder() const {
QString settingsDir = LC_GET_ONE_STR("Paths", "OtherSettingsDir", RS_System::instance()->getAppDataDir()).trimmed();
return settingsDir;
}
QString LC_ShortcutsManager::getDefaultShortcutsFileName() const {
QString path = getShortcutsMappingsFolder() + "/shortcuts.lcsc";
return QDir::toNativeSeparators(path);
}