File indexing completed on 2024-05-12 16:02:29
0001 /* ============================================================ 0002 * Author: Tom Albers <tomalbers@kde.nl> 0003 * Date : 2005-01-01 0004 * Description : 0005 * 0006 * SPDX-FileCopyrightText: 2005 Tom Albers <tomalbers@kde.nl> 0007 * 0008 * SPDX-License-Identifier: GPL-2.0-or-later 0009 * 0010 * ============================================================ */ 0011 0012 #include "KisSqueezedComboBox.h" 0013 /** @file KisSqueezedComboBox.cpp */ 0014 0015 // Qt includes. 0016 0017 #include <QComboBox> 0018 #include <QPair> 0019 #include <QTimer> 0020 #include <QStyle> 0021 #include <QApplication> 0022 #include <QResizeEvent> 0023 0024 KisSqueezedComboBox::KisSqueezedComboBox(QWidget *parent, const char *name) 0025 : QComboBox(parent) 0026 { 0027 setObjectName(name); 0028 setMinimumWidth(100); 0029 m_timer = new QTimer(this); 0030 m_timer->setSingleShot(true); 0031 connect(m_timer, SIGNAL(timeout()), 0032 SLOT(slotTimeOut())); 0033 } 0034 0035 KisSqueezedComboBox::~KisSqueezedComboBox() 0036 { 0037 delete m_timer; 0038 } 0039 0040 bool KisSqueezedComboBox::contains(const QString& _text) const 0041 { 0042 if (_text.isEmpty()) 0043 return false; 0044 0045 for (QMap<int, QString>::const_iterator it = m_originalItems.begin() ; it != m_originalItems.end(); 0046 ++it) { 0047 if (it.value() == _text) { 0048 return true; 0049 } 0050 } 0051 return false; 0052 } 0053 0054 qint32 KisSqueezedComboBox::findOriginalText(const QString& text) const 0055 { 0056 for (int i = 0; i < m_originalItems.size(); i++) { 0057 if(m_originalItems.value(i) == text) { 0058 return i; 0059 } 0060 } 0061 return -1; 0062 } 0063 0064 QStringList KisSqueezedComboBox::originalTexts() const 0065 { 0066 return m_originalItems.values(); 0067 } 0068 0069 void KisSqueezedComboBox::resetOriginalTexts(const QStringList &texts) 0070 { 0071 if (texts == m_originalItems.values()) return; 0072 0073 clear(); 0074 m_originalItems.clear(); 0075 0076 Q_FOREACH (const QString &item, texts) { 0077 addSqueezedItem(item); 0078 } 0079 } 0080 0081 QSize KisSqueezedComboBox::sizeHint() const 0082 { 0083 ensurePolished(); 0084 QFontMetrics fm = fontMetrics(); 0085 int maxW = count() ? 18 : 7 * fm.boundingRect(QChar('x')).width() + 18; 0086 int maxH = qMax(fm.lineSpacing(), 14) + 2; 0087 0088 QStyleOptionComboBox options; 0089 options.initFrom(this); 0090 0091 return style()->sizeFromContents(QStyle::CT_ComboBox, &options, QSize(maxW, maxH), this); 0092 } 0093 0094 void KisSqueezedComboBox::insertSqueezedItem(const QString& newItem, int index, QVariant userData) 0095 { 0096 m_originalItems[index] = newItem; 0097 QComboBox::insertItem(index, squeezeText(newItem, this), userData); 0098 setItemData(index, newItem, Qt::ToolTipRole); 0099 } 0100 0101 void KisSqueezedComboBox::insertSqueezedItem(const QIcon &icon, const QString &newItem, int index, QVariant userData) 0102 { 0103 m_originalItems[index] = newItem; 0104 QComboBox::insertItem(index, icon, squeezeText(newItem, this), userData); 0105 setItemData(index, newItem, Qt::ToolTipRole); 0106 } 0107 0108 void KisSqueezedComboBox::addSqueezedItem(const QString& newItem, QVariant userData) 0109 { 0110 insertSqueezedItem(newItem, count(), userData); 0111 } 0112 0113 void KisSqueezedComboBox::addSqueezedItem(const QIcon &icon, const QString &newItem, QVariant userData) 0114 { 0115 insertSqueezedItem(icon, newItem, count(), userData); 0116 } 0117 0118 void KisSqueezedComboBox::setCurrent(const QString& itemText) 0119 { 0120 qint32 itemIndex = findOriginalText(itemText); 0121 if (itemIndex >= 0) { 0122 setCurrentIndex(itemIndex); 0123 } 0124 } 0125 0126 void KisSqueezedComboBox::resizeEvent(QResizeEvent *) 0127 { 0128 m_timer->start(200); 0129 } 0130 0131 void KisSqueezedComboBox::slotTimeOut() 0132 { 0133 for (QMap<int, QString>::iterator it = m_originalItems.begin() ; it != m_originalItems.end(); 0134 ++it) { 0135 setItemText(it.key(), squeezeText(it.value(), this)); 0136 } 0137 } 0138 0139 QString KisSqueezedComboBox::squeezeText(const QString& original, const QWidget *widget) 0140 { 0141 // not the complete widgetSize is usable. Need to compensate for that. 0142 int widgetSize = widget->width() - 30; 0143 QFontMetrics fm(widget->fontMetrics()); 0144 0145 // If we can fit the full text, return that. 0146 if (fm.boundingRect(original).width() < widgetSize) 0147 return(original); 0148 0149 // We need to squeeze. 0150 QString sqItem = original; // prevent empty return value; 0151 widgetSize = widgetSize - fm.boundingRect("...").width(); 0152 for (int i = 0 ; i != original.length(); ++i) { 0153 if ((int)fm.boundingRect(original.right(i)).width() > widgetSize) { 0154 sqItem = QString("..." + original.right(--i)); 0155 break; 0156 } 0157 } 0158 return sqItem; 0159 } 0160 0161 QString KisSqueezedComboBox::currentUnsqueezedText() 0162 { 0163 int curItem = currentIndex(); 0164 return m_originalItems[curItem]; 0165 } 0166 0167 void KisSqueezedComboBox::removeSqueezedItem(int index) 0168 { 0169 removeItem(index); 0170 m_originalItems.remove(index); 0171 } 0172