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