Commit d3354588 authored by Martin Tobias Holmedahl Sandsmark's avatar Martin Tobias Holmedahl Sandsmark Committed by Tomaz Canabrava
Browse files

Use smart pointers for color schemes.

Also uses weak pointers in the cache in ViewManager, to avoid having
them loaded for longer than necessary.

It takes less than a millisecond to load them, and it is nice to pick up
new changes from disk. But we don't want to do it for those currently
used by code elsewhere, so we still cache them with a weak_ptr that will
expire once all other code is done with it.
parent 295435d8
Pipeline #97852 passed with stage
in 1 minute and 53 seconds
......@@ -826,9 +826,9 @@ TerminalDisplay *ViewManager::createTerminalDisplay(Session *session)
return display;
}
const ColorScheme *ViewManager::colorSchemeForProfile(const Profile::Ptr &profile)
std::shared_ptr<const ColorScheme> ViewManager::colorSchemeForProfile(const Profile::Ptr &profile)
{
const ColorScheme *colorScheme = ColorSchemeManager::instance()->findColorScheme(profile->colorScheme());
std::shared_ptr<const ColorScheme> colorScheme = ColorSchemeManager::instance()->findColorScheme(profile->colorScheme());
if (colorScheme == nullptr) {
colorScheme = ColorSchemeManager::instance()->defaultColorScheme();
}
......
......@@ -179,7 +179,7 @@ public:
TerminalDisplay *createView(Session *session);
void attachView(TerminalDisplay *terminal, Session *session);
static const ColorScheme *colorSchemeForProfile(const QExplicitlySharedDataPointer<Profile> &profile);
static std::shared_ptr<const ColorScheme> colorSchemeForProfile(const QExplicitlySharedDataPointer<Profile> &profile);
/** Reorder the terminal display history list */
void updateTerminalDisplayHistory(TerminalDisplay *terminalDisplay = nullptr, bool remove = false);
......
......@@ -25,6 +25,12 @@
// Konsole
#include "colorschemedebug.h"
//define DEBUG_LOADING_TIME
#ifdef DEBUG_LOADING_TIME
#include <QElapsedTimer>
#endif
namespace
{
const int FGCOLOR_INDEX = 0;
......@@ -436,6 +442,10 @@ bool ColorScheme::blur() const
void ColorScheme::read(const KConfig &config)
{
#ifdef DEBUG_LOADING_TIME
QElapsedTimer t; t.start();
#endif
KConfigGroup configGroup = config.group("General");
const QString schemeDescription = configGroup.readEntry("Description", i18nc("@item", "Un-named Color Scheme"));
......@@ -449,6 +459,10 @@ void ColorScheme::read(const KConfig &config)
for (int i = 0; i < TABLE_COLORS; i++) {
readColorEntry(config, i);
}
#ifdef DEBUG_LOADING_TIME
qDebug() << name() << "loaded in" << t.elapsed() << "ms";
#endif
}
void ColorScheme::readColorEntry(const KConfig &config, int index)
......
......@@ -13,6 +13,9 @@
#include <QMetaType>
#include <QSharedData>
// C++
#include <memory>
// Konsole
#include "ColorSchemeWallpaper.h"
......@@ -186,6 +189,6 @@ private:
};
}
Q_DECLARE_METATYPE(const Konsole::ColorScheme *)
Q_DECLARE_METATYPE(std::shared_ptr<const Konsole::ColorScheme>)
#endif // COLORSCHEME_H
......@@ -44,7 +44,6 @@ ColorSchemeEditor::ColorSchemeEditor(QWidget *parent)
: QDialog(parent)
, _isNewScheme(false)
, _ui(nullptr)
, _colors(nullptr)
{
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply);
auto mainWidget = new QWidget(this);
......@@ -133,7 +132,6 @@ ColorSchemeEditor::ColorSchemeEditor(QWidget *parent)
ColorSchemeEditor::~ColorSchemeEditor()
{
delete _colors;
delete _ui;
}
......@@ -228,13 +226,11 @@ void ColorSchemeEditor::setRandomizedBackgroundColor(bool randomized)
_colors->setColorRandomization(randomized);
}
void ColorSchemeEditor::setup(const ColorScheme *scheme, bool isNewScheme)
void ColorSchemeEditor::setup(const std::shared_ptr<const ColorScheme> &scheme, bool isNewScheme)
{
_isNewScheme = isNewScheme;
delete _colors;
_colors = new ColorScheme(*scheme);
_colors = std::make_shared<ColorScheme>(*scheme);
if (_isNewScheme) {
setWindowTitle(i18nc("@title:window", "New Color Scheme"));
......@@ -264,7 +260,7 @@ void ColorSchemeEditor::setup(const ColorScheme *scheme, bool isNewScheme)
_ui->wallpaperPath->setText(scheme->wallpaper()->path());
}
void ColorSchemeEditor::setupColorTable(const ColorScheme *colors)
void ColorSchemeEditor::setupColorTable(const std::shared_ptr<ColorScheme> &colors)
{
QColor table[TABLE_COLORS];
colors->getColorTable(table);
......
......@@ -48,14 +48,14 @@ public:
~ColorSchemeEditor() override;
/** Initializes the dialog with the properties of the specified color scheme. */
void setup(const ColorScheme *scheme, bool isNewScheme);
void setup(const std::shared_ptr<const ColorScheme> &scheme, bool isNewScheme);
/** Returns the modified color scheme. */
ColorScheme &colorScheme() const;
bool isNewScheme() const;
Q_SIGNALS:
/** Emitted when the colors in the color scheme change. */
void colorsChanged(ColorScheme *scheme);
void colorsChanged(std::shared_ptr<ColorScheme> scheme);
/** Used to send back colorscheme changes into the profile edited */
void colorSchemeSaveRequested(const ColorScheme &scheme, bool isNewScheme);
......@@ -76,11 +76,11 @@ private Q_SLOTS:
private:
Q_DISABLE_COPY(ColorSchemeEditor)
void setupColorTable(const ColorScheme *table);
void setupColorTable(const std::shared_ptr<ColorScheme> &table);
bool _isNewScheme;
Ui::ColorSchemeEditor *_ui;
ColorScheme *_colors;
std::shared_ptr<ColorScheme> _colors;
};
}
......
......@@ -23,16 +23,9 @@
using namespace Konsole;
ColorSchemeManager::ColorSchemeManager()
: _colorSchemes(QHash<QString, const ColorScheme *>())
, _haveLoadedAll(false)
{
}
ColorSchemeManager::~ColorSchemeManager()
{
qDeleteAll(_colorSchemes);
}
Q_GLOBAL_STATIC(ColorSchemeManager, theColorSchemeManager)
ColorSchemeManager *ColorSchemeManager::instance()
......@@ -40,62 +33,55 @@ ColorSchemeManager *ColorSchemeManager::instance()
return theColorSchemeManager;
}
void ColorSchemeManager::loadAllColorSchemes()
QList<std::shared_ptr<const ColorScheme>> ColorSchemeManager::allColorSchemes()
{
int failed = 0;
const QStringList nativeColorSchemes = listColorSchemes();
for (const QString &colorScheme : nativeColorSchemes) {
if (!loadColorScheme(colorScheme)) {
QList<std::shared_ptr<const ColorScheme>> ret;
for (const QString &name : listColorSchemes()) {
std::shared_ptr<const ColorScheme> scheme = findColorScheme(colorSchemeNameFromPath(name));
if (!scheme) {
failed++;
continue;
}
ret.append(scheme);
}
if (failed > 0) {
qCDebug(ColorSchemeDebug) << "failed to load " << failed << " color schemes.";
}
_haveLoadedAll = true;
}
QList<const ColorScheme *> ColorSchemeManager::allColorSchemes()
{
if (!_haveLoadedAll) {
loadAllColorSchemes();
}
return _colorSchemes.values();
return ret;
}
bool ColorSchemeManager::loadColorScheme(const QString &filePath)
std::shared_ptr<const ColorScheme> ColorSchemeManager::loadColorScheme(const QString &filePath)
{
if (!pathIsColorScheme(filePath) || !QFile::exists(filePath)) {
return false;
return nullptr;
}
auto name = colorSchemeNameFromPath(filePath);
const QString name = colorSchemeNameFromPath(filePath);
KConfig config(filePath, KConfig::NoGlobals);
auto scheme = new ColorScheme();
std::shared_ptr<ColorScheme> scheme = std::make_shared<ColorScheme>();
scheme->setName(name);
scheme->read(config);
if (scheme->name().isEmpty()) {
qCDebug(ColorSchemeDebug) << "Color scheme in" << filePath << "does not have a valid name and was not loaded.";
delete scheme;
return false;
return nullptr;
}
if (!_colorSchemes.contains(name)) {
_colorSchemes.insert(scheme->name(), scheme);
} else {
// qDebug() << "color scheme with name" << scheme->name() << "has already been" <<
// "found, ignoring.";
// "found, replacing.";
delete scheme;
_colorSchemes[name] = scheme;
}
return true;
return scheme;
}
bool ColorSchemeManager::unloadColorScheme(const QString &filePath)
......@@ -103,8 +89,7 @@ bool ColorSchemeManager::unloadColorScheme(const QString &filePath)
if (!pathIsColorScheme(filePath)) {
return false;
}
auto name = colorSchemeNameFromPath(filePath);
delete _colorSchemes.take(name);
_colorSchemes.remove(colorSchemeNameFromPath(filePath));
return true;
}
......@@ -131,20 +116,15 @@ QStringList ColorSchemeManager::listColorSchemes()
return colorschemes;
}
const ColorScheme ColorSchemeManager::_defaultColorScheme;
const ColorScheme *ColorSchemeManager::defaultColorScheme() const
const std::shared_ptr<const ColorScheme> &ColorSchemeManager::defaultColorScheme() const
{
return &_defaultColorScheme;
static const std::shared_ptr<const ColorScheme> defaultScheme = std::make_shared<const ColorScheme>();
return defaultScheme;
}
void ColorSchemeManager::addColorScheme(ColorScheme *scheme)
void ColorSchemeManager::addColorScheme(const std::shared_ptr<ColorScheme> &scheme)
{
// remove existing colorscheme with the same name
if (_colorSchemes.contains(scheme->name())) {
delete _colorSchemes.take(scheme->name());
}
_colorSchemes.insert(scheme->name(), scheme);
_colorSchemes[scheme->name()] = scheme;
// save changes to disk
......@@ -163,14 +143,14 @@ bool ColorSchemeManager::deleteColorScheme(const QString &name)
// look up the path and delete
QString path = findColorSchemePath(name);
if (QFile::remove(path)) {
delete _colorSchemes.take(name);
_colorSchemes.remove(name);
return true;
}
qCDebug(ColorSchemeDebug) << "Failed to remove color scheme -" << path;
return false;
}
const ColorScheme *ColorSchemeManager::findColorScheme(const QString &name)
std::shared_ptr<const ColorScheme> ColorSchemeManager::findColorScheme(const QString &name)
{
if (name.isEmpty()) {
return defaultColorScheme();
......@@ -185,17 +165,21 @@ const ColorScheme *ColorSchemeManager::findColorScheme(const QString &name)
}
if (_colorSchemes.contains(name)) {
return _colorSchemes[name];
std::shared_ptr<const ColorScheme> colorScheme = _colorSchemes.value(name).lock();
if (colorScheme) {
return colorScheme;
} else {
// Remove outdated weak pointer
_colorSchemes.remove(name);
}
}
// look for this color scheme
QString path = findColorSchemePath(name);
if (!path.isEmpty() && loadColorScheme(path)) {
return findColorScheme(name);
if (path.isEmpty()) {
qCDebug(ColorSchemeDebug) << "Could not find color scheme - " << name;
return nullptr;
}
qCDebug(ColorSchemeDebug) << "Could not find color scheme - " << name;
return nullptr;
return loadColorScheme(path);
}
QString ColorSchemeManager::findColorSchemePath(const QString &name) const
......
......@@ -34,15 +34,11 @@ public:
* requested via a call to findColorScheme()
*/
ColorSchemeManager();
/**
* Destroys the ColorSchemeManager and saves any modified color schemes to disk.
*/
~ColorSchemeManager();
/**
* Returns the default color scheme for Konsole
*/
const ColorScheme *defaultColorScheme() const;
const std::shared_ptr<const ColorScheme> &defaultColorScheme() const;
/**
* Returns the color scheme with the given name or 0 if no
......@@ -52,13 +48,13 @@ public:
* The first time that a color scheme with a particular name is
* requested, the configuration information is loaded from disk.
*/
const ColorScheme *findColorScheme(const QString &name);
std::shared_ptr<const ColorScheme> findColorScheme(const QString &name);
/**
* Adds a new color scheme to the manager. If @p scheme has the same name as
* an existing color scheme, it replaces the existing scheme.
*/
void addColorScheme(ColorScheme *scheme);
void addColorScheme(const std::shared_ptr<ColorScheme> &scheme);
/**
* Deletes a color scheme. Returns true on successful deletion or false otherwise.
......@@ -72,7 +68,7 @@ public:
*
* Subsequent calls will be inexpensive.
*/
QList<const ColorScheme *> allColorSchemes();
QList<std::shared_ptr<const ColorScheme>> allColorSchemes();
/** Returns the global color scheme manager instance. */
static ColorSchemeManager *instance();
......@@ -89,12 +85,12 @@ public:
*/
bool isColorSchemeDeletable(const QString &name);
// loads a color scheme from a KDE 4+ .colorscheme file
bool loadColorScheme(const QString &filePath);
// unloads a color scheme by it's file path (doesn't delete!)
bool unloadColorScheme(const QString &filePath);
// loads a color scheme from a KDE 4+ .colorscheme file
std::shared_ptr<const ColorScheme> loadColorScheme(const QString &filePath);
// @returns the scheme name of a given file or a null string if the file is
// no theme
static QString colorSchemeNameFromPath(const QString &path);
......@@ -102,18 +98,12 @@ public:
private:
// returns a list of paths of color schemes in the KDE 4+ .colorscheme file format
QStringList listColorSchemes();
// loads all of the color schemes
void loadAllColorSchemes();
// finds the path of a color scheme
QString findColorSchemePath(const QString &name) const;
// @returns whether a path is a valid color scheme name
static bool pathIsColorScheme(const QString &path);
QHash<QString, const ColorScheme *> _colorSchemes;
bool _haveLoadedAll;
static const ColorScheme _defaultColorScheme;
QHash<QString, std::weak_ptr<const ColorScheme>> _colorSchemes;
Q_DISABLE_COPY(ColorSchemeManager)
};
......
......@@ -28,7 +28,7 @@ ColorSchemeViewDelegate::ColorSchemeViewDelegate(QObject *parent)
void ColorSchemeViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
const auto *scheme = index.data(Qt::UserRole + 1).value<const ColorScheme *>();
std::shared_ptr<const ColorScheme> scheme = index.data(Qt::UserRole + 1).value<std::shared_ptr<const ColorScheme>>();
QFont profileFont = index.data(Qt::UserRole + 2).value<QFont>();
Q_ASSERT(scheme);
if (scheme == nullptr) {
......
......@@ -28,7 +28,7 @@ HTMLDecoder::HTMLDecoder(const QString &colorSchemeName, const QFont &profileFon
, _lastBackColor(CharacterColor())
, _validProfile(false)
{
const ColorScheme *colorScheme = nullptr;
std::shared_ptr<const ColorScheme> colorScheme = nullptr;
if (!colorSchemeName.isEmpty()) {
colorScheme = ColorSchemeManager::instance()->findColorScheme(colorSchemeName);
......
......@@ -29,7 +29,7 @@ TerminalColor::TerminalColor(QObject *parent)
setColorTable(ColorScheme::defaultTable);
}
void TerminalColor::applyProfile(const Profile::Ptr &profile, ColorScheme const *colorScheme, uint randomSeed)
void TerminalColor::applyProfile(const Profile::Ptr &profile, const std::shared_ptr<const ColorScheme> &colorScheme, uint randomSeed)
{
QColor table[TABLE_COLORS];
colorScheme->getColorTable(table, randomSeed);
......
......@@ -29,7 +29,7 @@ class KONSOLEPRIVATE_EXPORT TerminalColor : public QObject
public:
explicit TerminalColor(QObject *parent);
void applyProfile(const Profile::Ptr &profile, ColorScheme const *colorScheme, uint randomSeed);
void applyProfile(const Profile::Ptr &profile, const std::shared_ptr<const ColorScheme> &colorScheme, uint randomSeed);
QColor backgroundColor() const;
QColor foregroundColor() const;
......
......@@ -428,7 +428,7 @@ public Q_SLOTS:
/**
* Return the current color scheme
*/
ColorScheme const *colorScheme() const
const std::shared_ptr<const ColorScheme> &colorScheme() const
{
return _colorScheme;
}
......@@ -702,7 +702,7 @@ private:
QSize _size;
ColorScheme const *_colorScheme;
std::shared_ptr<const ColorScheme> _colorScheme;
ColorSchemeWallpaper::Ptr _wallpaper;
// list of filters currently applied to the display. used for links and
......
......@@ -906,7 +906,7 @@ void EditProfileDialog::updateColorSchemeList(const QString &selectedColorScheme
_appearanceUi->colorSchemeList->setModel(new QStandardItemModel(this));
}
const ColorScheme *selectedColorScheme = ColorSchemeManager::instance()->findColorScheme(selectedColorSchemeName);
std::shared_ptr<const ColorScheme> selectedColorScheme = ColorSchemeManager::instance()->findColorScheme(selectedColorSchemeName);
auto *model = qobject_cast<QStandardItemModel *>(_appearanceUi->colorSchemeList->model());
......@@ -916,9 +916,9 @@ void EditProfileDialog::updateColorSchemeList(const QString &selectedColorScheme
QStandardItem *selectedItem = nullptr;
const QList<const ColorScheme *> schemeList = ColorSchemeManager::instance()->allColorSchemes();
const QList<std::shared_ptr<const ColorScheme>> schemeList = ColorSchemeManager::instance()->allColorSchemes();
for (const ColorScheme *scheme : schemeList) {
for (const std::shared_ptr<const ColorScheme> &scheme : schemeList) {
QStandardItem *item = new QStandardItem(scheme->description());
item->setData(QVariant::fromValue(scheme), Qt::UserRole + 1);
item->setData(QVariant::fromValue(_profile->font()), Qt::UserRole + 2);
......@@ -1091,7 +1091,7 @@ void EditProfileDialog::preview(int property, const QVariant &value)
void EditProfileDialog::previewColorScheme(const QModelIndex &index)
{
const QString &name = index.data(Qt::UserRole + 1).value<const ColorScheme *>()->name();
const QString &name = index.data(Qt::UserRole + 1).value<std::shared_ptr<const ColorScheme>>()->name();
delayedPreview(Profile::ColorScheme, name);
}
......@@ -1135,7 +1135,7 @@ void EditProfileDialog::removeColorScheme()
if (selected.isEmpty()) {
return;
}
const QString &name = selected.first().data(Qt::UserRole + 1).value<const ColorScheme *>()->name();
const QString &name = selected.first().data(Qt::UserRole + 1).value<std::shared_ptr<const ColorScheme>>()->name();
Q_ASSERT(!name.isEmpty());
if (ColorSchemeManager::instance()->deleteColorScheme(name)) {
_appearanceUi->colorSchemeList->model()->removeRow(selected.first().row());
......@@ -1148,7 +1148,7 @@ void EditProfileDialog::gotNewColorSchemes(const KNS3::Entry::List &changedEntri
for (auto &entry : qAsConst(changedEntries)) {
switch (entry.status()) {
case KNS3::Entry::Installed:
for (const auto &file : entry.installedFiles()) {
for (const QString &file : entry.installedFiles()) {
if (ColorSchemeManager::instance()->loadColorScheme(file)) {
continue;
}
......@@ -1188,7 +1188,7 @@ void EditProfileDialog::resetColorScheme()
QModelIndexList selected = _appearanceUi->colorSchemeList->selectionModel()->selectedIndexes();
if (!selected.isEmpty()) {
const QString &name = selected.first().data(Qt::UserRole + 1).value<const ColorScheme *>()->name();
const QString &name = selected.first().data(Qt::UserRole + 1).value<std::shared_ptr<const ColorScheme>>()->name();
ColorSchemeManager::instance()->deleteColorScheme(name);
......@@ -1202,9 +1202,9 @@ void EditProfileDialog::showColorSchemeEditor(bool isNewScheme)
// Finding selected ColorScheme
QModelIndexList selected = _appearanceUi->colorSchemeList->selectionModel()->selectedIndexes();
QAbstractItemModel *model = _appearanceUi->colorSchemeList->model();
const ColorScheme *colors = nullptr;
std::shared_ptr<const ColorScheme> colors;
if (!selected.isEmpty()) {
colors = model->data(selected.first(), Qt::UserRole + 1).value<const ColorScheme *>();
colors = model->data(selected.first(), Qt::UserRole + 1).value<std::shared_ptr<const ColorScheme>>();
} else {
colors = ColorSchemeManager::instance()->defaultColorScheme();
}
......@@ -1244,7 +1244,7 @@ void EditProfileDialog::editColorScheme()
void EditProfileDialog::saveColorScheme(const ColorScheme &scheme, bool isNewScheme)
{
auto newScheme = new ColorScheme(scheme);
std::shared_ptr<ColorScheme> newScheme = std::make_shared<ColorScheme>(scheme);
// if this is a new color scheme, pick a name based on the description
if (isNewScheme) {
......@@ -1267,7 +1267,7 @@ void EditProfileDialog::colorSchemeSelected()
if (!selected.isEmpty()) {
QAbstractItemModel *model = _appearanceUi->colorSchemeList->model();
const auto *colors = model->data(selected.first(), Qt::UserRole + 1).value<const ColorScheme *>();
std::shared_ptr<const ColorScheme> colors = model->data(selected.first(), Qt::UserRole + 1).value<std::shared_ptr<const ColorScheme>>();
if (colors != nullptr) {
updateTempProfileProperty(Profile::ColorScheme, colors->name());
previewColorScheme(selected.first());
......@@ -1286,7 +1286,7 @@ void EditProfileDialog::updateColorSchemeButtons()
QModelIndexList selected = _appearanceUi->colorSchemeList->selectionModel()->selectedIndexes();
if (!selected.isEmpty()) {
const QString &name = selected.first().data(Qt::UserRole + 1).value<const ColorScheme *>()->name();
const QString &name = selected.first().data(Qt::UserRole + 1).value<std::shared_ptr<const ColorScheme>>()->name();
bool isResettable = ColorSchemeManager::instance()->canResetColorScheme(name);
_appearanceUi->resetColorSchemeButton->setEnabled(isResettable);
......@@ -1329,7 +1329,7 @@ void EditProfileDialog::updateTransparencyWarning()
// zero or one indexes can be selected
const QModelIndexList selected = _appearanceUi->colorSchemeList->selectionModel()->selectedIndexes();
for (const QModelIndex &index : selected) {
bool needTransparency = index.data(Qt::UserRole + 1).value<const ColorScheme *>()->opacity() < 1.0;
bool needTransparency = index.data(Qt::UserRole + 1).value<std::shared_ptr<const ColorScheme>>()->opacity() < 1.0;
if (!needTransparency) {
_appearanceUi->transparencyWarningWidget->setHidden(true);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment