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