File indexing completed on 2024-04-28 08:32:22
0001 /* This file is part of the KDE project 0002 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr> 0003 Copyright (C) 2004 Alexander Dymo <cloudtemple@mskat.net> 0004 Copyright (C) 2008-2015 Jarosław Staniek <staniek@kde.org> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "cursoredit.h" 0023 #include "KProperty.h" 0024 #include "KPropertyCoreUtils_p.h" 0025 #include "KPropertyListData.h" 0026 #include "KPropertyUtils_p.h" 0027 0028 #include "xpm/blank_cursor.xpm" 0029 #include "xpm/arrow_cursor.xpm" 0030 #include "xpm/bdiag_cursor.xpm" 0031 #include "xpm/busy_cursor.xpm" 0032 #include "xpm/closedhand_cursor.xpm" 0033 #include "xpm/cross_cursor.xpm" 0034 #include "xpm/fdiag_cursor.xpm" 0035 #include "xpm/forbidden_cursor.xpm" 0036 #include "xpm/hand_cursor.xpm" 0037 #include "xpm/ibeam_cursor.xpm" 0038 #include "xpm/openhand_cursor.xpm" 0039 #include "xpm/sizeall_cursor.xpm" 0040 #include "xpm/sizehor_cursor.xpm" 0041 #include "xpm/sizever_cursor.xpm" 0042 #include "xpm/splith_cursor.xpm" 0043 #include "xpm/splitv_cursor.xpm" 0044 #include "xpm/uparrow_cursor.xpm" 0045 #include "xpm/wait_cursor.xpm" 0046 #include "xpm/whatsthis_cursor.xpm" 0047 0048 #include <QVariant> 0049 #include <QCursor> 0050 0051 class CursorListData : public KPropertyListData 0052 { 0053 public: 0054 CursorListData() : KPropertyListData(keysInternal(), stringsInternal()) 0055 { 0056 } 0057 0058 Qt::CursorShape indexToShape(int index) const 0059 { 0060 return static_cast<Qt::CursorShape>( 0061 keys().value(index, static_cast<int>(Qt::ArrowCursor)).toInt()); 0062 } 0063 0064 int shapeToIndex(Qt::CursorShape _shape) const 0065 { 0066 int index = 0; 0067 for (const QVariant &shape : keys()) { 0068 if (shape.toInt() == _shape) 0069 return index; 0070 index++; 0071 } 0072 return 0; 0073 } 0074 0075 QPixmap pixmapForIndex(int index, const QPalette& pal, bool transparentBackground = false) const 0076 { 0077 if (index < 0 || index > 18) 0078 index = 0; 0079 QPixmap xpm(m_xpms[index]); 0080 if (transparentBackground) 0081 return xpm; 0082 QPixmap px(xpm.size()); 0083 QColor bg( pal.color(QPalette::Base) ); // paint bg with to avoid invisible black-on-black painting 0084 bg.setAlpha(127); 0085 px.fill(bg); 0086 QPainter p(&px); 0087 p.drawPixmap(0, 2, xpm); 0088 return px; 0089 } 0090 private: 0091 static QList<QVariant> keysInternal() { 0092 QList<QVariant> keys; 0093 keys 0094 << int(Qt::BlankCursor) 0095 << int(Qt::ArrowCursor) 0096 << int(Qt::UpArrowCursor) 0097 << int(Qt::CrossCursor) 0098 << int(Qt::WaitCursor) 0099 << int(Qt::IBeamCursor) 0100 << int(Qt::SizeVerCursor) 0101 << int(Qt::SizeHorCursor) 0102 << int(Qt::SizeBDiagCursor) 0103 << int(Qt::SizeFDiagCursor) 0104 << int(Qt::SizeAllCursor) 0105 << int(Qt::SplitVCursor) 0106 << int(Qt::SplitHCursor) 0107 << int(Qt::PointingHandCursor) 0108 << int(Qt::ForbiddenCursor) 0109 << int(Qt::WhatsThisCursor) 0110 << int(Qt::BusyCursor) 0111 << int(Qt::OpenHandCursor) 0112 << int(Qt::ClosedHandCursor); 0113 return keys; 0114 } 0115 0116 static QStringList stringsInternal() { 0117 QStringList strings; 0118 strings << QObject::tr("No cursor", "Mouse Cursor Shape") //0 0119 << QObject::tr("Arrow", "Mouse Cursor Shape") //1 0120 << QObject::tr("Up arrow", "Mouse Cursor Shape") //2 0121 << QObject::tr("Cross", "Mouse Cursor Shape") //3 0122 << QObject::tr("Waiting", "Mouse Cursor Shape") //4 0123 << QObject::tr("Text cursor", "Mouse Cursor Shape") //5 0124 << QObject::tr("Size vertical", "Mouse Cursor Shape") //6 0125 << QObject::tr("Size horizontal", "Mouse Cursor Shape") //7 0126 << QObject::tr("Size slash", "Mouse Cursor Shape") //8 0127 << QObject::tr("Size backslash", "Mouse Cursor Shape") //9 0128 << QObject::tr("Size all", "Mouse Cursor Shape") //10 0129 << QObject::tr("Split vertical", "Mouse Cursor Shape") //11 0130 << QObject::tr("Split horizontal", "Mouse Cursor Shape") //12 0131 << QObject::tr("Pointing hand", "Mouse Cursor Shape") //13 0132 << QObject::tr("Forbidden", "Mouse Cursor Shape") //14 0133 << QObject::tr("What's this?", "Mouse Cursor Shape") //15 0134 << QObject::tr("Busy", "Mouse Cursor Shape") //16 0135 << QObject::tr("Open hand", "Mouse Cursor Shape") //17 0136 << QObject::tr("Closed hand", "Mouse Cursor Shape"); //18 0137 return strings; 0138 } 0139 static const char * const * const m_xpms[]; 0140 }; 0141 0142 const char * const * const CursorListData::m_xpms[] = 0143 { 0144 blank_cursor_xpm, 0145 arrow_cursor_xpm, 0146 uparrow_cursor_xpm, 0147 cross_cursor_xpm, 0148 wait_cursor_xpm, 0149 ibeam_cursor_xpm, 0150 sizever_cursor_xpm, 0151 sizehor_cursor_xpm, 0152 bdiag_cursor_xpm, 0153 fdiag_cursor_xpm, 0154 sizeall_cursor_xpm, 0155 splitv_cursor_xpm, 0156 splith_cursor_xpm, 0157 hand_cursor_xpm, 0158 forbidden_cursor_xpm, 0159 whatsthis_cursor_xpm, 0160 busy_cursor_xpm, 0161 openhand_cursor_xpm, 0162 closedhand_cursor_xpm 0163 }; 0164 0165 Q_GLOBAL_STATIC(CursorListData, s_cursorListData) 0166 0167 //---------------------- 0168 0169 class CursorIconProvider : public KPropertyComboBoxEditorIconProviderInterface 0170 { 0171 public: 0172 explicit CursorIconProvider(QWidget* parent) : m_parent(parent) {} 0173 QIcon icon(int index) const override 0174 { 0175 return s_cursorListData->pixmapForIndex(index, m_parent->palette()); 0176 } 0177 KPropertyComboBoxEditorIconProviderInterface *clone() const override 0178 { 0179 return new CursorIconProvider(m_parent); 0180 } 0181 QWidget* m_parent; 0182 }; 0183 0184 //---------------------- 0185 0186 static KPropertyComboBoxEditorOptions initComboBoxOptions(QWidget* parent) 0187 { 0188 KPropertyComboBoxEditorOptions options; 0189 options.iconProvider = new CursorIconProvider(parent); 0190 return options; 0191 } 0192 0193 class Q_DECL_HIDDEN KPropertyCursorEditor::Private 0194 { 0195 public: 0196 Private() 0197 { 0198 } 0199 }; 0200 0201 KPropertyCursorEditor::KPropertyCursorEditor(QWidget *parent) 0202 : KPropertyComboBoxEditor(*s_cursorListData, initComboBoxOptions( this ), parent), 0203 d(new Private) 0204 { 0205 int paddingTop = 1; 0206 int paddingLeft = 2; 0207 const QString style(parent->style()->objectName()); 0208 if (!KPropertyUtilsPrivate::gridLineColor(this).isValid()) { 0209 setFrame(false); 0210 paddingTop = 0; 0211 } 0212 if (style == QLatin1String("windowsvista") || style == QLatin1String("fusion")) { 0213 paddingLeft = 1; 0214 } 0215 QString styleSheet = QString::fromLatin1("QComboBox { \ 0216 %1 \ 0217 padding-top: %2px; padding-left: %3px; }").arg(KPropertyComboBoxEditor::borderSheet(this)) 0218 .arg(paddingTop).arg(paddingLeft); 0219 setStyleSheet(styleSheet); 0220 } 0221 0222 KPropertyCursorEditor::~KPropertyCursorEditor() 0223 { 0224 delete d; 0225 } 0226 0227 QCursor KPropertyCursorEditor::cursorValue() const 0228 { 0229 return QCursor((Qt::CursorShape)KPropertyComboBoxEditor::value().toInt()); 0230 } 0231 0232 void KPropertyCursorEditor::setCursorValue(const QCursor &value) 0233 { 0234 KPropertyComboBoxEditor::setValue( (int)(value.shape()) ); 0235 } 0236 0237 //--------------- 0238 0239 KPropertyCursorDelegate::KPropertyCursorDelegate() 0240 { 0241 options()->setBordersVisible(true); 0242 } 0243 0244 QWidget * KPropertyCursorDelegate::createEditor( int type, QWidget *parent, 0245 const QStyleOptionViewItem & option, const QModelIndex & index ) const 0246 { 0247 Q_UNUSED(type); 0248 Q_UNUSED(option); 0249 Q_UNUSED(index); 0250 return new KPropertyCursorEditor(parent); 0251 } 0252 0253 void KPropertyCursorDelegate::paint( QPainter * painter, 0254 const QStyleOptionViewItem & option, const QModelIndex & index ) const 0255 { 0256 const KPropertyUtilsPrivate::PainterSaver saver(painter); 0257 int comboIndex = s_cursorListData->shapeToIndex( index.data(Qt::EditRole).value<QCursor>().shape() ); 0258 int pmSize = (option.rect.height() >= 32) ? 32 : 16; 0259 const QPixmap pm( s_cursorListData->pixmapForIndex(comboIndex, option.palette) 0260 .scaled(pmSize, pmSize, Qt::KeepAspectRatio, Qt::SmoothTransformation) ); 0261 QPoint pmPoint(option.rect.topLeft() + QPoint(2, 1)); 0262 painter->drawPixmap(pmPoint, pm); 0263 QRect r(option.rect); 0264 r.setLeft(7 + r.left() + 1 + pm.width()); 0265 painter->drawText(r, Qt::AlignVCenter | Qt::AlignLeft, valueToString(index.data(Qt::EditRole), QLocale())); 0266 } 0267 0268 QString KPropertyCursorDelegate::valueToString(const QVariant& value, const QLocale &locale) const 0269 { 0270 const Qt::CursorShape shape = value.value<QCursor>().shape(); 0271 if (locale.language() == QLocale::C) { 0272 return KPropertyUtils::keyForEnumValue("CursorShape", shape); 0273 } 0274 const int comboIndex = s_cursorListData->shapeToIndex(shape); 0275 return s_cursorListData->names().value(comboIndex).toString(); 0276 }