diff --git a/libs/libkis/Krita.cpp b/libs/libkis/Krita.cpp index 5e4692a2d0..a744baf2f0 100644 --- a/libs/libkis/Krita.cpp +++ b/libs/libkis/Krita.cpp @@ -1,423 +1,399 @@ /* * Copyright (c) 2016 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser 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 Lesser 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 "Krita.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include #include #include #include -#include #include #include +#include +#include + #include "View.h" #include "Document.h" #include "Window.h" #include "Extension.h" #include "DockWidgetFactoryBase.h" #include "Filter.h" #include "InfoObject.h" #include "Resource.h" Krita* Krita::s_instance = 0; struct Krita::Private { Private() {} QList extensions; bool batchMode {false}; Notifier *notifier{new Notifier()}; }; Krita::Krita(QObject *parent) : QObject(parent) , d(new Private) { qRegisterMetaType(); connect(KisPart::instance(), SIGNAL(sigWindowAdded(KisMainWindow*)), SLOT(mainWindowAdded(KisMainWindow*))); } Krita::~Krita() { qDeleteAll(d->extensions); delete d->notifier; delete d; } QList Krita::actions() const { KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow(); if (!mainWindow) { return QList(); } KActionCollection *actionCollection = mainWindow->actionCollection(); return actionCollection->actions(); } QAction *Krita::action(const QString &name) const { KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow(); if (!mainWindow) { return 0; } KActionCollection *actionCollection = mainWindow->actionCollection(); QAction *action = actionCollection->action(name); return action; } Document* Krita::activeDocument() const { KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow(); if (!mainWindow) { return 0; } KisView *view = mainWindow->activeView(); if (!view) { return 0; } KisDocument *document = view->document(); return new Document(document); } void Krita::setActiveDocument(Document* value) { Q_FOREACH(KisView *view, KisPart::instance()->views()) { if (view->document() == value->document().data()) { view->activateWindow(); break; } } } bool Krita::batchmode() const { return d->batchMode; } void Krita::setBatchmode(bool value) { d->batchMode = value; } QList Krita::documents() const { QList ret; foreach(QPointer doc, KisPart::instance()->documents()) { ret << new Document(doc); } return ret; } QStringList Krita::filters() const { QStringList ls = KisFilterRegistry::instance()->keys(); std::sort(ls.begin(), ls.end()); return ls; } Filter *Krita::filter(const QString &name) const { if (!filters().contains(name)) return 0; Filter *filter = new Filter(); filter->setName(name); KisFilterSP f = KisFilterRegistry::instance()->value(name); KisFilterConfigurationSP fc = f->defaultConfiguration(); InfoObject *info = new InfoObject(fc); filter->setConfiguration(info); return filter; } QStringList Krita::colorModels() const { QSet colorModelsIds; QList ids = KoColorSpaceRegistry::instance()->colorModelsList(KoColorSpaceRegistry::AllColorSpaces); Q_FOREACH(KoID id, ids) { colorModelsIds << id.id(); } return colorModelsIds.toList(); } QStringList Krita::colorDepths(const QString &colorModel) const { QSet colorDepthsIds; QList ids = KoColorSpaceRegistry::instance()->colorDepthList(colorModel, KoColorSpaceRegistry::AllColorSpaces); Q_FOREACH(KoID id, ids) { colorDepthsIds << id.id(); } return colorDepthsIds.toList(); } QStringList Krita::filterStrategies() const { return KisFilterStrategyRegistry::instance()->keys(); } QStringList Krita::profiles(const QString &colorModel, const QString &colorDepth) const { QSet profileNames; QString id = KoColorSpaceRegistry::instance()->colorSpaceId(colorModel, colorDepth); QList profiles = KoColorSpaceRegistry::instance()->profilesFor(id); Q_FOREACH(const KoColorProfile *profile, profiles) { profileNames << profile->name(); } QStringList r = profileNames.toList(); r.sort(); return r; } bool Krita::addProfile(const QString &profilePath) { KoColorSpaceEngine *iccEngine = KoColorSpaceEngineRegistry::instance()->get("icc"); return iccEngine->addProfile(profilePath); } Notifier* Krita::notifier() const { return d->notifier; } QString Krita::version() const { return KritaVersionWrapper::versionString(true); } QList Krita::views() const { QList ret; foreach(QPointer view, KisPart::instance()->views()) { ret << new View(view); } return ret; } Window *Krita::activeWindow() const { KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow(); if (!mainWindow) { return 0; } return new Window(mainWindow); } QList Krita::windows() const { QList ret; foreach(QPointer mainWin, KisPart::instance()->mainWindows()) { ret << new Window(mainWin); } return ret; } -QMap Krita::resources(const QString &type) const +QMap Krita::resources(const QString &type) const { - QMap resources = QMap (); + QMap resources; + KisResourceModel *resourceModel = KisResourceModelProvider::resourceModel(type); + for (int i = 0; i < resourceModel->rowCount(); ++i) { - if (type.toLower() == "pattern") { - KoResourceServer* server = KoResourceServerProvider::instance()->patternServer(); - Q_FOREACH (KoResourceSP res, server->resources()) { - resources[res->name()] = new Resource(res); - } - } - else if (type.toLower() == "gradient") { - KoResourceServer* server = KoResourceServerProvider::instance()->gradientServer(); - Q_FOREACH (KoResourceSP res, server->resources()) { - resources[res->name()] = new Resource(res); - } - } - else if (type.toLower() == "brush") { - KoResourceServer* server = KisBrushServerProvider::instance()->brushServer(); - Q_FOREACH (KisBrushSP res, server->resources()) { - resources[res->name()] = new Resource(res); - } - } - else if (type.toLower() == "preset") { - KisPaintOpPresetResourceServer* server = KisResourceServerProvider::instance()->paintOpPresetServer(); - Q_FOREACH (KisPaintOpPresetSP res, server->resources()) { - resources[res->name()] = new Resource(res); - } - } - else if (type.toLower() == "palette") { - KoResourceServer* server = KoResourceServerProvider::instance()->paletteServer(); - Q_FOREACH (KoResourceSP res, server->resources()) { - resources[res->name()] = new Resource(res); - } - } - else if (type.toLower() == "workspace") { - KoResourceServer< KisWorkspaceResource >* server = KisResourceServerProvider::instance()->workspaceServer(); - Q_FOREACH (KoResourceSP res, server->resources()) { - resources[res->name()] = new Resource(res); - } + QModelIndex idx = resourceModel->index(i, 0); + int id = resourceModel->data(idx, Qt::UserRole + KisResourceModel::Id).toInt(); + QString name = resourceModel->data(idx, Qt::UserRole + KisResourceModel::Name).toString(); + QString filename = resourceModel->data(idx, Qt::UserRole + KisResourceModel::Filename).toString(); + QImage image = resourceModel->data(idx, Qt::UserRole + KisResourceModel::Image).value(); + + resources[name] = new Resource(id, type, name, filename, image, 0); } + return resources; } QStringList Krita::recentDocuments() const { KConfigGroup grp = KSharedConfig::openConfig()->group(QString("RecentFiles")); QStringList keys = grp.keyList(); QStringList recentDocuments; for(int i = 0; i <= keys.filter("File").count(); i++) recentDocuments << grp.readEntry(QString("File%1").arg(i), QString("")); return recentDocuments; } Document* Krita::createDocument(int width, int height, const QString &name, const QString &colorModel, const QString &colorDepth, const QString &profile, double resolution) { KisDocument *document = KisPart::instance()->createDocument(); KisPart::instance()->addDocument(document); const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(colorModel, colorDepth, profile); Q_ASSERT(cs); QColor qc(Qt::white); qc.setAlpha(0); KoColor bgColor(qc, cs); if (!document->newImage(name, width, height, cs, bgColor, KisConfig::RASTER_LAYER, 1, "", double(resolution / 72) )) { return 0; } Q_ASSERT(document->image()); return new Document(document); } Document* Krita::openDocument(const QString &filename) { KisDocument *document = KisPart::instance()->createDocument(); document->setFileBatchMode(this->batchmode()); KisPart::instance()->addDocument(document); document->openUrl(QUrl::fromLocalFile(filename), KisDocument::DontAddToRecent); document->setFileBatchMode(false); return new Document(document); } Window* Krita::openWindow() { KisMainWindow *mw = KisPart::instance()->createMainWindow(); return new Window(mw); } void Krita::addExtension(Extension* extension) { d->extensions.append(extension); } QList< Extension* > Krita::extensions() { return d->extensions; } void Krita::writeSetting(const QString &group, const QString &name, const QString &value) { KConfigGroup grp = KSharedConfig::openConfig()->group(group); grp.writeEntry(name, value); } QString Krita::readSetting(const QString &group, const QString &name, const QString &defaultValue) { KConfigGroup grp = KSharedConfig::openConfig()->group(group); return grp.readEntry(name, defaultValue); } QIcon Krita::icon(QString &iconName) const { return KisIconUtils::loadIcon(iconName); } void Krita::addDockWidgetFactory(DockWidgetFactoryBase* factory) { KoDockRegistry::instance()->add(factory); } Krita* Krita::instance() { if (!s_instance) { s_instance = new Krita; } return s_instance; } /** * Scripter.fromVariant(variant) * variant is a QVariant * returns instance of QObject-subclass * * This is a helper method for PyQt because PyQt cannot cast a variant to a QObject or QWidget */ QObject *Krita::fromVariant(const QVariant& v) { if (v.canConvert< QWidget* >()) { QObject* obj = qvariant_cast< QWidget* >(v); return obj; } else if (v.canConvert< QObject* >()) { QObject* obj = qvariant_cast< QObject* >(v); return obj; } else return 0; } QString Krita::krita_i18n(const QString &text) { return i18n(text.toUtf8().constData()); } void Krita::mainWindowAdded(KisMainWindow *kisWindow) { Q_FOREACH(Extension *extension, d->extensions) { Window window(kisWindow); extension->createActions(&window); } } diff --git a/libs/libkis/PresetChooser.cpp b/libs/libkis/PresetChooser.cpp index 3c1d71e645..4c932e6272 100644 --- a/libs/libkis/PresetChooser.cpp +++ b/libs/libkis/PresetChooser.cpp @@ -1,55 +1,53 @@ /* * Copyright (c) 2017 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser 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 Lesser 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 "PresetChooser.h" #include #include #include "Resource.h" PresetChooser::PresetChooser(QWidget *parent) : KisPresetChooser(parent) { connect(this, SIGNAL(resourceSelected(KoResourceSP )), SLOT(slotResourceSelected(KoResourceSP ))); connect(this, SIGNAL(resourceClicked(KoResourceSP )), SLOT(slotResourceClicked(KoResourceSP ))); showTaggingBar(true); } void PresetChooser::setCurrentPreset(Resource *resource) { KoResourceSP r = resource->resource(); setCurrentResource(r); } Resource *PresetChooser::currentPreset() const { KoResourceSP r = currentResource(); - return new Resource(r); + return new Resource(r->resourceId(), "paintoppreset", r->name(), r->filename(), r->image()); } -void PresetChooser::slotResourceSelected(KoResourceSP resource) +void PresetChooser::slotResourceSelected(KoResourceSP r) { - Resource *r = new Resource(resource); - emit presetSelected(r); + emit presetSelected(Resource(r->resourceId(), "paintoppreset", r->name(), r->filename(), r->image())); } -void PresetChooser::slotResourceClicked(KoResourceSP resource) +void PresetChooser::slotResourceClicked(KoResourceSP r) { - Resource *r = new Resource(resource); - emit presetClicked(r); + emit presetClicked(Resource(r->resourceId(), "paintoppreset", r->name(), r->filename(), r->image())); } diff --git a/libs/libkis/PresetChooser.h b/libs/libkis/PresetChooser.h index e8dbfa1db0..ed1ff8676b 100644 --- a/libs/libkis/PresetChooser.h +++ b/libs/libkis/PresetChooser.h @@ -1,75 +1,75 @@ /* * Copyright (c) 2017 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser 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 Lesser 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. */ #ifndef PRESETCHOOSER_H #define PRESETCHOOSER_H #include #include #include #include "kritalibkis_export.h" #include "libkis.h" class Resource; /** * @brief The PresetChooser widget wraps the KisPresetChooser widget. * The widget provides for selecting brush presets. It has a tagging * bar and a filter field. It is not automatically synchronized with * the currently selected preset in the current Windows. */ class KRITALIBKIS_EXPORT PresetChooser : public KisPresetChooser { Q_OBJECT public: PresetChooser(QWidget *parent = 0); ~PresetChooser() override {} public Q_SLOTS: /** * Make the given preset active. */ void setCurrentPreset(Resource *resource); /** * @return a Resource wrapper around the currently selected * preset. */ Resource *currentPreset() const; Q_SIGNALS: /** * Emitted whenever a user selects the given preset. */ - void presetSelected(Resource *resource); + void presetSelected(Resource resource); /** * Emitted whenever a user clicks on the given preset. */ - void presetClicked(Resource *resource); + void presetClicked(Resource resource); private Q_SLOTS: void slotResourceSelected(KoResourceSP resource); void slotResourceClicked(KoResourceSP resource); }; #endif // PRESETCHOOSER_H diff --git a/libs/libkis/Resource.cpp b/libs/libkis/Resource.cpp index 10a5a4ef52..28b7458c5c 100644 --- a/libs/libkis/Resource.cpp +++ b/libs/libkis/Resource.cpp @@ -1,130 +1,138 @@ /* * Copyright (c) 2016 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser 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 Lesser 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 "Resource.h" #include #include #include #include #include #include #include #include #include +#include struct Resource::Private { - Private(KoResourceSP _resource) - : resource(_resource) - {} + Private() {} - KoResourceSP resource {0}; + int id {-1}; + QString type; + QString name; + QString filename; + QImage image; }; -Resource::Resource(KoResourceSP resource, QObject *parent) +Resource::Resource(int resourceId, const QString &type, const QString &name, const QString &filename, const QImage &image, QObject *parent) : QObject(parent) - , d(new Private(resource)) + , d(new Private()) { + d->id = resourceId; + d->type = type; + d->name = name; + d->filename = filename; + d->image = image; +} + +Resource::Resource(KoResourceSP resource, const QString &type, QObject *parent) + : QObject(parent) + , d(new Private()) +{ + d->id = resource->resourceId(); + d->type = type; + d->name = resource->name(); + d->filename = resource->filename(); + d->image = resource->image(); } Resource::~Resource() { - delete d; +} + +Resource::Resource(const Resource &rhs) + : QObject() + , d(new Private()) +{ + d->id = rhs.d->id; + d->type = rhs.d->type; + d->name = rhs.d->name; + d->filename = rhs.d->filename; + d->image = rhs.d->image; } bool Resource::operator==(const Resource &other) const { - return (d->resource == other.d->resource); + return (d->id == other.d->id); } bool Resource::operator!=(const Resource &other) const { return !(operator==(other)); } +Resource Resource::operator=(const Resource &rhs) +{ + Resource res(rhs.d->id, + rhs.d->type, + rhs.d->name, + rhs.d->filename, + rhs.d->image); + return res; +} + QString Resource::type() const { - if (!d->resource) return QString(); - if (d->resource.dynamicCast()) return "pattern"; - else if (d->resource.dynamicCast()) return "gradient"; - else if (d->resource.dynamicCast()) return "brush"; - else if (d->resource.dynamicCast()) return "preset"; - else if (d->resource.dynamicCast()) return "palette"; - else if (d->resource.dynamicCast()) return "workspace"; - else return ""; + return d->type; } QString Resource::name() const { - if (!d->resource) return QString(); - return d->resource->name(); + return d->name; } void Resource::setName(QString value) { - if (!d->resource) return; - d->resource->setName(value); + d->name = value; } - QString Resource::filename() const { - if (!d->resource) return QString(); - return d->resource->filename(); + return d->filename; } QImage Resource::image() const { - if (!d->resource) return QImage(); - return d->resource->image(); + return d->image; } void Resource::setImage(QImage image) { - if (!d->resource) return; - d->resource->setImage(image); -} - -QByteArray Resource::data() const -{ - QByteArray ba; - - if (!d->resource) return ba; - - QBuffer buf(&ba); - d->resource->saveToDevice(&buf); - return ba; -} - -bool Resource::setData(QByteArray data) -{ - if (!d->resource) return false; - QBuffer buf(&data); - return d->resource->loadFromDevice(&buf); + d->image = image; } KoResourceSP Resource::resource() const { - return d->resource; + return KisResourceLocator::instance()->resourceForId(d->id); } diff --git a/libs/libkis/Resource.h b/libs/libkis/Resource.h index 5da4eac2bd..108dccb2a8 100644 --- a/libs/libkis/Resource.h +++ b/libs/libkis/Resource.h @@ -1,120 +1,113 @@ /* * Copyright (c) 2016 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser 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 Lesser 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. */ #ifndef LIBKIS_RESOURCE_H #define LIBKIS_RESOURCE_H #include +#include #include #include "kritalibkis_export.h" #include "libkis.h" #include /** * A Resource represents a gradient, pattern, brush tip, brush preset, palette or * workspace definition. * * @code * allPresets = Application.resources("preset") * for preset in allPresets: * print(preset.name()) * @endcode * * Resources are identified by their type, name and filename. If you want to change * the contents of a resource, you should read its data using data(), parse it and * write the changed contents back. */ class KRITALIBKIS_EXPORT Resource : public QObject { Q_OBJECT public: - explicit Resource(KoResourceSP resource, QObject *parent = 0); + Resource(int resourceId, const QString &type, const QString &name, const QString &filename, const QImage &image, QObject *parent = 0); + Resource(KoResourceSP resource, const QString &type, QObject *parent = 0); ~Resource() override; + Resource(const Resource &rhs); + bool operator==(const Resource &other) const; bool operator!=(const Resource &other) const; + Resource operator=(const Resource &rhs); public Q_SLOTS: /** * Return the type of this resource. Valid types are: *
    *
  • pattern: a raster image representing a pattern *
  • gradient: a gradient *
  • brush: a brush tip *
  • preset: a brush preset *
  • palette: a color set *
  • workspace: a workspace definition. *
