/* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2005-01-01 * Description : a combo box with a width not depending of text * content size * * Copyright (C) 2005 by Tom Albers * Copyright (C) 2006-2007 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ /** @file squeezedcombobox.cpp */ // TQt includes. #include #include #include #include #include #include #include #include #include // Local includes. #include "squeezedcombobox.h" #include "squeezedcombobox.moc" namespace Digikam { class SqueezedComboBoxPriv { public: SqueezedComboBoxPriv() { timer = 0; tooltip = 0; } TQMap originalItems; TQTimer *timer; SqueezedComboBoxTip *tooltip; }; SqueezedComboBox::SqueezedComboBox(TQWidget *parent, const char *name) : TQComboBox(parent, name) { d = new SqueezedComboBoxPriv; d->timer = new TQTimer(this); // See B.K.O #138747 : always for TQComboBox instance to use a TQListbox to // render content independently of Widget style used. setListBox(new TQListBox(this)); d->tooltip = new SqueezedComboBoxTip(listBox()->viewport(), this); setMinimumWidth(100); connect(d->timer, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotTimeOut())); connect(this, TQ_SIGNAL(activated( int )), this, TQ_SLOT(slotUpdateToolTip( int ))); } SqueezedComboBox::~SqueezedComboBox() { delete d->tooltip; delete d->timer; delete d; } TQSize SqueezedComboBox::sizeHint() const { constPolish(); TQFontMetrics fm = fontMetrics(); int maxW = count() ? 18 : 7 * fm.width(TQChar('x')) + 18; int maxH = TQMAX( fm.lineSpacing(), 14 ) + 2; return style().sizeFromContents(TQStyle::CT_ComboBox, this, TQSize(maxW, maxH)).expandedTo(TQApplication::globalStrut()); } void SqueezedComboBox::insertSqueezedItem(const TQString& newItem, int index) { d->originalItems[index] = newItem; insertItem( squeezeText(newItem), index ); // if this is the first item, set the tooltip. if (index == 0) slotUpdateToolTip(0); } void SqueezedComboBox::insertSqueezedList(const TQStringList& newItems, int index) { for(TQStringList::const_iterator it = newItems.begin() ; it != newItems.end() ; ++it) { insertSqueezedItem(*it, index); index++; } } void SqueezedComboBox::resizeEvent(TQResizeEvent *) { d->timer->start(200, true); } void SqueezedComboBox::slotTimeOut() { TQMapIterator it; for (it = d->originalItems.begin() ; it != d->originalItems.end(); ++it) { changeItem(squeezeText(it.data()), it.key()); } } TQString SqueezedComboBox::squeezeText(const TQString& original) { // not the complete widgetSize is usable. Need to compensate for that. int widgetSize = width()-30; TQFontMetrics fm(fontMetrics()); // If we can fit the full text, return that. if (fm.width(original) < widgetSize) return(original); // We need to squeeze. TQString sqItem = original; // prevent empty return value; widgetSize = widgetSize-fm.width("..."); for (uint i = 0 ; i != original.length(); ++i) { if ((int)fm.width(original.right(i)) > widgetSize) { sqItem = TQString(original.left(i) + "..."); break; } } return sqItem; } void SqueezedComboBox::slotUpdateToolTip(int index) { TQToolTip::remove(this); TQToolTip::add(this, d->originalItems[index]); } TQString SqueezedComboBox::itemHighlighted() { int curItem = listBox()->currentItem(); return d->originalItems[curItem]; } // ------------------------------------------------------------------------ SqueezedComboBoxTip::SqueezedComboBoxTip(TQWidget *parent, SqueezedComboBox *name) : TQToolTip( parent ) { m_originalWidget = name; } void SqueezedComboBoxTip::maybeTip(const TQPoint &pos) { TQListBox* listBox = m_originalWidget->listBox(); if (!listBox) return; TQListBoxItem* selectedItem = listBox->itemAt( pos ); if (selectedItem) { TQRect positionToolTip = listBox->itemRect(selectedItem); TQString toolTipText = m_originalWidget->itemHighlighted(); if (!toolTipText.isNull()) tip(positionToolTip, toolTipText); } } } // namespace Digikam