/* * KFontInst - KDE Font Installer * * Copyright 2003-2007 Craig Drummond * * ---- * * 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; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /* * Inspired by konq_filetip.cc * * Copyright (C) 1998, 1999 Torben Weis * Copyright (C) 2000, 2001, 2002 David Faure * Copyright (C) 2004 Martin Koller */ #include "CharTip.h" #include "FontPreview.h" #include "UnicodeCategories.h" #include #include #include #include #include #include #include #include #include #include #include namespace KFI { EUnicodeCategory getCategory(quint32 ucs2) { for(int i=0; UNICODE_INVALID!=constUnicodeCategoryList[i].category; ++i) if(constUnicodeCategoryList[i].start<=ucs2 && constUnicodeCategoryList[i].end>=ucs2) return constUnicodeCategoryList[i].category; return UNICODE_UNASSIGNED; } static QString toStr(EUnicodeCategory cat) { switch (cat) { case UNICODE_CONTROL: return i18n("Other, Control"); case UNICODE_FORMAT: return i18n("Other, Format"); case UNICODE_UNASSIGNED: return i18n("Other, Not Assigned"); case UNICODE_PRIVATE_USE: return i18n("Other, Private Use"); case UNICODE_SURROGATE: return i18n("Other, Surrogate"); case UNICODE_LOWERCASE_LETTER: return i18n("Letter, Lowercase"); case UNICODE_MODIFIER_LETTER: return i18n("Letter, Modifier"); case UNICODE_OTHER_LETTER: return i18n("Letter, Other"); case UNICODE_TITLECASE_LETTER: return i18n("Letter, Titlecase"); case UNICODE_UPPERCASE_LETTER: return i18n("Letter, Uppercase"); case UNICODE_COMBINING_MARK: return i18n("Mark, Spacing Combining"); case UNICODE_ENCLOSING_MARK: return i18n("Mark, Enclosing"); case UNICODE_NON_SPACING_MARK: return i18n("Mark, Non-Spacing"); case UNICODE_DECIMAL_NUMBER: return i18n("Number, Decimal Digit"); case UNICODE_LETTER_NUMBER: return i18n("Number, Letter"); case UNICODE_OTHER_NUMBER: return i18n("Number, Other"); case UNICODE_CONNECT_PUNCTUATION: return i18n("Punctuation, Connector"); case UNICODE_DASH_PUNCTUATION: return i18n("Punctuation, Dash"); case UNICODE_CLOSE_PUNCTUATION: return i18n("Punctuation, Close"); case UNICODE_FINAL_PUNCTUATION: return i18n("Punctuation, Final Quote"); case UNICODE_INITIAL_PUNCTUATION: return i18n("Punctuation, Initial Quote"); case UNICODE_OTHER_PUNCTUATION: return i18n("Punctuation, Other"); case UNICODE_OPEN_PUNCTUATION: return i18n("Punctuation, Open"); case UNICODE_CURRENCY_SYMBOL: return i18n("Symbol, Currency"); case UNICODE_MODIFIER_SYMBOL: return i18n("Symbol, Modifier"); case UNICODE_MATH_SYMBOL: return i18n("Symbol, Math"); case UNICODE_OTHER_SYMBOL: return i18n("Symbol, Other"); case UNICODE_LINE_SEPARATOR: return i18n("Separator, Line"); case UNICODE_PARAGRAPH_SEPARATOR: return i18n("Separator, Paragraph"); case UNICODE_SPACE_SEPARATOR: return i18n("Separator, Space"); default: return ""; } } CCharTip::CCharTip(CFontPreview *parent) : QFrame(0, Qt::ToolTip | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint), itsParent(parent) { itsPixmapLabel = new QLabel(this); itsLabel = new QLabel(this); itsTimer = new QTimer(this); QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, this); layout->setMargin(8); layout->setSpacing(0); layout->addWidget(itsPixmapLabel); layout->addWidget(itsLabel); setPalette(QToolTip::palette()); setFrameShape(QFrame::Box); setFrameShadow(QFrame::Plain); hide(); } CCharTip::~CCharTip() { } void CCharTip::setItem(const CFcEngine::TChar &ch) { hideTip(); itsItem=ch; itsTimer->disconnect(this); connect(itsTimer, SIGNAL(timeout()), this, SLOT(showTip())); itsTimer->setSingleShot(true); itsTimer->start(300); } void CCharTip::showTip() { if(!itsParent->underMouse()) return; static const int constPixSize=96; EUnicodeCategory cat(getCategory(itsItem.ucs4)); QString details(""); details+=""; details+=""; QString str(QString::fromUcs4(&(itsItem.ucs4), 1)); details+=""; details+=""; details+="
"+i18n("Category")+" "+ toStr(cat)+"
"+i18n("UCS-4")+" "+ QString().sprintf("U+%4.4X", itsItem.ucs4)+" 
"+i18n("UTF-16")+" "; const ushort *utf16(str.utf16()); for(int i=0; utf16[i]; ++i) { if(i) details+=' '; details+=QString().sprintf("0x%4.4X", utf16[i]); } details+="
"+i18n("UTF-8")+" "; QByteArray utf8(str.toUtf8()); for(int i=0; i below is just to stop Qt converting the xml entry into // a character! if ((0x0001 <= itsItem.ucs4 && itsItem.ucs4 <= 0xD7FF) || (0xE000 <= itsItem.ucs4 && itsItem.ucs4 <= 0xFFFD) || (0x10000 <= itsItem.ucs4 && itsItem.ucs4 <= 0x10FFFF)) details+="
"+i18n("XML Decimal Entity")+" "+ QString().sprintf("&#%d;", itsItem.ucs4)+"
"; itsLabel->setText(details); QList range; range.append(CFcEngine::TRange(itsItem.ucs4, 0)); QColor bgnd(Qt::white); bgnd.setAlpha(0); QImage img=itsParent->engine()->draw(itsParent->itsFontName, itsParent->itsStyleInfo, itsParent->itsCurrentFace-1, palette().text().color(), bgnd, constPixSize, constPixSize, false, range, NULL); if(!img.isNull()) itsPixmapLabel->setPixmap(QPixmap::fromImage(img)); else itsPixmapLabel->setPixmap(QPixmap()); itsTimer->disconnect(this); connect(itsTimer, SIGNAL(timeout()), this, SLOT(hideTip())); itsTimer->setSingleShot(true); itsTimer->start(15000); kapp->installEventFilter(this); reposition(); show(); } void CCharTip::hideTip() { itsTimer->stop(); kapp->removeEventFilter(this); hide(); } void CCharTip::reposition() { QRect rect(itsItem); rect.moveTopRight(itsParent->mapToGlobal(rect.topRight())); QPoint pos(rect.center()); QRect desk(KGlobalSettings::desktopGeometry(rect.center())); if ((rect.center().x() + width()) > desk.right()) { if (pos.x() - width() < 0) pos.setX(0); else pos.setX( pos.x() - width() ); } // should the tooltip be shown above or below the ivi ? if (rect.bottom() + height() > desk.bottom()) pos.setY( rect.top() - height() ); else pos.setY(rect.bottom() + 1); move(pos); update(); } void CCharTip::resizeEvent(QResizeEvent *event) { QFrame::resizeEvent(event); reposition(); } bool CCharTip::eventFilter(QObject *, QEvent *e) { switch (e->type()) { case QEvent::Leave: case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::KeyPress: case QEvent::KeyRelease: case QEvent::FocusIn: case QEvent::FocusOut: case QEvent::Wheel: hideTip(); default: break; } return false; } } #include "moc_CharTip.cpp"