*/ QString type() const; /** * The user-visible name of the resource. */ QString name() const; /** * setName changes the user-visible name of the current resource. */ void setName(QString value); /** * The filename of the resource, if present. Not all resources * are loaded from files. */ QString filename() const; /** * An image that can be used to represent the resource in the * user interface. For some resources, like patterns, the * image is identical to the resource, for others it's a mere * icon. */ QImage image() const; /** * Change the image for this resource. */ void setImage(QImage image); - /** - * Return the resource as a byte array. - */ - QByteArray data() const; - - /** - * Change the internal data of the resource to the given byte - * array. If the byte array is not valid, setData returns - * false, otherwwise true. - */ - bool setData(QByteArray data); - private: friend class PresetChooser; friend class View; friend class Palette; KoResourceSP resource() const; struct Private; - const Private *const d; + QScopedPointer d; }; #endif // LIBKIS_RESOURCE_H diff --git a/libs/libkis/View.cpp b/libs/libkis/View.cpp index 0e431d0456..a5087f3a88 100644 --- a/libs/libkis/View.cpp +++ b/libs/libkis/View.cpp @@ -1,273 +1,273 @@ /* * Copyright (c) 2016 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser 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 Lesser 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 "View.h" #include #include #include #include #include #include #include #include #include #include #include #include #include - +#include #include "Document.h" #include "Canvas.h" #include "Window.h" #include "Resource.h" #include "ManagedColor.h" #include "LibKisUtils.h" struct View::Private { Private() {} QPointer view; }; View::View(KisView* view, QObject *parent) : QObject(parent) , d(new Private) { d->view = view; } View::~View() { delete d; } bool View::operator==(const View &other) const { return (d->view == other.d->view); } bool View::operator!=(const View &other) const { return !(operator==(other)); } Window* View::window() const { if (!d->view) return 0; KisMainWindow *mainwin = d->view->mainWindow(); Window *win = new Window(mainwin); return win; } Document* View::document() const { if (!d->view) return 0; Document *doc = new Document(d->view->document()); return doc; } bool View::visible() const { if (!d->view) return false; return d->view->isVisible(); } void View::setVisible() { if (!d->view) return; KisMainWindow *mainwin = d->view->mainWindow(); mainwin->setActiveView(d->view); mainwin->subWindowActivated(); } Canvas* View::canvas() const { if (!d->view) return 0; Canvas *c = new Canvas(d->view->canvasBase()); return c; } KisView *View::view() { return d->view; } void View::activateResource(Resource *resource) { if (!d->view) return; if (!resource) return; KoResourceSP r = resource->resource(); if (!r) return; if (r.dynamicCast()) { QVariant v; v.setValue(r); d->view->canvasBase()->resourceManager()->setResource(KisCanvasResourceProvider::CurrentPattern, v); } else if (r.dynamicCast()) { QVariant v; v.setValue(r); d->view->canvasBase()->resourceManager()->setResource(KisCanvasResourceProvider::CurrentGradient, v); } else if (r.dynamicCast()) { d->view->viewManager()->paintOpBox()->resourceSelected(r); } } ManagedColor *View::foregroundColor() const { if (!d->view) return 0; return new ManagedColor(d->view->resourceProvider()->fgColor()); } void View::setForeGroundColor(ManagedColor *color) { if (!d->view) return; d->view->resourceProvider()->setFGColor(color->color()); } ManagedColor *View::backgroundColor() const { if (!d->view) return 0; return new ManagedColor(d->view->resourceProvider()->bgColor()); } void View::setBackGroundColor(ManagedColor *color) { if (!d->view) return; d->view->resourceProvider()->setBGColor(color->color()); } Resource *View::currentBrushPreset() const { if (!d->view) return 0; - return new Resource(d->view->resourceProvider()->currentPreset()); + return new Resource(d->view->resourceProvider()->currentPreset(), ResourceType::PaintOpPresets); } void View::setCurrentBrushPreset(Resource *resource) { activateResource(resource); } Resource *View::currentPattern() const { if (!d->view) return 0; - return new Resource(d->view->resourceProvider()->currentPattern()); + return new Resource(d->view->resourceProvider()->currentPattern(), ResourceType::Patterns); } void View::setCurrentPattern(Resource *resource) { activateResource(resource); } Resource *View::currentGradient() const { if (!d->view) return 0; - return new Resource(d->view->resourceProvider()->currentGradient()); + return new Resource(d->view->resourceProvider()->currentGradient(), ResourceType::Gradients); } void View::setCurrentGradient(Resource *resource) { activateResource(resource); } QString View::currentBlendingMode() const { if (!d->view) return ""; return d->view->resourceProvider()->currentCompositeOp(); } void View::setCurrentBlendingMode(const QString &blendingMode) { if (!d->view) return; d->view->resourceProvider()->setCurrentCompositeOp(blendingMode); } float View::HDRExposure() const { if (!d->view) return 0.0; return d->view->resourceProvider()->HDRExposure(); } void View::setHDRExposure(float exposure) { if (!d->view) return; d->view->resourceProvider()->setHDRExposure(exposure); } float View::HDRGamma() const { if (!d->view) return 0.0; return d->view->resourceProvider()->HDRGamma(); } void View::setHDRGamma(float gamma) { if (!d->view) return; d->view->resourceProvider()->setHDRGamma(gamma); } qreal View::paintingOpacity() const { if (!d->view) return 0.0; return d->view->resourceProvider()->opacity(); } void View::setPaintingOpacity(qreal opacity) { if (!d->view) return; d->view->resourceProvider()->setOpacity(opacity); } qreal View::brushSize() const { if (!d->view) return 0.0; return d->view->resourceProvider()->size(); } void View::setBrushSize(qreal brushSize) { if (!d->view) return; d->view->resourceProvider()->setSize(brushSize); } qreal View::paintingFlow() const { if (!d->view) return 0.0; return d->view->resourceProvider()->flow(); } void View::setPaintingFlow(qreal flow) { if (!d->view) return; d->view->resourceProvider()->setFlow(flow); } QList View::selectedNodes() const { if (!d->view) return QList(); if (!d->view->viewManager()) return QList(); if (!d->view->viewManager()->nodeManager()) return QList(); KisNodeList selectedNodes = d->view->viewManager()->nodeManager()->selectedNodes(); return LibKisUtils::createNodeList(selectedNodes, d->view->image()); } diff --git a/libs/resources/KisResourceLocator.h b/libs/resources/KisResourceLocator.h index 9a7a86ea6e..77d6fe9d33 100644 --- a/libs/resources/KisResourceLocator.h +++ b/libs/resources/KisResourceLocator.h @@ -1,200 +1,201 @@ /* * Copyright (C) 2018 Boudewijn Rempt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KISRESOURCELOCATOR_H #define KISRESOURCELOCATOR_H #include #include #include #include #include "kritaresources_export.h" #include /** * The KisResourceLocator class locates all resource storages (folders, * bundles, various adobe resource libraries) in the resource location. * * The resource location is always a writable folder. * * There is one resource locator which is owned by the QApplication * object. * * The resource location is configurable, but there is only one location * where Krita will look for resources. */ class KRITARESOURCES_EXPORT KisResourceLocator : public QObject { Q_OBJECT public: // The configuration key that holds the resource location // for this installation of Krita. The location is // QStandardPaths::AppDataLocation by default, but that // can be changed. static const QString resourceLocationKey; static KisResourceLocator *instance(); ~KisResourceLocator(); enum class LocatorError { Ok, LocationReadOnly, CannotCreateLocation, CannotInitializeDb, CannotSynchronizeDb }; /** * @brief initialize Setup the resource locator for use. * * @param installationResourcesLocation the place where the resources * that come packaged with Krita reside. */ LocatorError initialize(const QString &installationResourcesLocation); /** * @brief errorMessages * @return */ QStringList errorMessages() const; /** * @brief resourceLocationBase is the place where all resource storages (folder, * bundles etc. are located. This is a writable place. * @return the base location for all storages. */ QString resourceLocationBase() const; /** * @brief removeResource * @param resourceId * @return */ bool removeResource(int resourceId); /** * @brief importResourceFromFile * @param resourceType * @param fileName * @return */ bool importResourceFromFile(const QString &resourceType, const QString &fileName); /** * @brief addResource * @param resourceType * @param resource * @param save * @return */ bool addResource(const QString &resourceType, const KoResourceSP resource, bool save = true); /** * @brief updateResource * @param resourceType * @param resource * @return */ bool updateResource(const QString &resourceType, const KoResourceSP resource); /** * @brief purge purges the local resource cache */ void purge(); Q_SIGNALS: void progressMessage(const QString&); private: friend class KisResourceModel; friend class TestResourceLocator; friend class TestResourceModel; + friend class Resource; /// @return true if the resource is present in the cache, false if it hasn't been loaded bool resourceCached(QString storageLocation, const QString &resourceType, const QString &filename) const; /** * @brief resource finds a physical resource in one of the storages * @param storageLocation the storage containing the resource. If empty, * this is the folder storage. * * Note that the resource does not have the version or id field set, so this cannot be used directly, * but only through KisResourceModel. * * @param resourceType the type of the resource * @param filename the filename of the resource including extension, but withou * any paths * @return A resource if found, or 0 */ KoResourceSP resource(QString storageLocation, const QString &resourceType, const QString &filename); /** * @brief resourceForId returns the resource with the given id, or 0 if no such resource exists. * The resource object will have its id set but not its version. * @param resourceId the id */ KoResourceSP resourceForId(int resourceId); KisResourceLocator(QObject *parent); KisResourceLocator(const KisResourceLocator&); KisResourceLocator operator=(const KisResourceLocator&); enum class InitalizationStatus { Unknown, // We don't know whether Krita has run on this system for this resource location yet Initialized, // Everything is ready to start synchronizing the database FirstRun, // Krita hasn't run for this resource location yet FirstUpdate, // Krita was installed, but it's a version from before the resource locator existed, only user-defined resources are present Updating // Krita is updating from an older version with resource locator }; LocatorError firstTimeInstallation(InitalizationStatus initalizationStatus, const QString &installationResourcesLocation); // First time installation bool initializeDb(); // Synchronize on restarting Krita to see whether the user has added any storages or resources to the resources location bool synchronizeDb(); void findStorages(); QList storages() const; KisResourceStorageSP storageByName(const QString &name) const; KisResourceStorageSP folderStorage() const; KisResourceStorageSP memoryStorage() const; struct ResourceStorage { QString storageLocation; QString resourceType; QString resourceFileName; }; ResourceStorage getResourceStorage(int resourceId) const; QString makeStorageLocationAbsolute(QString storageLocation) const; class Private; QScopedPointer d; }; #endif // KISRESOURCELOCATOR_H diff --git a/libs/resources/KoResource.h b/libs/resources/KoResource.h index a731311a28..3f8015b40f 100644 --- a/libs/resources/KoResource.h +++ b/libs/resources/KoResource.h @@ -1,189 +1,186 @@ /* This file is part of the KDE project Copyright (c) 2003 Patrick Julien Copyright (c) 2005 Boudewijn Rempt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef KORESOURCE_H #define KORESOURCE_H #include #include #include #include #include #include "KisResourceTypes.h" #include class QDomDocument; class QDomElement; /** * The KoResource class provides a representation of resources. This * includes, but not limited to, brushes and patterns. * * A resource knows its filename, but not the location where it's stored. * A new version of a resource is stored with an updated filename, the old * version isn't renamed. * */ class KRITARESOURCES_EXPORT KoResource { public: /** * Creates a new KoResource object using @p filename. No file is opened * in the constructor, you have to call load. * * @param filename the file name to save and load from. */ explicit KoResource(const QString &filename); virtual ~KoResource(); bool operator ==(const KoResource &other) const { return other.md5() == md5(); } public: /** * Load this resource. * @return true if loading the resource succeeded. */ virtual bool load() = 0; virtual bool loadFromDevice(QIODevice *dev) = 0; /** * Save this resource. *@return true if saving the resource succeeded. */ virtual bool save() = 0; virtual bool saveToDevice(QIODevice* dev) const; /** * @returns a QImage thumbnail image representing this resource. * * This image could be null. The image can be in any valid format. */ QImage image() const; void setImage(const QImage &image); /// @return the md5sum calculated over the contents of the resource. QByteArray md5() const; /// @return the full path to this resource QString filename() const; void setFilename(const QString& filename); /// @return the name of the file without the path QString shortFilename() const; /// @return the user-visible name of the resource QString name() const; void setName(const QString& name); /// @return true if the resource is ready for use bool valid() const; void setValid(bool valid); /// @return the default file extension which should be used when saving the resource virtual QString defaultFileExtension() const; /// @return true if the resource is permanent and can't be removed by the user bool permanent() const; void setPermanent(bool permanent); /// @return the name of the storage location of the resource QString storageLocation() const; /// Mark the preset as modified but not saved void setDirty(bool value); /// @return true if the preset has been modified, but not saved bool isDirty() const; /// store the given key, value pair in the resource void addMetaData(QString key, QVariant value); /// get a map with all the metadata QMap metadata() const; /// Get the version of the resource int version() const; + /// @return the unique id of the resource in the resource database + int resourceId() const; + private: friend class KisResourceModel; friend class KisResourceLocator; friend class TestResourceModel; friend class TestResourceLocator; friend class TestFolderStorage; friend class KisFolderStorage; void setVersion(int version); - - - /// @return the unique id of the resource in the resource database - int resourceId() const; void setResourceId(int id); - - void setStorageLocation(const QString &location); protected: /// override generateMD5 and in your resource subclass virtual QByteArray generateMD5() const; /// call this when the contents of the resource change so the md5 needs to be recalculated void setMD5(const QByteArray &md5); protected: KoResource(const KoResource &rhs); private: struct Private; Private* const d; }; static inline bool operator==(const KoResource &resource1, const KoResource &resource2) { return (resource1.md5() == resource2.md5()); } static inline uint qHash(const KoResource &resource) { return qHash(resource.md5()); } typedef QSharedPointer KoResourceSP; Q_DECLARE_METATYPE(QSharedPointer) inline QDebug operator<<(QDebug dbg, const KoResourceSP res) { dbg.nospace() << "[RESOURCE] Name: " << res->name() << " Version: " << res->version() << " Filename: " << res->filename() << " Valid: " << res->valid() << " Storage: " << res->storageLocation(); return dbg.space(); } #endif // KORESOURCE_H_ diff --git a/libs/widgets/KoResourceServer.h b/libs/widgets/KoResourceServer.h index eba026556d..94d74099f3 100644 --- a/libs/widgets/KoResourceServer.h +++ b/libs/widgets/KoResourceServer.h @@ -1,273 +1,274 @@ /* This file is part of the KDE project Copyright (c) 1999 Matthias Elter Copyright (c) 2003 Patrick Julien Copyright (c) 2005 Sven Langkamp Copyright (c) 2007 Jan Hambrecht Copyright (C) 2011 Srikanth Tiyyagura Copyright (c) 2013 Sascha Suelzer This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef KORESOURCESERVER_H #define KORESOURCESERVER_H #include #include #include #include #include #include #include #include "KoResource.h" #include "KoResourceServerObserver.h" #include "KoResourcePaths.h" #include #include #include #include #include "kritawidgets_export.h" #include "WidgetsDebug.h" class KoResource; /** * KoResourceServer manages the resources of one type. It stores, * loads and saves the resources. To keep track of changes the server * can be observed with a KoResourceServerObserver */ template class KoResourceServer { public: typedef KoResourceServerObserver ObserverType; KoResourceServer(const QString& type) : m_resourceModel(KisResourceModelProvider::resourceModel(type)) , m_type(type) { } virtual ~KoResourceServer() { Q_FOREACH (ObserverType* observer, m_observers) { observer->unsetResourceServer(); } } /// @return the active resource model KisResourceModel *resourceModel() const { return m_resourceModel; } /// Return the first resource available QSharedPointer firstResource() const { return m_resourceModel->resourceForIndex(m_resourceModel->index(0, 0)).dynamicCast(); } int resourceCount() const { return m_resourceModel->rowCount(); } /// Adds an already loaded resource to the server bool addResource(QSharedPointer resource, bool save = true) { if (!resource->valid()) { warnWidgets << "Tried to add an invalid resource!"; return false; } if (m_resourceModel->addResource(resource, save)) { notifyResourceAdded(resource); return true; } return false; } /// Remove a resource from Resource Server but not from a file bool removeResourceFromServer(QSharedPointer resource){ if (m_resourceModel->removeResource(resource)) { notifyRemovingResource(resource); return true; } return false; } QList> resources() { qDebug() << "KoResourceServer::resources()" << m_type; + Q_ASSERT(m_type != "paintoppresets"); QList> resourceList; for (int row = 0; row < m_resourceModel->rowCount(); ++row) { resourceList << m_resourceModel->resourceForIndex(m_resourceModel->index(row, 0)).dynamicCast(); } return resourceList; } /// Returns path where to save user defined and imported resources to QString saveLocation() { return KoResourcePaths::saveLocation(m_type.toLatin1()); } /** * Creates a new resource from a given file and adds them to the resource server * The base implementation does only load one resource per file, override to implement collections * @param filename file name of the resource file to be imported * @param fileCreation decides whether to create the file in the saveLocation() directory */ bool importResourceFile(const QString &filename) { return m_resourceModel->importResourceFile(filename); } /// Removes the resource file from the resource server void removeResourceFile(const QString & filename) { QFileInfo fi(filename); QSharedPointer resource = resourceByFilename(fi.fileName()); if (!resource) { warnWidgets << "Resource file do not exist "; return; } removeResourceFromServer(resource); } /** * Addes an observer to the server * @param observer the observer to be added * @param notifyLoadedResources determines if the observer should be notified about the already loaded resources */ void addObserver(ObserverType* observer) { if (observer && !m_observers.contains(observer)) { m_observers.append(observer); } } /** * Removes an observer from the server * @param observer the observer to be removed */ void removeObserver(ObserverType* observer) { int index = m_observers.indexOf(observer); if (index < 0) { return; } m_observers.removeAt( index ); } QSharedPointer resourceByFilename(const QString& filename) const { qDebug() << "resourceByFilename" << filename; // if (m_resourcesByFilename.contains(filename)) { // return m_resourcesByFilename[filename]; // } return 0; } QSharedPointer resourceByName(const QString& name) const { qDebug() << "resourceByName" << name; // if (m_resourcesByName.contains(name)) { // return m_resourcesByName[name]; // } return 0; } QSharedPointer resourceByMD5(const QByteArray& md5) const { qDebug() << "resourceByMD5" << md5; // return m_resourcesByMd5.value(md5); return 0; } /** * Call after changing the content of a resource; * Notifies the connected views. */ void updateResource(QSharedPointer resource) { m_resourceModel->updateResource(resource); notifyResourceChanged(resource); } // don't use these method directly since it doesn't update views! void addTag(KoResourceSP resource, const QString& tag) { // m_tagStore->addTag(resource, tag); } // don't use these method directly since it doesn't update views! void delTag(KoResourceSP resource, const QString& tag) { // m_tagStore->delTag(resource, tag); } QStringList assignedTagsList(KoResourceSP resource) const { return QStringList(); //m_tagStore->assignedTagsList(resource); } /// Return the currently stored resources in alphabetical order, overwrite for customized sorting virtual QList> sortedResources() { QMap> sortedNames; // Q_FOREACH (const QString &name, m_resourcesByName.keys()) { // sortedNames.insert(name.toLower(), m_resourcesByName[name]); // } return sortedNames.values(); } protected: void notifyResourceAdded(QSharedPointer resource) { Q_FOREACH (ObserverType* observer, m_observers) { observer->resourceAdded(resource); } } void notifyRemovingResource(QSharedPointer resource) { Q_FOREACH (ObserverType* observer, m_observers) { observer->removingResource(resource); } } void notifyResourceChanged(QSharedPointer resource) { Q_FOREACH (ObserverType* observer, m_observers) { observer->resourceChanged(resource); } } private: QList m_observers; KisResourceModel *m_resourceModel {0}; QString m_type; }; #endif // KORESOURCESERVER_H diff --git a/plugins/extensions/pykrita/sip/krita/PresetChooser.sip b/plugins/extensions/pykrita/sip/krita/PresetChooser.sip index c53c004aa9..cf1ebec034 100644 --- a/plugins/extensions/pykrita/sip/krita/PresetChooser.sip +++ b/plugins/extensions/pykrita/sip/krita/PresetChooser.sip @@ -1,20 +1,20 @@ class PresetChooser : public QWidget /NoDefaultCtors/ { %TypeHeaderCode #include "PresetChooser.h" %End public: PresetChooser(QWidget *parent = 0); public Q_SLOTS: void setCurrentPreset(Resource *resource); Resource *currentPreset() const /Factory/; Q_SIGNALS: - void presetSelected(Resource *resource) /Factory/; - void presetClicked(Resource *resource) /Factory/; + void presetSelected(Resource resource) /Factory/; + void presetClicked(Resource resource) /Factory/; }; diff --git a/plugins/extensions/pykrita/sip/krita/Resource.sip b/plugins/extensions/pykrita/sip/krita/Resource.sip index 1b2d641553..360516e640 100644 --- a/plugins/extensions/pykrita/sip/krita/Resource.sip +++ b/plugins/extensions/pykrita/sip/krita/Resource.sip @@ -1,24 +1,22 @@ class Resource : QObject { %TypeHeaderCode #include "Resource.h" %End Resource(const Resource & __0); public: bool operator==(const Resource &other) const; bool operator!=(const Resource &other) const; public: virtual ~Resource(); public Q_SLOTS: QString type() const; QString name() const; void setName(QString value); QString filename() const; QImage image() const; void setImage(QImage image); - QByteArray data() const; - bool setData(QByteArray data); public Q_SLOTS: Q_SIGNALS: private: };