File indexing completed on 2024-05-12 15:59:06
0001 /* 0002 * SPDX-FileCopyrightText: 2016 Boudewijn Rempt <boud@valdyas.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 #include "Krita.h" 0007 0008 #include <QPointer> 0009 #include <QVariant> 0010 #include <QStringList> 0011 0012 #include <ksharedconfig.h> 0013 #include <kconfiggroup.h> 0014 #include <klocalizedstring.h> 0015 0016 #include <KoColorSpaceRegistry.h> 0017 #include <KoColorProfile.h> 0018 #include <KoColorSpace.h> 0019 #include <KoDockRegistry.h> 0020 #include <KoColorSpaceEngine.h> 0021 #include <KoColorModelStandardIds.h> 0022 #include <KoID.h> 0023 0024 #include <kis_filter_strategy.h> 0025 #include <kactioncollection.h> 0026 #include <KisPart.h> 0027 #include <KisMainWindow.h> 0028 #include <KisDocument.h> 0029 #include <kis_image.h> 0030 #include <kis_action.h> 0031 #include <KisViewManager.h> 0032 #include <KritaVersionWrapper.h> 0033 #include <kis_filter_registry.h> 0034 #include <kis_filter.h> 0035 #include <kis_filter_configuration.h> 0036 #include <kis_properties_configuration.h> 0037 #include <kis_config.h> 0038 #include <kis_workspace_resource.h> 0039 #include <brushengine/kis_paintop_preset.h> 0040 #include <KisBrushServerProvider.h> 0041 #include <KoResourceServerProvider.h> 0042 #include <KisResourceServerProvider.h> 0043 #include <KisBrushServerProvider.h> 0044 #include <kis_action_registry.h> 0045 #include <kis_icon_utils.h> 0046 0047 #include <KisResourceModel.h> 0048 #include <KisGlobalResourcesInterface.h> 0049 0050 #include "View.h" 0051 #include "Document.h" 0052 #include "Window.h" 0053 #include "Extension.h" 0054 #include "DockWidgetFactoryBase.h" 0055 #include "Filter.h" 0056 #include "InfoObject.h" 0057 #include "Resource.h" 0058 0059 Krita* Krita::s_instance = 0; 0060 0061 struct Krita::Private { 0062 Private() {} 0063 QList<Extension*> extensions; 0064 bool batchMode {false}; 0065 Notifier *notifier{new Notifier()}; 0066 }; 0067 0068 Krita::Krita(QObject *parent) 0069 : QObject(parent) 0070 , d(new Private) 0071 { 0072 qRegisterMetaType<Notifier*>(); 0073 connect(KisPart::instance(), SIGNAL(sigMainWindowIsBeingCreated(KisMainWindow*)), SLOT(mainWindowIsBeingCreated(KisMainWindow*))); 0074 } 0075 0076 Krita::~Krita() 0077 { 0078 qDeleteAll(d->extensions); 0079 delete d->notifier; 0080 delete d; 0081 } 0082 0083 QList<QAction *> Krita::actions() const 0084 { 0085 KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow(); 0086 if (!mainWindow) { 0087 return QList<QAction*>(); 0088 } 0089 KisKActionCollection *actionCollection = mainWindow->actionCollection(); 0090 return actionCollection->actions(); 0091 } 0092 0093 QAction *Krita::action(const QString &name) const 0094 { 0095 KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow(); 0096 if (!mainWindow) { 0097 return 0; 0098 } 0099 KisKActionCollection *actionCollection = mainWindow->actionCollection(); 0100 QAction *action = actionCollection->action(name); 0101 return action; 0102 } 0103 0104 Document* Krita::activeDocument() const 0105 { 0106 KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow(); 0107 if (!mainWindow) { 0108 return 0; 0109 } 0110 KisView *view = mainWindow->activeView(); 0111 if (!view) { 0112 return 0; 0113 } 0114 KisDocument *document = view->document(); 0115 Document *d = new Document(document, false); 0116 return d; 0117 } 0118 0119 void Krita::setActiveDocument(Document* value) 0120 { 0121 Q_FOREACH(KisView *view, KisPart::instance()->views()) { 0122 if (view->document() == value->document().data()) { 0123 view->activateWindow(); 0124 break; 0125 } 0126 } 0127 } 0128 0129 bool Krita::batchmode() const 0130 { 0131 return d->batchMode; 0132 } 0133 0134 void Krita::setBatchmode(bool value) 0135 { 0136 d->batchMode = value; 0137 } 0138 0139 0140 QList<Document *> Krita::documents() const 0141 { 0142 QList<Document *> ret; 0143 foreach(QPointer<KisDocument> doc, KisPart::instance()->documents()) { 0144 ret << new Document(doc, false); 0145 } 0146 return ret; 0147 } 0148 0149 QStringList Krita::filters() const 0150 { 0151 QStringList ls = KisFilterRegistry::instance()->keys(); 0152 std::sort(ls.begin(), ls.end()); 0153 return ls; 0154 } 0155 0156 Filter *Krita::filter(const QString &name) const 0157 { 0158 if (!filters().contains(name)) return 0; 0159 0160 Filter *filter = new Filter(); 0161 filter->setName(name); 0162 KisFilterSP f = KisFilterRegistry::instance()->value(name); 0163 KisFilterConfigurationSP fc = f->defaultConfiguration(KisGlobalResourcesInterface::instance()); 0164 InfoObject *info = new InfoObject(fc); 0165 filter->setConfiguration(info); 0166 return filter; 0167 } 0168 0169 QStringList Krita::colorModels() const 0170 { 0171 QSet<QString> colorModelsIds; 0172 QList<KoID> ids = KoColorSpaceRegistry::instance()->colorModelsList(KoColorSpaceRegistry::AllColorSpaces); 0173 Q_FOREACH(KoID id, ids) { 0174 colorModelsIds << id.id(); 0175 } 0176 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0) 0177 return QStringList(colorModelsIds.begin(), colorModelsIds.end()); 0178 #else 0179 return QStringList::fromSet(colorModelsIds); 0180 #endif 0181 } 0182 0183 QStringList Krita::colorDepths(const QString &colorModel) const 0184 { 0185 QSet<QString> colorDepthsIds; 0186 QList<KoID> ids = KoColorSpaceRegistry::instance()->colorDepthList(colorModel, KoColorSpaceRegistry::AllColorSpaces); 0187 Q_FOREACH(KoID id, ids) { 0188 colorDepthsIds << id.id(); 0189 } 0190 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0) 0191 return QStringList(colorDepthsIds.begin(), colorDepthsIds.end()); 0192 #else 0193 return QStringList::fromSet(colorDepthsIds); 0194 #endif 0195 } 0196 0197 QStringList Krita::filterStrategies() const 0198 { 0199 return KisFilterStrategyRegistry::instance()->keys(); 0200 } 0201 0202 QStringList Krita::profiles(const QString &colorModel, const QString &colorDepth) const 0203 { 0204 QSet<QString> profileNames; 0205 QString id = KoColorSpaceRegistry::instance()->colorSpaceId(colorModel, colorDepth); 0206 QList<const KoColorProfile *> profiles = KoColorSpaceRegistry::instance()->profilesFor(id); 0207 Q_FOREACH(const KoColorProfile *profile, profiles) { 0208 profileNames << profile->name(); 0209 } 0210 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0) 0211 QStringList r(profileNames.begin(), profileNames.end()); 0212 #else 0213 QStringList r = QStringList::fromSet(profileNames); 0214 #endif 0215 r.sort(); 0216 return r; 0217 } 0218 0219 bool Krita::addProfile(const QString &profilePath) 0220 { 0221 KoColorSpaceEngine *iccEngine = KoColorSpaceEngineRegistry::instance()->get("icc"); 0222 KIS_ASSERT(iccEngine); 0223 return iccEngine->addProfile(profilePath); 0224 } 0225 0226 Notifier* Krita::notifier() const 0227 { 0228 return d->notifier; 0229 } 0230 0231 QString Krita::version() const 0232 { 0233 return KritaVersionWrapper::versionString(true); 0234 } 0235 0236 QList<View *> Krita::views() const 0237 { 0238 QList<View *> ret; 0239 foreach(QPointer<KisView> view, KisPart::instance()->views()) { 0240 ret << new View(view); 0241 } 0242 return ret; 0243 } 0244 0245 Window *Krita::activeWindow() const 0246 { 0247 KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow(); 0248 if (!mainWindow) { 0249 return 0; 0250 } 0251 return new Window(mainWindow); 0252 } 0253 0254 QList<Window*> Krita::windows() const 0255 { 0256 QList<Window*> ret; 0257 foreach(QPointer<KisMainWindow> mainWin, KisPart::instance()->mainWindows()) { 0258 ret << new Window(mainWin); 0259 } 0260 return ret; 0261 } 0262 0263 QMap<QString, Resource*> Krita::resources(QString &type) const 0264 { 0265 QMap<QString, Resource*> resources; 0266 KisResourceModel *resourceModel = 0; 0267 if (type == "pattern") { 0268 resourceModel = KoResourceServerProvider::instance()->patternServer()->resourceModel(); 0269 type = ResourceType::Patterns; 0270 } 0271 else if (type == "gradient") { 0272 type = ResourceType::Gradients; 0273 resourceModel = KoResourceServerProvider::instance()->gradientServer()->resourceModel(); 0274 } 0275 else if (type == "brush") { 0276 resourceModel = KisBrushServerProvider::instance()->brushServer()->resourceModel(); 0277 type = ResourceType::Brushes; 0278 } 0279 else if (type == "palette") { 0280 resourceModel = KoResourceServerProvider::instance()->paletteServer()->resourceModel(); 0281 type = ResourceType::Palettes; 0282 } 0283 else if (type == "workspace") { 0284 resourceModel = KisResourceServerProvider::instance()->workspaceServer()->resourceModel(); 0285 type = ResourceType::Workspaces; 0286 } 0287 else if (type == "preset") { 0288 resourceModel = KisResourceServerProvider::instance()->paintOpPresetServer()->resourceModel(); 0289 } 0290 0291 if (resourceModel) { 0292 for (int i = 0; i < resourceModel->rowCount(); ++i) { 0293 0294 QModelIndex idx = resourceModel->index(i, 0); 0295 int id = resourceModel->data(idx, Qt::UserRole + KisAbstractResourceModel::Id).toInt(); 0296 QString name = resourceModel->data(idx, Qt::UserRole + KisAbstractResourceModel::Name).toString(); 0297 QString filename = resourceModel->data(idx, Qt::UserRole + KisAbstractResourceModel::Filename).toString(); 0298 QImage image = resourceModel->data(idx, Qt::UserRole + KisAbstractResourceModel::Thumbnail).value<QImage>(); 0299 0300 resources[name] = new Resource(id, type, name, filename, image, 0); 0301 } 0302 } 0303 0304 return resources; 0305 } 0306 0307 0308 QList<QDockWidget*> Krita::dockers() const 0309 { 0310 KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow(); 0311 return mainWindow->dockWidgets(); 0312 } 0313 0314 0315 QStringList Krita::recentDocuments() const 0316 { 0317 KConfigGroup grp = KSharedConfig::openConfig()->group(QString("RecentFiles")); 0318 QStringList keys = grp.keyList(); 0319 QStringList recentDocuments; 0320 0321 for(int i = 0; i <= keys.filter("File").count(); i++) 0322 recentDocuments << grp.readEntry(QString("File%1").arg(i), QString("")); 0323 0324 return recentDocuments; 0325 } 0326 0327 Document* Krita::createDocument(int width, int height, const QString &name, const QString &colorModel, const QString &colorDepth, const QString &profile, double resolution) 0328 { 0329 KisDocument *document = KisPart::instance()->createDocument(); 0330 document->setObjectName(name); 0331 0332 KisPart::instance()->addDocument(document, false); 0333 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(colorModel, colorDepth, profile); 0334 Q_ASSERT(cs); 0335 0336 QColor qc(Qt::white); 0337 KoColor bgColor(qc, cs); 0338 0339 if (!document->newImage(name, width, height, cs, bgColor, KisConfig::RASTER_LAYER, 1, "", double(resolution / 72) )) { 0340 return 0; 0341 } 0342 0343 Q_ASSERT(document->image()); 0344 Document *doc = new Document(document, true); 0345 0346 return doc; 0347 } 0348 0349 Document* Krita::openDocument(const QString &filename) 0350 { 0351 KisDocument *document = KisPart::instance()->createDocument(); 0352 document->setFileBatchMode(this->batchmode()); 0353 if (!document->openPath(filename, KisDocument::DontAddToRecent)) { 0354 delete document; 0355 return 0; 0356 } 0357 KisPart::instance()->addDocument(document); 0358 document->setFileBatchMode(false); 0359 return new Document(document, true); 0360 } 0361 0362 Window* Krita::openWindow() 0363 { 0364 KisMainWindow *mw = KisPart::instance()->createMainWindow(); 0365 return new Window(mw); 0366 } 0367 0368 void Krita::addExtension(Extension* extension) 0369 { 0370 d->extensions.append(extension); 0371 } 0372 0373 QList< Extension* > Krita::extensions() 0374 { 0375 return d->extensions; 0376 } 0377 0378 void Krita::writeSetting(const QString &group, const QString &name, const QString &value) 0379 { 0380 KConfigGroup grp = KSharedConfig::openConfig()->group(group); 0381 grp.writeEntry(name, value); 0382 } 0383 0384 QString Krita::readSetting(const QString &group, const QString &name, const QString &defaultValue) 0385 { 0386 KConfigGroup grp = KSharedConfig::openConfig()->group(group); 0387 return grp.readEntry(name, defaultValue); 0388 } 0389 0390 QIcon Krita::icon(QString &iconName) const 0391 { 0392 return KisIconUtils::loadIcon(iconName); 0393 } 0394 0395 void Krita::addDockWidgetFactory(DockWidgetFactoryBase* factory) 0396 { 0397 KoDockRegistry::instance()->add(factory); 0398 } 0399 0400 Krita* Krita::instance() 0401 { 0402 if (!s_instance) 0403 { 0404 s_instance = new Krita; 0405 } 0406 return s_instance; 0407 } 0408 0409 /** 0410 * Scripter.fromVariant(variant) 0411 * variant is a QVariant 0412 * returns instance of QObject-subclass 0413 * 0414 * This is a helper method for PyQt because PyQt cannot cast a variant to a QObject or QWidget 0415 */ 0416 QObject *Krita::fromVariant(const QVariant& v) 0417 { 0418 0419 if (v.canConvert< QWidget* >()) 0420 { 0421 QObject* obj = qvariant_cast< QWidget* >(v); 0422 return obj; 0423 } 0424 else if (v.canConvert< QObject* >()) 0425 { 0426 QObject* obj = qvariant_cast< QObject* >(v); 0427 return obj; 0428 } 0429 else 0430 return 0; 0431 } 0432 0433 QString Krita::krita_i18n(const QString &text) 0434 { 0435 return i18n(text.toUtf8().constData()); 0436 } 0437 0438 QString Krita::krita_i18nc(const QString &context, const QString &text) 0439 { 0440 return i18nc(context.toUtf8().constData(), text.toUtf8().constData()); 0441 } 0442 0443 QString Krita::getAppDataLocation() 0444 { 0445 return KoResourcePaths::getAppDataLocation(); 0446 } 0447 0448 void Krita::mainWindowIsBeingCreated(KisMainWindow *kisWindow) 0449 { 0450 Q_FOREACH(Extension *extension, d->extensions) { 0451 Window window(kisWindow); 0452 extension->createActions(&window); 0453 } 0454 } 0455 0456 #include "moc_Krita.cpp"