diff --git a/libs/ui/input/kis_input_manager.cpp b/libs/ui/input/kis_input_manager.cpp index 30a1aa97a8..1aa0e0bc29 100644 --- a/libs/ui/input/kis_input_manager.cpp +++ b/libs/ui/input/kis_input_manager.cpp @@ -1,688 +1,688 @@ /* This file is part of the KDE project * * Copyright (C) 2012 Arjen Hiemstra * Copyright (C) 2015 Michael Abrahams * * 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 "kis_input_manager.h" #include #include #include #include #include #include #include #include "kis_tool_proxy.h" #include #include #include #include #include #include #include "kis_abstract_input_action.h" #include "kis_tool_invocation_action.h" #include "kis_pan_action.h" #include "kis_alternate_invocation_action.h" #include "kis_rotate_canvas_action.h" #include "kis_zoom_action.h" #include "kis_show_palette_action.h" #include "kis_change_primary_setting_action.h" #include "kis_shortcut_matcher.h" #include "kis_stroke_shortcut.h" #include "kis_single_action_shortcut.h" #include "kis_touch_shortcut.h" #include "kis_input_profile.h" #include "kis_input_profile_manager.h" #include "kis_shortcut_configuration.h" #include #include #include "kis_extended_modifiers_mapper.h" #include "kis_input_manager_p.h" template uint qHash(QPointer value) { return reinterpret_cast(value.data()); } KisInputManager::KisInputManager(QObject *parent) : QObject(parent), d(new Private(this)) { d->setupActions(); connect(KoToolManager::instance(), SIGNAL(aboutToChangeTool(KoCanvasController*)), SLOT(slotAboutToChangeTool())); connect(KoToolManager::instance(), SIGNAL(changedTool(KoCanvasController*,int)), SLOT(slotToolChanged())); connect(&d->moveEventCompressor, SIGNAL(timeout()), SLOT(slotCompressedMoveEvent())); QApplication::instance()-> installEventFilter(new Private::ProximityNotifier(d, this)); } KisInputManager::~KisInputManager() { delete d; } void KisInputManager::addTrackedCanvas(KisCanvas2 *canvas) { d->canvasSwitcher.addCanvas(canvas); } void KisInputManager::removeTrackedCanvas(KisCanvas2 *canvas) { d->canvasSwitcher.removeCanvas(canvas); } void KisInputManager::toggleTabletLogger() { KisTabletDebugger::instance()->toggleDebugging(); } void KisInputManager::attachPriorityEventFilter(QObject *filter, int priority) { Private::PriorityList::iterator begin = d->priorityEventFilter.begin(); Private::PriorityList::iterator it = begin; Private::PriorityList::iterator end = d->priorityEventFilter.end(); it = std::find_if(begin, end, [filter] (const Private::PriorityPair &a) { return a.second == filter; }); if (it != end) return; it = std::find_if(begin, end, [priority] (const Private::PriorityPair &a) { return a.first > priority; }); d->priorityEventFilter.insert(it, qMakePair(priority, filter)); d->priorityEventFilterSeqNo++; } void KisInputManager::detachPriorityEventFilter(QObject *filter) { Private::PriorityList::iterator it = d->priorityEventFilter.begin(); Private::PriorityList::iterator end = d->priorityEventFilter.end(); it = std::find_if(it, end, [filter] (const Private::PriorityPair &a) { return a.second == filter; }); if (it != end) { d->priorityEventFilter.erase(it); } } void KisInputManager::setupAsEventFilter(QObject *receiver) { if (d->eventsReceiver) { d->eventsReceiver->removeEventFilter(this); } d->eventsReceiver = receiver; if (d->eventsReceiver) { d->eventsReceiver->installEventFilter(this); } } void KisInputManager::stopIgnoringEvents() { d->allowMouseEvents(); } #if defined (__clang__) #pragma GCC diagnostic ignored "-Wswitch" #endif bool KisInputManager::eventFilter(QObject* object, QEvent* event) { if (object != d->eventsReceiver) return false; if (d->eventEater.eventFilter(object, event)) return false; if (!d->matcher.hasRunningShortcut()) { int savedPriorityEventFilterSeqNo = d->priorityEventFilterSeqNo; for (auto it = d->priorityEventFilter.begin(); it != d->priorityEventFilter.end(); /*noop*/) { const QPointer &filter = it->second; if (filter.isNull()) { it = d->priorityEventFilter.erase(it); d->priorityEventFilterSeqNo++; savedPriorityEventFilterSeqNo++; continue; } if (filter->eventFilter(object, event)) return true; /** * If the filter removed itself from the filters list or * added something there, just exit the loop */ if (d->priorityEventFilterSeqNo != savedPriorityEventFilterSeqNo) { return true; } ++it; } // KoToolProxy needs to pre-process some events to ensure the // global shortcuts (not the input manager's ones) are not // executed, in particular, this line will accept events when the // tool is in text editing, preventing shortcut triggering if (d->toolProxy) { d->toolProxy->processEvent(event); } } // Continue with the actual switch statement... return eventFilterImpl(event); } template bool KisInputManager::compressMoveEventCommon(Event *event) { /** * We construct a copy of this event object, so we must ensure it * has a correct type. */ static_assert(std::is_same::value || std::is_same::value, "event should be a mouse or a tablet event"); bool retval = false; /** * Compress the events if the tool doesn't need high resolution input */ if ((event->type() == QEvent::MouseMove || event->type() == QEvent::TabletMove) && (!d->matcher.supportsHiResInputEvents() || d->testingCompressBrushEvents)) { d->compressedMoveEvent.reset(new Event(*event)); d->moveEventCompressor.start(); /** * On Linux Qt eats the rest of unneeded events if we * ignore the first of the chunk of tablet events. So * generally we should never activate this feature. Only * for testing purposes! */ if (d->testingAcceptCompressedTabletEvents) { event->setAccepted(true); } retval = true; } else { slotCompressedMoveEvent(); retval = d->handleCompressedTabletEvent(event); } return retval; } bool KisInputManager::eventFilterImpl(QEvent * event) { bool retval = false; if (event->type() != QEvent::Wheel) { d->accumulatedScrollDelta = 0; } switch (event->type()) { case QEvent::MouseButtonPress: case QEvent::MouseButtonDblClick: { d->debugEvent(event); //Block mouse press events on Genius tablets if (d->tabletActive) break; if (d->ignoringQtCursorEvents()) break; if (d->touchHasBlockedPressEvents) break; QMouseEvent *mouseEvent = static_cast(event); if (d->tryHidePopupPalette()) { retval = true; } else { //Make sure the input actions know we are active. KisAbstractInputAction::setInputManager(this); retval = d->matcher.buttonPressed(mouseEvent->button(), mouseEvent); } //Reset signal compressor to prevent processing events before press late d->resetCompressor(); event->setAccepted(retval); break; } case QEvent::MouseButtonRelease: { d->debugEvent(event); if (d->ignoringQtCursorEvents()) break; if (d->touchHasBlockedPressEvents) break; QMouseEvent *mouseEvent = static_cast(event); retval = d->matcher.buttonReleased(mouseEvent->button(), mouseEvent); event->setAccepted(retval); break; } case QEvent::ShortcutOverride: { d->debugEvent(event); QKeyEvent *keyEvent = static_cast(event); Qt::Key key = KisExtendedModifiersMapper::workaroundShiftAltMetaHell(keyEvent); if (!keyEvent->isAutoRepeat()) { retval = d->matcher.keyPressed(key); } else { retval = d->matcher.autoRepeatedKeyPressed(key); } /** * Workaround for temporary switching of tools by * KoCanvasControllerWidget. We don't need this switch because * we handle it ourselves. */ retval |= !d->forwardAllEventsToTool && (keyEvent->key() == Qt::Key_Space || keyEvent->key() == Qt::Key_Escape); break; } case QEvent::KeyRelease: { d->debugEvent(event); QKeyEvent *keyEvent = static_cast(event); if (!keyEvent->isAutoRepeat()) { Qt::Key key = KisExtendedModifiersMapper::workaroundShiftAltMetaHell(keyEvent); retval = d->matcher.keyReleased(key); } break; } case QEvent::MouseMove: { d->debugEvent(event); if (d->ignoringQtCursorEvents()) break; QMouseEvent *mouseEvent = static_cast(event); retval = compressMoveEventCommon(mouseEvent); break; } case QEvent::Wheel: { d->debugEvent(event); QWheelEvent *wheelEvent = static_cast(event); #ifdef Q_OS_OSX // Some QT wheel events are actually touch pad pan events. From the QT docs: // "Wheel events are generated for both mouse wheels and trackpad scroll gestures." // We differentiate between touchpad events and real mouse wheels by inspecting the // event source. if (wheelEvent->source() == Qt::MouseEventSource::MouseEventSynthesizedBySystem) { KisAbstractInputAction::setInputManager(this); retval = d->matcher.wheelEvent(KisSingleActionShortcut::WheelTrackpad, wheelEvent); break; } #endif d->accumulatedScrollDelta += wheelEvent->delta(); KisSingleActionShortcut::WheelAction action; /** * Ignore delta 0 events on OSX, since they are triggered by tablet * proximity when using Wacom devices. */ #ifdef Q_OS_OSX if(wheelEvent->delta() == 0) { retval = true; break; } #endif if (wheelEvent->orientation() == Qt::Horizontal) { if(wheelEvent->delta() < 0) { action = KisSingleActionShortcut::WheelRight; } else { action = KisSingleActionShortcut::WheelLeft; } } else { if(wheelEvent->delta() > 0) { action = KisSingleActionShortcut::WheelUp; } else { action = KisSingleActionShortcut::WheelDown; } } if (qAbs(d->accumulatedScrollDelta) >= QWheelEvent::DefaultDeltasPerStep) { //Make sure the input actions know we are active. KisAbstractInputAction::setInputManager(this); retval = d->matcher.wheelEvent(action, wheelEvent); d->accumulatedScrollDelta = 0; } else { retval = true; } break; } case QEvent::Enter: d->debugEvent(event); //Make sure the input actions know we are active. KisAbstractInputAction::setInputManager(this); if (!d->containsPointer) { d->containsPointer = true; d->allowMouseEvents(); d->touchHasBlockedPressEvents = false; } d->matcher.enterEvent(); break; case QEvent::Leave: d->debugEvent(event); d->containsPointer = false; /** * We won't get a TabletProximityLeave event when the tablet * is hovering above some other widget, so restore cursor * events processing right now. */ d->allowMouseEvents(); d->touchHasBlockedPressEvents = false; d->matcher.leaveEvent(); break; case QEvent::FocusIn: d->debugEvent(event); KisAbstractInputAction::setInputManager(this); //Clear all state so we don't have half-matched shortcuts dangling around. d->matcher.reinitialize(); { // Emulate pressing of the key that are already pressed KisExtendedModifiersMapper mapper; Qt::KeyboardModifiers modifiers = mapper.queryStandardModifiers(); Q_FOREACH (Qt::Key key, mapper.queryExtendedModifiers()) { QKeyEvent kevent(QEvent::ShortcutOverride, key, modifiers); eventFilterImpl(&kevent); } } d->allowMouseEvents(); break; case QEvent::FocusOut: { d->debugEvent(event); KisAbstractInputAction::setInputManager(this); QPointF currentLocalPos = canvas()->canvasWidget()->mapFromGlobal(QCursor::pos()); d->matcher.lostFocusEvent(currentLocalPos); break; } case QEvent::TabletPress: { d->debugEvent(event); QTabletEvent *tabletEvent = static_cast(event); if (d->tryHidePopupPalette()) { retval = true; } else { //Make sure the input actions know we are active. KisAbstractInputAction::setInputManager(this); retval = d->matcher.buttonPressed(tabletEvent->button(), tabletEvent); if (!d->containsPointer) { d->containsPointer = true; d->touchHasBlockedPressEvents = false; } } event->setAccepted(true); retval = true; d->blockMouseEvents(); //Reset signal compressor to prevent processing events before press late d->resetCompressor(); d->eatOneMousePress(); break; } case QEvent::TabletMove: { d->debugEvent(event); QTabletEvent *tabletEvent = static_cast(event); retval = compressMoveEventCommon(tabletEvent); if (d->tabletLatencyTracker) { d->tabletLatencyTracker->push(tabletEvent->timestamp()); } /** * The flow of tablet events means the tablet is in the * proximity area, so activate it even when the * TabletEnterProximity event was missed (may happen when * changing focus of the window with tablet in the proximity * area) */ d->blockMouseEvents(); break; } case QEvent::TabletRelease: { #ifdef Q_OS_MAC d->allowMouseEvents(); #endif d->debugEvent(event); QTabletEvent *tabletEvent = static_cast(event); retval = d->matcher.buttonReleased(tabletEvent->button(), tabletEvent); retval = true; event->setAccepted(true); break; } case QEvent::TouchBegin: { if (startTouch(retval)) { QTouchEvent *tevent = static_cast(event); KisAbstractInputAction::setInputManager(this); retval = d->matcher.touchBeginEvent(tevent); event->accept(); } break; } case QEvent::TouchUpdate: { QTouchEvent *tevent = static_cast(event); #ifdef Q_OS_MAC int count = 0; Q_FOREACH (const QTouchEvent::TouchPoint &point, tevent->touchPoints()) { if (point.state() != Qt::TouchPointReleased) { count++; } } if (count < 2 && tevent->touchPoints().length() > count) { d->touchHasBlockedPressEvents = false; retval = d->matcher.touchEndEvent(tevent); } else { #endif d->touchHasBlockedPressEvents = KisConfig(true).disableTouchOnCanvas(); KisAbstractInputAction::setInputManager(this); retval = d->matcher.touchUpdateEvent(tevent); #ifdef Q_OS_OSX } #endif event->accept(); break; } case QEvent::TouchEnd: { endTouch(); QTouchEvent *tevent = static_cast(event); retval = d->matcher.touchEndEvent(tevent); event->accept(); break; } case QEvent::NativeGesture: { QNativeGestureEvent *gevent = static_cast(event); switch (gevent->gestureType()) { case Qt::BeginNativeGesture: { if (startTouch(retval)) { KisAbstractInputAction::setInputManager(this); retval = d->matcher.nativeGestureBeginEvent(gevent); event->accept(); } break; } case Qt::EndNativeGesture: { endTouch(); retval = d->matcher.nativeGestureEndEvent(gevent); event->accept(); break; } default: { KisAbstractInputAction::setInputManager(this); retval = d->matcher.nativeGestureEvent(gevent); event->accept(); break; } } break; } default: break; } return !retval ? d->processUnhandledEvent(event) : true; } bool KisInputManager::startTouch(bool &retval) { d->touchHasBlockedPressEvents = KisConfig(true).disableTouchOnCanvas(); // Touch rejection: if touch is disabled on canvas, no need to block mouse press events if (KisConfig(true).disableTouchOnCanvas()) { d->eatOneMousePress(); } if (d->tryHidePopupPalette()) { retval = true; return false; } else { return true; } } void KisInputManager::endTouch() { d->touchHasBlockedPressEvents = false; } void KisInputManager::slotCompressedMoveEvent() { if (d->compressedMoveEvent) { // d->touchHasBlockedPressEvents = false; (void) d->handleCompressedTabletEvent(d->compressedMoveEvent.data()); d->compressedMoveEvent.reset(); - dbgInput << "Compressed move event received."; + //dbgInput << "Compressed move event received."; } else { - dbgInput << "Unexpected empty move event"; + //dbgInput << "Unexpected empty move event"; } } KisCanvas2* KisInputManager::canvas() const { return d->canvas; } QPointer KisInputManager::toolProxy() const { return d->toolProxy; } void KisInputManager::slotAboutToChangeTool() { QPointF currentLocalPos; if (canvas() && canvas()->canvasWidget()) { currentLocalPos = canvas()->canvasWidget()->mapFromGlobal(QCursor::pos()); } d->matcher.lostFocusEvent(currentLocalPos); } void KisInputManager::slotToolChanged() { if (!d->canvas) return; KoToolManager *toolManager = KoToolManager::instance(); KoToolBase *tool = toolManager->toolById(canvas(), toolManager->activeToolId()); if (tool) { d->setMaskSyntheticEvents(tool->maskSyntheticEvents()); if (tool->isInTextMode()) { d->forwardAllEventsToTool = true; d->matcher.suppressAllActions(true); } else { d->forwardAllEventsToTool = false; d->matcher.suppressAllActions(false); } } } void KisInputManager::profileChanged() { d->matcher.clearShortcuts(); KisInputProfile *profile = KisInputProfileManager::instance()->currentProfile(); if (profile) { const QList shortcuts = profile->allShortcuts(); for (KisShortcutConfiguration * const shortcut : shortcuts) { dbgUI << "Adding shortcut" << shortcut->keys() << "for action" << shortcut->action()->name(); switch(shortcut->type()) { case KisShortcutConfiguration::KeyCombinationType: d->addKeyShortcut(shortcut->action(), shortcut->mode(), shortcut->keys()); break; case KisShortcutConfiguration::MouseButtonType: d->addStrokeShortcut(shortcut->action(), shortcut->mode(), shortcut->keys(), shortcut->buttons()); break; case KisShortcutConfiguration::MouseWheelType: d->addWheelShortcut(shortcut->action(), shortcut->mode(), shortcut->keys(), shortcut->wheel()); break; case KisShortcutConfiguration::GestureType: if (!d->addNativeGestureShortcut(shortcut->action(), shortcut->mode(), shortcut->gesture())) { d->addTouchShortcut(shortcut->action(), shortcut->mode(), shortcut->gesture()); } break; default: break; } } } else { dbgInput << "No Input Profile Found: canvas interaction will be impossible"; } } diff --git a/plugins/dockers/logdocker/LogDockerDock.cpp b/plugins/dockers/logdocker/LogDockerDock.cpp index 8e6c022048..1f2fc4db9b 100644 --- a/plugins/dockers/logdocker/LogDockerDock.cpp +++ b/plugins/dockers/logdocker/LogDockerDock.cpp @@ -1,338 +1,336 @@ /* * Copyright (c) 2018 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; version 2.1 of the License. * * 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 program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "LogDockerDock.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_canvas2.h" #include "KisViewManager.h" #include "kis_config.h" MessageSender *LogDockerDock::s_messageSender {new MessageSender()}; QTextCharFormat LogDockerDock::s_debug; QTextCharFormat LogDockerDock::s_info; QTextCharFormat LogDockerDock::s_warning; QTextCharFormat LogDockerDock::s_critical; QTextCharFormat LogDockerDock::s_fatal; LogDockerDock::LogDockerDock( ) : QDockWidget(i18n("Log Viewer")) { QWidget *page = new QWidget(this); setupUi(page); setWidget(page); bnToggle->setIcon(koIcon("view-list-text")); connect(bnToggle, SIGNAL(clicked(bool)), SLOT(toggleLogging(bool))); bnToggle->setChecked(KisConfig(true).readEntry("logviewer_enabled", false)); toggleLogging(KisConfig(true).readEntry("logviewer_enabled", false)); bnClear->setIcon(koIcon("edit-clear")); connect(bnClear, SIGNAL(clicked(bool)), SLOT(clearLog())); bnSave->setIcon(koIcon("document-save")); connect(bnSave, SIGNAL(clicked(bool)), SLOT(saveLog())); bnSettings->setIcon(koIcon("configure")); connect(bnSettings, SIGNAL(clicked(bool)), SLOT(settings())); qRegisterMetaType("QtMsgType"); connect(s_messageSender, SIGNAL(emitMessage(QtMsgType,QString)), this, SLOT(insertMessage(QtMsgType,QString)), Qt::AutoConnection); applyCategories(); changeTheme(); } void LogDockerDock::setCanvas(KoCanvasBase *) { setEnabled(true); } void LogDockerDock::setViewManager(KisViewManager *kisview) { connect(static_cast(kisview->mainWindow()), SIGNAL(themeChanged()), SLOT(changeTheme())); } void LogDockerDock::toggleLogging(bool toggle) { KisConfig(false).writeEntry("logviewer_enabled", toggle); if (toggle) { qInstallMessageHandler(messageHandler); applyCategories(); } else { qInstallMessageHandler(0); } } void LogDockerDock::clearLog() { txtLogViewer->document()->clear(); } void LogDockerDock::saveLog() { KoFileDialog fileDialog(this, KoFileDialog::SaveFile, "logfile"); fileDialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/" + QString("krita_%1.log").arg(QDateTime::currentDateTime().toString())); QString filename = fileDialog.filename(); if (!filename.isEmpty()) { QFile f(filename); f.open(QFile::WriteOnly); f.write(txtLogViewer->document()->toPlainText().toUtf8()); f.close(); } } void LogDockerDock::settings() { KoDialog dlg(this); dlg.setButtons(KoDialog::Ok | KoDialog::Cancel); dlg.setCaption(i18n("Log Settings")); QWidget *page = new QWidget(&dlg); dlg.setMainWidget(page); QVBoxLayout *layout = new QVBoxLayout(page); KConfigGroup cfg( KSharedConfig::openConfig(), "LogDocker"); QCheckBox *chkKrita = new QCheckBox(i18n("General"), page); chkKrita->setChecked(cfg.readEntry("krita_41000", false)); layout->addWidget(chkKrita); QCheckBox *chkResources = new QCheckBox(i18n("Resource Management"), page); chkResources->setChecked(cfg.readEntry("resources_30009", false)); layout->addWidget(chkResources); QCheckBox *chkImage = new QCheckBox(i18n("Image Core"), page); chkImage->setChecked(cfg.readEntry("image_41001", false)); layout->addWidget(chkImage); QCheckBox *chkRegistry = new QCheckBox(i18n("Registries"), page); chkRegistry->setChecked(cfg.readEntry("registry_41002", false)); layout->addWidget(chkRegistry); QCheckBox *chkTools = new QCheckBox(i18n("Tools"), page); chkTools->setChecked(cfg.readEntry("tools_41003", false)); layout->addWidget(chkTools); QCheckBox *chkTiles = new QCheckBox(i18n("Tile Engine"), page); chkTiles->setChecked(cfg.readEntry("tiles_41004", false)); layout->addWidget(chkTiles); QCheckBox *chkFilters = new QCheckBox(i18n("Filters"), page); chkFilters->setChecked(cfg.readEntry("filters_41005", false)); layout->addWidget(chkFilters); QCheckBox *chkPlugins = new QCheckBox(i18n("Plugin Management"), page); chkPlugins->setChecked(cfg.readEntry("plugins_41006", false)); layout->addWidget(chkPlugins); QCheckBox *chkUi = new QCheckBox(i18n("User Interface"), page); chkUi->setChecked(cfg.readEntry("ui_41007", false)); layout->addWidget(chkUi); QCheckBox *chkFile = new QCheckBox(i18n("File loading and saving"), page); chkFile->setChecked(cfg.readEntry("file_41008", false)); layout->addWidget(chkFile); QCheckBox *chkMath = new QCheckBox(i18n("Mathematics and calcuations"), page); chkMath->setChecked(cfg.readEntry("math_41009", false)); layout->addWidget(chkMath); QCheckBox *chkRender = new QCheckBox(i18n("Image Rendering"), page); chkRender->setChecked(cfg.readEntry("render_41010", false)); layout->addWidget(chkRender); QCheckBox *chkScript = new QCheckBox(i18n("Scripting"), page); chkScript->setChecked(cfg.readEntry("script_41011", false)); layout->addWidget(chkScript); QCheckBox *chkInput = new QCheckBox(i18n("Input handling"), page); chkInput->setChecked(cfg.readEntry("input_41012", false)); layout->addWidget(chkInput); QCheckBox *chkAction = new QCheckBox(i18n("Actions"), page); chkAction->setChecked(cfg.readEntry("action_41013", false)); layout->addWidget(chkAction); QCheckBox *chkTablet = new QCheckBox(i18n("Tablet Handling"), page); chkTablet->setChecked(cfg.readEntry("tablet_41014", false)); layout->addWidget(chkTablet); QCheckBox *chkOpenGL = new QCheckBox(i18n("GPU Canvas"), page); chkOpenGL->setChecked(cfg.readEntry("opengl_41015", false)); layout->addWidget(chkOpenGL); QCheckBox *chkMetaData = new QCheckBox(i18n("Metadata"), page); chkMetaData->setChecked(cfg.readEntry("metadata_41016", false)); layout->addWidget(chkMetaData); QCheckBox *chkPigment = new QCheckBox(i18n("Color Management"), page); chkPigment->setChecked(cfg.readEntry("pigment", false)); layout->addWidget(chkPigment); if (dlg.exec()) { // Apply the new settings cfg.writeEntry("resources_30009", chkResources->isChecked()); cfg.writeEntry("krita_41000", chkKrita->isChecked()); cfg.writeEntry("image_41001", chkImage->isChecked()); cfg.writeEntry("registry_41002", chkRegistry->isChecked()); cfg.writeEntry("tools_41003", chkTools->isChecked()); cfg.writeEntry("tiles_41004", chkTiles->isChecked()); cfg.writeEntry("filters_41005", chkFilters->isChecked()); cfg.writeEntry("plugins_41006", chkPlugins->isChecked()); cfg.writeEntry("ui_41007", chkUi->isChecked()); cfg.writeEntry("file_41008", chkFile->isChecked()); cfg.writeEntry("math_41009", chkMath->isChecked()); cfg.writeEntry("render_41010", chkRender->isChecked()); cfg.writeEntry("script_41011", chkScript->isChecked()); cfg.writeEntry("input_41012", chkInput->isChecked()); cfg.writeEntry("action_41013", chkAction->isChecked()); cfg.writeEntry("tablet_41014", chkTablet->isChecked()); cfg.writeEntry("opengl_41015", chkOpenGL->isChecked()); cfg.writeEntry("metadata_41016", chkMetaData->isChecked()); cfg.writeEntry("pigment", chkPigment->isChecked()); applyCategories(); } } QString cfgToString(QString tpl, bool cfg) { return tpl.arg(cfg ? "true" : "false"); } void LogDockerDock::applyCategories() { QStringList filters; KConfigGroup cfg( KSharedConfig::openConfig(), "LogDocker"); filters << cfgToString("krita.general=%1", cfg.readEntry("krita_41000", false)); filters << cfgToString("krita.lib.resources=%1", cfg.readEntry("resources_30009", false)); filters << cfgToString("krita.core=%1", cfg.readEntry("image_41001", false)); filters << cfgToString("krita.registry=%1", cfg.readEntry("registry_41002", false)); filters << cfgToString("krita.tools=%1", cfg.readEntry("tools_41003", false)); filters << cfgToString("krita.lib.flake=%1", cfg.readEntry("tools_41003", false)); filters << cfgToString("krita.tiles=%1", cfg.readEntry("tiles_41004", false)); filters << cfgToString("krita.filters=%1", cfg.readEntry("filters_41005", false)); filters << cfgToString("krita.plugins=%1", cfg.readEntry("plugins_41006", false)); filters << cfgToString("krita.lib.plugin=%1", cfg.readEntry("plugins_41006", false)); filters << cfgToString("krita.ui=%1", cfg.readEntry("ui_41007", false)); filters << cfgToString("krita.widgets=%1", cfg.readEntry("ui_41007", false)); filters << cfgToString("krita.widgetutils=%1", cfg.readEntry("ui_41007", false)); filters << cfgToString("krita.file=%1", cfg.readEntry("file_41008", false)); filters << cfgToString("krita.lib.store=%1", cfg.readEntry("file_41008", false)); filters << cfgToString("krita.lib.odf=%1", cfg.readEntry("file_41008", false)); filters << cfgToString("krita.math=%1", cfg.readEntry("math_41009", false)); filters << cfgToString("krita.grender=%1", cfg.readEntry("render_41010", false)); filters << cfgToString("krita.scripting=%1", cfg.readEntry("script_41011", false)); filters << cfgToString("krita.input=%1", cfg.readEntry("input_41012", false)); filters << cfgToString("krita.action=%1", cfg.readEntry("action_41013", false)); filters << cfgToString("krita.tablet=%1", cfg.readEntry("tablet_41014", false)); filters << cfgToString("krita.opengl=%1", cfg.readEntry("opengl_41015", false)); filters << cfgToString("krita.metadata=%1", cfg.readEntry("metadata_41016", false)); filters << cfgToString("krita.lib.pigment=%1", cfg.readEntry("pigment", false)); - qDebug() << filters.join("\n"); - QLoggingCategory::setFilterRules(filters.join("\n")); } void LogDockerDock::messageHandler(QtMsgType type, const QMessageLogContext &/*context*/, const QString &msg) { s_messageSender->sendMessage(type, msg); } void LogDockerDock::insertMessage(QtMsgType type, const QString &msg) { QTextDocument *doc = txtLogViewer->document(); QTextCursor cursor(doc); cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); cursor.beginEditBlock(); switch (type) { case QtDebugMsg: cursor.insertText(msg + "\n", s_debug); break; case QtInfoMsg: cursor.insertText(msg + "\n", s_info); break; case QtWarningMsg: cursor.insertText(msg + "\n", s_warning); break; case QtCriticalMsg: cursor.insertText(msg + "\n", s_critical); break; case QtFatalMsg: cursor.insertText(msg + "\n", s_fatal); break; } cursor.endEditBlock(); txtLogViewer->verticalScrollBar()->setValue(txtLogViewer->verticalScrollBar()->maximum()); } void LogDockerDock::changeTheme() { clearLog(); QColor background = qApp->palette().background().color(); if (background.value() > 100) { s_debug.setForeground(Qt::black); s_info.setForeground(Qt::darkGreen); s_warning.setForeground(Qt::darkYellow); s_critical.setForeground(Qt::darkRed); s_fatal.setForeground(Qt::darkRed); } else { s_debug.setForeground(Qt::white); s_info.setForeground(Qt::green); s_warning.setForeground(Qt::yellow); s_critical.setForeground(Qt::red); s_fatal.setForeground(Qt::red); } s_fatal.setFontWeight(QFont::Bold); } void MessageSender::sendMessage(QtMsgType type, const QString &msg) { emit emitMessage(type, msg); }