diff --git a/krita/data/cursors/cursor-pixel-black.xpm b/krita/data/cursors/cursor-pixel-black.xpm
new file mode 100644
index 0000000000..95d479668b
--- /dev/null
+++ b/krita/data/cursors/cursor-pixel-black.xpm
@@ -0,0 +1,37 @@
+/* XPM */
+static char *dummy[]={
+"31 31 3 1",
+". c None",
+"# c None",
+"a c #000000",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"..............###..............",
+"..............#a#..............",
+"..............###..............",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"..............................."};
diff --git a/krita/data/cursors/cursor-pixel-white.xpm b/krita/data/cursors/cursor-pixel-white.xpm
new file mode 100644
index 0000000000..f6c61df628
--- /dev/null
+++ b/krita/data/cursors/cursor-pixel-white.xpm
@@ -0,0 +1,37 @@
+/* XPM */
+static char *dummy[]={
+"31 31 3 1",
+". c None",
+"# c None",
+"a c #ffffff",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"..............###..............",
+"...............a...............",
+"..............###..............",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"...............................",
+"..............................."};
diff --git a/krita/data/cursors/cursors.qrc b/krita/data/cursors/cursors.qrc
index 26896e33ee..fb52b2dbc9 100644
--- a/krita/data/cursors/cursors.qrc
+++ b/krita/data/cursors/cursors.qrc
@@ -1,21 +1,23 @@
color-picker_image_background.xpm
color-picker_image_foreground.xpm
color-picker_layer_background.xpm
color-picker_layer_foreground.xpm
cursor-cross.xpm
+ cursor-pixel-white.xpm
+ cursor-pixel-black.xpm
cursor-round.xpm
cursor-triangle_lefthanded.xpm
cursor-triangle_righthanded.xpm
exposure-cursor-gesture.xpm
gamma-cursor-gesture.xpm
precise-pick-layer-icon.xpm
rotate_discrete.xpm
rotate_smooth.xpm
zoom_discrete.xpm
zoom_smooth.xpm
tool_freehand_cursor.png
diff --git a/libs/global/kis_global.h b/libs/global/kis_global.h
index 72f2dcc3c1..cc0811b700 100644
--- a/libs/global/kis_global.h
+++ b/libs/global/kis_global.h
@@ -1,238 +1,240 @@
/*
* Copyright (c) 2000 Matthias Elter
* Copyright (c) 2002 Patrick Julien
*
* 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.
*/
#ifndef KISGLOBAL_H_
#define KISGLOBAL_H_
#include
#include
#include
#include "kis_assert.h"
#include
#include
#define KRITA_VERSION CALLIGRA_VERSION
const quint8 quint8_MAX = UCHAR_MAX;
const quint16 quint16_MAX = 65535;
const qint32 qint32_MAX = (2147483647);
const qint32 qint32_MIN = (-2147483647 - 1);
const quint8 MAX_SELECTED = UCHAR_MAX;
const quint8 MIN_SELECTED = 0;
const quint8 SELECTION_THRESHOLD = 1;
enum OutlineStyle {
OUTLINE_NONE = 0,
OUTLINE_CIRCLE,
OUTLINE_FULL,
OUTLINE_TILT,
OUTLINE_COLOR,
N_OUTLINE_STYLE_SIZE
};
enum CursorStyle {
CURSOR_STYLE_NO_CURSOR = 0,
CURSOR_STYLE_TOOLICON,
CURSOR_STYLE_POINTER,
CURSOR_STYLE_SMALL_ROUND,
CURSOR_STYLE_CROSSHAIR,
CURSOR_STYLE_TRIANGLE_RIGHTHANDED,
CURSOR_STYLE_TRIANGLE_LEFTHANDED,
+ CURSOR_STYLE_BLACK_PIXEL,
+ CURSOR_STYLE_WHITE_PIXEL,
N_CURSOR_STYLE_SIZE
};
enum OldCursorStyle {
OLD_CURSOR_STYLE_TOOLICON = 0,
OLD_CURSOR_STYLE_CROSSHAIR = 1,
OLD_CURSOR_STYLE_POINTER = 2,
OLD_CURSOR_STYLE_OUTLINE = 3,
OLD_CURSOR_STYLE_NO_CURSOR = 4,
OLD_CURSOR_STYLE_SMALL_ROUND = 5,
OLD_CURSOR_STYLE_OUTLINE_CENTER_DOT = 6,
OLD_CURSOR_STYLE_OUTLINE_CENTER_CROSS = 7,
OLD_CURSOR_STYLE_TRIANGLE_RIGHTHANDED = 8,
OLD_CURSOR_STYLE_TRIANGLE_LEFTHANDED = 9,
OLD_CURSOR_STYLE_OUTLINE_TRIANGLE_RIGHTHANDED = 10,
OLD_CURSOR_STYLE_OUTLINE_TRIANGLE_LEFTHANDED = 11
};
/*
* Most wacom pads have 512 levels of pressure; Qt only supports 256, and even
* this is downscaled to 127 levels because the line would be too jittery, and
* the amount of masks take too much memory otherwise.
*/
const qint32 PRESSURE_LEVELS = 127;
const double PRESSURE_MIN = 0.0;
const double PRESSURE_MAX = 1.0;
const double PRESSURE_DEFAULT = PRESSURE_MAX;
const double PRESSURE_THRESHOLD = 5.0 / 255.0;
// copy of lcms.h
#define INTENT_PERCEPTUAL 0
#define INTENT_RELATIVE_COLORIMETRIC 1
#define INTENT_SATURATION 2
#define INTENT_ABSOLUTE_COLORIMETRIC 3
#include
#include
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
// converts \p a to [0, 2 * M_PI) range
inline qreal normalizeAngle(qreal a) {
if (a < 0.0) {
a = 2 * M_PI + fmod(a, 2 * M_PI);
}
return a > 2 * M_PI ? fmod(a, 2 * M_PI) : a;
}
// converts \p a to [0, 360.0) range
inline qreal normalizeAngleDegrees(qreal a) {
if (a < 0.0) {
a = 360.0 + fmod(a, 360.0);
}
return a > 360.0 ? fmod(a, 360.0) : a;
}
inline qreal shortestAngularDistance(qreal a, qreal b) {
qreal dist = fmod(qAbs(a - b), 2 * M_PI);
if (dist > M_PI) dist = 2 * M_PI - dist;
return dist;
}
inline qreal incrementInDirection(qreal a, qreal inc, qreal direction) {
qreal b1 = a + inc;
qreal b2 = a - inc;
qreal d1 = shortestAngularDistance(b1, direction);
qreal d2 = shortestAngularDistance(b2, direction);
return d1 < d2 ? b1 : b2;
}
template
inline T pow2(const T& x) {
return x * x;
}
template
inline T kisDegreesToRadians(T degrees) {
return degrees * M_PI / 180.0;
}
template
inline T kisRadiansToDegrees(T radians) {
return radians * 180.0 / M_PI;
}
template
inline T kisGrowRect(const T &rect, U offset) {
return rect.adjusted(-offset, -offset, offset, offset);
}
inline qreal kisDistance(const QPointF &pt1, const QPointF &pt2) {
return std::sqrt(pow2(pt1.x() - pt2.x()) + pow2(pt1.y() - pt2.y()));
}
inline qreal kisSquareDistance(const QPointF &pt1, const QPointF &pt2) {
return pow2(pt1.x() - pt2.x()) + pow2(pt1.y() - pt2.y());
}
#include
inline qreal kisDistanceToLine(const QPointF &m, const QLineF &line)
{
const QPointF &p1 = line.p1();
const QPointF &p2 = line.p2();
qreal distance = 0;
if (qFuzzyCompare(p1.x(), p2.x())) {
distance = qAbs(m.x() - p2.x());
} else if (qFuzzyCompare(p1.y(), p2.y())) {
distance = qAbs(m.y() - p2.y());
} else {
qreal A = 1;
qreal B = - (p1.x() - p2.x()) / (p1.y() - p2.y());
qreal C = - p1.x() - B * p1.y();
distance = qAbs(A * m.x() + B * m.y() + C) / std::sqrt(pow2(A) + pow2(B));
}
return distance;
}
inline QPointF kisProjectOnVector(const QPointF &base, const QPointF &v)
{
const qreal prod = base.x() * v.x() + base.y() * v.y();
const qreal lengthSq = pow2(base.x()) + pow2(base.y());
qreal coeff = prod / lengthSq;
return coeff * base;
}
#include
inline QRect kisEnsureInRect(QRect rc, const QRect &bounds)
{
if(rc.right() > bounds.right()) {
rc.translate(bounds.right() - rc.right(), 0);
}
if(rc.left() < bounds.left()) {
rc.translate(bounds.left() - rc.left(), 0);
}
if(rc.bottom() > bounds.bottom()) {
rc.translate(0, bounds.bottom() - rc.bottom());
}
if(rc.top() < bounds.top()) {
rc.translate(0, bounds.top() - rc.top());
}
return rc;
}
#include
template
inline QSharedPointer toQShared(T* ptr) {
return QSharedPointer(ptr);
}
#endif // KISGLOBAL_H_
diff --git a/libs/ui/dialogs/kis_dlg_preferences.cc b/libs/ui/dialogs/kis_dlg_preferences.cc
index b81392b2ec..feca9bd478 100644
--- a/libs/ui/dialogs/kis_dlg_preferences.cc
+++ b/libs/ui/dialogs/kis_dlg_preferences.cc
@@ -1,1147 +1,1149 @@
/*
* preferencesdlg.cc - part of KImageShop
*
* Copyright (c) 1999 Michael Koch
* Copyright (c) 2003-2011 Boudewijn Rempt
*
* 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_dlg_preferences.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 "KoID.h"
#include
#include
#include
#include
#include
#include "widgets/squeezedcombobox.h"
#include "kis_clipboard.h"
#include "widgets/kis_cmb_idlist.h"
#include "KoColorSpace.h"
#include "KoColorSpaceRegistry.h"
#include "kis_cursor.h"
#include "kis_config.h"
#include "kis_canvas_resource_provider.h"
#include "kis_preference_set_registry.h"
#include "kis_color_manager.h"
#include "slider_and_spin_box_sync.h"
// for the performance update
#include
#include "input/config/kis_input_configuration_page.h"
GeneralTab::GeneralTab(QWidget *_parent, const char *_name)
: WdgGeneralSettings(_parent, _name)
{
KisConfig cfg;
m_cmbCursorShape->addItem(i18n("No Cursor"));
m_cmbCursorShape->addItem(i18n("Tool Icon"));
m_cmbCursorShape->addItem(i18n("Arrow"));
m_cmbCursorShape->addItem(i18n("Small Circle"));
m_cmbCursorShape->addItem(i18n("Crosshair"));
m_cmbCursorShape->addItem(i18n("Triangle Righthanded"));
m_cmbCursorShape->addItem(i18n("Triangle Lefthanded"));
+ m_cmbCursorShape->addItem(i18n("Black Pixel"));
+ m_cmbCursorShape->addItem(i18n("White Pixel"));
m_cmbOutlineShape->addItem(i18n("No Outline"));
m_cmbOutlineShape->addItem(i18n("Circle Outline"));
m_cmbOutlineShape->addItem(i18n("Preview Outline"));
m_cmbOutlineShape->addItem(i18n("Tilt Outline"));
m_cmbCursorShape->setCurrentIndex(cfg.newCursorStyle());
m_cmbOutlineShape->setCurrentIndex(cfg.newOutlineStyle());
chkShowRootLayer->setChecked(cfg.showRootLayer());
int autosaveInterval = cfg.autoSaveInterval();
//convert to minutes
m_autosaveSpinBox->setValue(autosaveInterval / 60);
m_autosaveCheckBox->setChecked(autosaveInterval > 0);
m_undoStackSize->setValue(cfg.undoStackLimit());
m_backupFileCheckBox->setChecked(cfg.backupFile());
m_showOutlinePainting->setChecked(cfg.showOutlineWhilePainting());
m_hideSplashScreen->setChecked(cfg.hideSplashScreen());
m_cmbMDIType->setCurrentIndex(cfg.readEntry("mdi_viewmode", (int)QMdiArea::TabbedView));
m_chkRubberBand->setChecked(cfg.readEntry("mdi_rubberband", cfg.useOpenGL()));
m_favoritePresetsSpinBox->setValue(cfg.favoritePresets());
m_mdiColor->setColor(cfg.getMDIBackgroundColor());
m_backgroundimage->setText(cfg.getMDIBackgroundImage());
m_chkCanvasMessages->setChecked(cfg.showCanvasMessages());
m_chkCompressKra->setChecked(cfg.compressKra());
m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker());
m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt());
connect(m_bnFileName, SIGNAL(clicked()), SLOT(getBackgroundImage()));
connect(clearBgImageButton, SIGNAL(clicked()), SLOT(clearBackgroundImage()));
}
void GeneralTab::setDefault()
{
KisConfig cfg;
m_cmbCursorShape->setCurrentIndex(cfg.newCursorStyle(true));
m_cmbOutlineShape->setCurrentIndex(cfg.newOutlineStyle(true));
chkShowRootLayer->setChecked(cfg.showRootLayer(true));
m_autosaveCheckBox->setChecked(cfg.autoSaveInterval(true) > 0);
//convert to minutes
m_autosaveSpinBox->setValue(cfg.autoSaveInterval(true) / 60);
m_undoStackSize->setValue(cfg.undoStackLimit(true));
m_backupFileCheckBox->setChecked(cfg.backupFile(true));
m_showOutlinePainting->setChecked(cfg.showOutlineWhilePainting(true));
m_hideSplashScreen->setChecked(cfg.hideSplashScreen(true));
m_cmbMDIType->setCurrentIndex((int)QMdiArea::TabbedView);
m_chkRubberBand->setChecked(cfg.useOpenGL(true));
m_favoritePresetsSpinBox->setValue(cfg.favoritePresets(true));
m_mdiColor->setColor(cfg.getMDIBackgroundColor(true));
m_backgroundimage->setText(cfg.getMDIBackgroundImage(true));
m_chkCanvasMessages->setChecked(cfg.showCanvasMessages(true));
m_chkCompressKra->setChecked(cfg.compressKra(true));
m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker(true));
m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt(true));
}
CursorStyle GeneralTab::cursorStyle()
{
return (CursorStyle)m_cmbCursorShape->currentIndex();
}
OutlineStyle GeneralTab::outlineStyle()
{
return (OutlineStyle)m_cmbOutlineShape->currentIndex();
}
bool GeneralTab::showRootLayer()
{
return chkShowRootLayer->isChecked();
}
int GeneralTab::autoSaveInterval()
{
//convert to seconds
return m_autosaveCheckBox->isChecked() ? m_autosaveSpinBox->value()*60 : 0;
}
int GeneralTab::undoStackSize()
{
return m_undoStackSize->value();
}
bool GeneralTab::showOutlineWhilePainting()
{
return m_showOutlinePainting->isChecked();
}
bool GeneralTab::hideSplashScreen()
{
return m_hideSplashScreen->isChecked();
}
int GeneralTab::mdiMode()
{
return m_cmbMDIType->currentIndex();
}
int GeneralTab::favoritePresets()
{
return m_favoritePresetsSpinBox->value();
}
bool GeneralTab::showCanvasMessages()
{
return m_chkCanvasMessages->isChecked();
}
bool GeneralTab::compressKra()
{
return m_chkCompressKra->isChecked();
}
bool GeneralTab::toolOptionsInDocker()
{
return m_radioToolOptionsInDocker->isChecked();
}
bool GeneralTab::switchSelectionCtrlAlt()
{
return m_chkSwitchSelectionCtrlAlt->isChecked();
}
void GeneralTab::getBackgroundImage()
{
KoFileDialog dialog(this, KoFileDialog::OpenFile, "BackgroundImages");
dialog.setCaption(i18n("Select a Background Image"));
dialog.setDefaultDir(QDesktopServices::storageLocation(QDesktopServices::PicturesLocation));
dialog.setImageFilters();
QString fn = dialog.filename();
// dialog box was canceled or somehow no file was selected
if (fn.isEmpty()) {
return;
}
QImage image(fn);
if (image.isNull()) {
QMessageBox::warning(this, i18nc("@title:window", "Krita"), i18n("%1 is not a valid image file!", fn));
}
else {
m_backgroundimage->setText(fn);
}
}
void GeneralTab::clearBackgroundImage()
{
// clearing the background image text will implicitly make the background color be used
m_backgroundimage->setText("");
}
ColorSettingsTab::ColorSettingsTab(QWidget *parent, const char *name)
: QWidget(parent)
{
setObjectName(name);
// XXX: Make sure only profiles that fit the specified color model
// are shown in the profile combos
QGridLayout * l = new QGridLayout(this);
l->setMargin(0);
m_page = new WdgColorSettings(this);
l->addWidget(m_page, 0, 0);
KisConfig cfg;
m_page->chkUseSystemMonitorProfile->setChecked(cfg.useSystemMonitorProfile());
connect(m_page->chkUseSystemMonitorProfile, SIGNAL(toggled(bool)), this, SLOT(toggleAllowMonitorProfileSelection(bool)));
// XXX: no color management integration on Windows or OSX yet
#ifndef HAVE_X11
m_page->chkUseSystemMonitorProfile->setVisible(false);
#endif
m_page->cmbWorkingColorSpace->setIDList(KoColorSpaceRegistry::instance()->listKeys());
m_page->cmbWorkingColorSpace->setCurrent(cfg.workingColorSpace());
m_page->cmbPrintingColorSpace->setIDList(KoColorSpaceRegistry::instance()->listKeys());
m_page->cmbPrintingColorSpace->setCurrent(cfg.printerColorSpace());
m_page->bnAddColorProfile->setIcon(KisIconUtils::loadIcon("document-open"));
m_page->bnAddColorProfile->setToolTip( i18n("Open Color Profile") );
connect(m_page->bnAddColorProfile, SIGNAL(clicked()), SLOT(installProfile()));
refillPrintProfiles(KoID(cfg.printerColorSpace(), ""));
//hide printing settings
m_page->groupBox2->hide();
QGridLayout *monitorProfileGrid = new QGridLayout(m_page->monitorprofileholder);
for(int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
QLabel *lbl = new QLabel(i18nc("The number of the screen", "Screen %1:", i + 1));
monitorProfileGrid->addWidget(lbl, i, 0);
m_monitorProfileLabels << lbl;
SqueezedComboBox *cmb = new SqueezedComboBox();
monitorProfileGrid->addWidget(cmb, i, 1);
m_monitorProfileWidgets << cmb;
}
refillMonitorProfiles(KoID("RGBA", ""));
for(int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
}
}
if (m_page->cmbPrintProfile->contains(cfg.printerProfile()))
m_page->cmbPrintProfile->setCurrentIndex(m_page->cmbPrintProfile->findText(cfg.printerProfile()));
m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation());
m_page->chkAllowLCMSOptimization->setChecked(cfg.allowLCMSOptimization());
m_pasteBehaviourGroup.addButton(m_page->radioPasteWeb, PASTE_ASSUME_WEB);
m_pasteBehaviourGroup.addButton(m_page->radioPasteMonitor, PASTE_ASSUME_MONITOR);
m_pasteBehaviourGroup.addButton(m_page->radioPasteAsk, PASTE_ASK);
QAbstractButton *button = m_pasteBehaviourGroup.button(cfg.pasteBehaviour());
Q_ASSERT(button);
if (button) {
button->setChecked(true);
}
m_page->cmbMonitorIntent->setCurrentIndex(cfg.monitorRenderIntent());
toggleAllowMonitorProfileSelection(cfg.useSystemMonitorProfile());
connect(m_page->cmbPrintingColorSpace, SIGNAL(activated(const KoID &)),
this, SLOT(refillPrintProfiles(const KoID &)));
}
void ColorSettingsTab::installProfile()
{
QStringList mime;
mime << "ICM Profile (*.icm)" << "ICC Profile (*.icc)";
KoFileDialog dialog(this, KoFileDialog::OpenFiles, "OpenDocumentICC");
dialog.setCaption(i18n("Install Color Profiles"));
dialog.setDefaultDir(QDesktopServices::storageLocation(QDesktopServices::HomeLocation));
dialog.setNameFilters(mime);
QStringList profileNames = dialog.filenames();
KoColorSpaceEngine *iccEngine = KoColorSpaceEngineRegistry::instance()->get("icc");
Q_ASSERT(iccEngine);
QString saveLocation = KoResourcePaths::saveLocation("icc_profiles");
Q_FOREACH (const QString &profileName, profileNames) {
QUrl file(profileName);
if (!QFile::copy(profileName, saveLocation + file.fileName())) {
dbgKrita << "Could not install profile!";
return;
}
iccEngine->addProfile(saveLocation + file.fileName());
}
KisConfig cfg;
refillMonitorProfiles(KoID("RGBA", ""));
refillPrintProfiles(KoID(cfg.printerColorSpace(), ""));
for(int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
}
}
if (m_page->cmbPrintProfile->contains(cfg.printerProfile()))
m_page->cmbPrintProfile->setCurrentIndex(m_page->cmbPrintProfile->findText(cfg.printerProfile()));
}
void ColorSettingsTab::toggleAllowMonitorProfileSelection(bool useSystemProfile)
{
if (useSystemProfile) {
KisConfig cfg;
QStringList devices = KisColorManager::instance()->devices();
if (devices.size() == QApplication::desktop()->screenCount()) {
for(int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
m_monitorProfileWidgets[i]->clear();
QString monitorForScreen = cfg.monitorForScreen(i, devices[i]);
Q_FOREACH (const QString &device, devices) {
m_monitorProfileLabels[i]->setText(i18nc("The display/screen we got from Qt", "Screen %1:", i + 1));
m_monitorProfileWidgets[i]->addSqueezedItem(KisColorManager::instance()->deviceName(device), device);
if (devices[i] == monitorForScreen) {
m_monitorProfileWidgets[i]->setCurrentIndex(i);
}
}
}
}
}
else {
KisConfig cfg;
refillMonitorProfiles(KoID("RGBA", ""));
for(int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
}
}
}
}
void ColorSettingsTab::setDefault()
{
m_page->cmbWorkingColorSpace->setCurrent("RGBA");
m_page->cmbPrintingColorSpace->setCurrent("CMYK");
refillPrintProfiles(KoID("CMYK", ""));
refillMonitorProfiles(KoID("RGBA", ""));
KisConfig cfg;
m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation(true));
m_page->chkAllowLCMSOptimization->setChecked(cfg.allowLCMSOptimization(true));
m_page->cmbMonitorIntent->setCurrentIndex(cfg.monitorRenderIntent(true));
m_page->chkUseSystemMonitorProfile->setChecked(cfg.useSystemMonitorProfile(true));
QAbstractButton *button = m_pasteBehaviourGroup.button(cfg.pasteBehaviour(true));
Q_ASSERT(button);
if (button) {
button->setChecked(true);
}
}
void ColorSettingsTab::refillMonitorProfiles(const KoID & s)
{
const KoColorSpaceFactory * csf = KoColorSpaceRegistry::instance()->colorSpaceFactory(s.id());
for (int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
m_monitorProfileWidgets[i]->clear();
}
if (!csf)
return;
QList profileList = KoColorSpaceRegistry::instance()->profilesFor(csf);
Q_FOREACH (const KoColorProfile *profile, profileList) {
// //dbgKrita << "Profile" << profile->name() << profile->isSuitableForDisplay() << csf->defaultProfile();
if (profile->isSuitableForDisplay()) {
for (int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
m_monitorProfileWidgets[i]->addSqueezedItem(profile->name());
}
}
}
for (int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
m_monitorProfileLabels[i]->setText(i18nc("The number of the screen", "Screen %1:", i + 1));
m_monitorProfileWidgets[i]->setCurrent(csf->defaultProfile());
}
}
void ColorSettingsTab::refillPrintProfiles(const KoID & s)
{
const KoColorSpaceFactory * csf = KoColorSpaceRegistry::instance()->colorSpaceFactory(s.id());
m_page->cmbPrintProfile->clear();
if (!csf)
return;
QList profileList = KoColorSpaceRegistry::instance()->profilesFor(csf);
Q_FOREACH (const KoColorProfile *profile, profileList) {
if (profile->isSuitableForPrinting())
m_page->cmbPrintProfile->addSqueezedItem(profile->name());
}
m_page->cmbPrintProfile->setCurrent(csf->defaultProfile());
}
//---------------------------------------------------------------------------------------------------
void TabletSettingsTab::setDefault()
{
KisCubicCurve curve;
curve.fromString(DEFAULT_CURVE_STRING);
m_page->pressureCurve->setCurve(curve);
}
TabletSettingsTab::TabletSettingsTab(QWidget* parent, const char* name): QWidget(parent)
{
setObjectName(name);
QGridLayout * l = new QGridLayout(this);
l->setMargin(0);
m_page = new WdgTabletSettings(this);
l->addWidget(m_page, 0, 0);
KisConfig cfg;
KisCubicCurve curve;
curve.fromString( cfg.pressureTabletCurve() );
m_page->pressureCurve->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
m_page->pressureCurve->setCurve(curve);
}
//---------------------------------------------------------------------------------------------------
#include "kis_image_config.h"
#include "kis_acyclic_signal_connector.h"
int getTotalRAM() {
KisImageConfig cfg;
return cfg.totalRAM();
}
int PerformanceTab::realTilesRAM()
{
return intMemoryLimit->value() - intPoolLimit->value();
}
PerformanceTab::PerformanceTab(QWidget *parent, const char *name)
: WdgPerformanceSettings(parent, name)
{
KisImageConfig cfg;
const int totalRAM = cfg.totalRAM();
lblTotalMemory->setText(i18n("%1 MiB", totalRAM));
sliderMemoryLimit->setSuffix(i18n(" %"));
sliderMemoryLimit->setRange(1, 100, 2);
sliderMemoryLimit->setSingleStep(0.01);
sliderPoolLimit->setSuffix(i18n(" %"));
sliderPoolLimit->setRange(0, 20, 2);
sliderMemoryLimit->setSingleStep(0.01);
sliderUndoLimit->setSuffix(i18n(" %"));
sliderUndoLimit->setRange(0, 50, 2);
sliderMemoryLimit->setSingleStep(0.01);
intMemoryLimit->setMinimumWidth(80);
intPoolLimit->setMinimumWidth(80);
intUndoLimit->setMinimumWidth(80);
SliderAndSpinBoxSync *sync1 =
new SliderAndSpinBoxSync(sliderMemoryLimit,
intMemoryLimit,
getTotalRAM);
sync1->slotParentValueChanged();
m_syncs << sync1;
SliderAndSpinBoxSync *sync2 =
new SliderAndSpinBoxSync(sliderPoolLimit,
intPoolLimit,
std::bind(&QSpinBox::value,
intMemoryLimit));
connect(intMemoryLimit, SIGNAL(valueChanged(int)), sync2, SLOT(slotParentValueChanged()));
sync2->slotParentValueChanged();
m_syncs << sync2;
SliderAndSpinBoxSync *sync3 =
new SliderAndSpinBoxSync(sliderUndoLimit,
intUndoLimit,
std::bind(&PerformanceTab::realTilesRAM,
this));
connect(intPoolLimit, SIGNAL(valueChanged(int)), sync3, SLOT(slotParentValueChanged()));
sync3->slotParentValueChanged();
m_syncs << sync3;
sliderSwapSize->setSuffix(i18n(" GiB"));
sliderSwapSize->setRange(1, 64);
intSwapSize->setRange(1, 64);
KisAcyclicSignalConnector *swapSizeConnector = new KisAcyclicSignalConnector(this);
swapSizeConnector->connectForwardInt(sliderSwapSize, SIGNAL(valueChanged(int)),
intSwapSize, SLOT(setValue(int)));
swapSizeConnector->connectBackwardInt(intSwapSize, SIGNAL(valueChanged(int)),
sliderSwapSize, SLOT(setValue(int)));
lblSwapFileLocation->setText(cfg.swapDir());
connect(bnSwapFile, SIGNAL(clicked()), SLOT(selectSwapDir()));
load(false);
}
PerformanceTab::~PerformanceTab()
{
qDeleteAll(m_syncs);
}
void PerformanceTab::load(bool requestDefault)
{
KisImageConfig cfg;
sliderMemoryLimit->setValue(cfg.memoryHardLimitPercent(requestDefault));
sliderPoolLimit->setValue(cfg.memoryPoolLimitPercent(requestDefault));
sliderUndoLimit->setValue(cfg.memorySoftLimitPercent(requestDefault));
chkPerformanceLogging->setChecked(cfg.enablePerfLog(requestDefault));
chkProgressReporting->setChecked(cfg.enableProgressReporting(requestDefault));
sliderSwapSize->setValue(cfg.maxSwapSize(requestDefault) / 1024);
lblSwapFileLocation->setText(cfg.swapDir(requestDefault));
{
KisConfig cfg2;
chkOpenGLLogging->setChecked(cfg2.enableOpenGLDebugging(requestDefault));
chkDisableVectorOptimizations->setChecked(cfg2.enableAmdVectorizationWorkaround(requestDefault));
}
}
void PerformanceTab::save()
{
KisImageConfig cfg;
cfg.setMemoryHardLimitPercent(sliderMemoryLimit->value());
cfg.setMemorySoftLimitPercent(sliderUndoLimit->value());
cfg.setMemoryPoolLimitPercent(sliderPoolLimit->value());
cfg.setEnablePerfLog(chkPerformanceLogging->isChecked());
cfg.setEnableProgressReporting(chkProgressReporting->isChecked());
cfg.setMaxSwapSize(sliderSwapSize->value() * 1024);
cfg.setSwapDir(lblSwapFileLocation->text());
{
KisConfig cfg2;
cfg2.setEnableOpenGLDebugging(chkOpenGLLogging->isChecked());
cfg2.setEnableAmdVectorizationWorkaround(chkDisableVectorOptimizations->isChecked());
}
}
void PerformanceTab::selectSwapDir()
{
KisImageConfig cfg;
QString swapDir = cfg.swapDir();
swapDir = QFileDialog::getExistingDirectory(0, i18nc("@title:window", "Select a swap directory"), swapDir);
lblSwapFileLocation->setText(swapDir);
}
//---------------------------------------------------------------------------------------------------
#include "KoColor.h"
#include "KoColorPopupAction.h"
DisplaySettingsTab::DisplaySettingsTab(QWidget *parent, const char *name)
: WdgDisplaySettings(parent, name)
{
KisConfig cfg;
#ifdef HAVE_OPENGL
if (!KisOpenGL::hasOpenGL()) {
grpOpenGL->setEnabled(false);
grpOpenGL->setChecked(false);
chkUseTextureBuffer->setEnabled(false);
chkDisableDoubleBuffering->setEnabled(false);
chkDisableVsync->setEnabled(false);
cmbFilterMode->setEnabled(false);
} else {
grpOpenGL->setEnabled(true);
grpOpenGL->setChecked(cfg.useOpenGL());
chkUseTextureBuffer->setEnabled(cfg.useOpenGL());
chkUseTextureBuffer->setChecked(cfg.useOpenGLTextureBuffer());
chkDisableDoubleBuffering->setVisible(cfg.showAdvancedOpenGLSettings());
chkDisableDoubleBuffering->setEnabled(cfg.useOpenGL());
chkDisableDoubleBuffering->setChecked(cfg.disableDoubleBuffering());
chkDisableVsync->setVisible(cfg.showAdvancedOpenGLSettings());
chkDisableVsync->setEnabled(cfg.useOpenGL());
chkDisableVsync->setChecked(cfg.disableVSync());
cmbFilterMode->setEnabled(cfg.useOpenGL());
cmbFilterMode->setCurrentIndex(cfg.openGLFilteringMode());
}
if (qApp->applicationName() == "kritasketch" || qApp->applicationName() == "kritagemini") {
grpOpenGL->setVisible(false);
grpOpenGL->setMaximumHeight(0);
}
#else
grpOpenGL->setEnabled(false);
grpOpenGL->setChecked(false);
#endif
KoColor c;
c.fromQColor(cfg.selectionOverlayMaskColor());
m_selectionOverlayColorAction = new KoColorPopupAction(this);
m_selectionOverlayColorAction->setCurrentColor(c);
m_selectionOverlayColorAction->setIcon(KisIconUtils::loadIcon("format-stroke-color"));
m_selectionOverlayColorAction->setToolTip(i18n("Change the background color of the image"));
btnSelectionOverlayColor->setDefaultAction(m_selectionOverlayColorAction);
intCheckSize->setValue(cfg.checkSize());
chkMoving->setChecked(cfg.scrollCheckers());
colorChecks1->setColor(cfg.checkersColor1());
colorChecks2->setColor(cfg.checkersColor2());
canvasBorder->setColor(cfg.canvasBorderColor());
hideScrollbars->setChecked(cfg.hideScrollbars());
chkCurveAntialiasing->setChecked(cfg.antialiasCurves());
chkSelectionOutlineAntialiasing->setChecked(cfg.antialiasSelectionOutline());
chkChannelsAsColor->setChecked(cfg.showSingleChannelAsColor());
chkHidePopups->setChecked(cfg.hidePopups());
connect(grpOpenGL, SIGNAL(toggled(bool)), SLOT(slotUseOpenGLToggled(bool)));
}
void DisplaySettingsTab::setDefault()
{
KisConfig cfg;
#ifdef HAVE_OPENGL
if (!KisOpenGL::hasOpenGL()) {
grpOpenGL->setEnabled(false);
grpOpenGL->setChecked(false);
chkUseTextureBuffer->setEnabled(false);
chkDisableDoubleBuffering->setEnabled(false);
chkDisableVsync->setEnabled(false);
cmbFilterMode->setEnabled(false);
}
else {
grpOpenGL->setEnabled(true);
grpOpenGL->setChecked(cfg.useOpenGL(true));
chkUseTextureBuffer->setChecked(cfg.useOpenGLTextureBuffer(true));
chkUseTextureBuffer->setEnabled(true);
chkDisableDoubleBuffering->setEnabled(true);
chkDisableDoubleBuffering->setChecked(cfg.disableDoubleBuffering(true));
chkDisableVsync->setEnabled(true);
chkDisableVsync->setChecked(cfg.disableVSync(true));
cmbFilterMode->setEnabled(true);
cmbFilterMode->setCurrentIndex(cfg.openGLFilteringMode(true));
}
#else
grpOpenGL->setEnabled(false);
grpOpenGL->setChecked(false);
#endif
chkMoving->setChecked(cfg.scrollCheckers(true));
intCheckSize->setValue(cfg.checkSize(true));
colorChecks1->setColor(cfg.checkersColor1(true));
colorChecks2->setColor(cfg.checkersColor2(true));
canvasBorder->setColor(cfg.canvasBorderColor(true));
hideScrollbars->setChecked(cfg.hideScrollbars(true));
chkCurveAntialiasing->setChecked(cfg.antialiasCurves(true));
chkSelectionOutlineAntialiasing->setChecked(cfg.antialiasSelectionOutline(true));
chkChannelsAsColor->setChecked(cfg.showSingleChannelAsColor(true));
chkHidePopups->setChecked(cfg.hidePopups(true));
}
void DisplaySettingsTab::slotUseOpenGLToggled(bool isChecked)
{
#ifdef HAVE_OPENGL
chkUseTextureBuffer->setEnabled(isChecked);
chkDisableDoubleBuffering->setEnabled(isChecked);
chkDisableVsync->setEnabled(isChecked);
cmbFilterMode->setEnabled(isChecked);
#else
Q_UNUSED(isChecked);
#endif
}
//---------------------------------------------------------------------------------------------------
GridSettingsTab::GridSettingsTab(QWidget* parent) : WdgGridSettingsBase(parent)
{
KisConfig cfg;
selectMainStyle->setCurrentIndex(cfg.getGridMainStyle());
selectSubdivisionStyle->setCurrentIndex(cfg.getGridSubdivisionStyle());
colorMain->setColor(cfg.getGridMainColor());
colorSubdivision->setColor(cfg.getGridSubdivisionColor());
intHSpacing->setValue(cfg.getGridHSpacing());
intHSpacing->setSuffix(i18n(" px"));
intVSpacing->setValue(cfg.getGridVSpacing());
intVSpacing->setSuffix(i18n(" px"));
spacingAspectButton->setKeepAspectRatio(cfg.getGridSpacingAspect());
linkSpacingToggled(cfg.getGridSpacingAspect());
intSubdivision->setValue(cfg.getGridSubdivisions());
intXOffset->setValue(cfg.getGridOffsetX());
intXOffset->setSuffix(i18n(" px"));
intYOffset->setValue(cfg.getGridOffsetY());
intYOffset->setSuffix(i18n(" px"));
offsetAspectButton->setKeepAspectRatio(cfg.getGridOffsetAspect());
linkOffsetToggled(cfg.getGridOffsetAspect());
connect(spacingAspectButton, SIGNAL(keepAspectRatioChanged(bool)), this, SLOT(linkSpacingToggled(bool)));
connect(offsetAspectButton, SIGNAL(keepAspectRatioChanged(bool)), this, SLOT(linkOffsetToggled(bool)));
connect(intHSpacing, SIGNAL(valueChanged(int)), this, SLOT(spinBoxHSpacingChanged(int)));
connect(intVSpacing, SIGNAL(valueChanged(int)), this, SLOT(spinBoxVSpacingChanged(int)));
connect(intXOffset, SIGNAL(valueChanged(int)), this, SLOT(spinBoxXOffsetChanged(int)));
connect(intYOffset, SIGNAL(valueChanged(int)), this, SLOT(spinBoxYOffsetChanged(int)));
}
void GridSettingsTab::setDefault()
{
KisConfig cfg;
selectMainStyle->setCurrentIndex(cfg.getGridMainStyle(true));
selectSubdivisionStyle->setCurrentIndex(cfg.getGridSubdivisionStyle(true));
colorMain->setColor(cfg.getGridMainColor(true));
colorSubdivision->setColor(cfg.getGridSubdivisionColor(true));
intHSpacing->setValue(cfg.getGridHSpacing(true));
intVSpacing->setValue(cfg.getGridVSpacing(true));
linkSpacingToggled(cfg.getGridSpacingAspect(true));
intSubdivision->setValue(cfg.getGridSubdivisions(true));
intXOffset->setValue(cfg.getGridOffsetX(true));
intYOffset->setValue(cfg.getGridOffsetY());
linkOffsetToggled(cfg.getGridOffsetAspect(true));
}
void GridSettingsTab::spinBoxHSpacingChanged(int v)
{
if (m_linkSpacing) {
intVSpacing->setValue(v);
}
}
void GridSettingsTab::spinBoxVSpacingChanged(int v)
{
if (m_linkSpacing) {
intHSpacing->setValue(v);
}
}
void GridSettingsTab::linkSpacingToggled(bool b)
{
m_linkSpacing = b;
if (m_linkSpacing) {
intVSpacing->setValue(intHSpacing->value());
}
}
void GridSettingsTab::spinBoxXOffsetChanged(int v)
{
if (m_linkOffset) {
intYOffset->setValue(v);
}
}
void GridSettingsTab::spinBoxYOffsetChanged(int v)
{
if (m_linkOffset) {
intXOffset->setValue(v);
}
}
void GridSettingsTab::linkOffsetToggled(bool b)
{
m_linkOffset = b;
if (m_linkOffset) {
intYOffset->setValue(intXOffset->value());
}
}
//---------------------------------------------------------------------------------------------------
FullscreenSettingsTab::FullscreenSettingsTab(QWidget* parent) : WdgFullscreenSettingsBase(parent)
{
KisConfig cfg;
chkDockers->setChecked(cfg.hideDockersFullscreen());
chkMenu->setChecked(cfg.hideMenuFullscreen());
chkScrollbars->setChecked(cfg.hideScrollbarsFullscreen());
chkStatusbar->setChecked(cfg.hideStatusbarFullscreen());
chkTitlebar->setChecked(cfg.hideTitlebarFullscreen());
chkToolbar->setChecked(cfg.hideToolbarFullscreen());
}
void FullscreenSettingsTab::setDefault()
{
KisConfig cfg;
chkDockers->setChecked(cfg.hideDockersFullscreen(true));
chkMenu->setChecked(cfg.hideMenuFullscreen(true));
chkScrollbars->setChecked(cfg.hideScrollbarsFullscreen(true));
chkStatusbar->setChecked(cfg.hideStatusbarFullscreen(true));
chkTitlebar->setChecked(cfg.hideTitlebarFullscreen(true));
chkToolbar->setChecked(cfg.hideToolbarFullscreen(true));
}
//---------------------------------------------------------------------------------------------------
KisDlgPreferences::KisDlgPreferences(QWidget* parent, const char* name)
: KPageDialog(parent)
{
Q_UNUSED(name);
setWindowTitle(i18n("Preferences"));
// QT5TODO: help button needs custom wiring up to whatever help should be shown
setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::RestoreDefaults);
button(QDialogButtonBox::Ok)->setDefault(true);
setFaceType(KPageDialog::List);
// General
KoVBox *vbox = new KoVBox();
KPageWidgetItem *page = new KPageWidgetItem(vbox, i18n("General"));
page->setObjectName("general");
page->setHeader(i18n("General"));
page->setIcon(KisIconUtils::loadIcon("configure"));
addPage(page);
m_general = new GeneralTab(vbox);
// Display
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, i18n("Display"));
page->setObjectName("display");
page->setHeader(i18n("Display"));
page->setIcon(KisIconUtils::loadIcon("preferences-desktop-display"));
addPage(page);
m_displaySettings = new DisplaySettingsTab(vbox);
// Color
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, i18n("Color Management"));
page->setObjectName("colormanagement");
page->setHeader(i18n("Color"));
page->setIcon(KisIconUtils::loadIcon("preferences-desktop-color"));
addPage(page);
m_colorSettings = new ColorSettingsTab(vbox);
// Performance
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, i18n("Performance"));
page->setObjectName("performance");
page->setHeader(i18n("Performance"));
page->setIcon(KisIconUtils::loadIcon("applications-system"));
addPage(page);
m_performanceSettings = new PerformanceTab(vbox);
// Grid
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, i18n("Grid"));
page->setObjectName("grid");
page->setHeader(i18n("Grid"));
page->setIcon(KisIconUtils::loadIcon("view-grid"));
addPage(page);
m_gridSettings = new GridSettingsTab(vbox);
// Tablet
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, i18n("Tablet settings"));
page->setObjectName("tablet");
page->setHeader(i18n("Tablet"));
page->setIcon(KisIconUtils::loadIcon("document-edit"));
addPage(page);
m_tabletSettings = new TabletSettingsTab(vbox);
// full-screen mode
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, i18n("Canvas-only settings"));
page->setObjectName("canvasonly");
page->setHeader(i18n("Canvas-only"));
page->setIcon(KisIconUtils::loadIcon("folder-pictures"));
addPage(page);
m_fullscreenSettings = new FullscreenSettingsTab(vbox);
// Author profiles
m_authorPage = new KoConfigAuthorPage();
page = addPage(m_authorPage, i18nc("@title:tab Author page", "Author" ));
page->setObjectName("author");
page->setHeader(i18n("Author"));
page->setIcon(KisIconUtils::loadIcon("im-user"));
// input settings
m_inputConfiguration = new KisInputConfigurationPage();
page = addPage(m_inputConfiguration, i18n("Canvas Input Settings"));
page->setHeader(i18n("Canvas Input"));
page->setObjectName("canvasinput");
page->setIcon(KisIconUtils::loadIcon("applications-system"));
QPushButton *restoreDefaultsButton = button(QDialogButtonBox::RestoreDefaults);
connect(this, SIGNAL(accepted()), m_inputConfiguration, SLOT(saveChanges()));
connect(this, SIGNAL(rejected()), m_inputConfiguration, SLOT(revertChanges()));
connect(restoreDefaultsButton, SIGNAL(clicked(bool)), m_inputConfiguration, SLOT(setDefaults()));
KisPreferenceSetRegistry *preferenceSetRegistry = KisPreferenceSetRegistry::instance();
Q_FOREACH (KisAbstractPreferenceSetFactory *preferenceSetFactory, preferenceSetRegistry->values()) {
KisPreferenceSet* preferenceSet = preferenceSetFactory->createPreferenceSet();
vbox = new KoVBox();
page = new KPageWidgetItem(vbox, preferenceSet->name());
page->setHeader(preferenceSet->header());
page->setIcon(preferenceSet->icon());
addPage(page);
preferenceSet->setParent(vbox);
preferenceSet->loadPreferences();
connect(restoreDefaultsButton, SIGNAL(clicked(bool)), preferenceSet, SLOT(loadDefaultPreferences()), Qt::UniqueConnection);
connect(this, SIGNAL(accepted()), preferenceSet, SLOT(savePreferences()), Qt::UniqueConnection);
}
connect(restoreDefaultsButton, SIGNAL(clicked(bool)), this, SLOT(slotDefault()));
}
KisDlgPreferences::~KisDlgPreferences()
{
}
void KisDlgPreferences::slotDefault()
{
if (currentPage()->objectName() == "default") {
m_general->setDefault();
}
else if (currentPage()->objectName() == "display") {
m_displaySettings->setDefault();
}
else if (currentPage()->objectName() == "colormanagement") {
m_colorSettings->setDefault();
}
else if (currentPage()->objectName() == "performance") {
m_performanceSettings->load(true);
}
else if (currentPage()->objectName() == "grid") {
m_gridSettings->setDefault();
}
else if (currentPage()->objectName() == "tablet") {
m_tabletSettings->setDefault();
}
else if (currentPage()->objectName() == "canvasonly") {
m_fullscreenSettings->setDefault();
}
else if (currentPage()->objectName() == "canvasinput") {
m_inputConfiguration->setDefaults();
}
}
bool KisDlgPreferences::editPreferences()
{
KisDlgPreferences* dialog;
dialog = new KisDlgPreferences();
bool baccept = (dialog->exec() == Accepted);
if (baccept) {
// General settings
KisConfig cfg;
cfg.setNewCursorStyle(dialog->m_general->cursorStyle());
cfg.setNewOutlineStyle(dialog->m_general->outlineStyle());
cfg.setShowRootLayer(dialog->m_general->showRootLayer());
cfg.setShowOutlineWhilePainting(dialog->m_general->showOutlineWhilePainting());
cfg.setHideSplashScreen(dialog->m_general->hideSplashScreen());
cfg.writeEntry("mdi_viewmode", dialog->m_general->mdiMode());
cfg.setMDIBackgroundColor(dialog->m_general->m_mdiColor->color());
cfg.setMDIBackgroundImage(dialog->m_general->m_backgroundimage->text());
cfg.setAutoSaveInterval(dialog->m_general->autoSaveInterval());
cfg.setBackupFile(dialog->m_general->m_backupFileCheckBox->isChecked());
cfg.setShowCanvasMessages(dialog->m_general->showCanvasMessages());
cfg.setCompressKra(dialog->m_general->compressKra());
cfg.setToolOptionsInDocker(dialog->m_general->toolOptionsInDocker());
cfg.setSwitchSelectionCtrlAlt(dialog->m_general->switchSelectionCtrlAlt());
KisPart *part = KisPart::instance();
if (part) {
Q_FOREACH (QPointer doc, part->documents()) {
if (doc) {
doc->setAutoSave(dialog->m_general->autoSaveInterval());
doc->setBackupFile(dialog->m_general->m_backupFileCheckBox->isChecked());
doc->undoStack()->setUndoLimit(dialog->m_general->undoStackSize());
}
}
}
cfg.setUndoStackLimit(dialog->m_general->undoStackSize());
cfg.setFavoritePresets(dialog->m_general->favoritePresets());
// Color settings
cfg.setUseSystemMonitorProfile(dialog->m_colorSettings->m_page->chkUseSystemMonitorProfile->isChecked());
for (int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
if (dialog->m_colorSettings->m_page->chkUseSystemMonitorProfile->isChecked()) {
int currentIndex = dialog->m_colorSettings->m_monitorProfileWidgets[i]->currentIndex();
QString monitorid = dialog->m_colorSettings->m_monitorProfileWidgets[i]->itemData(currentIndex).toString();
cfg.setMonitorForScreen(i, monitorid);
}
else {
cfg.setMonitorProfile(i,
dialog->m_colorSettings->m_monitorProfileWidgets[i]->itemHighlighted(),
dialog->m_colorSettings->m_page->chkUseSystemMonitorProfile->isChecked());
}
}
cfg.setWorkingColorSpace(dialog->m_colorSettings->m_page->cmbWorkingColorSpace->currentItem().id());
cfg.setPrinterColorSpace(dialog->m_colorSettings->m_page->cmbPrintingColorSpace->currentItem().id());
cfg.setPrinterProfile(dialog->m_colorSettings->m_page->cmbPrintProfile->itemHighlighted());
cfg.setUseBlackPointCompensation(dialog->m_colorSettings->m_page->chkBlackpoint->isChecked());
cfg.setAllowLCMSOptimization(dialog->m_colorSettings->m_page->chkAllowLCMSOptimization->isChecked());
cfg.setPasteBehaviour(dialog->m_colorSettings->m_pasteBehaviourGroup.checkedId());
cfg.setRenderIntent(dialog->m_colorSettings->m_page->cmbMonitorIntent->currentIndex());
// Tablet settings
cfg.setPressureTabletCurve( dialog->m_tabletSettings->m_page->pressureCurve->curve().toString() );
dialog->m_performanceSettings->save();
#ifdef HAVE_OPENGL
if (!cfg.useOpenGL() && dialog->m_displaySettings->grpOpenGL->isChecked())
cfg.setCanvasState("TRY_OPENGL");
cfg.setUseOpenGL(dialog->m_displaySettings->grpOpenGL->isChecked());
cfg.setUseOpenGLTextureBuffer(dialog->m_displaySettings->chkUseTextureBuffer->isChecked());
cfg.setOpenGLFilteringMode(dialog->m_displaySettings->cmbFilterMode->currentIndex());
cfg.setDisableDoubleBuffering(dialog->m_displaySettings->chkDisableDoubleBuffering->isChecked());
cfg.setDisableVSync(dialog->m_displaySettings->chkDisableVsync->isChecked());
#endif
cfg.setCheckSize(dialog->m_displaySettings->intCheckSize->value());
cfg.setScrollingCheckers(dialog->m_displaySettings->chkMoving->isChecked());
cfg.setCheckersColor1(dialog->m_displaySettings->colorChecks1->color());
cfg.setCheckersColor2(dialog->m_displaySettings->colorChecks2->color());
cfg.setCanvasBorderColor(dialog->m_displaySettings->canvasBorder->color());
cfg.setHideScrollbars(dialog->m_displaySettings->hideScrollbars->isChecked());
cfg.setSelectionOverlayMaskColor(dialog->m_displaySettings->m_selectionOverlayColorAction->currentKoColor().toQColor());
cfg.setAntialiasCurves(dialog->m_displaySettings->chkCurveAntialiasing->isChecked());
cfg.setAntialiasSelectionOutline(dialog->m_displaySettings->chkSelectionOutlineAntialiasing->isChecked());
cfg.setShowSingleChannelAsColor(dialog->m_displaySettings->chkChannelsAsColor->isChecked());
cfg.setHidePopups(dialog->m_displaySettings->chkHidePopups->isChecked());
// Grid settings
cfg.setGridMainStyle(dialog->m_gridSettings->selectMainStyle->currentIndex());
cfg.setGridSubdivisionStyle(dialog->m_gridSettings->selectSubdivisionStyle->currentIndex());
cfg.setGridMainColor(dialog->m_gridSettings->colorMain->color());
cfg.setGridSubdivisionColor(dialog->m_gridSettings->colorSubdivision->color());
cfg.setGridHSpacing(dialog->m_gridSettings->intHSpacing->value());
cfg.setGridVSpacing(dialog->m_gridSettings->intVSpacing->value());
cfg.setGridSpacingAspect(dialog->m_gridSettings->spacingAspectButton->keepAspectRatio());
cfg.setGridSubdivisions(dialog->m_gridSettings->intSubdivision->value());
cfg.setGridOffsetX(dialog->m_gridSettings->intXOffset->value());
cfg.setGridOffsetY(dialog->m_gridSettings->intYOffset->value());
cfg.setGridOffsetAspect(dialog->m_gridSettings->offsetAspectButton->keepAspectRatio());
cfg.setHideDockersFullscreen(dialog->m_fullscreenSettings->chkDockers->checkState());
cfg.setHideMenuFullscreen(dialog->m_fullscreenSettings->chkMenu->checkState());
cfg.setHideScrollbarsFullscreen(dialog->m_fullscreenSettings->chkScrollbars->checkState());
cfg.setHideStatusbarFullscreen(dialog->m_fullscreenSettings->chkStatusbar->checkState());
cfg.setHideTitlebarFullscreen(dialog->m_fullscreenSettings->chkTitlebar->checkState());
cfg.setHideToolbarFullscreen(dialog->m_fullscreenSettings->chkToolbar->checkState());
dialog->m_authorPage->apply();
}
delete dialog;
return baccept;
}
diff --git a/libs/ui/kis_cursor.cc b/libs/ui/kis_cursor.cc
index a31c107792..274f7c6629 100644
--- a/libs/ui/kis_cursor.cc
+++ b/libs/ui/kis_cursor.cc
@@ -1,466 +1,476 @@
/*
* kis_cursor.cc - part of KImageShop
*
* Copyright (c) 1999 Matthias Elter
* Copyright (c) 2004 Adrian Page
* Copyright (c) 2013 David Revoy
*
* 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_cursor.h"
#include
#include
#include
#include
#include
#include
#include
#include
KisCursor::KisCursor() {}
/*
* Predefined Qt cursors
*/
QCursor KisCursor::arrowCursor()
{
return Qt::ArrowCursor;
}
QCursor KisCursor::upArrowCursor()
{
return Qt::UpArrowCursor;
}
QCursor KisCursor::crossCursor()
{
return load("cursor-cross.xpm");
}
QCursor KisCursor::roundCursor()
{
return load("cursor-round.xpm");
}
+QCursor KisCursor::pixelBlackCursor()
+{
+ return load("cursor-pixel-black.xpm");
+}
+
+QCursor KisCursor::pixelWhiteCursor()
+{
+ return load("cursor-pixel-white.xpm");
+}
+
QCursor KisCursor::waitCursor()
{
return Qt::WaitCursor;
}
QCursor KisCursor::ibeamCursor()
{
return Qt::IBeamCursor;
}
QCursor KisCursor::sizeVerCursor()
{
return Qt::SizeVerCursor;
}
QCursor KisCursor::sizeHorCursor()
{
return Qt::SizeHorCursor;
}
QCursor KisCursor::sizeBDiagCursor()
{
return Qt::SizeBDiagCursor;
}
QCursor KisCursor::sizeFDiagCursor()
{
return Qt::SizeFDiagCursor;
}
QCursor KisCursor::sizeAllCursor()
{
return Qt::SizeAllCursor;
}
QCursor KisCursor::blankCursor()
{
return Qt::BlankCursor;
}
QCursor KisCursor::splitVCursor()
{
return Qt::SplitVCursor;
}
QCursor KisCursor::splitHCursor()
{
return Qt::SplitHCursor;
}
QCursor KisCursor::pointingHandCursor()
{
return Qt::PointingHandCursor;
}
/*
* Existing custom KimageShop cursors. Use the 'load' function for all new cursors.
*/
QCursor KisCursor::pickerCursor()
{
return pickerLayerForegroundCursor();
}
QCursor KisCursor::pickerPlusCursor()
{
static const unsigned char pickerplus_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x80, 0x1e,
0x00, 0x00, 0x40, 0x1f, 0x00, 0x00, 0xb0, 0x1f, 0x00, 0x00, 0xe8, 0x0f,
0x00, 0x00, 0xd0, 0x07, 0x00, 0x00, 0xa8, 0x03, 0x00, 0x00, 0x64, 0x03,
0x00, 0x00, 0x72, 0x01, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x80, 0x1c, 0x00,
0x00, 0x40, 0x0e, 0x00, 0x00, 0x20, 0x07, 0x00, 0x00, 0x90, 0x03, 0x00,
0x00, 0xc8, 0x01, 0x01, 0x40, 0xe4, 0x00, 0x01, 0x40, 0x74, 0xc0, 0x07,
0x40, 0x3c, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
};
QBitmap picker_bitmap = bitmapFromData(QSize(32, 32), pickerplus_bits);
QBitmap picker_mask = picker_bitmap.createHeuristicMask(false);
return QCursor(picker_bitmap, picker_mask, 6, 25);
}
QCursor KisCursor::pickerMinusCursor()
{
static const unsigned char pickerminus_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x80, 0x1e,
0x00, 0x00, 0x40, 0x1f, 0x00, 0x00, 0xb0, 0x1f, 0x00, 0x00, 0xe8, 0x0f,
0x00, 0x00, 0xd0, 0x07, 0x00, 0x00, 0xa8, 0x03, 0x00, 0x00, 0x64, 0x03,
0x00, 0x00, 0x72, 0x01, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x80, 0x1c, 0x00,
0x00, 0x40, 0x0e, 0x00, 0x00, 0x20, 0x07, 0x00, 0x00, 0x90, 0x03, 0x00,
0x00, 0xc8, 0x01, 0x00, 0x40, 0xe4, 0x00, 0x00, 0x40, 0x74, 0xc0, 0x07,
0x40, 0x3c, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
};
QBitmap picker_bitmap = bitmapFromData(QSize(32, 32), pickerminus_bits);
QBitmap picker_mask = picker_bitmap.createHeuristicMask(false);
return QCursor(picker_bitmap, picker_mask, 6, 25);
}
QCursor KisCursor::pickLayerCursor()
{
return load("precise-pick-layer-icon.xpm", 7, 23);
}
QCursor KisCursor::penCursor()
{
static const unsigned char pen_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x7d,
0x00, 0x80, 0x7e, 0x00, 0x40, 0x7f, 0x00, 0xa0, 0x3f, 0x00, 0xd0, 0x1f,
0x00, 0xe8, 0x0f, 0x00, 0xf4, 0x07, 0x00, 0xfa, 0x03, 0x00, 0xfd, 0x01,
0x80, 0xfe, 0x00, 0x40, 0x7f, 0x00, 0xa0, 0x3f, 0x00, 0xf0, 0x1f, 0x00,
0xd0, 0x0f, 0x00, 0x88, 0x07, 0x00, 0x88, 0x03, 0x00, 0xe4, 0x01, 0x00,
0x7c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00
};
QBitmap pen_bitmap = bitmapFromData(QSize(24, 24), pen_bits);
QBitmap pen_mask = pen_bitmap.createHeuristicMask(false);
return QCursor(pen_bitmap, pen_mask, 1, 22);
}
QCursor KisCursor::brushCursor()
{
static const unsigned char brush_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x68, 0x00,
0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0xfd, 0x00,
0x00, 0x80, 0x7e, 0x00, 0x00, 0x40, 0x3f, 0x00, 0x00, 0xa0, 0x1f, 0x00,
0x00, 0xd0, 0x0f, 0x00, 0x00, 0xe8, 0x07, 0x00, 0x00, 0xf4, 0x03, 0x00,
0x00, 0xe4, 0x01, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x80, 0x41, 0x00, 0x00,
0x40, 0x32, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x00, 0xd0, 0x0f, 0x00, 0x00,
0xd0, 0x0f, 0x00, 0x00, 0xe8, 0x07, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
QBitmap brush_bitmap = bitmapFromData(QSize(25, 23), brush_bits);
QBitmap brush_mask = brush_bitmap.createHeuristicMask(false);
return QCursor(brush_bitmap, brush_mask, 1, 21);
}
QCursor KisCursor::airbrushCursor()
{
static const unsigned char airbrush_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x68, 0x00, 0x00, 0x74,
0x00, 0x00, 0x7a, 0xf0, 0x00, 0x3d, 0x08, 0x81, 0x1e, 0xe8, 0x41, 0x0f,
0xe8, 0xa1, 0x07, 0xe8, 0xd1, 0x03, 0xe8, 0xe9, 0x01, 0xe8, 0xf5, 0x00,
0xe8, 0x7b, 0x00, 0xf0, 0x33, 0x00, 0xf0, 0x23, 0x1f, 0xa0, 0x9f, 0x3f,
0xd0, 0xff, 0x31, 0xe8, 0xf7, 0x30, 0xf4, 0x03, 0x18, 0xfc, 0x01, 0x0c,
0xf8, 0x00, 0x06, 0x76, 0x00, 0x03, 0x36, 0x00, 0x03, 0x00, 0x00, 0x00
};
QBitmap airbrush_bitmap = bitmapFromData(QSize(24, 24), airbrush_bits);
QBitmap airbrush_mask = airbrush_bitmap.createHeuristicMask(false);
return QCursor(airbrush_bitmap, airbrush_mask, 1, 22);
}
QCursor KisCursor::eraserCursor()
{
static const unsigned char eraser_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1d, 0x00,
0x00, 0x80, 0x3e, 0x00, 0x00, 0x40, 0x7f, 0x00, 0x00, 0xa0, 0xff, 0x00,
0x00, 0xd0, 0xff, 0x00, 0x00, 0xe8, 0x7f, 0x00, 0x00, 0xf4, 0x3f, 0x00,
0x00, 0xfe, 0x1f, 0x00, 0x00, 0xf9, 0x0f, 0x00, 0x80, 0xf2, 0x07, 0x00,
0x40, 0xe7, 0x03, 0x00, 0xa0, 0xcf, 0x01, 0x00, 0xd0, 0x9f, 0x00, 0x00,
0xe8, 0x7f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0xf2, 0x1f, 0x00, 0x00,
0xe2, 0x0f, 0x00, 0x00, 0xc4, 0x07, 0x00, 0x00, 0x88, 0x03, 0x00, 0x00,
0x10, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
QBitmap eraser_bitmap = bitmapFromData(QSize(25, 24), eraser_bits);
QBitmap eraser_mask = eraser_bitmap.createHeuristicMask(false);
return QCursor(eraser_bitmap, eraser_mask, 7, 22);
}
QCursor KisCursor::fillerCursor()
{
static const unsigned char filler_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x28, 0x00,
0x00, 0x54, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x85, 0x00, 0x80, 0x0a, 0x01,
0x40, 0x11, 0x01, 0xe0, 0x00, 0x02, 0x58, 0x01, 0x04, 0x2c, 0x02, 0x04,
0x44, 0x04, 0x08, 0x0c, 0x08, 0x18, 0x3c, 0x00, 0x14, 0x5c, 0x00, 0x0a,
0x9c, 0x01, 0x05, 0x1c, 0x82, 0x02, 0x18, 0x4c, 0x01, 0x18, 0xb0, 0x00,
0x08, 0x60, 0x00, 0x00, 0x00, 0x00
};
QBitmap filler_bitmap = bitmapFromData(QSize(22, 22), filler_bits);
QBitmap filler_mask = filler_bitmap.createHeuristicMask(false);
return QCursor(filler_bitmap, filler_mask, 3, 20);
}
QCursor KisCursor::colorChangerCursor()
{
static const unsigned char colorChanger_bits[] = {
0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x10, 0x01, 0x0e, 0x08, 0x02, 0x11,
0x04, 0x82, 0x20, 0x64, 0x84, 0x20, 0x92, 0x44, 0x46, 0x12, 0x49, 0x5f,
0x12, 0x31, 0x5f, 0x22, 0x01, 0x5f, 0xc2, 0x00, 0x4e, 0x02, 0x00, 0x40,
0xc2, 0x00, 0x46, 0xe2, 0x01, 0x4f, 0xe4, 0x19, 0x2f, 0xe4, 0x3d, 0x2f,
0xe8, 0x3d, 0x17, 0xd0, 0x3c, 0x10, 0x20, 0x38, 0x08, 0x40, 0x00, 0x06,
0x80, 0x81, 0x01, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00
};
QBitmap colorChanger_bitmap = bitmapFromData(QSize(24, 23), colorChanger_bits);
QBitmap colorChanger_mask = colorChanger_bitmap.createHeuristicMask(false);
return QCursor(colorChanger_bitmap, colorChanger_mask, 12, 10);
}
QCursor KisCursor::zoomSmoothCursor()
{
return load("zoom_smooth.xpm");
}
QCursor KisCursor::zoomDiscreteCursor()
{
return load("zoom_discrete.xpm");
}
QCursor KisCursor::rotateCanvasSmoothCursor()
{
return load("rotate_smooth.xpm");
}
QCursor KisCursor::rotateCanvasDiscreteCursor()
{
return load("rotate_discrete.xpm");
}
QCursor KisCursor::pickerImageForegroundCursor()
{
return load("color-picker_image_foreground.xpm", 8, 23);
}
QCursor KisCursor::pickerImageBackgroundCursor()
{
return load("color-picker_image_background.xpm", 8, 23);
}
QCursor KisCursor::pickerLayerForegroundCursor()
{
return load("color-picker_layer_foreground.xpm", 8, 23);
}
QCursor KisCursor::pickerLayerBackgroundCursor()
{
return load("color-picker_layer_background.xpm", 8, 23);
}
QCursor KisCursor::changeExposureCursor()
{
return load("exposure-cursor-gesture.xpm", 8, 23);
}
QCursor KisCursor::changeGammaCursor()
{
return load("gamma-cursor-gesture.xpm", 8, 23);
}
QCursor KisCursor::triangleLeftHandedCursor()
{
return load("cursor-triangle_lefthanded.xpm");
}
QCursor KisCursor::triangleRightHandedCursor()
{
return load("cursor-triangle_righthanded.xpm");
}
QCursor KisCursor::moveCursor()
{
static const unsigned char move_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x7e, 0x00,
0x00, 0xff, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00,
0x10, 0x18, 0x08, 0x18, 0x18, 0x18, 0x1c, 0x18, 0x38, 0xfe, 0xff, 0x7f,
0xfe, 0xff, 0x7f, 0x1c, 0x18, 0x38, 0x18, 0x18, 0x18, 0x10, 0x18, 0x08,
0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0xff, 0x00,
0x00, 0x7e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00
};
QBitmap move_bitmap = bitmapFromData(QSize(24, 24), move_bits);
QBitmap move_mask = move_bitmap.createHeuristicMask(false);
return QCursor(move_bitmap, move_mask, 12, 11);
}
QCursor KisCursor::handCursor()
{
return Qt::PointingHandCursor;
}
QCursor KisCursor::selectCursor()
{
static const unsigned char select_bits[] = {
0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00,
0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00,
0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0xff, 0xff, 0x7f,
0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00,
0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00,
0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00
};
QBitmap select_bitmap = bitmapFromData(QSize(23, 23), select_bits);
QBitmap select_mask = select_bitmap.createHeuristicMask(false);
return QCursor(select_bitmap, select_mask, 11, 11);
}
QCursor KisCursor::openHandCursor()
{
return Qt::OpenHandCursor;
}
QCursor KisCursor::closedHandCursor()
{
return Qt::ClosedHandCursor;
}
QCursor KisCursor::rotateCursor()
{
return load("rotate_cursor.xpm");
}
QCursor KisCursor::load(const QString & cursorName, int hotspotX, int hotspotY)
{
QImage cursorImage = QImage(":/" + cursorName);
if (cursorImage.isNull()) {
qWarning() << "Could not load cursor from qrc, trying filesystem" << cursorName;
cursorImage = QImage(KoResourcePaths::findResource("kis_pics", cursorName));
if (cursorImage.isNull()) {
qWarning() << "Could not load cursor from filesystem" << cursorName;
return Qt::ArrowCursor;
}
}
#ifdef Q_OS_WIN
// cursor width must be multiple of 16 on Windows
int bitmapWidth = qCeil(cursorImage.width() / 16.0) * 16;
if (hotspotX < 0) {
hotspotX = cursorImage.width() / 2;
}
QBitmap bitmap(bitmapWidth, cursorImage.height());
QBitmap mask(bitmapWidth, cursorImage.height());
if (bitmapWidth != cursorImage.width()) {
bitmap.clear();
mask.clear();
}
#else
QBitmap bitmap(cursorImage.width(), cursorImage.height());
QBitmap mask(cursorImage.width(), cursorImage.height());
#endif
QPainter bitmapPainter(&bitmap);
QPainter maskPainter(&mask);
for (qint32 x = 0; x < cursorImage.width(); ++x) {
for (qint32 y = 0; y < cursorImage.height(); ++y) {
QRgb pixel = cursorImage.pixel(x, y);
if (qAlpha(pixel) < 128) {
bitmapPainter.setPen(Qt::color0);
maskPainter.setPen(Qt::color0);
} else {
maskPainter.setPen(Qt::color1);
if (qGray(pixel) < 128) {
bitmapPainter.setPen(Qt::color1);
} else {
bitmapPainter.setPen(Qt::color0);
}
}
bitmapPainter.drawPoint(x, y);
maskPainter.drawPoint(x, y);
}
}
return QCursor(bitmap, mask, hotspotX, hotspotY);
}
QBitmap KisCursor::bitmapFromData(const QSize& size, const unsigned char* data)
{
QBitmap result(32, 32);
result.fill(Qt::color0);
QPainter painter(&result);
painter.drawPixmap(0, 0, QBitmap::fromData(size, data));
return result;
}
diff --git a/libs/ui/kis_cursor.h b/libs/ui/kis_cursor.h
index dc5f336d11..766c8bf47c 100644
--- a/libs/ui/kis_cursor.h
+++ b/libs/ui/kis_cursor.h
@@ -1,95 +1,97 @@
/*
* kis_cursor.h - part of KImageShop
*
* Copyright (c) 1999 Matthias Elter
* Copyright (c) 2004 Adrian Page
*
* 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.
*/
#ifndef __kis_cursor_h__
#define __kis_cursor_h__
#include
#include
class KRITAUI_EXPORT KisCursor
{
public:
KisCursor();
// Predefined Qt cursors.
static QCursor arrowCursor(); // standard arrow cursor
static QCursor upArrowCursor(); // upwards arrow
static QCursor crossCursor(); // crosshair
static QCursor roundCursor(); // small open circle
+ static QCursor pixelBlackCursor(); // black single pixel
+ static QCursor pixelWhiteCursor(); // white single pixel
static QCursor waitCursor(); // hourglass/watch
static QCursor ibeamCursor(); // ibeam/text entry
static QCursor sizeVerCursor(); // vertical resize
static QCursor sizeHorCursor(); // horizontal resize
static QCursor sizeBDiagCursor(); // diagonal resize (/)
static QCursor sizeFDiagCursor(); // diagonal resize (\)
static QCursor sizeAllCursor(); // all directions resize
static QCursor blankCursor(); // blank/invisible cursor
static QCursor splitVCursor(); // vertical splitting
static QCursor splitHCursor(); // horizontal splitting
static QCursor pointingHandCursor(); // a pointing hand
static QCursor zoomSmoothCursor();
static QCursor zoomDiscreteCursor();
static QCursor rotateCanvasSmoothCursor();
static QCursor rotateCanvasDiscreteCursor();
static QCursor pickerImageForegroundCursor();
static QCursor pickerImageBackgroundCursor();
static QCursor pickerLayerForegroundCursor();
static QCursor pickerLayerBackgroundCursor();
static QCursor changeExposureCursor();
static QCursor changeGammaCursor();
static QCursor triangleLeftHandedCursor();
static QCursor triangleRightHandedCursor();
// Existing custom KimageShop cursors. Use the 'load' function for all new cursors.
static QCursor moveCursor(); // move tool cursor
static QCursor penCursor(); // pen tool cursor
static QCursor brushCursor(); // brush tool cursor
static QCursor airbrushCursor(); // airbrush tool cursor
static QCursor eraserCursor(); // eraser tool cursor
static QCursor fillerCursor(); // filler tool cursor
static QCursor pickerCursor(); // color picker cursor
static QCursor pickerPlusCursor(); // color picker cursor
static QCursor pickerMinusCursor(); // color picker cursor
static QCursor pickLayerCursor(); // pick layer cursor
static QCursor colorChangerCursor(); // color changer tool cursor
static QCursor selectCursor(); // select cursor
static QCursor handCursor(); // hand tool cursor
static QCursor openHandCursor(); // Pan tool cursor
static QCursor closedHandCursor(); // Pan tool cursor
static QCursor rotateCursor(); // Transform tool cursor
// Load a cursor from an image file. The image should have an alpha channel
// and will be converted to black and white on loading. Any format loadable by
// QImage can be used.
static QCursor load(const QString & cursorName, int hotspotX = -1, int hotspotY = -1);
private:
// Makes a 32x32 bitmap that is compatible with different platforms
static QBitmap bitmapFromData(const QSize& size, const unsigned char* data);
};
#endif // __kis_cursor_h__
diff --git a/libs/ui/tool/kis_tool_freehand.cc b/libs/ui/tool/kis_tool_freehand.cc
index a1ae9d05fb..fed64b280a 100644
--- a/libs/ui/tool/kis_tool_freehand.cc
+++ b/libs/ui/tool/kis_tool_freehand.cc
@@ -1,418 +1,424 @@
/*
* kis_tool_freehand.cc - part of Krita
*
* Copyright (c) 2003-2007 Boudewijn Rempt
* Copyright (c) 2004 Bart Coppens
* Copyright (c) 2007,2008,2010 Cyrille Berger
* Copyright (c) 2009 Lukáš Tvrdý
*
* 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_tool_freehand.h"
#include
#include
#include
#include
#include
#include
#include
//pop up palette
#include
// Krita/image
#include
#include
#include
#include
#include
#include
// Krita/ui
#include "kis_abstract_perspective_grid.h"
#include "kis_config.h"
#include "canvas/kis_canvas2.h"
#include "kis_cursor.h"
#include
#include
#include "kis_painting_information_builder.h"
#include "kis_tool_freehand_helper.h"
#include "kis_recording_adapter.h"
#include "strokes/freehand_stroke.h"
KisToolFreehand::KisToolFreehand(KoCanvasBase * canvas, const QCursor & cursor, const KUndo2MagicString &transactionText)
: KisToolPaint(canvas, cursor)
{
m_assistant = false;
m_magnetism = 1.0;
m_only_one_assistant = true;
setSupportOutline(true);
setMaskSyntheticEvents(true); // Disallow mouse events from finger presses.
m_infoBuilder = new KisToolFreehandPaintingInformationBuilder(this);
m_recordingAdapter = new KisRecordingAdapter();
m_helper = new KisToolFreehandHelper(m_infoBuilder, transactionText, m_recordingAdapter);
connect(m_helper, SIGNAL(requestExplicitUpdateOutline()),
SLOT(explicitUpdateOutline()));
}
KisToolFreehand::~KisToolFreehand()
{
delete m_helper;
delete m_recordingAdapter;
delete m_infoBuilder;
}
KisSmoothingOptionsSP KisToolFreehand::smoothingOptions() const
{
return m_helper->smoothingOptions();
}
void KisToolFreehand::resetCursorStyle()
{
KisConfig cfg;
switch (cfg.newCursorStyle()) {
case CURSOR_STYLE_NO_CURSOR:
useCursor(KisCursor::blankCursor());
break;
case CURSOR_STYLE_POINTER:
useCursor(KisCursor::arrowCursor());
break;
case CURSOR_STYLE_SMALL_ROUND:
useCursor(KisCursor::roundCursor());
break;
case CURSOR_STYLE_CROSSHAIR:
useCursor(KisCursor::crossCursor());
break;
case CURSOR_STYLE_TRIANGLE_RIGHTHANDED:
useCursor(KisCursor::triangleRightHandedCursor());
break;
case CURSOR_STYLE_TRIANGLE_LEFTHANDED:
useCursor(KisCursor::triangleLeftHandedCursor());
break;
+ case CURSOR_STYLE_BLACK_PIXEL:
+ useCursor(KisCursor::pixelBlackCursor());
+ break;
+ case CURSOR_STYLE_WHITE_PIXEL:
+ useCursor(KisCursor::pixelWhiteCursor());
+ break;
case CURSOR_STYLE_TOOLICON:
default:
KisToolPaint::resetCursorStyle();
break;
}
}
KisPaintingInformationBuilder* KisToolFreehand::paintingInformationBuilder() const
{
return m_infoBuilder;
}
KisRecordingAdapter* KisToolFreehand::recordingAdapter() const
{
return m_recordingAdapter;
}
void KisToolFreehand::resetHelper(KisToolFreehandHelper *helper)
{
delete m_helper;
m_helper = helper;
}
int KisToolFreehand::flags() const
{
return KisTool::FLAG_USES_CUSTOM_COMPOSITEOP|KisTool::FLAG_USES_CUSTOM_PRESET;
}
void KisToolFreehand::activate(ToolActivation activation, const QSet &shapes)
{
KisToolPaint::activate(activation, shapes);
}
void KisToolFreehand::deactivate()
{
if (mode() == PAINT_MODE) {
endStroke();
setMode(KisTool::HOVER_MODE);
}
KisToolPaint::deactivate();
}
void KisToolFreehand::initStroke(KoPointerEvent *event)
{
setCurrentNodeLocked(true);
m_helper->initPaint(event, canvas()->resourceManager(),
image(),
currentNode(),
image().data(),
image()->postExecutionUndoAdapter());
}
void KisToolFreehand::doStroke(KoPointerEvent *event)
{
//set canvas information here?//
KisCanvas2 *canvas2 = dynamic_cast(canvas());
if (canvas2) {
m_helper->setCanvasHorizontalMirrorState(canvas2->xAxisMirrored());
m_helper->setCanvasRotation(canvas2->rotationAngle());
}
m_helper->paint(event);
}
void KisToolFreehand::endStroke()
{
m_helper->endPaint();
setCurrentNodeLocked(false);
}
bool KisToolFreehand::primaryActionSupportsHiResEvents() const
{
return true;
}
void KisToolFreehand::beginPrimaryAction(KoPointerEvent *event)
{
// FIXME: workaround for the Duplicate Op
tryPickByPaintOp(event, PickFgImage);
requestUpdateOutline(event->point, event);
NodePaintAbility paintability = nodePaintAbility();
if (!nodeEditable() || paintability != PAINT) {
if(paintability == KisToolPaint::VECTOR){
KisCanvas2 * kiscanvas = static_cast(canvas());
QString message = i18n("The brush tool cannot paint on this layer. Please select a paint layer or mask.");
kiscanvas->viewManager()->showFloatingMessage(message, koIcon("object-locked"));
}
event->ignore();
return;
}
setMode(KisTool::PAINT_MODE);
KisCanvas2 *canvas2 = dynamic_cast(canvas());
if (canvas2) {
canvas2->viewManager()->disableControls();
}
initStroke(event);
}
void KisToolFreehand::continuePrimaryAction(KoPointerEvent *event)
{
CHECK_MODE_SANITY_OR_RETURN(KisTool::PAINT_MODE);
requestUpdateOutline(event->point, event);
/**
* Actual painting
*/
doStroke(event);
}
void KisToolFreehand::endPrimaryAction(KoPointerEvent *event)
{
Q_UNUSED(event);
CHECK_MODE_SANITY_OR_RETURN(KisTool::PAINT_MODE);
endStroke();
if (m_assistant && static_cast(canvas())->paintingAssistantsDecoration()) {
static_cast(canvas())->paintingAssistantsDecoration()->endStroke();
}
notifyModified();
KisCanvas2 *canvas2 = dynamic_cast(canvas());
if (canvas2) {
canvas2->viewManager()->enableControls();
}
setMode(KisTool::HOVER_MODE);
}
bool KisToolFreehand::tryPickByPaintOp(KoPointerEvent *event, AlternateAction action)
{
if (action != PickFgNode && action != PickFgImage) return false;
/**
* FIXME: we need some better way to implement modifiers
* for a paintop level. This method is used in DuplicateOp only!
*/
QPointF pos = adjustPosition(event->point, event->point);
qreal perspective = 1.0;
Q_FOREACH (const QPointer grid, static_cast(canvas())->viewManager()->resourceProvider()->perspectiveGrids()) {
if (grid && grid->contains(pos)) {
perspective = grid->distance(pos);
break;
}
}
if (!currentPaintOpPreset()) {
return false;
}
bool paintOpIgnoredEvent = currentPaintOpPreset()->settings()->
mousePressEvent(KisPaintInformation(convertToPixelCoord(event->point),
pressureToCurve(event->pressure()),
event->xTilt(), event->yTilt(),
event->rotation(),
event->tangentialPressure(),
perspective, 0, 0),
event->modifiers(),
currentNode());
return !paintOpIgnoredEvent;
}
void KisToolFreehand::activateAlternateAction(AlternateAction action)
{
if (action != ChangeSize) {
KisToolPaint::activateAlternateAction(action);
return;
}
useCursor(KisCursor::blankCursor());
setOutlineEnabled(true);
}
void KisToolFreehand::deactivateAlternateAction(AlternateAction action)
{
if (action != ChangeSize) {
KisToolPaint::deactivateAlternateAction(action);
return;
}
resetCursorStyle();
setOutlineEnabled(false);
}
void KisToolFreehand::beginAlternateAction(KoPointerEvent *event, AlternateAction action)
{
if (tryPickByPaintOp(event, action)) return;
if (action != ChangeSize) {
KisToolPaint::beginAlternateAction(event, action);
return;
}
setMode(GESTURE_MODE);
m_initialGestureDocPoint = event->point;
m_initialGestureGlobalPoint = QCursor::pos();
m_lastDocumentPoint = event->point;
}
void KisToolFreehand::continueAlternateAction(KoPointerEvent *event, AlternateAction action)
{
if (tryPickByPaintOp(event, action)) return;
if (action != ChangeSize) {
KisToolPaint::continueAlternateAction(event, action);
return;
}
QPointF lastWidgetPosition = convertDocumentToWidget(m_lastDocumentPoint);
QPointF actualWidgetPosition = convertDocumentToWidget(event->point);
QPointF offset = actualWidgetPosition - lastWidgetPosition;
/**
* view pixels != widget pixels, but we do this anyway, we only
* need to scale the gesture down, not rotate or anything
*/
QPointF scaledOffset = canvas()->viewConverter()->viewToDocument(offset);
if (qRound(scaledOffset.x()) != 0) {
currentPaintOpPreset()->settings()->changePaintOpSize(scaledOffset.x(), scaledOffset.y());
requestUpdateOutline(m_initialGestureDocPoint, 0);
m_lastDocumentPoint = event->point;
}
}
void KisToolFreehand::endAlternateAction(KoPointerEvent *event, AlternateAction action)
{
if (tryPickByPaintOp(event, action)) return;
if (action != ChangeSize) {
KisToolPaint::endAlternateAction(event, action);
return;
}
QCursor::setPos(m_initialGestureGlobalPoint);
requestUpdateOutline(m_initialGestureDocPoint, 0);
setMode(HOVER_MODE);
}
bool KisToolFreehand::wantsAutoScroll() const
{
return false;
}
void KisToolFreehand::setAssistant(bool assistant)
{
m_assistant = assistant;
}
void KisToolFreehand::setOnlyOneAssistantSnap(bool assistant)
{
m_only_one_assistant = assistant;
}
QPointF KisToolFreehand::adjustPosition(const QPointF& point, const QPointF& strokeBegin)
{
if (m_assistant && static_cast(canvas())->paintingAssistantsDecoration()) {
static_cast(canvas())->paintingAssistantsDecoration()->setOnlyOneAssistantSnap(m_only_one_assistant);
QPointF ap = static_cast(canvas())->paintingAssistantsDecoration()->adjustPosition(point, strokeBegin);
return (1.0 - m_magnetism) * point + m_magnetism * ap;
}
return point;
}
qreal KisToolFreehand::calculatePerspective(const QPointF &documentPoint)
{
qreal perspective = 1.0;
Q_FOREACH (const QPointer grid, static_cast(canvas())->viewManager()->resourceProvider()->perspectiveGrids()) {
if (grid && grid->contains(documentPoint)) {
perspective = grid->distance(documentPoint);
break;
}
}
return perspective;
}
void KisToolFreehand::explicitUpdateOutline()
{
requestUpdateOutline(m_outlineDocPoint, 0);
}
QPainterPath KisToolFreehand::getOutlinePath(const QPointF &documentPos,
const KoPointerEvent *event,
KisPaintOpSettings::OutlineMode outlineMode)
{
QPointF imagePos = currentImage()->documentToPixel(documentPos);
if (currentPaintOpPreset())
return m_helper->paintOpOutline(imagePos,
event,
currentPaintOpPreset()->settings(),
outlineMode);
else
return QPainterPath();
}