File indexing completed on 2024-05-12 05:46:34

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