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.
632 lines
22 KiB
632 lines
22 KiB
/***************************************************************************
|
|
* Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> *
|
|
* *
|
|
* 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 of the License, 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. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
***************************************************************************/
|
|
|
|
#include "infosidebarpage.h"
|
|
#include <assert.h>
|
|
|
|
#include <tqlayout.h>
|
|
#include <tqpixmap.h>
|
|
#include <tqlabel.h>
|
|
#include <tqtimer.h>
|
|
#include <tqpushbutton.h>
|
|
#include <tqvbox.h>
|
|
#include <tqvgroupbox.h>
|
|
#include <tqpopupmenu.h>
|
|
#include <tqpainter.h>
|
|
#include <tqfontmetrics.h>
|
|
#include <tqgrid.h>
|
|
#include <tqhgroupbox.h>
|
|
|
|
#include <kbookmarkmanager.h>
|
|
#include <tdelocale.h>
|
|
#include <kstandarddirs.h>
|
|
#include <tdeio/previewjob.h>
|
|
#include <tdefileitem.h>
|
|
#include <kdialog.h>
|
|
#include <tdeglobalsettings.h>
|
|
#include <tdefilemetainfo.h>
|
|
|
|
#include "dolphin.h"
|
|
#include "pixmapviewer.h"
|
|
#include "dolphinsettings.h"
|
|
|
|
InfoSidebarPage::InfoSidebarPage(TQWidget* parent) :
|
|
SidebarPage(parent),
|
|
m_multipleSelection(false),
|
|
m_pendingPreview(false),
|
|
m_timer(0),
|
|
m_preview(0),
|
|
m_name(0),
|
|
m_currInfoLineIdx(0),
|
|
m_infoGrid(0),
|
|
m_actionBox(0)
|
|
{
|
|
const int spacing = KDialog::spacingHint();
|
|
|
|
m_timer = new TQTimer(this);
|
|
connect(m_timer, TQT_SIGNAL(timeout()),
|
|
this, TQT_SLOT(slotTimeout()));
|
|
|
|
TQVBoxLayout* layout = new TQVBoxLayout(this);
|
|
layout->setSpacing(spacing);
|
|
|
|
// preview
|
|
m_preview = new PixmapViewer(this);
|
|
m_preview->setMinimumWidth(TDEIcon::SizeEnormous);
|
|
m_preview->setFixedHeight(TDEIcon::SizeEnormous);
|
|
|
|
// name
|
|
m_name = new TQLabel(this);
|
|
m_name->setTextFormat(TQt::RichText);
|
|
m_name->setAlignment(m_name->alignment() | TQt::AlignHCenter);
|
|
TQFontMetrics fontMetrics(m_name->font());
|
|
m_name->setMinimumHeight(fontMetrics.height() * 3);
|
|
m_name->setSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::Maximum);
|
|
|
|
TQWidget* sep1 = new TQHGroupBox(this); // TODO: check whether default widget exist for this?
|
|
sep1->setFixedHeight(1);
|
|
|
|
// general information
|
|
m_infoGrid = new TQGrid(2, this);
|
|
m_infoGrid->setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Fixed);
|
|
|
|
TQWidget* sep2 = new TQHGroupBox(this); // TODO: check whether default widget exist for this?
|
|
sep2->setFixedHeight(1);
|
|
|
|
// actions
|
|
m_actionBox = new TQVBox(this);
|
|
m_actionBox->setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Fixed);
|
|
|
|
// Add a dummy widget with no restriction regarding a vertical resizing.
|
|
// This assures that information is always top aligned.
|
|
TQWidget* dummy = new TQWidget(this);
|
|
|
|
layout->addItem(new TQSpacerItem(spacing, spacing, TQSizePolicy::Preferred, TQSizePolicy::Fixed));
|
|
layout->addWidget(m_preview);
|
|
layout->addWidget(m_name);
|
|
layout->addWidget(sep1);
|
|
layout->addWidget(m_infoGrid);
|
|
layout->addWidget(sep2);
|
|
layout->addWidget(m_actionBox);
|
|
layout->addWidget(dummy);
|
|
|
|
connect(&Dolphin::mainWin(), TQT_SIGNAL(selectionChanged()),
|
|
this, TQT_SLOT(showItemInfo()));
|
|
|
|
connectToActiveView();
|
|
}
|
|
|
|
InfoSidebarPage::~InfoSidebarPage()
|
|
{
|
|
}
|
|
|
|
void InfoSidebarPage::activeViewChanged()
|
|
{
|
|
connectToActiveView();
|
|
}
|
|
|
|
void InfoSidebarPage::requestDelayedItemInfo(const KURL& url)
|
|
{
|
|
cancelRequest();
|
|
|
|
if (!url.isEmpty() && !m_multipleSelection) {
|
|
m_urlCandidate = url;
|
|
m_timer->start(300, true);
|
|
}
|
|
}
|
|
|
|
void InfoSidebarPage::requestItemInfo(const KURL& url)
|
|
{
|
|
cancelRequest();
|
|
|
|
if (!url.isEmpty() && !m_multipleSelection) {
|
|
m_shownURL = url;
|
|
showItemInfo();
|
|
}
|
|
}
|
|
|
|
void InfoSidebarPage::showItemInfo()
|
|
{
|
|
cancelRequest();
|
|
|
|
m_multipleSelection = false;
|
|
|
|
// show the preview...
|
|
DolphinView* view = Dolphin::mainWin().activeView();
|
|
const KFileItemList* selectedItems = view->selectedItems();
|
|
if ((selectedItems != 0) && selectedItems->count() > 1) {
|
|
m_multipleSelection = true;
|
|
}
|
|
|
|
if (m_multipleSelection) {
|
|
TDEIconLoader iconLoader;
|
|
TQPixmap icon = iconLoader.loadIcon("application-x-executable",
|
|
TDEIcon::NoGroup,
|
|
TDEIcon::SizeEnormous);
|
|
m_preview->setPixmap(icon);
|
|
m_name->setText(i18n("%n items selected", "%n items selected", selectedItems->count()));
|
|
}
|
|
else if (!applyBookmark()) {
|
|
// try to get a preview pixmap from the item...
|
|
KURL::List list;
|
|
list.append(m_shownURL);
|
|
|
|
m_pendingPreview = true;
|
|
m_preview->setPixmap(TQPixmap());
|
|
|
|
TDEIO::PreviewJob* job = TDEIO::filePreview(list,
|
|
m_preview->width(),
|
|
TDEIcon::SizeEnormous);
|
|
connect(job, TQT_SIGNAL(gotPreview(const KFileItem*, const TQPixmap&)),
|
|
this, TQT_SLOT(gotPreview(const KFileItem*, const TQPixmap&)));
|
|
connect(job, TQT_SIGNAL(failed(const KFileItem*)),
|
|
this, TQT_SLOT(slotPreviewFailed(const KFileItem*)));
|
|
|
|
TQString text("<b>");
|
|
text.append(m_shownURL.fileName());
|
|
text.append("</b>");
|
|
m_name->setText(text);
|
|
}
|
|
|
|
createMetaInfo();
|
|
insertActions();
|
|
}
|
|
|
|
void InfoSidebarPage::slotTimeout()
|
|
{
|
|
m_shownURL = m_urlCandidate;
|
|
showItemInfo();
|
|
}
|
|
|
|
void InfoSidebarPage::slotPreviewFailed(const KFileItem* item)
|
|
{
|
|
m_pendingPreview = false;
|
|
if (!applyBookmark()) {
|
|
m_preview->setPixmap(item->pixmap(TDEIcon::SizeEnormous));
|
|
}
|
|
}
|
|
|
|
void InfoSidebarPage::gotPreview(const KFileItem* /* item */,
|
|
const TQPixmap& pixmap)
|
|
{
|
|
if (m_pendingPreview) {
|
|
m_preview->setPixmap(pixmap);
|
|
m_pendingPreview = false;
|
|
}
|
|
}
|
|
|
|
void InfoSidebarPage::startService(int index)
|
|
{
|
|
DolphinView* view = Dolphin::mainWin().activeView();
|
|
if (view->hasSelection()) {
|
|
KURL::List selectedURLs = view->selectedURLs();
|
|
KDEDesktopMimeType::executeService(selectedURLs, m_actionsVector[index]);
|
|
}
|
|
else {
|
|
KDEDesktopMimeType::executeService(m_shownURL, m_actionsVector[index]);
|
|
}
|
|
}
|
|
|
|
void InfoSidebarPage::connectToActiveView()
|
|
{
|
|
cancelRequest();
|
|
|
|
DolphinView* view = Dolphin::mainWin().activeView();
|
|
connect(view, TQT_SIGNAL(signalRequestItemInfo(const KURL&)),
|
|
this, TQT_SLOT(requestDelayedItemInfo(const KURL&)));
|
|
connect(view, TQT_SIGNAL(signalURLChanged(const KURL&)),
|
|
this, TQT_SLOT(requestItemInfo(const KURL&)));
|
|
|
|
m_shownURL = view->url();
|
|
showItemInfo();
|
|
}
|
|
|
|
bool InfoSidebarPage::applyBookmark()
|
|
{
|
|
KBookmarkGroup root = DolphinSettings::instance().bookmarkManager()->root();
|
|
KBookmark bookmark = root.first();
|
|
while (!bookmark.isNull()) {
|
|
if (m_shownURL.equals(bookmark.url(), true)) {
|
|
TQString text("<b>");
|
|
text.append(bookmark.text());
|
|
text.append("</b>");
|
|
m_name->setText(text);
|
|
|
|
TDEIconLoader iconLoader;
|
|
TQPixmap icon = iconLoader.loadIcon(bookmark.icon(),
|
|
TDEIcon::NoGroup,
|
|
TDEIcon::SizeEnormous);
|
|
m_preview->setPixmap(icon);
|
|
return true;
|
|
}
|
|
bookmark = root.next(bookmark);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void InfoSidebarPage::cancelRequest()
|
|
{
|
|
m_timer->stop();
|
|
m_pendingPreview = false;
|
|
}
|
|
|
|
void InfoSidebarPage::createMetaInfo()
|
|
{
|
|
// To prevent a flickering it's important to reuse available
|
|
// labels instead of deleting them and recreate them afterwards.
|
|
// The methods beginInfoLines(), addInfoLine() and endInfoLines()
|
|
// take care of this.
|
|
beginInfoLines();
|
|
DolphinView* view = Dolphin::mainWin().activeView();
|
|
if (!view->hasSelection()) {
|
|
KFileItem fileItem(S_IFDIR, KFileItem::Unknown, m_shownURL);
|
|
fileItem.refresh();
|
|
|
|
if (fileItem.isDir()) {
|
|
addInfoLine(i18n("Type:"), i18n("Directory"));
|
|
}
|
|
else {
|
|
addInfoLine(i18n("Type:"), fileItem.mimeComment());
|
|
|
|
TQString sizeText(TDEIO::convertSize(fileItem.size()));
|
|
addInfoLine(i18n("Size:"), sizeText);
|
|
addInfoLine(i18n("Modified:"), fileItem.timeString());
|
|
|
|
const KFileMetaInfo& metaInfo = fileItem.metaInfo();
|
|
if (metaInfo.isValid()) {
|
|
TQStringList keys = metaInfo.supportedKeys();
|
|
for (TQStringList::Iterator it = keys.begin(); it != keys.end(); ++it) {
|
|
if (showMetaInfo(*it)) {
|
|
KFileMetaInfoItem metaInfoItem = metaInfo.item(*it);
|
|
addInfoLine(*it, metaInfoItem.string());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
endInfoLines();
|
|
}
|
|
|
|
void InfoSidebarPage::beginInfoLines()
|
|
{
|
|
m_currInfoLineIdx = 0;
|
|
}
|
|
|
|
void InfoSidebarPage::endInfoLines()
|
|
{
|
|
if (m_currInfoLineIdx <= 0) {
|
|
return;
|
|
}
|
|
|
|
// remove labels which have not been used
|
|
if (m_currInfoLineIdx < static_cast<int>(m_infoWidgets.count())) {
|
|
TQPtrListIterator<TQLabel> deleteIter(m_infoWidgets);
|
|
deleteIter += m_currInfoLineIdx;
|
|
|
|
TQWidget* widget = 0;
|
|
int removeCount = 0;
|
|
while ((widget = deleteIter.current()) != 0) {
|
|
widget->close();
|
|
widget->deleteLater();
|
|
++deleteIter;
|
|
++removeCount;
|
|
}
|
|
for (int i = 0; i < removeCount; ++i) {
|
|
m_infoWidgets.removeLast();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool InfoSidebarPage::showMetaInfo(const TQString& key) const
|
|
{
|
|
// sorted list of keys, where it's data should be shown
|
|
static const char* keys[] = {
|
|
"Album",
|
|
"Artist",
|
|
"Author",
|
|
"Bitrate",
|
|
"Date",
|
|
"Dimensions",
|
|
"Genre",
|
|
"Length",
|
|
"Lines",
|
|
"Pages",
|
|
"Title",
|
|
"Words"
|
|
};
|
|
|
|
// do a binary search for the key...
|
|
int top = 0;
|
|
int bottom = sizeof(keys) / sizeof(char*) - 1;
|
|
while (top < bottom) {
|
|
const int middle = (top + bottom) / 2;
|
|
const int result = key.compare(keys[middle]);
|
|
if (result < 0) {
|
|
bottom = middle - 1;
|
|
}
|
|
else if (result > 0) {
|
|
top = middle + 1;
|
|
}
|
|
else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void InfoSidebarPage::addInfoLine(const TQString& labelText, const TQString& infoText)
|
|
{
|
|
TQString labelStr("<b>");
|
|
labelStr.append(labelText);
|
|
labelStr.append("</b> ");
|
|
|
|
const int count = m_infoWidgets.count();
|
|
if (m_currInfoLineIdx < count - 1) {
|
|
// reuse available labels
|
|
m_infoWidgets.at(m_currInfoLineIdx++)->setText(labelStr);
|
|
m_infoWidgets.at(m_currInfoLineIdx++)->setText(infoText);
|
|
}
|
|
else {
|
|
// no labels are available anymore, hence create 2 new ones
|
|
TQLabel* label = new TQLabel(labelStr, m_infoGrid);
|
|
label->setTextFormat(TQt::RichText);
|
|
label->setAlignment(TQt::AlignRight |
|
|
TQt::AlignTop);
|
|
label->show();
|
|
m_infoWidgets.append(label);
|
|
|
|
TQLabel* info = new TQLabel(infoText, m_infoGrid);
|
|
info->setTextFormat(TQt::RichText);
|
|
info->setAlignment(TQt::AlignTop | TQt::WordBreak);
|
|
info->show();
|
|
m_infoWidgets.append(info);
|
|
|
|
m_currInfoLineIdx += 2;
|
|
}
|
|
}
|
|
|
|
void InfoSidebarPage::insertActions()
|
|
{
|
|
// delete all existing action widgets
|
|
// TODO: just use children() from TQObject...
|
|
TQPtrListIterator<TQWidget> deleteIter(m_actionWidgets);
|
|
TQWidget* widget = 0;
|
|
while ((widget = deleteIter.current()) != 0) {
|
|
widget->close();
|
|
widget->deleteLater();
|
|
++deleteIter;
|
|
}
|
|
|
|
m_actionWidgets.clear();
|
|
m_actionsVector.clear();
|
|
|
|
int actionsIndex = 0;
|
|
|
|
// The algorithm for searching the available actions works on a list
|
|
// of KFileItems. If no selection is given, a temporary KFileItem
|
|
// by the given URL 'url' is created and added to the list.
|
|
KFileItem fileItem(S_IFDIR, KFileItem::Unknown, m_shownURL);
|
|
KFileItemList localList;
|
|
const KFileItemList* itemList = Dolphin::mainWin().activeView()->selectedItems();
|
|
if ((itemList == 0) || itemList->isEmpty()) {
|
|
fileItem.refresh();
|
|
localList.append(&fileItem);
|
|
itemList = &localList;
|
|
}
|
|
|
|
// 'itemList' contains now all KFileItems, where an item information should be shown.
|
|
// TODO: the following algorithm is quite equal to DolphinContextMenu::insertActionItems().
|
|
// It's open yet whether they should be merged or whether they have to work slightly different.
|
|
TQStringList dirs = TDEGlobal::dirs()->findDirs("data", "d3lphin/servicemenus/");
|
|
for (TQStringList::ConstIterator dirIt = dirs.begin(); dirIt != dirs.end(); ++dirIt) {
|
|
TQDir dir(*dirIt);
|
|
TQStringList entries = dir.entryList("*.desktop", TQDir::Files);
|
|
|
|
for (TQStringList::ConstIterator entryIt = entries.begin(); entryIt != entries.end(); ++entryIt) {
|
|
KSimpleConfig cfg(*dirIt + *entryIt, true);
|
|
cfg.setDesktopGroup();
|
|
if ((cfg.hasKey("Actions") || cfg.hasKey("X-TDE-GetActionMenu")) && cfg.hasKey("X-TDE-ServiceTypes")) {
|
|
const TQStringList types = cfg.readListEntry("X-TDE-ServiceTypes");
|
|
for (TQStringList::ConstIterator it = types.begin(); it != types.end(); ++it) {
|
|
// check whether the mime type is equal or whether the
|
|
// mimegroup (e. g. image/*) is supported
|
|
|
|
bool insert = false;
|
|
if ((*it) == "all/allfiles") {
|
|
// The service type is valid for all files, but not for directories.
|
|
// Check whether the selected items only consist of files...
|
|
KFileItemListIterator mimeIt(*itemList);
|
|
KFileItem* item = 0;
|
|
insert = true;
|
|
while (insert && ((item = mimeIt.current()) != 0)) {
|
|
insert = !item->isDir();
|
|
++mimeIt;
|
|
}
|
|
}
|
|
|
|
if (!insert) {
|
|
// Check whether the MIME types of all selected files match
|
|
// to the mimetype of the service action. As soon as one MIME
|
|
// type does not match, no service menu is shown at all.
|
|
KFileItemListIterator mimeIt(*itemList);
|
|
KFileItem* item = 0;
|
|
insert = true;
|
|
while (insert && ((item = mimeIt.current()) != 0)) {
|
|
const TQString mimeType((*mimeIt)->mimetype());
|
|
const TQString mimeGroup(mimeType.left(mimeType.find('/')));
|
|
|
|
insert = (*it == mimeType) ||
|
|
((*it).right(1) == "*") &&
|
|
((*it).left((*it).find('/')) == mimeGroup);
|
|
++mimeIt;
|
|
}
|
|
}
|
|
|
|
if (insert) {
|
|
const TQString submenuName = cfg.readEntry( "X-TDE-Submenu" );
|
|
TQPopupMenu* popup = 0;
|
|
if (!submenuName.isEmpty()) {
|
|
// create a sub menu containing all actions
|
|
popup = new TQPopupMenu();
|
|
connect(popup, TQT_SIGNAL(activated(int)),
|
|
this, TQT_SLOT(startService(int)));
|
|
|
|
TQPushButton* button = new TQPushButton(submenuName, m_actionBox);
|
|
button->setFlat(true);
|
|
button->setPopup(popup);
|
|
button->show();
|
|
m_actionWidgets.append(button);
|
|
}
|
|
|
|
TQValueList<KDEDesktopMimeType::Service> userServices =
|
|
KDEDesktopMimeType::userDefinedServices(*dirIt + *entryIt, true);
|
|
|
|
// iterate through all actions and add them to a widget
|
|
TQValueList<KDEDesktopMimeType::Service>::Iterator serviceIt;
|
|
for (serviceIt = userServices.begin(); serviceIt != userServices.end(); ++serviceIt) {
|
|
KDEDesktopMimeType::Service service = (*serviceIt);
|
|
if (popup == 0) {
|
|
ServiceButton* button = new ServiceButton(SmallIcon(service.m_strIcon),
|
|
service.m_strName,
|
|
m_actionBox,
|
|
actionsIndex);
|
|
connect(button, TQT_SIGNAL(requestServiceStart(int)),
|
|
this, TQT_SLOT(startService(int)));
|
|
m_actionWidgets.append(button);
|
|
button->show();
|
|
}
|
|
else {
|
|
popup->insertItem(SmallIcon(service.m_strIcon), service.m_strName, actionsIndex);
|
|
}
|
|
|
|
m_actionsVector.append(service);
|
|
++actionsIndex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ServiceButton::ServiceButton(const TQIconSet& icon,
|
|
const TQString& text,
|
|
TQWidget* parent,
|
|
int index) :
|
|
TQPushButton(icon, text, parent),
|
|
m_hover(false),
|
|
m_index(index)
|
|
{
|
|
setEraseColor(colorGroup().background());
|
|
setFocusPolicy(TQ_NoFocus);
|
|
connect(this, TQT_SIGNAL(released()),
|
|
this, TQT_SLOT(slotReleased()));
|
|
}
|
|
|
|
ServiceButton::~ServiceButton()
|
|
{
|
|
}
|
|
|
|
void ServiceButton::drawButton(TQPainter* painter)
|
|
{
|
|
const int buttonWidth = width();
|
|
const int buttonHeight = height();
|
|
|
|
TQColor backgroundColor;
|
|
TQColor foregroundColor;
|
|
if (m_hover) {
|
|
backgroundColor = TDEGlobalSettings::highlightColor();
|
|
foregroundColor = TDEGlobalSettings::highlightedTextColor();
|
|
}
|
|
else {
|
|
backgroundColor = colorGroup().background();
|
|
foregroundColor = TDEGlobalSettings::buttonTextColor();
|
|
}
|
|
|
|
// draw button background
|
|
painter->setPen(NoPen);
|
|
painter->setBrush(backgroundColor);
|
|
painter->drawRect(0, 0, buttonWidth, buttonHeight);
|
|
|
|
const int spacing = KDialog::spacingHint();
|
|
|
|
// draw icon
|
|
int x = spacing;
|
|
const int y = (buttonHeight - TDEIcon::SizeSmall) / 2;
|
|
const TQIconSet* set = iconSet();
|
|
if (set != 0) {
|
|
painter->drawPixmap(x, y, set->pixmap(TQIconSet::Small, TQIconSet::Normal));
|
|
}
|
|
x += TDEIcon::SizeSmall + spacing;
|
|
|
|
// draw text
|
|
painter->setPen(foregroundColor);
|
|
|
|
const int textWidth = buttonWidth - x;
|
|
TQFontMetrics fontMetrics(font());
|
|
const bool clipped = fontMetrics.width(text()) >= textWidth;
|
|
//const int align = clipped ? TQt::AlignVCenter : TQt::AlignCenter;
|
|
painter->drawText(TQRect(x, 0, textWidth, buttonHeight), TQt::AlignVCenter, text());
|
|
|
|
if (clipped) {
|
|
// Blend the right area of the text with the background, as the
|
|
// text is clipped.
|
|
// TODO #1: use alpha blending in TQt4 instead of drawing the text that often
|
|
// TODO #2: same code as in URLNavigatorButton::drawButton() -> provide helper class?
|
|
const int blendSteps = 16;
|
|
|
|
TQColor blendColor(backgroundColor);
|
|
const int redInc = (foregroundColor.red() - backgroundColor.red()) / blendSteps;
|
|
const int greenInc = (foregroundColor.green() - backgroundColor.green()) / blendSteps;
|
|
const int blueInc = (foregroundColor.blue() - backgroundColor.blue()) / blendSteps;
|
|
for (int i = 0; i < blendSteps; ++i) {
|
|
painter->setClipRect(TQRect(x + textWidth - i, 0, 1, buttonHeight));
|
|
painter->setPen(blendColor);
|
|
painter->drawText(TQRect(x, 0, textWidth, buttonHeight), TQt::AlignVCenter, text());
|
|
|
|
blendColor.setRgb(blendColor.red() + redInc,
|
|
blendColor.green() + greenInc,
|
|
blendColor.blue() + blueInc);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ServiceButton::enterEvent(TQEvent* event)
|
|
{
|
|
TQPushButton::enterEvent(event);
|
|
m_hover = true;
|
|
update();
|
|
}
|
|
|
|
void ServiceButton::leaveEvent(TQEvent* event)
|
|
{
|
|
TQPushButton::leaveEvent(event);
|
|
m_hover = false;
|
|
update();
|
|
}
|
|
|
|
void ServiceButton::slotReleased()
|
|
{
|
|
emit requestServiceStart(m_index);
|
|
}
|
|
|
|
#include "infosidebarpage.moc"
|