You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
digikam/digikam/libs/widgets/common/squeezedcombobox.cpp

199 lines
5.1 KiB

/* ============================================================
*
* 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 <tomalbers@kde.nl>
* Copyright (C) 2006-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
*
* 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 <tqlistbox.h>
#include <tqcombobox.h>
#include <tqpair.h>
#include <tqtimer.h>
#include <tqvaluelist.h>
#include <tqstyle.h>
#include <tqapplication.h>
#include <tqtooltip.h>
#include <tqmap.h>
// Local includes.
#include "squeezedcombobox.h"
#include "squeezedcombobox.moc"
namespace Digikam
{
class SqueezedComboBoxPriv
{
public:
SqueezedComboBoxPriv()
{
timer = 0;
tooltip = 0;
}
TQMap<int, TQString> 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, TQT_SIGNAL(timeout()),
this, TQT_SLOT(slotTimeOut()));
connect(this, TQT_SIGNAL(activated( int )),
this, TQT_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<int,TQString> 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