From 0e787fb7f5b56b4fe87cd8ada64ae740bbca87bc Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Wed, 24 Jul 2024 19:37:05 +0900 Subject: Rename text class nt* related files to equivalent tq* Signed-off-by: Michele Calgaro --- src/codecs/tqtextcodec.cpp | 2 +- src/dialogs/ntqprogressdialog.h | 2 +- src/dialogs/qdialog.cpp | 2 +- src/dialogs/qerrormessage.cpp | 2 +- src/dialogs/qinputdialog.cpp | 2 +- src/dialogs/qmessagebox.cpp | 2 +- src/dialogs/qprintdialog.cpp | 2 +- src/dialogs/qwizard.cpp | 2 +- src/dialogs/tqcolordialog.cpp | 2 +- src/dialogs/tqfiledialog.cpp | 2 +- src/dialogs/tqfontdialog.cpp | 2 +- src/kernel/ntqsimplerichtext.h | 104 - src/kernel/ntqt.h | 8 +- src/kernel/qaccel.cpp | 2 +- src/kernel/qapplication_x11.cpp | 2 +- src/kernel/qsimplerichtext.cpp | 421 --- src/kernel/qt_kernel.pri | 4 +- src/kernel/qt_pch.h | 2 +- src/kernel/tqfontengine_x11.cpp | 41 +- src/kernel/tqsimplerichtext.cpp | 421 +++ src/kernel/tqsimplerichtext.h | 104 + src/moc/moc.pro | 2 +- src/sql/tqeditorfactory.cpp | 2 +- src/sql/tqsqleditorfactory.cpp | 2 +- src/styles/qinterlacestyle.cpp | 2 +- src/styles/qwindowsstyle.cpp | 2 +- src/tools/ntqlocale.h | 494 --- src/tools/qfeatures.txt | 2 +- src/tools/qglobal.cpp | 2 +- src/tools/qlocale.cpp | 6322 ----------------------------------- src/tools/qlocale_p.h | 131 - src/tools/qt_tools.pri | 8 +- src/tools/tqlocale.cpp | 6322 +++++++++++++++++++++++++++++++++++ src/tools/tqlocale.h | 494 +++ src/tools/tqlocale_p.h | 131 + src/tools/tqstring.cpp | 4 +- src/widgets/ntqlabel.h | 174 - src/widgets/ntqsyntaxhighlighter.h | 81 - src/widgets/ntqwhatsthis.h | 81 - src/widgets/qlabel.cpp | 1191 ------- src/widgets/qlineedit.cpp | 2 +- src/widgets/qsyntaxhighlighter.cpp | 221 -- src/widgets/qsyntaxhighlighter_p.h | 97 - src/widgets/qt_widgets.pri | 18 +- src/widgets/qtitlebar_p.h | 2 +- src/widgets/qwhatsthis.cpp | 1001 ------ src/widgets/tqaction.cpp | 2 +- src/widgets/tqlabel.cpp | 1191 +++++++ src/widgets/tqlabel.h | 174 + src/widgets/tqmainwindow.cpp | 2 +- src/widgets/tqpopupmenu.cpp | 8 +- src/widgets/tqsyntaxhighlighter.cpp | 221 ++ src/widgets/tqsyntaxhighlighter.h | 81 + src/widgets/tqsyntaxhighlighter_p.h | 97 + src/widgets/tqtextbrowser.cpp | 2 +- src/widgets/tqtextedit.cpp | 2 +- src/widgets/tqtooltip.cpp | 2 +- src/widgets/tqwhatsthis.cpp | 1001 ++++++ src/widgets/tqwhatsthis.h | 81 + src/workspace/tqworkspace.cpp | 2 +- 60 files changed, 10381 insertions(+), 10404 deletions(-) delete mode 100644 src/kernel/ntqsimplerichtext.h delete mode 100644 src/kernel/qsimplerichtext.cpp create mode 100644 src/kernel/tqsimplerichtext.cpp create mode 100644 src/kernel/tqsimplerichtext.h delete mode 100644 src/tools/ntqlocale.h delete mode 100644 src/tools/qlocale.cpp delete mode 100644 src/tools/qlocale_p.h create mode 100644 src/tools/tqlocale.cpp create mode 100644 src/tools/tqlocale.h create mode 100644 src/tools/tqlocale_p.h delete mode 100644 src/widgets/ntqlabel.h delete mode 100644 src/widgets/ntqsyntaxhighlighter.h delete mode 100644 src/widgets/ntqwhatsthis.h delete mode 100644 src/widgets/qlabel.cpp delete mode 100644 src/widgets/qsyntaxhighlighter.cpp delete mode 100644 src/widgets/qsyntaxhighlighter_p.h delete mode 100644 src/widgets/qwhatsthis.cpp create mode 100644 src/widgets/tqlabel.cpp create mode 100644 src/widgets/tqlabel.h create mode 100644 src/widgets/tqsyntaxhighlighter.cpp create mode 100644 src/widgets/tqsyntaxhighlighter.h create mode 100644 src/widgets/tqsyntaxhighlighter_p.h create mode 100644 src/widgets/tqwhatsthis.cpp create mode 100644 src/widgets/tqwhatsthis.h (limited to 'src') diff --git a/src/codecs/tqtextcodec.cpp b/src/codecs/tqtextcodec.cpp index c5cdedc3c..ac22ea7f1 100644 --- a/src/codecs/tqtextcodec.cpp +++ b/src/codecs/tqtextcodec.cpp @@ -69,7 +69,7 @@ #include "tqfile.h" #include "tqstrlist.h" #include "tqstring.h" -#include "../tools/qlocale_p.h" +#include "../tools/tqlocale_p.h" #if !defined(TQT_NO_CODECS) && !defined(TQT_NO_BIG_CODECS) && defined(TQ_WS_X11) # include "tqfontcodecs_p.h" diff --git a/src/dialogs/ntqprogressdialog.h b/src/dialogs/ntqprogressdialog.h index eb5e065a1..dc32aa390 100644 --- a/src/dialogs/ntqprogressdialog.h +++ b/src/dialogs/ntqprogressdialog.h @@ -43,7 +43,7 @@ #ifndef QT_H #include "ntqdialog.h" -#include "ntqlabel.h" // ### remove or keep for users' convenience? +#include "tqlabel.h" // ### remove or keep for users' convenience? #include "ntqprogressbar.h" // ### remove or keep for users' convenience? #endif // QT_H diff --git a/src/dialogs/qdialog.cpp b/src/dialogs/qdialog.cpp index 46844a568..9f1f624a9 100644 --- a/src/dialogs/qdialog.cpp +++ b/src/dialogs/qdialog.cpp @@ -49,7 +49,7 @@ #include "tqwidgetlist.h" #include "ntqlayout.h" #include "tqsizegrip.h" -#include "ntqwhatsthis.h" +#include "tqwhatsthis.h" #include "tqpopupmenu.h" #include "ntqcursor.h" #if defined(QT_ACCESSIBILITY_SUPPORT) diff --git a/src/dialogs/qerrormessage.cpp b/src/dialogs/qerrormessage.cpp index 116712ec1..5d21cf717 100644 --- a/src/dialogs/qerrormessage.cpp +++ b/src/dialogs/qerrormessage.cpp @@ -45,7 +45,7 @@ #include "ntqapplication.h" #include "ntqcheckbox.h" #include "tqdict.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "ntqlayout.h" #include "ntqmessagebox.h" #include "ntqpushbutton.h" diff --git a/src/dialogs/qinputdialog.cpp b/src/dialogs/qinputdialog.cpp index 084039c7a..6e8e7627c 100644 --- a/src/dialogs/qinputdialog.cpp +++ b/src/dialogs/qinputdialog.cpp @@ -43,7 +43,7 @@ #ifndef TQT_NO_INPUTDIALOG #include "ntqlayout.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "ntqlineedit.h" #include "ntqpushbutton.h" #include "ntqspinbox.h" diff --git a/src/dialogs/qmessagebox.cpp b/src/dialogs/qmessagebox.cpp index e0bbae0cf..a80a26886 100644 --- a/src/dialogs/qmessagebox.cpp +++ b/src/dialogs/qmessagebox.cpp @@ -43,7 +43,7 @@ #ifndef TQT_NO_MESSAGEBOX #include "ntqaccel.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "ntqpushbutton.h" #include "tqimage.h" #include "ntqapplication.h" diff --git a/src/dialogs/qprintdialog.cpp b/src/dialogs/qprintdialog.cpp index 42efc6e81..0fc6f6935 100644 --- a/src/dialogs/qprintdialog.cpp +++ b/src/dialogs/qprintdialog.cpp @@ -47,7 +47,7 @@ #include "tqtextstream.h" #include "ntqcombobox.h" #include "ntqframe.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "ntqlineedit.h" #include "ntqpushbutton.h" #include "tqprinter.h" diff --git a/src/dialogs/qwizard.cpp b/src/dialogs/qwizard.cpp index 3f8371ea7..6669a4e7a 100644 --- a/src/dialogs/qwizard.cpp +++ b/src/dialogs/qwizard.cpp @@ -45,7 +45,7 @@ #include "ntqlayout.h" #include "ntqpushbutton.h" #include "ntqcursor.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "tqwidgetstack.h" #include "ntqapplication.h" #include "tqptrlist.h" diff --git a/src/dialogs/tqcolordialog.cpp b/src/dialogs/tqcolordialog.cpp index f90f8df2e..19e08c61a 100644 --- a/src/dialogs/tqcolordialog.cpp +++ b/src/dialogs/tqcolordialog.cpp @@ -44,7 +44,7 @@ #include "tqpainter.h" #include "ntqlayout.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "ntqpushbutton.h" #include "ntqlineedit.h" #include "tqimage.h" diff --git a/src/dialogs/tqfiledialog.cpp b/src/dialogs/tqfiledialog.cpp index 194d7478a..5ed1ff6be 100644 --- a/src/dialogs/tqfiledialog.cpp +++ b/src/dialogs/tqfiledialog.cpp @@ -68,7 +68,7 @@ #include "ntqguardedptr.h" #include "ntqhbox.h" #include "ntqheader.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "ntqlayout.h" #include "ntqlibrary.h" #include "ntqlineedit.h" diff --git a/src/dialogs/tqfontdialog.cpp b/src/dialogs/tqfontdialog.cpp index 8e7999a2b..c9b5daef0 100644 --- a/src/dialogs/tqfontdialog.cpp +++ b/src/dialogs/tqfontdialog.cpp @@ -52,7 +52,7 @@ #include "ntqlayout.h" #include "ntqvgroupbox.h" #include "ntqhgroupbox.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "ntqapplication.h" #include "tqfontdatabase.h" #include "tqstyle.h" diff --git a/src/kernel/ntqsimplerichtext.h b/src/kernel/ntqsimplerichtext.h deleted file mode 100644 index 8d3d9ad8b..000000000 --- a/src/kernel/ntqsimplerichtext.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Definition of the TQSimpleRichText class -** -** Created : 990101 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the kernel module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#ifndef TQSIMPLERICHTEXT_H -#define TQSIMPLERICHTEXT_H - -#ifndef QT_H -#include "ntqnamespace.h" -#include "tqstring.h" -#include "tqregion.h" -#endif // QT_H - -#ifndef TQT_NO_RICHTEXT - -class TQPainter; -class TQWidget; -class TQStyleSheet; -class TQBrush; -class TQMimeSourceFactory; -class TQSimpleRichTextData; - -class TQ_EXPORT TQSimpleRichText -{ -public: - TQSimpleRichText( const TQString& text, const TQFont& fnt, - const TQString& context = TQString::null, const TQStyleSheet* sheet = 0); - TQSimpleRichText( const TQString& text, const TQFont& fnt, - const TQString& context, const TQStyleSheet* sheet, - const TQMimeSourceFactory* factory, int pageBreak = -1, - const TQColor& linkColor = TQt::blue, bool linkUnderline = TRUE ); - ~TQSimpleRichText(); - - void setWidth( int ); - void setWidth( TQPainter*, int ); - void setDefaultFont( const TQFont &f ); - int width() const; - int widthUsed() const; - int height() const; - void adjustSize(); - - void draw( TQPainter* p, int x, int y, const TQRect& clipRect, - const TQColorGroup& cg, const TQBrush* paper = 0) const; - - // obsolete - void draw( TQPainter* p, int x, int y, const TQRegion& clipRegion, - const TQColorGroup& cg, const TQBrush* paper = 0) const { - draw( p, x, y, clipRegion.boundingRect(), cg, paper ); - } - - TQString context() const; - TQString anchorAt( const TQPoint& pos ) const; - - bool inText( const TQPoint& pos ) const; - -private: - TQSimpleRichTextData* d; - -private: // Disabled copy constructor and operator= -#if defined(TQ_DISABLE_COPY) - TQSimpleRichText( const TQSimpleRichText & ); - TQSimpleRichText &operator=( const TQSimpleRichText & ); -#endif -}; - -#endif // TQT_NO_RICHTEXT - -#endif // TQSIMPLERICHTEXT_H diff --git a/src/kernel/ntqt.h b/src/kernel/ntqt.h index 51eb62b33..5d9f7d4bc 100644 --- a/src/kernel/ntqt.h +++ b/src/kernel/ntqt.h @@ -116,7 +116,7 @@ #include #include #include -#include "ntqlabel.h" +#include "tqlabel.h" #include "ntqlayout.h" #include #include @@ -188,7 +188,7 @@ #include "tqtimer.h" #include #include -#include +#include #include "tqwmatrix.h" #include #include @@ -225,7 +225,7 @@ #include #include #include "tqtextedit.h" -#include +#include #include #include "tqsqleditorfactory.h" #include @@ -258,7 +258,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/kernel/qaccel.cpp b/src/kernel/qaccel.cpp index b11c6b427..fabd7dcf4 100644 --- a/src/kernel/qaccel.cpp +++ b/src/kernel/qaccel.cpp @@ -46,7 +46,7 @@ #include "ntqapplication.h" #include "tqwidget.h" #include "tqptrlist.h" -#include "ntqwhatsthis.h" +#include "tqwhatsthis.h" #include "ntqguardedptr.h" #include "tqstatusbar.h" #include "ntqdockwindow.h" diff --git a/src/kernel/qapplication_x11.cpp b/src/kernel/qapplication_x11.cpp index fbe329e98..aa6fd907b 100644 --- a/src/kernel/qapplication_x11.cpp +++ b/src/kernel/qapplication_x11.cpp @@ -83,7 +83,7 @@ #include "tqdict.h" #include "ntqguardedptr.h" #include "tqclipboard.h" -#include "ntqwhatsthis.h" // ######## dependency +#include "tqwhatsthis.h" // ######## dependency #include "tqsettings.h" #include "tqstylefactory.h" #include "tqfileinfo.h" diff --git a/src/kernel/qsimplerichtext.cpp b/src/kernel/qsimplerichtext.cpp deleted file mode 100644 index a6e1271c4..000000000 --- a/src/kernel/qsimplerichtext.cpp +++ /dev/null @@ -1,421 +0,0 @@ -/**************************************************************************** -** -** Implementation of the TQSimpleRichText class -** -** Created : 990101 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the kernel module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#include "ntqsimplerichtext.h" - -#ifndef TQT_NO_RICHTEXT -#include "qrichtext_p.h" -#include "ntqapplication.h" - -class TQSimpleRichTextData -{ -public: - TQTextDocument *doc; - TQFont font; - int cachedWidth; - bool cachedWidthWithPainter; - void adjustSize(TQPainter *p = 0); -}; - -// Pull this private function in from qglobal.cpp -extern unsigned int qt_int_sqrt( unsigned int n ); - -void TQSimpleRichTextData::adjustSize(TQPainter *p) { - TQFontMetrics fm( font ); - int mw = fm.width( 'x' ) * 80; - int w = mw; - doc->doLayout(p, w); - if ( doc->widthUsed() != 0 ) { - w = qt_int_sqrt( 5 * doc->height() * doc->widthUsed() / 3 ); - doc->doLayout(p, TQMIN(w, mw)); - - if ( w*3 < 5*doc->height() ) { - w = qt_int_sqrt( 2 * doc->height() * doc->widthUsed() ); - doc->doLayout(p, TQMIN(w, mw)); - } - } - cachedWidth = doc->width(); - cachedWidthWithPainter = FALSE; -} - -/*! - \class TQSimpleRichText ntqsimplerichtext.h - \brief The TQSimpleRichText class provides a small displayable piece of rich text. - - \ingroup text - \mainclass - - This class encapsulates simple rich text usage in which a string - is interpreted as rich text and can be drawn. This is particularly - useful if you want to display some rich text in a custom widget. A - TQStyleSheet is needed to interpret the tags and format the rich - text. TQt provides a default HTML-like style sheet, but you may - define custom style sheets. - - Once created, the rich text object can be queried for its width(), - height(), and the actual width used (see widthUsed()). Most - importantly, it can be drawn on any given TQPainter with draw(). - TQSimpleRichText can also be used to implement hypertext or active - text facilities by using anchorAt(). A hit test through inText() - makes it possible to use simple rich text for text objects in - editable drawing canvases. - - Once constructed from a string the contents cannot be changed, - only resized. If the contents change, just throw the rich text - object away and make a new one with the new contents. - - For large documents use TQTextEdit or TQTextBrowser. For very small - items of rich text you can use a TQLabel. - - If you are using TQSimpleRichText to print in high resolution you - should call setWidth(TQPainter, int) so that the content will be - laid out properly on the page. -*/ - -/*! - Constructs a TQSimpleRichText from the rich text string \a text and - the font \a fnt. - - The font is used as a basis for the text rendering. When using - rich text rendering on a widget \e w, you would normally specify - the widget's font, for example: - - \code - TQSimpleRichText myrichtext( contents, mywidget->font() ); - \endcode - - \a context is the optional context of the rich text object. This - becomes important if \a text contains relative references, for - example within image tags. TQSimpleRichText always uses the default - mime source factory (see \l{TQMimeSourceFactory::defaultFactory()}) - to resolve those references. The context will then be used to - calculate the absolute path. See - TQMimeSourceFactory::makeAbsolute() for details. - - The \a sheet is an optional style sheet. If it is 0, the default - style sheet will be used (see \l{TQStyleSheet::defaultSheet()}). -*/ - -TQSimpleRichText::TQSimpleRichText( const TQString& text, const TQFont& fnt, - const TQString& context, const TQStyleSheet* sheet ) -{ - d = new TQSimpleRichTextData; - d->cachedWidth = -1; - d->cachedWidthWithPainter = FALSE; - d->font = fnt; - d->doc = new TQTextDocument( 0 ); - d->doc->setTextFormat( TQt::RichText ); - d->doc->setLeftMargin( 0 ); - d->doc->setRightMargin( 0 ); - d->doc->setFormatter( new TQTextFormatterBreakWords ); - d->doc->setStyleSheet( (TQStyleSheet*)sheet ); - d->doc->setDefaultFormat( fnt, TQColor() ); - d->doc->setText( text, context ); -} - - -/*! - Constructs a TQSimpleRichText from the rich text string \a text and - the font \a fnt. - - This is a slightly more complex constructor for TQSimpleRichText - that takes an additional mime source factory \a factory, a page - break parameter \a pageBreak and a bool \a linkUnderline. \a - linkColor is only provided for compatibility, but has no effect, - as TQColorGroup's TQColorGroup::link() color is used now. - - \a context is the optional context of the rich text object. This - becomes important if \a text contains relative references, for - example within image tags. TQSimpleRichText always uses the default - mime source factory (see \l{TQMimeSourceFactory::defaultFactory()}) - to resolve those references. The context will then be used to - calculate the absolute path. See - TQMimeSourceFactory::makeAbsolute() for details. - - The \a sheet is an optional style sheet. If it is 0, the default - style sheet will be used (see \l{TQStyleSheet::defaultSheet()}). - - This constructor is useful for creating a TQSimpleRichText object - suitable for printing. Set \a pageBreak to be the height of the - contents area of the pages. -*/ - -TQSimpleRichText::TQSimpleRichText( const TQString& text, const TQFont& fnt, - const TQString& context, const TQStyleSheet* sheet, - const TQMimeSourceFactory* factory, int pageBreak, - const TQColor& /*linkColor*/, bool linkUnderline ) -{ - d = new TQSimpleRichTextData; - d->cachedWidth = -1; - d->cachedWidthWithPainter = FALSE; - d->font = fnt; - d->doc = new TQTextDocument( 0 ); - d->doc->setTextFormat( TQt::RichText ); - d->doc->setFormatter( new TQTextFormatterBreakWords ); - d->doc->setStyleSheet( (TQStyleSheet*)sheet ); - d->doc->setDefaultFormat( fnt, TQColor() ); - d->doc->flow()->setPageSize( pageBreak ); - d->doc->setPageBreakEnabled( TRUE ); -#ifndef TQT_NO_MIME - d->doc->setMimeSourceFactory( (TQMimeSourceFactory*)factory ); -#endif - d->doc->setUnderlineLinks( linkUnderline ); - d->doc->setText( text, context ); -} - -/*! - Destroys the rich text object, freeing memory. -*/ - -TQSimpleRichText::~TQSimpleRichText() -{ - delete d->doc; - delete d; -} - -/*! - \overload - - Sets the width of the rich text object to \a w pixels. - - \sa height(), adjustSize() -*/ - -void TQSimpleRichText::setWidth( int w ) -{ - if ( w == d->cachedWidth && !d->cachedWidthWithPainter ) - return; - d->doc->formatter()->setAllowBreakInWords( d->doc->isPageBreakEnabled() ); - d->cachedWidth = w; - d->cachedWidthWithPainter = FALSE; - d->doc->doLayout( 0, w ); -} - -/*! - Sets the width of the rich text object to \a w pixels, - recalculating the layout as if it were to be drawn with painter \a - p. - - Passing a painter is useful when you intend drawing on devices - other than the screen, for example a TQPrinter. - - \sa height(), adjustSize() -*/ - -void TQSimpleRichText::setWidth( TQPainter *p, int w ) -{ - if ( w == d->cachedWidth && d->cachedWidthWithPainter ) - return; - d->doc->formatter()->setAllowBreakInWords( d->doc->isPageBreakEnabled() || - (p && p->device() && - (p->device()->devType() == TQInternal::Printer)) ); - p->save(); - d->cachedWidth = w; - d->cachedWidthWithPainter = TRUE; - d->doc->doLayout( p, w ); - p->restore(); -} - -/*! - Returns the set width of the rich text object in pixels. - - \sa widthUsed() -*/ - -int TQSimpleRichText::width() const -{ - if ( d->cachedWidth < 0 ) - d->adjustSize(); - return d->doc->width(); -} - -/*! - Returns the width in pixels that is actually used by the rich text - object. This can be smaller or wider than the set width. - - It may be wider, for example, if the text contains images or - non-breakable words that are already wider than the available - space. It's smaller when the object only consists of lines that do - not fill the width completely. - - \sa width() -*/ - -int TQSimpleRichText::widthUsed() const -{ - if ( d->cachedWidth < 0 ) - d->adjustSize(); - return d->doc->widthUsed(); -} - -/*! - Returns the height of the rich text object in pixels. - - \sa setWidth() -*/ - -int TQSimpleRichText::height() const -{ - if ( d->cachedWidth < 0 ) - d->adjustSize(); - return d->doc->height(); -} - -/*! - Adjusts the richt text object to a reasonable size. - - \sa setWidth() -*/ - -void TQSimpleRichText::adjustSize() -{ - d->adjustSize(); -} - -/*! - Draws the formatted text with painter \a p, at position (\a x, \a - y), clipped to \a clipRect. The clipping rectangle is given in the - rich text object's coordinates translated by (\a x, \a y). Passing - an null rectangle results in no clipping. Colors from the color - group \a cg are used as needed, and if not 0, \a *paper is used as - the background brush. - - Note that the display code is highly optimized to reduce flicker, - so passing a brush for \a paper is preferable to simply clearing - the area to be painted and then calling this without a brush. -*/ - -void TQSimpleRichText::draw( TQPainter *p, int x, int y, const TQRect& clipRect, - const TQColorGroup& cg, const TQBrush* paper ) const -{ - p->save(); - if ( d->cachedWidth < 0 ) - d->adjustSize(p); - - TQRect r = clipRect; - if ( !r.isNull() ) - r.moveBy( -x, -y ); - - if ( paper ) - d->doc->setPaper( new TQBrush( *paper ) ); - TQColorGroup g = cg; - if ( d->doc->paper() ) - g.setBrush( TQColorGroup::Base, *d->doc->paper() ); - - if ( !clipRect.isNull() ) - p->setClipRect( clipRect, TQPainter::CoordPainter ); - p->translate( x, y ); - d->doc->draw( p, r, g, paper ); - p->translate( -x, -y ); - p->restore(); -} - - -/*! \fn void TQSimpleRichText::draw( TQPainter *p, int x, int y, const TQRegion& clipRegion, - const TQColorGroup& cg, const TQBrush* paper ) const - - \obsolete - - Use the version with clipRect instead. The region version has - problems with larger documents on some platforms (on X11 regions - internally are represented with 16bit coordinates). -*/ - - - -/*! - Returns the context of the rich text object. If no context has - been specified in the constructor, a null string is returned. The - context is the path to use to look up relative links, such as - image tags and anchor references. -*/ - -TQString TQSimpleRichText::context() const -{ - return d->doc->context(); -} - -/*! - Returns the anchor at the requested position, \a pos. An empty - string is returned if no anchor is specified for this position. -*/ - -TQString TQSimpleRichText::anchorAt( const TQPoint& pos ) const -{ - if ( d->cachedWidth < 0 ) - d->adjustSize(); - TQTextCursor c( d->doc ); - c.place( pos, d->doc->firstParagraph(), TRUE ); - return c.paragraph()->at( c.index() )->anchorHref(); -} - -/*! - Returns TRUE if \a pos is within a text line of the rich text - object; otherwise returns FALSE. -*/ - -bool TQSimpleRichText::inText( const TQPoint& pos ) const -{ - if ( d->cachedWidth < 0 ) - d->adjustSize(); - if ( pos.y() > d->doc->height() ) - return FALSE; - TQTextCursor c( d->doc ); - c.place( pos, d->doc->firstParagraph() ); - return c.totalOffsetX() + c.paragraph()->at( c.index() )->x + - c.paragraph()->at( c.index() )->format()->width( c.paragraph()->at( c.index() )->c ) > pos.x(); -} - -/*! - Sets the default font for the rich text object to \a f -*/ - -void TQSimpleRichText::setDefaultFont( const TQFont &f ) -{ - if ( d->font == f ) - return; - d->font = f; - d->cachedWidth = -1; - d->cachedWidthWithPainter = FALSE; - d->doc->setDefaultFormat( f, TQColor() ); - d->doc->setText( d->doc->originalText(), d->doc->context() ); -} - -#endif //TQT_NO_RICHTEXT diff --git a/src/kernel/qt_kernel.pri b/src/kernel/qt_kernel.pri index c56afb6b2..c97ca4618 100644 --- a/src/kernel/qt_kernel.pri +++ b/src/kernel/qt_kernel.pri @@ -92,7 +92,7 @@ kernel { $$KERNEL_P/qrichtext_p.h \ $$KERNEL_P/qinternal_p.h \ $$KERNEL_H/ntqgplugin.h \ - $$KERNEL_H/ntqsimplerichtext.h \ + $$KERNEL_H/tqsimplerichtext.h \ $$KERNEL_CPP/qscriptengine_p.h \ $$KERNEL_CPP/tqtextengine_p.h \ $$KERNEL_CPP/tqfontengine_p.h \ @@ -261,7 +261,7 @@ kernel { $$KERNEL_CPP/qinternal.cpp \ $$KERNEL_CPP/qrichtext_p.cpp \ $$KERNEL_CPP/qgplugin.cpp \ - $$KERNEL_CPP/qsimplerichtext.cpp \ + $$KERNEL_CPP/tqsimplerichtext.cpp \ $$KERNEL_CPP/qscriptengine.cpp \ $$KERNEL_CPP/tqtextlayout.cpp \ $$KERNEL_CPP/tqtextengine.cpp diff --git a/src/kernel/qt_pch.h b/src/kernel/qt_pch.h index 54ca333f9..908254769 100644 --- a/src/kernel/qt_pch.h +++ b/src/kernel/qt_pch.h @@ -18,7 +18,7 @@ # if defined(__GNUC__) # ifndef TQT_NO_STL # include -# undef _GLIBCPP_FULLY_COMPLIANT_HEADERS // Makes qlocale.cpp compile +# undef _GLIBCPP_FULLY_COMPLIANT_HEADERS // Makes tqlocale.cpp compile # endif # endif #include // I must be first! diff --git a/src/kernel/tqfontengine_x11.cpp b/src/kernel/tqfontengine_x11.cpp index 8002c42df..6363aac97 100644 --- a/src/kernel/tqfontengine_x11.cpp +++ b/src/kernel/tqfontengine_x11.cpp @@ -2264,8 +2264,6 @@ struct OTScripts { int flags; }; -// Refer to https://learn.microsoft.com/en-us/typography/opentype/spec/scripttags -// for OpenType language tags definition static const OTScripts ot_scripts [] = { // // European Alphabetic Scripts // Latin, @@ -2353,7 +2351,6 @@ static const OTScripts ot_scripts [] = { { FT_MAKE_TAG( 'c', 'a', 'n', 's' ), 0 }, // Mongolian, { FT_MAKE_TAG( 'm', 'o', 'n', 'g' ), 0 }, - // // Symbols // CurrencySymbols, { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 }, @@ -2373,26 +2370,13 @@ static const OTScripts ot_scripts [] = { { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 }, // Braille, { FT_MAKE_TAG( 'b', 'r', 'a', 'i' ), 0 }, - -// Unicode - { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 }, - -// Tagalog, - { FT_MAKE_TAG( 't', 'g', 'l', 'g' ), 0 }, -// Hanunoo, - { FT_MAKE_TAG( 'h', 'a', 'n', 'o' ), 0 }, -// Buhid, - { FT_MAKE_TAG( 'b', 'u', 'h', 'd' ), 0 }, -// Tagbanwa, - { FT_MAKE_TAG( 't', 'a', 'g', 'b' ), 0 }, - -// KatakanaHalfWidth, -- can't find it, use Katakana code - { FT_MAKE_TAG( 'k', 'a', 'n', 'a' ), 0 }, - -// Limbu, - { FT_MAKE_TAG( 'l', 'i', 'm', 'b' ), 0 }, -// TaiLe, - { FT_MAKE_TAG( 't', 'a', 'l', 'e' ), 0 } +// Unicode, should be used + { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 } + // ### where are these? +// { FT_MAKE_TAG( 'b', 'y', 'z', 'm' ), 0 }, +// { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 }, + // ### Hangul Jamo +// { FT_MAKE_TAG( 'j', 'a', 'm', 'o' ), 0 }, }; TQOpenType::TQOpenType(TQFontEngineXft *fe) @@ -2451,10 +2435,7 @@ TQOpenType::~TQOpenType() bool TQOpenType::checkScript(unsigned int script) { - if (script >= TQFont::NScripts || script >= sizeof(ot_scripts) / sizeof(OTScripts)) - { - return false; - } + assert(script < TQFont::NScripts); uint tag = ot_scripts[script].tag; int requirements = ot_scripts[script].flags; @@ -2496,11 +2477,7 @@ void TQOpenType::selectScript(unsigned int script, const Features *features) if (current_script == script) return; - if (script >= TQFont::NScripts || script >= sizeof(ot_scripts) / sizeof(OTScripts)) - { - return; - } - + assert(script < TQFont::NScripts); // find script in our list of supported scripts. uint tag = ot_scripts[script].tag; diff --git a/src/kernel/tqsimplerichtext.cpp b/src/kernel/tqsimplerichtext.cpp new file mode 100644 index 000000000..2288a5692 --- /dev/null +++ b/src/kernel/tqsimplerichtext.cpp @@ -0,0 +1,421 @@ +/**************************************************************************** +** +** Implementation of the TQSimpleRichText class +** +** Created : 990101 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the kernel module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "tqsimplerichtext.h" + +#ifndef TQT_NO_RICHTEXT +#include "qrichtext_p.h" +#include "ntqapplication.h" + +class TQSimpleRichTextData +{ +public: + TQTextDocument *doc; + TQFont font; + int cachedWidth; + bool cachedWidthWithPainter; + void adjustSize(TQPainter *p = 0); +}; + +// Pull this private function in from qglobal.cpp +extern unsigned int qt_int_sqrt( unsigned int n ); + +void TQSimpleRichTextData::adjustSize(TQPainter *p) { + TQFontMetrics fm( font ); + int mw = fm.width( 'x' ) * 80; + int w = mw; + doc->doLayout(p, w); + if ( doc->widthUsed() != 0 ) { + w = qt_int_sqrt( 5 * doc->height() * doc->widthUsed() / 3 ); + doc->doLayout(p, TQMIN(w, mw)); + + if ( w*3 < 5*doc->height() ) { + w = qt_int_sqrt( 2 * doc->height() * doc->widthUsed() ); + doc->doLayout(p, TQMIN(w, mw)); + } + } + cachedWidth = doc->width(); + cachedWidthWithPainter = FALSE; +} + +/*! + \class TQSimpleRichText tqsimplerichtext.h + \brief The TQSimpleRichText class provides a small displayable piece of rich text. + + \ingroup text + \mainclass + + This class encapsulates simple rich text usage in which a string + is interpreted as rich text and can be drawn. This is particularly + useful if you want to display some rich text in a custom widget. A + TQStyleSheet is needed to interpret the tags and format the rich + text. TQt provides a default HTML-like style sheet, but you may + define custom style sheets. + + Once created, the rich text object can be queried for its width(), + height(), and the actual width used (see widthUsed()). Most + importantly, it can be drawn on any given TQPainter with draw(). + TQSimpleRichText can also be used to implement hypertext or active + text facilities by using anchorAt(). A hit test through inText() + makes it possible to use simple rich text for text objects in + editable drawing canvases. + + Once constructed from a string the contents cannot be changed, + only resized. If the contents change, just throw the rich text + object away and make a new one with the new contents. + + For large documents use TQTextEdit or TQTextBrowser. For very small + items of rich text you can use a TQLabel. + + If you are using TQSimpleRichText to print in high resolution you + should call setWidth(TQPainter, int) so that the content will be + laid out properly on the page. +*/ + +/*! + Constructs a TQSimpleRichText from the rich text string \a text and + the font \a fnt. + + The font is used as a basis for the text rendering. When using + rich text rendering on a widget \e w, you would normally specify + the widget's font, for example: + + \code + TQSimpleRichText myrichtext( contents, mywidget->font() ); + \endcode + + \a context is the optional context of the rich text object. This + becomes important if \a text contains relative references, for + example within image tags. TQSimpleRichText always uses the default + mime source factory (see \l{TQMimeSourceFactory::defaultFactory()}) + to resolve those references. The context will then be used to + calculate the absolute path. See + TQMimeSourceFactory::makeAbsolute() for details. + + The \a sheet is an optional style sheet. If it is 0, the default + style sheet will be used (see \l{TQStyleSheet::defaultSheet()}). +*/ + +TQSimpleRichText::TQSimpleRichText( const TQString& text, const TQFont& fnt, + const TQString& context, const TQStyleSheet* sheet ) +{ + d = new TQSimpleRichTextData; + d->cachedWidth = -1; + d->cachedWidthWithPainter = FALSE; + d->font = fnt; + d->doc = new TQTextDocument( 0 ); + d->doc->setTextFormat( TQt::RichText ); + d->doc->setLeftMargin( 0 ); + d->doc->setRightMargin( 0 ); + d->doc->setFormatter( new TQTextFormatterBreakWords ); + d->doc->setStyleSheet( (TQStyleSheet*)sheet ); + d->doc->setDefaultFormat( fnt, TQColor() ); + d->doc->setText( text, context ); +} + + +/*! + Constructs a TQSimpleRichText from the rich text string \a text and + the font \a fnt. + + This is a slightly more complex constructor for TQSimpleRichText + that takes an additional mime source factory \a factory, a page + break parameter \a pageBreak and a bool \a linkUnderline. \a + linkColor is only provided for compatibility, but has no effect, + as TQColorGroup's TQColorGroup::link() color is used now. + + \a context is the optional context of the rich text object. This + becomes important if \a text contains relative references, for + example within image tags. TQSimpleRichText always uses the default + mime source factory (see \l{TQMimeSourceFactory::defaultFactory()}) + to resolve those references. The context will then be used to + calculate the absolute path. See + TQMimeSourceFactory::makeAbsolute() for details. + + The \a sheet is an optional style sheet. If it is 0, the default + style sheet will be used (see \l{TQStyleSheet::defaultSheet()}). + + This constructor is useful for creating a TQSimpleRichText object + suitable for printing. Set \a pageBreak to be the height of the + contents area of the pages. +*/ + +TQSimpleRichText::TQSimpleRichText( const TQString& text, const TQFont& fnt, + const TQString& context, const TQStyleSheet* sheet, + const TQMimeSourceFactory* factory, int pageBreak, + const TQColor& /*linkColor*/, bool linkUnderline ) +{ + d = new TQSimpleRichTextData; + d->cachedWidth = -1; + d->cachedWidthWithPainter = FALSE; + d->font = fnt; + d->doc = new TQTextDocument( 0 ); + d->doc->setTextFormat( TQt::RichText ); + d->doc->setFormatter( new TQTextFormatterBreakWords ); + d->doc->setStyleSheet( (TQStyleSheet*)sheet ); + d->doc->setDefaultFormat( fnt, TQColor() ); + d->doc->flow()->setPageSize( pageBreak ); + d->doc->setPageBreakEnabled( TRUE ); +#ifndef TQT_NO_MIME + d->doc->setMimeSourceFactory( (TQMimeSourceFactory*)factory ); +#endif + d->doc->setUnderlineLinks( linkUnderline ); + d->doc->setText( text, context ); +} + +/*! + Destroys the rich text object, freeing memory. +*/ + +TQSimpleRichText::~TQSimpleRichText() +{ + delete d->doc; + delete d; +} + +/*! + \overload + + Sets the width of the rich text object to \a w pixels. + + \sa height(), adjustSize() +*/ + +void TQSimpleRichText::setWidth( int w ) +{ + if ( w == d->cachedWidth && !d->cachedWidthWithPainter ) + return; + d->doc->formatter()->setAllowBreakInWords( d->doc->isPageBreakEnabled() ); + d->cachedWidth = w; + d->cachedWidthWithPainter = FALSE; + d->doc->doLayout( 0, w ); +} + +/*! + Sets the width of the rich text object to \a w pixels, + recalculating the layout as if it were to be drawn with painter \a + p. + + Passing a painter is useful when you intend drawing on devices + other than the screen, for example a TQPrinter. + + \sa height(), adjustSize() +*/ + +void TQSimpleRichText::setWidth( TQPainter *p, int w ) +{ + if ( w == d->cachedWidth && d->cachedWidthWithPainter ) + return; + d->doc->formatter()->setAllowBreakInWords( d->doc->isPageBreakEnabled() || + (p && p->device() && + (p->device()->devType() == TQInternal::Printer)) ); + p->save(); + d->cachedWidth = w; + d->cachedWidthWithPainter = TRUE; + d->doc->doLayout( p, w ); + p->restore(); +} + +/*! + Returns the set width of the rich text object in pixels. + + \sa widthUsed() +*/ + +int TQSimpleRichText::width() const +{ + if ( d->cachedWidth < 0 ) + d->adjustSize(); + return d->doc->width(); +} + +/*! + Returns the width in pixels that is actually used by the rich text + object. This can be smaller or wider than the set width. + + It may be wider, for example, if the text contains images or + non-breakable words that are already wider than the available + space. It's smaller when the object only consists of lines that do + not fill the width completely. + + \sa width() +*/ + +int TQSimpleRichText::widthUsed() const +{ + if ( d->cachedWidth < 0 ) + d->adjustSize(); + return d->doc->widthUsed(); +} + +/*! + Returns the height of the rich text object in pixels. + + \sa setWidth() +*/ + +int TQSimpleRichText::height() const +{ + if ( d->cachedWidth < 0 ) + d->adjustSize(); + return d->doc->height(); +} + +/*! + Adjusts the richt text object to a reasonable size. + + \sa setWidth() +*/ + +void TQSimpleRichText::adjustSize() +{ + d->adjustSize(); +} + +/*! + Draws the formatted text with painter \a p, at position (\a x, \a + y), clipped to \a clipRect. The clipping rectangle is given in the + rich text object's coordinates translated by (\a x, \a y). Passing + an null rectangle results in no clipping. Colors from the color + group \a cg are used as needed, and if not 0, \a *paper is used as + the background brush. + + Note that the display code is highly optimized to reduce flicker, + so passing a brush for \a paper is preferable to simply clearing + the area to be painted and then calling this without a brush. +*/ + +void TQSimpleRichText::draw( TQPainter *p, int x, int y, const TQRect& clipRect, + const TQColorGroup& cg, const TQBrush* paper ) const +{ + p->save(); + if ( d->cachedWidth < 0 ) + d->adjustSize(p); + + TQRect r = clipRect; + if ( !r.isNull() ) + r.moveBy( -x, -y ); + + if ( paper ) + d->doc->setPaper( new TQBrush( *paper ) ); + TQColorGroup g = cg; + if ( d->doc->paper() ) + g.setBrush( TQColorGroup::Base, *d->doc->paper() ); + + if ( !clipRect.isNull() ) + p->setClipRect( clipRect, TQPainter::CoordPainter ); + p->translate( x, y ); + d->doc->draw( p, r, g, paper ); + p->translate( -x, -y ); + p->restore(); +} + + +/*! \fn void TQSimpleRichText::draw( TQPainter *p, int x, int y, const TQRegion& clipRegion, + const TQColorGroup& cg, const TQBrush* paper ) const + + \obsolete + + Use the version with clipRect instead. The region version has + problems with larger documents on some platforms (on X11 regions + internally are represented with 16bit coordinates). +*/ + + + +/*! + Returns the context of the rich text object. If no context has + been specified in the constructor, a null string is returned. The + context is the path to use to look up relative links, such as + image tags and anchor references. +*/ + +TQString TQSimpleRichText::context() const +{ + return d->doc->context(); +} + +/*! + Returns the anchor at the requested position, \a pos. An empty + string is returned if no anchor is specified for this position. +*/ + +TQString TQSimpleRichText::anchorAt( const TQPoint& pos ) const +{ + if ( d->cachedWidth < 0 ) + d->adjustSize(); + TQTextCursor c( d->doc ); + c.place( pos, d->doc->firstParagraph(), TRUE ); + return c.paragraph()->at( c.index() )->anchorHref(); +} + +/*! + Returns TRUE if \a pos is within a text line of the rich text + object; otherwise returns FALSE. +*/ + +bool TQSimpleRichText::inText( const TQPoint& pos ) const +{ + if ( d->cachedWidth < 0 ) + d->adjustSize(); + if ( pos.y() > d->doc->height() ) + return FALSE; + TQTextCursor c( d->doc ); + c.place( pos, d->doc->firstParagraph() ); + return c.totalOffsetX() + c.paragraph()->at( c.index() )->x + + c.paragraph()->at( c.index() )->format()->width( c.paragraph()->at( c.index() )->c ) > pos.x(); +} + +/*! + Sets the default font for the rich text object to \a f +*/ + +void TQSimpleRichText::setDefaultFont( const TQFont &f ) +{ + if ( d->font == f ) + return; + d->font = f; + d->cachedWidth = -1; + d->cachedWidthWithPainter = FALSE; + d->doc->setDefaultFormat( f, TQColor() ); + d->doc->setText( d->doc->originalText(), d->doc->context() ); +} + +#endif //TQT_NO_RICHTEXT diff --git a/src/kernel/tqsimplerichtext.h b/src/kernel/tqsimplerichtext.h new file mode 100644 index 000000000..8d3d9ad8b --- /dev/null +++ b/src/kernel/tqsimplerichtext.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Definition of the TQSimpleRichText class +** +** Created : 990101 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the kernel module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TQSIMPLERICHTEXT_H +#define TQSIMPLERICHTEXT_H + +#ifndef QT_H +#include "ntqnamespace.h" +#include "tqstring.h" +#include "tqregion.h" +#endif // QT_H + +#ifndef TQT_NO_RICHTEXT + +class TQPainter; +class TQWidget; +class TQStyleSheet; +class TQBrush; +class TQMimeSourceFactory; +class TQSimpleRichTextData; + +class TQ_EXPORT TQSimpleRichText +{ +public: + TQSimpleRichText( const TQString& text, const TQFont& fnt, + const TQString& context = TQString::null, const TQStyleSheet* sheet = 0); + TQSimpleRichText( const TQString& text, const TQFont& fnt, + const TQString& context, const TQStyleSheet* sheet, + const TQMimeSourceFactory* factory, int pageBreak = -1, + const TQColor& linkColor = TQt::blue, bool linkUnderline = TRUE ); + ~TQSimpleRichText(); + + void setWidth( int ); + void setWidth( TQPainter*, int ); + void setDefaultFont( const TQFont &f ); + int width() const; + int widthUsed() const; + int height() const; + void adjustSize(); + + void draw( TQPainter* p, int x, int y, const TQRect& clipRect, + const TQColorGroup& cg, const TQBrush* paper = 0) const; + + // obsolete + void draw( TQPainter* p, int x, int y, const TQRegion& clipRegion, + const TQColorGroup& cg, const TQBrush* paper = 0) const { + draw( p, x, y, clipRegion.boundingRect(), cg, paper ); + } + + TQString context() const; + TQString anchorAt( const TQPoint& pos ) const; + + bool inText( const TQPoint& pos ) const; + +private: + TQSimpleRichTextData* d; + +private: // Disabled copy constructor and operator= +#if defined(TQ_DISABLE_COPY) + TQSimpleRichText( const TQSimpleRichText & ); + TQSimpleRichText &operator=( const TQSimpleRichText & ); +#endif +}; + +#endif // TQT_NO_RICHTEXT + +#endif // TQSIMPLERICHTEXT_H diff --git a/src/moc/moc.pro b/src/moc/moc.pro index dabdef560..e1b56f668 100644 --- a/src/moc/moc.pro +++ b/src/moc/moc.pro @@ -28,7 +28,7 @@ SOURCES = ../tools/tqbuffer.cpp \ ../tools/tqiodevice.cpp \ ../tools/tqregexp.cpp \ ../tools/tqstring.cpp \ - ../tools/qlocale.cpp \ + ../tools/tqlocale.cpp \ ../tools/qunicodetables.cpp \ ../tools/tqstringlist.cpp \ ../tools/tqtextstream.cpp \ diff --git a/src/sql/tqeditorfactory.cpp b/src/sql/tqeditorfactory.cpp index 7893a1355..00f625b55 100644 --- a/src/sql/tqeditorfactory.cpp +++ b/src/sql/tqeditorfactory.cpp @@ -39,7 +39,7 @@ **********************************************************************/ #include "ntqcleanuphandler.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "ntqlineedit.h" #include "ntqspinbox.h" #include "ntqcombobox.h" diff --git a/src/sql/tqsqleditorfactory.cpp b/src/sql/tqsqleditorfactory.cpp index 6be4a2d36..cf4944ae4 100644 --- a/src/sql/tqsqleditorfactory.cpp +++ b/src/sql/tqsqleditorfactory.cpp @@ -44,7 +44,7 @@ #include "tqsqlfield.h" #include "ntqcleanuphandler.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "ntqlineedit.h" #include "ntqspinbox.h" #include "ntqcombobox.h" diff --git a/src/styles/qinterlacestyle.cpp b/src/styles/qinterlacestyle.cpp index 5322c68ba..43917bd27 100644 --- a/src/styles/qinterlacestyle.cpp +++ b/src/styles/qinterlacestyle.cpp @@ -49,7 +49,7 @@ #include "ntqdrawutil.h" // for now #include "tqpalette.h" // for now #include "tqwidget.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "ntqpushbutton.h" #include "tqwidget.h" #include "ntqrangecontrol.h" diff --git a/src/styles/qwindowsstyle.cpp b/src/styles/qwindowsstyle.cpp index 1a9fff5e9..27437724f 100644 --- a/src/styles/qwindowsstyle.cpp +++ b/src/styles/qwindowsstyle.cpp @@ -48,7 +48,7 @@ #include "ntqdrawutil.h" // for now #include "tqpixmap.h" // for now #include "tqwidget.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "tqimage.h" #include "ntqpushbutton.h" #include "ntqcombobox.h" diff --git a/src/tools/ntqlocale.h b/src/tools/ntqlocale.h deleted file mode 100644 index d3a578d1c..000000000 --- a/src/tools/ntqlocale.h +++ /dev/null @@ -1,494 +0,0 @@ -/**************************************************************************** -** -** Declaration of the TQLocale class -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the tools module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#ifndef TQLOCALE_H -#define TQLOCALE_H - -#include "tqstring.h" - -struct TQLocalePrivate; - -class TQ_EXPORT TQLocale -{ - friend class TQString; - -public: - enum Language { - C = 1, - Abkhazian = 2, - Afan = 3, - Afar = 4, - Afrikaans = 5, - Albanian = 6, - Amharic = 7, - Arabic = 8, - Armenian = 9, - Assamese = 10, - Aymara = 11, - Azerbaijani = 12, - Bashkir = 13, - Basque = 14, - Bengali = 15, - Bhutani = 16, - Bihari = 17, - Bislama = 18, - Breton = 19, - Bulgarian = 20, - Burmese = 21, - Byelorussian = 22, - Cambodian = 23, - Catalan = 24, - Chinese = 25, - Corsican = 26, - Croatian = 27, - Czech = 28, - Danish = 29, - Dutch = 30, - English = 31, - Esperanto = 32, - Estonian = 33, - Faroese = 34, - FijiLanguage = 35, - Finnish = 36, - French = 37, - Frisian = 38, - Gaelic = 39, - Galician = 40, - Georgian = 41, - German = 42, - Greek = 43, - Greenlandic = 44, - Guarani = 45, - Gujarati = 46, - Hausa = 47, - Hebrew = 48, - Hindi = 49, - Hungarian = 50, - Icelandic = 51, - Indonesian = 52, - Interlingua = 53, - Interlingue = 54, - Inuktitut = 55, - Inupiak = 56, - Irish = 57, - Italian = 58, - Japanese = 59, - Javanese = 60, - Kannada = 61, - Kashmiri = 62, - Kazakh = 63, - Kinyarwanda = 64, - Kirghiz = 65, - Korean = 66, - Kurdish = 67, - Kurundi = 68, - Laothian = 69, - Latin = 70, - Latvian = 71, - Lingala = 72, - Lithuanian = 73, - Macedonian = 74, - Malagasy = 75, - Malay = 76, - Malayalam = 77, - Maltese = 78, - Maori = 79, - Marathi = 80, - Moldavian = 81, - Mongolian = 82, - NauruLanguage = 83, - Nepali = 84, - Norwegian = 85, - Occitan = 86, - Oriya = 87, - Pashto = 88, - Persian = 89, - Polish = 90, - Portuguese = 91, - Punjabi = 92, - Quechua = 93, - RhaetoRomance = 94, - Romanian = 95, - Russian = 96, - Samoan = 97, - Sangho = 98, - Sanskrit = 99, - Serbian = 100, - SerboCroatian = 101, - Sesotho = 102, - Setswana = 103, - Shona = 104, - Sindhi = 105, - Singhalese = 106, - Siswati = 107, - Slovak = 108, - Slovenian = 109, - Somali = 110, - Spanish = 111, - Sundanese = 112, - Swahili = 113, - Swedish = 114, - Tagalog = 115, - Tajik = 116, - Tamil = 117, - Tatar = 118, - Telugu = 119, - Thai = 120, - Tibetan = 121, - Tigrinya = 122, - TongaLanguage = 123, - Tsonga = 124, - Turkish = 125, - Turkmen = 126, - Twi = 127, - Uigur = 128, - Ukrainian = 129, - Urdu = 130, - Uzbek = 131, - Vietnamese = 132, - Volapuk = 133, - Welsh = 134, - Wolof = 135, - Xhosa = 136, - Yiddish = 137, - Yoruba = 138, - Zhuang = 139, - Zulu = 140, - LastLanguage = Zulu - }; - - enum Country { - AnyCountry = 0, - Afghanistan = 1, - Albania = 2, - Algeria = 3, - AmericanSamoa = 4, - Andorra = 5, - Angola = 6, - Anguilla = 7, - Antarctica = 8, - AntiguaAndBarbuda = 9, - Argentina = 10, - Armenia = 11, - Aruba = 12, - Australia = 13, - Austria = 14, - Azerbaijan = 15, - Bahamas = 16, - Bahrain = 17, - Bangladesh = 18, - Barbados = 19, - Belarus = 20, - Belgium = 21, - Belize = 22, - Benin = 23, - Bermuda = 24, - Bhutan = 25, - Bolivia = 26, - BosniaAndHerzegowina = 27, - Botswana = 28, - BouvetIsland = 29, - Brazil = 30, - BritishIndianOceanTerritory = 31, - BruneiDarussalam = 32, - Bulgaria = 33, - BurkinaFaso = 34, - Burundi = 35, - Cambodia = 36, - Cameroon = 37, - Canada = 38, - CapeVerde = 39, - CaymanIslands = 40, - CentralAfricanRepublic = 41, - Chad = 42, - Chile = 43, - China = 44, - ChristmasIsland = 45, - CocosIslands = 46, - Colombia = 47, - Comoros = 48, - DemocraticRepublicOfCongo = 49, - PeoplesRepublicOfCongo = 50, - CookIslands = 51, - CostaRica = 52, - IvoryCoast = 53, - Croatia = 54, - Cuba = 55, - Cyprus = 56, - CzechRepublic = 57, - Denmark = 58, - Djibouti = 59, - Dominica = 60, - DominicanRepublic = 61, - EastTimor = 62, - Ecuador = 63, - Egypt = 64, - ElSalvador = 65, - EquatorialGuinea = 66, - Eritrea = 67, - Estonia = 68, - Ethiopia = 69, - FalklandIslands = 70, - FaroeIslands = 71, - FijiCountry = 72, - Finland = 73, - France = 74, - MetropolitanFrance = 75, - FrenchGuiana = 76, - FrenchPolynesia = 77, - FrenchSouthernTerritories = 78, - Gabon = 79, - Gambia = 80, - Georgia = 81, - Germany = 82, - Ghana = 83, - Gibraltar = 84, - Greece = 85, - Greenland = 86, - Grenada = 87, - Guadeloupe = 88, - Guam = 89, - Guatemala = 90, - Guinea = 91, - GuineaBissau = 92, - Guyana = 93, - Haiti = 94, - HeardAndMcDonaldIslands = 95, - Honduras = 96, - HongKong = 97, - Hungary = 98, - Iceland = 99, - India = 100, - Indonesia = 101, - Iran = 102, - Iraq = 103, - Ireland = 104, - Israel = 105, - Italy = 106, - Jamaica = 107, - Japan = 108, - Jordan = 109, - Kazakhstan = 110, - Kenya = 111, - Kiribati = 112, - DemocraticRepublicOfKorea = 113, - RepublicOfKorea = 114, - Kuwait = 115, - Kyrgyzstan = 116, - Lao = 117, - Latvia = 118, - Lebanon = 119, - Lesotho = 120, - Liberia = 121, - LibyanArabJamahiriya = 122, - Liechtenstein = 123, - Lithuania = 124, - Luxembourg = 125, - Macau = 126, - Macedonia = 127, - Madagascar = 128, - Malawi = 129, - Malaysia = 130, - Maldives = 131, - Mali = 132, - Malta = 133, - MarshallIslands = 134, - Martinique = 135, - Mauritania = 136, - Mauritius = 137, - Mayotte = 138, - Mexico = 139, - Micronesia = 140, - Moldova = 141, - Monaco = 142, - Mongolia = 143, - Montserrat = 144, - Morocco = 145, - Mozambique = 146, - Myanmar = 147, - Namibia = 148, - NauruCountry = 149, - Nepal = 150, - Netherlands = 151, - NetherlandsAntilles = 152, - NewCaledonia = 153, - NewZealand = 154, - Nicaragua = 155, - Niger = 156, - Nigeria = 157, - Niue = 158, - NorfolkIsland = 159, - NorthernMarianaIslands = 160, - Norway = 161, - Oman = 162, - Pakistan = 163, - Palau = 164, - PalestinianTerritory = 165, - Panama = 166, - PapuaNewGuinea = 167, - Paraguay = 168, - Peru = 169, - Philippines = 170, - Pitcairn = 171, - Poland = 172, - Portugal = 173, - PuertoRico = 174, - Qatar = 175, - Reunion = 176, - Romania = 177, - RussianFederation = 178, - Rwanda = 179, - SaintKittsAndNevis = 180, - StLucia = 181, - StVincentAndTheGrenadines = 182, - Samoa = 183, - SanMarino = 184, - SaoTomeAndPrincipe = 185, - SaudiArabia = 186, - Senegal = 187, - Seychelles = 188, - SierraLeone = 189, - Singapore = 190, - Slovakia = 191, - Slovenia = 192, - SolomonIslands = 193, - Somalia = 194, - SouthAfrica = 195, - SouthGeorgiaAndTheSouthSandwichIslands = 196, - Spain = 197, - SriLanka = 198, - StHelena = 199, - StPierreAndMiquelon = 200, - Sudan = 201, - Suriname = 202, - SvalbardAndJanMayenIslands = 203, - Swaziland = 204, - Sweden = 205, - Switzerland = 206, - SyrianArabRepublic = 207, - Taiwan = 208, - Tajikistan = 209, - Tanzania = 210, - Thailand = 211, - Togo = 212, - Tokelau = 213, - TongaCountry = 214, - TrinidadAndTobago = 215, - Tunisia = 216, - Turkey = 217, - Turkmenistan = 218, - TurksAndCaicosIslands = 219, - Tuvalu = 220, - Uganda = 221, - Ukraine = 222, - UnitedArabEmirates = 223, - UnitedKingdom = 224, - UnitedStates = 225, - UnitedStatesMinorOutlyingIslands = 226, - Uruguay = 227, - Uzbekistan = 228, - Vanuatu = 229, - VaticanCityState = 230, - Venezuela = 231, - VietNam = 232, - BritishVirginIslands = 233, - USVirginIslands = 234, - WallisAndFutunaIslands = 235, - WesternSahara = 236, - Yemen = 237, - Yugoslavia = 238, - Zambia = 239, - Zimbabwe = 240, - LastCountry = Zimbabwe - }; - - TQLocale(); - TQLocale(const TQString &name); - TQLocale(Language language, Country country = AnyCountry); - TQLocale(const TQLocale &other); - - TQLocale &operator=(const TQLocale &other); - - Language language() const; - Country country() const; - TQString name() const; - - short toShort(const TQString &s, bool *ok = 0) const; - ushort toUShort(const TQString &s, bool *ok = 0) const; - int toInt(const TQString &s, bool *ok = 0) const; - uint toUInt(const TQString &s, bool *ok = 0) const; - TQ_LONG toLong(const TQString &s, bool *ok = 0) const; - TQ_ULONG toULong(const TQString &s, bool *ok = 0) const; - TQ_LLONG toLongLong(const TQString &s, bool *ok = 0) const; - TQ_ULLONG toULongLong(const TQString &s, bool *ok = 0) const; - float toFloat(const TQString &s, bool *ok = 0) const; - double toDouble(const TQString &s, bool *ok = 0) const; - - TQString toString(short i) const - { return toString((TQ_LLONG)i); } - TQString toString(ushort i) const - { return toString((TQ_ULLONG)i); } - TQString toString(int i) const - { return toString((TQ_LLONG)i); } - TQString toString(uint i) const - { return toString((TQ_ULLONG)i); } -#if !defined(Q_OS_WIN64) - TQString toString(TQ_LONG i) const - { return toString((TQ_LLONG)i); } - TQString toString(TQ_ULONG i) const - { return toString((TQ_ULLONG)i); } -#endif - TQString toString(TQ_LLONG i) const; - TQString toString(TQ_ULLONG i) const; - TQString toString(float i, char f = 'g', int prec = 6) const - { return toString((double) i, f, prec); } - TQString toString(double i, char f = 'g', int prec = 6) const; - - static TQString languageToString(Language language); - static TQString countryToString(Country country); - static void setDefault(const TQLocale &locale); - - static TQLocale c() { return TQLocale(C); } - static TQLocale system(); - -private: - const TQLocalePrivate *d; - static const TQLocalePrivate *default_d; -}; - -#endif diff --git a/src/tools/qfeatures.txt b/src/tools/qfeatures.txt index 323f38109..89917cbec 100644 --- a/src/tools/qfeatures.txt +++ b/src/tools/qfeatures.txt @@ -591,7 +591,7 @@ SeeAlso: ??? Feature: LABEL Section: Widgets Requires: FRAME -Name: QLabel +Name: TQLabel SeeAlso: ??? Feature: TOOLBAR diff --git a/src/tools/qglobal.cpp b/src/tools/qglobal.cpp index ff5fd5c74..5e9f38a8a 100644 --- a/src/tools/qglobal.cpp +++ b/src/tools/qglobal.cpp @@ -862,7 +862,7 @@ TQtMsgHandler qInstallMsgHandler( TQtMsgHandler h ) /* Dijkstra's bisection algorithm to find the square root as an integer. Deliberately not exported as part of the TQt API, but used in - qsimplerichtext.cpp + tqsimplerichtext.cpp */ unsigned int qt_int_sqrt( unsigned int n ) { diff --git a/src/tools/qlocale.cpp b/src/tools/qlocale.cpp deleted file mode 100644 index fc02f8ef2..000000000 --- a/src/tools/qlocale.cpp +++ /dev/null @@ -1,6322 +0,0 @@ -/**************************************************************************** -** -** Implementation of the TQLocale class -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the tools module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "ntqlocale.h" -#include "qlocale_p.h" -#include "ntqnamespace.h" - -#ifdef QT_QLOCALE_USES_FCVT -# include -# include -#endif - -#if defined (Q_OS_WIN) -# include -# undef NAN // we want to use our fallback on Windows -# undef INFINITY -#endif - -#ifdef Q_OS_LINUX -# include -#endif - -#if defined( Q_OS_MAC ) -# include -#endif - -#if defined (Q_OS_SOLARIS) -# include -#endif - -#if defined (Q_OS_OSF) && (defined(__DECC) || defined(__DECCXX)) -# define INFINITY DBL_INFINITY -# define NAN DBL_QNAN -#endif - -#if (defined(Q_CC_GNU) && defined(Q_OS_WIN)) || __GNUC__ == 4 || defined(QT_QLOCALE_NEEDS_VOLATILE) -# define NEEDS_VOLATILE volatile -#else -# define NEEDS_VOLATILE -#endif - -enum { - LittleEndian, - BigEndian - -#ifdef TQ_BYTE_ORDER -# if TQ_BYTE_ORDER == TQ_BIG_ENDIAN - , ByteOrder = BigEndian -# elif TQ_BYTE_ORDER == TQ_LITTLE_ENDIAN - , ByteOrder = LittleEndian -# else -# error "undefined byte order" -# endif -}; -#else -}; -static const unsigned int one = 1; -static const bool ByteOrder = ((*((unsigned char *) &one) == 0) ? BigEndian : LittleEndian); -#endif - -#if !defined(INFINITY) -static const unsigned char be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }; -static const unsigned char le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; -static inline double inf() -{ - return (ByteOrder == BigEndian ? - *((const double *) be_inf_bytes) : - *((const double *) le_inf_bytes)); -} -# define INFINITY (::inf()) -#endif - -#if !defined(NAN) -static const unsigned char be_nan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }; -static const unsigned char le_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; -static inline double nan() -{ - return (ByteOrder == BigEndian ? - *((const double *) be_nan_bytes) : - *((const double *) le_nan_bytes)); -} -# define NAN (::nan()) -#endif - -// We can't rely on -NAN, since all operations on a NAN should return a NAN. -static double be_neg_nan; -static double le_neg_nan; -static const unsigned char be_neg_nan_bytes[] = { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 }; -static const unsigned char le_neg_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0xff }; -static bool neg_nan_init = false; - -static inline double negNan() -{ - if (!neg_nan_init) - { - memcpy(&be_neg_nan,be_neg_nan_bytes,sizeof(be_neg_nan_bytes)); - memcpy(&le_neg_nan,le_neg_nan_bytes,sizeof(le_neg_nan_bytes)); - neg_nan_init = true; - } - return (ByteOrder == BigEndian ? - be_neg_nan : - le_neg_nan); - -} - -// Sizes as defined by the ISO C99 standard - fallback -#ifndef LLONG_MAX -# define LLONG_MAX TQ_INT64_C(9223372036854775807) -#endif -#ifndef LLONG_MIN -# define LLONG_MIN (-LLONG_MAX - TQ_INT64_C(1)) -#endif -#ifndef ULLONG_MAX -# define ULLONG_MAX TQ_UINT64_C(0xffffffffffffffff) -#endif - -#ifndef QT_QLOCALE_USES_FCVT -static char *qdtoa(double d, int mode, int ndigits, int *decpt, - int *sign, char **rve, char **digits_str); -static char *_qdtoa(double d, int mode, int ndigits, int *decpt, - int *sign, char **rve, char **digits_str); -static double qstrtod(const char *s00, char const **se, bool *ok); -#endif -static TQ_LLONG qstrtoll(const char *nptr, const char **endptr, int base, bool *ok); -static TQ_ULLONG qstrtoull(const char *nptr, const char **endptr, int base, bool *ok); - -static inline bool compareBits(double d1, double d2) -{ - return memcmp((const char*)&d1, (const char*)&d2, sizeof(double)) == 0; -} - -static inline bool qIsInf(double d) -{ - return compareBits(d, INFINITY) || compareBits(d, -INFINITY); -} - -static inline bool qIsNan(double d) -{ - return compareBits(d, NAN) || compareBits(d, negNan()); -} - -static const uint locale_index[] = { - 0, // unused - 0, // C - 0, // Abkhazian - 0, // Afan - 0, // Afar - 1, // Afrikaans - 2, // Albanian - 0, // Amharic - 3, // Arabic - 19, // Armenian - 0, // Assamese - 0, // Aymara - 20, // Azerbaijani - 0, // Bashkir - 21, // Basque - 22, // Bengali - 0, // Bhutani - 0, // Bihari - 0, // Bislama - 0, // Breton - 23, // Bulgarian - 0, // Burmese - 24, // Byelorussian - 0, // Cambodian - 25, // Catalan - 26, // Chinese - 0, // Corsican - 31, // Croatian - 32, // Czech - 33, // Danish - 34, // Dutch - 36, // English - 0, // Esperanto - 48, // Estonian - 49, // Faroese - 0, // Fiji - 50, // Finnish - 51, // French - 0, // Frisian - 0, // Gaelic - 57, // Galician - 58, // Georgian - 59, // German - 64, // Greek - 0, // Greenlandic - 0, // Guarani - 65, // Gujarati - 0, // Hausa - 66, // Hebrew - 67, // Hindi - 68, // Hungarian - 69, // Icelandic - 70, // Indonesian - 0, // Interlingua - 0, // Interlingue - 0, // Inuktitut - 0, // Inupiak - 0, // Irish - 71, // Italian - 73, // Japanese - 0, // Javanese - 74, // Kannada - 0, // Kashmiri - 75, // Kazakh - 0, // Kinyarwanda - 76, // Kirghiz - 77, // Korean - 0, // Kurdish - 0, // Kurundi - 0, // Laothian - 0, // Latin - 78, // Latvian - 0, // Lingala - 79, // Lithuanian - 80, // Macedonian - 0, // Malagasy - 81, // Malay - 0, // Malayalam - 0, // Maltese - 0, // Maori - 83, // Marathi - 0, // Moldavian - 84, // Mongolian - 0, // Nauru - 0, // Nepali - 85, // Norwegian - 0, // Occitan - 0, // Oriya - 0, // Pashto - 86, // Persian - 87, // Polish - 88, // Portuguese - 90, // Punjabi - 0, // Quechua - 0, // RhaetoRomance - 91, // Romanian - 92, // Russian - 0, // Samoan - 0, // Sangho - 93, // Sanskrit - 0, // Serbian - 0, // SerboCroatian - 0, // Sesotho - 0, // Setswana - 0, // Shona - 0, // Sindhi - 0, // Singhalese - 0, // Siswati - 94, // Slovak - 95, // Slovenian - 0, // Somali - 96, // Spanish - 0, // Sundanese - 115, // Swahili - 116, // Swedish - 0, // Tagalog - 0, // Tajik - 118, // Tamil - 0, // Tatar - 119, // Telugu - 120, // Thai - 0, // Tibetan - 0, // Tigrinya - 0, // Tonga - 0, // Tsonga - 121, // Turkish - 0, // Turkmen - 0, // Twi - 0, // Uigur - 122, // Ukrainian - 123, // Urdu - 124, // Uzbek - 125, // Vietnamese - 0, // Volapuk - 0, // Welsh - 0, // Wolof - 0, // Xhosa - 0, // Yiddish - 0, // Yoruba - 0, // Zhuang - 0, // Zulu - 0 // trailing 0 -}; - -static const TQLocalePrivate locale_data[] = { -// lang terr dec group list prcnt zero minus exp - { 1, 0, 46, 44, 59, 37, 48, 45, 101 }, // C/AnyCountry - { 5, 195, 46, 44, 44, 37, 48, 45, 101 }, // Afrikaans/SouthAfrica - { 6, 2, 44, 46, 59, 37, 48, 45, 101 }, // Albanian/Albania - { 8, 186, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/SaudiArabia - { 8, 3, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Algeria - { 8, 17, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Bahrain - { 8, 64, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Egypt - { 8, 103, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Iraq - { 8, 109, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Jordan - { 8, 115, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Kuwait - { 8, 119, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Lebanon - { 8, 122, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/LibyanArabJamahiriya - { 8, 145, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Morocco - { 8, 162, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Oman - { 8, 175, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Qatar - { 8, 207, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/SyrianArabRepublic - { 8, 216, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Tunisia - { 8, 223, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/UnitedArabEmirates - { 8, 237, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Yemen - { 9, 11, 46, 44, 44, 37, 48, 45, 101 }, // Armenian/Armenia - { 12, 15, 44, 160, 59, 37, 48, 45, 101 }, // Azerbaijani/Azerbaijan - { 14, 197, 44, 46, 59, 37, 48, 45, 101 }, // Basque/Spain - { 15, 100, 46, 44, 59, 37, 48, 45, 101 }, // Bengali/India - { 20, 33, 44, 160, 59, 37, 48, 45, 101 }, // Bulgarian/Bulgaria - { 22, 20, 44, 160, 59, 37, 48, 45, 101 }, // Byelorussian/Belarus - { 24, 197, 44, 46, 59, 37, 48, 45, 101 }, // Catalan/Spain - { 25, 44, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/China - { 25, 97, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/HongKong - { 25, 126, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Macau - { 25, 190, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Singapore - { 25, 208, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Taiwan - { 27, 54, 44, 46, 59, 37, 48, 45, 101 }, // Croatian/Croatia - { 28, 57, 44, 160, 59, 37, 48, 45, 101 }, // Czech/CzechRepublic - { 29, 58, 44, 46, 59, 37, 48, 45, 101 }, // Danish/Denmark - { 30, 151, 44, 46, 59, 37, 48, 45, 101 }, // Dutch/Netherlands - { 30, 21, 44, 46, 59, 37, 48, 45, 101 }, // Dutch/Belgium - { 31, 225, 46, 44, 44, 37, 48, 45, 101 }, // English/UnitedStates - { 31, 13, 46, 44, 44, 37, 48, 45, 101 }, // English/Australia - { 31, 22, 46, 44, 59, 37, 48, 45, 101 }, // English/Belize - { 31, 38, 46, 44, 44, 37, 48, 45, 101 }, // English/Canada - { 31, 104, 46, 44, 44, 37, 48, 45, 101 }, // English/Ireland - { 31, 107, 46, 44, 44, 37, 48, 45, 101 }, // English/Jamaica - { 31, 154, 46, 44, 44, 37, 48, 45, 101 }, // English/NewZealand - { 31, 170, 46, 44, 44, 37, 48, 45, 101 }, // English/Philippines - { 31, 195, 46, 44, 44, 37, 48, 45, 101 }, // English/SouthAfrica - { 31, 215, 46, 44, 59, 37, 48, 45, 101 }, // English/TrinidadAndTobago - { 31, 224, 46, 44, 44, 37, 48, 45, 101 }, // English/UnitedKingdom - { 31, 240, 46, 44, 44, 37, 48, 45, 101 }, // English/Zimbabwe - { 33, 68, 44, 160, 59, 37, 48, 45, 101 }, // Estonian/Estonia - { 34, 71, 44, 46, 59, 37, 48, 45, 101 }, // Faroese/FaroeIslands - { 36, 73, 44, 160, 59, 37, 48, 45, 101 }, // Finnish/Finland - { 37, 74, 44, 160, 59, 37, 48, 45, 101 }, // French/France - { 37, 21, 44, 46, 59, 37, 48, 45, 101 }, // French/Belgium - { 37, 38, 44, 160, 59, 37, 48, 45, 101 }, // French/Canada - { 37, 125, 44, 160, 59, 37, 48, 45, 101 }, // French/Luxembourg - { 37, 142, 44, 160, 59, 37, 48, 45, 101 }, // French/Monaco - { 37, 206, 46, 39, 59, 37, 48, 45, 101 }, // French/Switzerland - { 40, 197, 44, 46, 44, 37, 48, 45, 101 }, // Galician/Spain - { 41, 81, 44, 160, 59, 37, 48, 45, 101 }, // Georgian/Georgia - { 42, 82, 44, 46, 59, 37, 48, 45, 101 }, // German/Germany - { 42, 14, 44, 46, 59, 37, 48, 45, 101 }, // German/Austria - { 42, 123, 46, 39, 59, 37, 48, 45, 101 }, // German/Liechtenstein - { 42, 125, 44, 46, 59, 37, 48, 45, 101 }, // German/Luxembourg - { 42, 206, 46, 39, 59, 37, 48, 45, 101 }, // German/Switzerland - { 43, 85, 44, 46, 59, 37, 48, 45, 101 }, // Greek/Greece - { 46, 100, 46, 44, 44, 37, 2790, 45, 101 }, // Gujarati/India - { 48, 105, 46, 44, 44, 37, 48, 45, 101 }, // Hebrew/Israel - { 49, 100, 46, 44, 44, 37, 48, 45, 101 }, // Hindi/India - { 50, 98, 44, 160, 59, 37, 48, 45, 101 }, // Hungarian/Hungary - { 51, 99, 44, 46, 59, 37, 48, 45, 101 }, // Icelandic/Iceland - { 52, 101, 44, 46, 59, 37, 48, 45, 101 }, // Indonesian/Indonesia - { 58, 106, 44, 46, 59, 37, 48, 45, 101 }, // Italian/Italy - { 58, 206, 46, 39, 59, 37, 48, 45, 101 }, // Italian/Switzerland - { 59, 108, 46, 44, 44, 37, 48, 45, 101 }, // Japanese/Japan - { 61, 100, 46, 44, 44, 37, 3302, 45, 101 }, // Kannada/India - { 63, 110, 44, 160, 59, 37, 48, 45, 101 }, // Kazakh/Kazakhstan - { 65, 116, 44, 160, 59, 37, 48, 45, 101 }, // Kirghiz/Kyrgyzstan - { 66, 114, 46, 44, 44, 37, 48, 45, 101 }, // Korean/RepublicOfKorea - { 71, 118, 44, 160, 59, 37, 48, 45, 101 }, // Latvian/Latvia - { 73, 124, 44, 46, 59, 37, 48, 45, 101 }, // Lithuanian/Lithuania - { 74, 127, 44, 46, 59, 37, 48, 45, 101 }, // Macedonian/Macedonia - { 76, 130, 44, 46, 59, 37, 48, 45, 101 }, // Malay/Malaysia - { 76, 32, 44, 46, 59, 37, 48, 45, 101 }, // Malay/BruneiDarussalam - { 80, 100, 46, 44, 44, 37, 2406, 45, 101 }, // Marathi/India - { 82, 143, 44, 160, 59, 37, 48, 45, 101 }, // Mongolian/Mongolia - { 85, 161, 44, 160, 59, 37, 48, 45, 101 }, // Norwegian/Norway - { 89, 102, 46, 44, 59, 37, 1776, 45, 101 }, // Persian/Iran - { 90, 172, 44, 160, 59, 37, 48, 45, 101 }, // Polish/Poland - { 91, 173, 44, 46, 59, 37, 48, 45, 101 }, // Portuguese/Portugal - { 91, 30, 44, 46, 59, 37, 48, 45, 101 }, // Portuguese/Brazil - { 92, 100, 46, 44, 44, 37, 2662, 45, 101 }, // Punjabi/India - { 95, 177, 44, 46, 59, 37, 48, 45, 101 }, // Romanian/Romania - { 96, 178, 44, 160, 59, 37, 48, 45, 101 }, // Russian/RussianFederation - { 99, 100, 46, 44, 44, 37, 2406, 45, 101 }, // Sanskrit/India - { 108, 191, 44, 160, 59, 37, 48, 45, 101 }, // Slovak/Slovakia - { 109, 192, 44, 46, 59, 37, 48, 45, 101 }, // Slovenian/Slovenia - { 111, 197, 44, 46, 59, 37, 48, 45, 101 }, // Spanish/Spain - { 111, 10, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Argentina - { 111, 26, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Bolivia - { 111, 43, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Chile - { 111, 47, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Colombia - { 111, 52, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/CostaRica - { 111, 61, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/DominicanRepublic - { 111, 63, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Ecuador - { 111, 65, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/ElSalvador - { 111, 90, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Guatemala - { 111, 96, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Honduras - { 111, 139, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Mexico - { 111, 155, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Nicaragua - { 111, 166, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Panama - { 111, 168, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Paraguay - { 111, 169, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Peru - { 111, 174, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/PuertoRico - { 111, 227, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Uruguay - { 111, 231, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Venezuela - { 113, 111, 46, 44, 44, 37, 48, 45, 101 }, // Swahili/Kenya - { 114, 205, 44, 160, 59, 37, 48, 45, 101 }, // Swedish/Sweden - { 114, 73, 44, 160, 59, 37, 48, 45, 101 }, // Swedish/Finland - { 117, 100, 46, 44, 44, 37, 48, 45, 101 }, // Tamil/India - { 119, 100, 46, 44, 44, 37, 3174, 45, 101 }, // Telugu/India - { 120, 211, 46, 44, 44, 37, 3664, 45, 101 }, // Thai/Thailand - { 125, 217, 44, 46, 59, 37, 48, 45, 101 }, // Turkish/Turkey - { 129, 222, 44, 160, 59, 37, 48, 45, 101 }, // Ukrainian/Ukraine - { 130, 163, 46, 44, 59, 37, 1776, 45, 101 }, // Urdu/Pakistan - { 131, 228, 44, 160, 59, 37, 48, 45, 101 }, // Uzbek/Uzbekistan - { 132, 232, 44, 46, 44, 37, 48, 45, 101 }, // Vietnamese/VietNam - { 0, 0, 0, 0, 0, 0, 0, 0, 0 } // trailing 0s -}; - -static const char language_name_list[] = -"Default\0" -"C\0" -"Abkhazian\0" -"Afan\0" -"Afar\0" -"Afrikaans\0" -"Albanian\0" -"Amharic\0" -"Arabic\0" -"Armenian\0" -"Assamese\0" -"Aymara\0" -"Azerbaijani\0" -"Bashkir\0" -"Basque\0" -"Bengali\0" -"Bhutani\0" -"Bihari\0" -"Bislama\0" -"Breton\0" -"Bulgarian\0" -"Burmese\0" -"Byelorussian\0" -"Cambodian\0" -"Catalan\0" -"Chinese\0" -"Corsican\0" -"Croatian\0" -"Czech\0" -"Danish\0" -"Dutch\0" -"English\0" -"Esperanto\0" -"Estonian\0" -"Faroese\0" -"Fiji\0" -"Finnish\0" -"French\0" -"Frisian\0" -"Gaelic\0" -"Galician\0" -"Georgian\0" -"German\0" -"Greek\0" -"Greenlandic\0" -"Guarani\0" -"Gujarati\0" -"Hausa\0" -"Hebrew\0" -"Hindi\0" -"Hungarian\0" -"Icelandic\0" -"Indonesian\0" -"Interlingua\0" -"Interlingue\0" -"Inuktitut\0" -"Inupiak\0" -"Irish\0" -"Italian\0" -"Japanese\0" -"Javanese\0" -"Kannada\0" -"Kashmiri\0" -"Kazakh\0" -"Kinyarwanda\0" -"Kirghiz\0" -"Korean\0" -"Kurdish\0" -"Kurundi\0" -"Laothian\0" -"Latin\0" -"Latvian\0" -"Lingala\0" -"Lithuanian\0" -"Macedonian\0" -"Malagasy\0" -"Malay\0" -"Malayalam\0" -"Maltese\0" -"Maori\0" -"Marathi\0" -"Moldavian\0" -"Mongolian\0" -"Nauru\0" -"Nepali\0" -"Norwegian\0" -"Occitan\0" -"Oriya\0" -"Pashto\0" -"Persian\0" -"Polish\0" -"Portuguese\0" -"Punjabi\0" -"Quechua\0" -"RhaetoRomance\0" -"Romanian\0" -"Russian\0" -"Samoan\0" -"Sangho\0" -"Sanskrit\0" -"Serbian\0" -"SerboCroatian\0" -"Sesotho\0" -"Setswana\0" -"Shona\0" -"Sindhi\0" -"Singhalese\0" -"Siswati\0" -"Slovak\0" -"Slovenian\0" -"Somali\0" -"Spanish\0" -"Sundanese\0" -"Swahili\0" -"Swedish\0" -"Tagalog\0" -"Tajik\0" -"Tamil\0" -"Tatar\0" -"Telugu\0" -"Thai\0" -"Tibetan\0" -"Tigrinya\0" -"Tonga\0" -"Tsonga\0" -"Turkish\0" -"Turkmen\0" -"Twi\0" -"Uigur\0" -"Ukrainian\0" -"Urdu\0" -"Uzbek\0" -"Vietnamese\0" -"Volapuk\0" -"Welsh\0" -"Wolof\0" -"Xhosa\0" -"Yiddish\0" -"Yoruba\0" -"Zhuang\0" -"Zulu\0"; - -static const uint language_name_index[] = { - 0,// Unused - 8,// C - 10,// Abkhazian - 20,// Afan - 25,// Afar - 30,// Afrikaans - 40,// Albanian - 49,// Amharic - 57,// Arabic - 64,// Armenian - 73,// Assamese - 82,// Aymara - 89,// Azerbaijani - 101,// Bashkir - 109,// Basque - 116,// Bengali - 124,// Bhutani - 132,// Bihari - 139,// Bislama - 147,// Breton - 154,// Bulgarian - 164,// Burmese - 172,// Byelorussian - 185,// Cambodian - 195,// Catalan - 203,// Chinese - 211,// Corsican - 220,// Croatian - 229,// Czech - 235,// Danish - 242,// Dutch - 248,// English - 256,// Esperanto - 266,// Estonian - 275,// Faroese - 283,// Fiji - 288,// Finnish - 296,// French - 303,// Frisian - 311,// Gaelic - 318,// Galician - 327,// Georgian - 336,// German - 343,// Greek - 349,// Greenlandic - 361,// Guarani - 369,// Gujarati - 378,// Hausa - 384,// Hebrew - 391,// Hindi - 397,// Hungarian - 407,// Icelandic - 417,// Indonesian - 428,// Interlingua - 440,// Interlingue - 452,// Inuktitut - 462,// Inupiak - 470,// Irish - 476,// Italian - 484,// Japanese - 493,// Javanese - 502,// Kannada - 510,// Kashmiri - 519,// Kazakh - 526,// Kinyarwanda - 538,// Kirghiz - 546,// Korean - 553,// Kurdish - 561,// Kurundi - 569,// Laothian - 578,// Latin - 584,// Latvian - 592,// Lingala - 600,// Lithuanian - 611,// Macedonian - 622,// Malagasy - 631,// Malay - 637,// Malayalam - 647,// Maltese - 655,// Maori - 661,// Marathi - 669,// Moldavian - 679,// Mongolian - 689,// Nauru - 695,// Nepali - 702,// Norwegian - 712,// Occitan - 720,// Oriya - 726,// Pashto - 733,// Persian - 741,// Polish - 748,// Portuguese - 759,// Punjabi - 767,// Quechua - 775,// RhaetoRomance - 789,// Romanian - 798,// Russian - 806,// Samoan - 813,// Sangho - 820,// Sanskrit - 829,// Serbian - 837,// SerboCroatian - 851,// Sesotho - 859,// Setswana - 868,// Shona - 874,// Sindhi - 881,// Singhalese - 892,// Siswati - 900,// Slovak - 907,// Slovenian - 917,// Somali - 924,// Spanish - 932,// Sundanese - 942,// Swahili - 950,// Swedish - 958,// Tagalog - 966,// Tajik - 972,// Tamil - 978,// Tatar - 984,// Telugu - 991,// Thai - 996,// Tibetan - 1004,// Tigrinya - 1013,// Tonga - 1019,// Tsonga - 1026,// Turkish - 1034,// Turkmen - 1042,// Twi - 1046,// Uigur - 1052,// Ukrainian - 1062,// Urdu - 1067,// Uzbek - 1073,// Vietnamese - 1084,// Volapuk - 1092,// Welsh - 1098,// Wolof - 1104,// Xhosa - 1110,// Yiddish - 1118,// Yoruba - 1125,// Zhuang - 1132// Zulu -}; - -static const char country_name_list[] = -"Default\0" -"Afghanistan\0" -"Albania\0" -"Algeria\0" -"AmericanSamoa\0" -"Andorra\0" -"Angola\0" -"Anguilla\0" -"Antarctica\0" -"AntiguaAndBarbuda\0" -"Argentina\0" -"Armenia\0" -"Aruba\0" -"Australia\0" -"Austria\0" -"Azerbaijan\0" -"Bahamas\0" -"Bahrain\0" -"Bangladesh\0" -"Barbados\0" -"Belarus\0" -"Belgium\0" -"Belize\0" -"Benin\0" -"Bermuda\0" -"Bhutan\0" -"Bolivia\0" -"BosniaAndHerzegowina\0" -"Botswana\0" -"BouvetIsland\0" -"Brazil\0" -"BritishIndianOceanTerritory\0" -"BruneiDarussalam\0" -"Bulgaria\0" -"BurkinaFaso\0" -"Burundi\0" -"Cambodia\0" -"Cameroon\0" -"Canada\0" -"CapeVerde\0" -"CaymanIslands\0" -"CentralAfricanRepublic\0" -"Chad\0" -"Chile\0" -"China\0" -"ChristmasIsland\0" -"CocosIslands\0" -"Colombia\0" -"Comoros\0" -"DemocraticRepublicOfCongo\0" -"PeoplesRepublicOfCongo\0" -"CookIslands\0" -"CostaRica\0" -"IvoryCoast\0" -"Croatia\0" -"Cuba\0" -"Cyprus\0" -"CzechRepublic\0" -"Denmark\0" -"Djibouti\0" -"Dominica\0" -"DominicanRepublic\0" -"EastTimor\0" -"Ecuador\0" -"Egypt\0" -"ElSalvador\0" -"EquatorialGuinea\0" -"Eritrea\0" -"Estonia\0" -"Ethiopia\0" -"FalklandIslands\0" -"FaroeIslands\0" -"Fiji\0" -"Finland\0" -"France\0" -"MetropolitanFrance\0" -"FrenchGuiana\0" -"FrenchPolynesia\0" -"FrenchSouthernTerritories\0" -"Gabon\0" -"Gambia\0" -"Georgia\0" -"Germany\0" -"Ghana\0" -"Gibraltar\0" -"Greece\0" -"Greenland\0" -"Grenada\0" -"Guadeloupe\0" -"Guam\0" -"Guatemala\0" -"Guinea\0" -"GuineaBissau\0" -"Guyana\0" -"Haiti\0" -"HeardAndMcDonaldIslands\0" -"Honduras\0" -"HongKong\0" -"Hungary\0" -"Iceland\0" -"India\0" -"Indonesia\0" -"Iran\0" -"Iraq\0" -"Ireland\0" -"Israel\0" -"Italy\0" -"Jamaica\0" -"Japan\0" -"Jordan\0" -"Kazakhstan\0" -"Kenya\0" -"Kiribati\0" -"DemocraticRepublicOfKorea\0" -"RepublicOfKorea\0" -"Kuwait\0" -"Kyrgyzstan\0" -"Lao\0" -"Latvia\0" -"Lebanon\0" -"Lesotho\0" -"Liberia\0" -"LibyanArabJamahiriya\0" -"Liechtenstein\0" -"Lithuania\0" -"Luxembourg\0" -"Macau\0" -"Macedonia\0" -"Madagascar\0" -"Malawi\0" -"Malaysia\0" -"Maldives\0" -"Mali\0" -"Malta\0" -"MarshallIslands\0" -"Martinique\0" -"Mauritania\0" -"Mauritius\0" -"Mayotte\0" -"Mexico\0" -"Micronesia\0" -"Moldova\0" -"Monaco\0" -"Mongolia\0" -"Montserrat\0" -"Morocco\0" -"Mozambique\0" -"Myanmar\0" -"Namibia\0" -"Nauru\0" -"Nepal\0" -"Netherlands\0" -"NetherlandsAntilles\0" -"NewCaledonia\0" -"NewZealand\0" -"Nicaragua\0" -"Niger\0" -"Nigeria\0" -"Niue\0" -"NorfolkIsland\0" -"NorthernMarianaIslands\0" -"Norway\0" -"Oman\0" -"Pakistan\0" -"Palau\0" -"PalestinianTerritory\0" -"Panama\0" -"PapuaNewGuinea\0" -"Paraguay\0" -"Peru\0" -"Philippines\0" -"Pitcairn\0" -"Poland\0" -"Portugal\0" -"PuertoRico\0" -"Qatar\0" -"Reunion\0" -"Romania\0" -"RussianFederation\0" -"Rwanda\0" -"SaintKittsAndNevis\0" -"StLucia\0" -"StVincentAndTheGrenadines\0" -"Samoa\0" -"SanMarino\0" -"SaoTomeAndPrincipe\0" -"SaudiArabia\0" -"Senegal\0" -"Seychelles\0" -"SierraLeone\0" -"Singapore\0" -"Slovakia\0" -"Slovenia\0" -"SolomonIslands\0" -"Somalia\0" -"SouthAfrica\0" -"SouthGeorgiaAndTheSouthSandwichIslands\0" -"Spain\0" -"SriLanka\0" -"StHelena\0" -"StPierreAndMiquelon\0" -"Sudan\0" -"Suriname\0" -"SvalbardAndJanMayenIslands\0" -"Swaziland\0" -"Sweden\0" -"Switzerland\0" -"SyrianArabRepublic\0" -"Taiwan\0" -"Tajikistan\0" -"Tanzania\0" -"Thailand\0" -"Togo\0" -"Tokelau\0" -"Tonga\0" -"TrinidadAndTobago\0" -"Tunisia\0" -"Turkey\0" -"Turkmenistan\0" -"TurksAndCaicosIslands\0" -"Tuvalu\0" -"Uganda\0" -"Ukraine\0" -"UnitedArabEmirates\0" -"UnitedKingdom\0" -"UnitedStates\0" -"UnitedStatesMinorOutlyingIslands\0" -"Uruguay\0" -"Uzbekistan\0" -"Vanuatu\0" -"VaticanCityState\0" -"Venezuela\0" -"VietNam\0" -"BritishVirginIslands\0" -"USVirginIslands\0" -"WallisAndFutunaIslands\0" -"WesternSahara\0" -"Yemen\0" -"Yugoslavia\0" -"Zambia\0" -"Zimbabwe\0"; - -static const uint country_name_index[] = { - 0,// AnyCountry - 8,// Afghanistan - 20,// Albania - 28,// Algeria - 36,// AmericanSamoa - 50,// Andorra - 58,// Angola - 65,// Anguilla - 74,// Antarctica - 85,// AntiguaAndBarbuda - 103,// Argentina - 113,// Armenia - 121,// Aruba - 127,// Australia - 137,// Austria - 145,// Azerbaijan - 156,// Bahamas - 164,// Bahrain - 172,// Bangladesh - 183,// Barbados - 192,// Belarus - 200,// Belgium - 208,// Belize - 215,// Benin - 221,// Bermuda - 229,// Bhutan - 236,// Bolivia - 244,// BosniaAndHerzegowina - 265,// Botswana - 274,// BouvetIsland - 287,// Brazil - 294,// BritishIndianOceanTerritory - 322,// BruneiDarussalam - 339,// Bulgaria - 348,// BurkinaFaso - 360,// Burundi - 368,// Cambodia - 377,// Cameroon - 386,// Canada - 393,// CapeVerde - 403,// CaymanIslands - 417,// CentralAfricanRepublic - 440,// Chad - 445,// Chile - 451,// China - 457,// ChristmasIsland - 473,// CocosIslands - 486,// Colombia - 495,// Comoros - 503,// DemocraticRepublicOfCongo - 529,// PeoplesRepublicOfCongo - 552,// CookIslands - 564,// CostaRica - 574,// IvoryCoast - 585,// Croatia - 593,// Cuba - 598,// Cyprus - 605,// CzechRepublic - 619,// Denmark - 627,// Djibouti - 636,// Dominica - 645,// DominicanRepublic - 663,// EastTimor - 673,// Ecuador - 681,// Egypt - 687,// ElSalvador - 698,// EquatorialGuinea - 715,// Eritrea - 723,// Estonia - 731,// Ethiopia - 740,// FalklandIslands - 756,// FaroeIslands - 769,// Fiji - 774,// Finland - 782,// France - 789,// MetropolitanFrance - 808,// FrenchGuiana - 821,// FrenchPolynesia - 837,// FrenchSouthernTerritories - 863,// Gabon - 869,// Gambia - 876,// Georgia - 884,// Germany - 892,// Ghana - 898,// Gibraltar - 908,// Greece - 915,// Greenland - 925,// Grenada - 933,// Guadeloupe - 944,// Guam - 949,// Guatemala - 959,// Guinea - 966,// GuineaBissau - 979,// Guyana - 986,// Haiti - 992,// HeardAndMcDonaldIslands - 1016,// Honduras - 1025,// HongKong - 1034,// Hungary - 1042,// Iceland - 1050,// India - 1056,// Indonesia - 1066,// Iran - 1071,// Iraq - 1076,// Ireland - 1084,// Israel - 1091,// Italy - 1097,// Jamaica - 1105,// Japan - 1111,// Jordan - 1118,// Kazakhstan - 1129,// Kenya - 1135,// Kiribati - 1144,// DemocraticRepublicOfKorea - 1170,// RepublicOfKorea - 1186,// Kuwait - 1193,// Kyrgyzstan - 1204,// Lao - 1208,// Latvia - 1215,// Lebanon - 1223,// Lesotho - 1231,// Liberia - 1239,// LibyanArabJamahiriya - 1260,// Liechtenstein - 1274,// Lithuania - 1284,// Luxembourg - 1295,// Macau - 1301,// Macedonia - 1311,// Madagascar - 1322,// Malawi - 1329,// Malaysia - 1338,// Maldives - 1347,// Mali - 1352,// Malta - 1358,// MarshallIslands - 1374,// Martinique - 1385,// Mauritania - 1396,// Mauritius - 1406,// Mayotte - 1414,// Mexico - 1421,// Micronesia - 1432,// Moldova - 1440,// Monaco - 1447,// Mongolia - 1456,// Montserrat - 1467,// Morocco - 1475,// Mozambique - 1486,// Myanmar - 1494,// Namibia - 1502,// Nauru - 1508,// Nepal - 1514,// Netherlands - 1526,// NetherlandsAntilles - 1546,// NewCaledonia - 1559,// NewZealand - 1570,// Nicaragua - 1580,// Niger - 1586,// Nigeria - 1594,// Niue - 1599,// NorfolkIsland - 1613,// NorthernMarianaIslands - 1636,// Norway - 1643,// Oman - 1648,// Pakistan - 1657,// Palau - 1663,// PalestinianTerritory - 1684,// Panama - 1691,// PapuaNewGuinea - 1706,// Paraguay - 1715,// Peru - 1720,// Philippines - 1732,// Pitcairn - 1741,// Poland - 1748,// Portugal - 1757,// PuertoRico - 1768,// Qatar - 1774,// Reunion - 1782,// Romania - 1790,// RussianFederation - 1808,// Rwanda - 1815,// SaintKittsAndNevis - 1834,// StLucia - 1842,// StVincentAndTheGrenadines - 1868,// Samoa - 1874,// SanMarino - 1884,// SaoTomeAndPrincipe - 1903,// SaudiArabia - 1915,// Senegal - 1923,// Seychelles - 1934,// SierraLeone - 1946,// Singapore - 1956,// Slovakia - 1965,// Slovenia - 1974,// SolomonIslands - 1989,// Somalia - 1997,// SouthAfrica - 2009,// SouthGeorgiaAndTheSouthSandwichIslands - 2048,// Spain - 2054,// SriLanka - 2063,// StHelena - 2072,// StPierreAndMiquelon - 2092,// Sudan - 2098,// Suriname - 2107,// SvalbardAndJanMayenIslands - 2134,// Swaziland - 2144,// Sweden - 2151,// Switzerland - 2163,// SyrianArabRepublic - 2182,// Taiwan - 2189,// Tajikistan - 2200,// Tanzania - 2209,// Thailand - 2218,// Togo - 2223,// Tokelau - 2231,// Tonga - 2237,// TrinidadAndTobago - 2255,// Tunisia - 2263,// Turkey - 2270,// Turkmenistan - 2283,// TurksAndCaicosIslands - 2305,// Tuvalu - 2312,// Uganda - 2319,// Ukraine - 2327,// UnitedArabEmirates - 2346,// UnitedKingdom - 2360,// UnitedStates - 2373,// UnitedStatesMinorOutlyingIslands - 2406,// Uruguay - 2414,// Uzbekistan - 2425,// Vanuatu - 2433,// VaticanCityState - 2450,// Venezuela - 2460,// VietNam - 2468,// BritishVirginIslands - 2489,// USVirginIslands - 2505,// WallisAndFutunaIslands - 2528,// WesternSahara - 2542,// Yemen - 2548,// Yugoslavia - 2559,// Zambia - 2566// Zimbabwe -}; - -static const char language_code_list[] = -" " // Unused -" " // C -"ab" // Abkhazian -"om" // Afan -"aa" // Afar -"af" // Afrikaans -"sq" // Albanian -"am" // Amharic -"ar" // Arabic -"hy" // Armenian -"as" // Assamese -"ay" // Aymara -"az" // Azerbaijani -"ba" // Bashkir -"eu" // Basque -"bn" // Bengali -"dz" // Bhutani -"bh" // Bihari -"bi" // Bislama -"br" // Breton -"bg" // Bulgarian -"my" // Burmese -"be" // Byelorussian -"km" // Cambodian -"ca" // Catalan -"zh" // Chinese -"co" // Corsican -"hr" // Croatian -"cs" // Czech -"da" // Danish -"nl" // Dutch -"en" // English -"eo" // Esperanto -"et" // Estonian -"fo" // Faroese -"fj" // Fiji -"fi" // Finnish -"fr" // French -"fy" // Frisian -"gd" // Gaelic -"gl" // Galician -"ka" // Georgian -"de" // German -"el" // Greek -"kl" // Greenlandic -"gn" // Guarani -"gu" // Gujarati -"ha" // Hausa -"he" // Hebrew -"hi" // Hindi -"hu" // Hungarian -"is" // Icelandic -"id" // Indonesian -"ia" // Interlingua -"ie" // Interlingue -"iu" // Inuktitut -"ik" // Inupiak -"ga" // Irish -"it" // Italian -"ja" // Japanese -"jv" // Javanese -"kn" // Kannada -"ks" // Kashmiri -"kk" // Kazakh -"rw" // Kinyarwanda -"ky" // Kirghiz -"ko" // Korean -"ku" // Kurdish -"rn" // Kurundi -"lo" // Laothian -"la" // Latin -"lv" // Latvian -"ln" // Lingala -"lt" // Lithuanian -"mk" // Macedonian -"mg" // Malagasy -"ms" // Malay -"ml" // Malayalam -"mt" // Maltese -"mi" // Maori -"mr" // Marathi -"mo" // Moldavian -"mn" // Mongolian -"na" // Nauru -"ne" // Nepali -"no" // Norwegian -"oc" // Occitan -"or" // Oriya -"ps" // Pashto -"fa" // Persian -"pl" // Polish -"pt" // Portuguese -"pa" // Punjabi -"qu" // Quechua -"rm" // RhaetoRomance -"ro" // Romanian -"ru" // Russian -"sm" // Samoan -"sg" // Sangho -"sa" // Sanskrit -"sr" // Serbian -"sh" // SerboCroatian -"st" // Sesotho -"tn" // Setswana -"sn" // Shona -"sd" // Sindhi -"si" // Singhalese -"ss" // Siswati -"sk" // Slovak -"sl" // Slovenian -"so" // Somali -"es" // Spanish -"su" // Sundanese -"sw" // Swahili -"sv" // Swedish -"tl" // Tagalog -"tg" // Tajik -"ta" // Tamil -"tt" // Tatar -"te" // Telugu -"th" // Thai -"bo" // Tibetan -"ti" // Tigrinya -"to" // Tonga -"ts" // Tsonga -"tr" // Turkish -"tk" // Turkmen -"tw" // Twi -"ug" // Uigur -"uk" // Ukrainian -"ur" // Urdu -"uz" // Uzbek -"vi" // Vietnamese -"vo" // Volapuk -"cy" // Welsh -"wo" // Wolof -"xh" // Xhosa -"yi" // Yiddish -"yo" // Yoruba -"za" // Zhuang -"zu" // Zulu -; - -static const char country_code_list[] = -" " // AnyLanguage -"AF" // Afghanistan -"AL" // Albania -"DZ" // Algeria -"AS" // AmericanSamoa -"AD" // Andorra -"AO" // Angola -"AI" // Anguilla -"AQ" // Antarctica -"AG" // AntiguaAndBarbuda -"AR" // Argentina -"AM" // Armenia -"AW" // Aruba -"AU" // Australia -"AT" // Austria -"AZ" // Azerbaijan -"BS" // Bahamas -"BH" // Bahrain -"BD" // Bangladesh -"BB" // Barbados -"BY" // Belarus -"BE" // Belgium -"BZ" // Belize -"BJ" // Benin -"BM" // Bermuda -"BT" // Bhutan -"BO" // Bolivia -"BA" // BosniaAndHerzegowina -"BW" // Botswana -"BV" // BouvetIsland -"BR" // Brazil -"IO" // BritishIndianOceanTerritory -"BN" // BruneiDarussalam -"BG" // Bulgaria -"BF" // BurkinaFaso -"BI" // Burundi -"KH" // Cambodia -"CM" // Cameroon -"CA" // Canada -"CV" // CapeVerde -"KY" // CaymanIslands -"CF" // CentralAfricanRepublic -"TD" // Chad -"CL" // Chile -"CN" // China -"CX" // ChristmasIsland -"CC" // CocosIslands -"CO" // Colombia -"KM" // Comoros -"CD" // DemocraticRepublicOfCongo -"CG" // PeoplesRepublicOfCongo -"CK" // CookIslands -"CR" // CostaRica -"CI" // IvoryCoast -"HR" // Croatia -"CU" // Cuba -"CY" // Cyprus -"CZ" // CzechRepublic -"DK" // Denmark -"DJ" // Djibouti -"DM" // Dominica -"DO" // DominicanRepublic -"TL" // EastTimor -"EC" // Ecuador -"EG" // Egypt -"SV" // ElSalvador -"GQ" // EquatorialGuinea -"ER" // Eritrea -"EE" // Estonia -"ET" // Ethiopia -"FK" // FalklandIslands -"FO" // FaroeIslands -"FJ" // Fiji -"FI" // Finland -"FR" // France -"FX" // MetropolitanFrance -"GF" // FrenchGuiana -"PF" // FrenchPolynesia -"TF" // FrenchSouthernTerritories -"GA" // Gabon -"GM" // Gambia -"GE" // Georgia -"DE" // Germany -"GH" // Ghana -"GI" // Gibraltar -"GR" // Greece -"GL" // Greenland -"GD" // Grenada -"GP" // Guadeloupe -"GU" // Guam -"GT" // Guatemala -"GN" // Guinea -"GW" // GuineaBissau -"GY" // Guyana -"HT" // Haiti -"HM" // HeardAndMcDonaldIslands -"HN" // Honduras -"HK" // HongKong -"HU" // Hungary -"IS" // Iceland -"IN" // India -"ID" // Indonesia -"IR" // Iran -"IQ" // Iraq -"IE" // Ireland -"IL" // Israel -"IT" // Italy -"JM" // Jamaica -"JP" // Japan -"JO" // Jordan -"KZ" // Kazakhstan -"KE" // Kenya -"KI" // Kiribati -"KP" // DemocraticRepublicOfKorea -"KR" // RepublicOfKorea -"KW" // Kuwait -"KG" // Kyrgyzstan -"LA" // Lao -"LV" // Latvia -"LB" // Lebanon -"LS" // Lesotho -"LR" // Liberia -"LY" // LibyanArabJamahiriya -"LI" // Liechtenstein -"LT" // Lithuania -"LU" // Luxembourg -"MO" // Macau -"MK" // Macedonia -"MG" // Madagascar -"MW" // Malawi -"MY" // Malaysia -"MV" // Maldives -"ML" // Mali -"MT" // Malta -"MH" // MarshallIslands -"MQ" // Martinique -"MR" // Mauritania -"MU" // Mauritius -"YT" // Mayotte -"MX" // Mexico -"FM" // Micronesia -"MD" // Moldova -"MC" // Monaco -"MN" // Mongolia -"MS" // Montserrat -"MA" // Morocco -"MZ" // Mozambique -"MM" // Myanmar -"NA" // Namibia -"NR" // Nauru -"NP" // Nepal -"NL" // Netherlands -"AN" // NetherlandsAntilles -"NC" // NewCaledonia -"NZ" // NewZealand -"NI" // Nicaragua -"NE" // Niger -"NG" // Nigeria -"NU" // Niue -"NF" // NorfolkIsland -"MP" // NorthernMarianaIslands -"NO" // Norway -"OM" // Oman -"PK" // Pakistan -"PW" // Palau -"PS" // PalestinianTerritory -"PA" // Panama -"PG" // PapuaNewGuinea -"PY" // Paraguay -"PE" // Peru -"PH" // Philippines -"PN" // Pitcairn -"PL" // Poland -"PT" // Portugal -"PR" // PuertoRico -"QA" // Qatar -"RE" // Reunion -"RO" // Romania -"RU" // RussianFederation -"RW" // Rwanda -"KN" // SaintKittsAndNevis -"LC" // StLucia -"VC" // StVincentAndTheGrenadines -"WS" // Samoa -"SM" // SanMarino -"ST" // SaoTomeAndPrincipe -"SA" // SaudiArabia -"SN" // Senegal -"SC" // Seychelles -"SL" // SierraLeone -"SG" // Singapore -"SK" // Slovakia -"SI" // Slovenia -"SB" // SolomonIslands -"SO" // Somalia -"ZA" // SouthAfrica -"GS" // SouthGeorgiaAndTheSouthSandwichIslands -"ES" // Spain -"LK" // SriLanka -"SH" // StHelena -"PM" // StPierreAndMiquelon -"SD" // Sudan -"SR" // Suriname -"SJ" // SvalbardAndJanMayenIslands -"SZ" // Swaziland -"SE" // Sweden -"CH" // Switzerland -"SY" // SyrianArabRepublic -"TW" // Taiwan -"TJ" // Tajikistan -"TZ" // Tanzania -"TH" // Thailand -"TG" // Togo -"TK" // Tokelau -"TO" // Tonga -"TT" // TrinidadAndTobago -"TN" // Tunisia -"TR" // Turkey -"TM" // Turkmenistan -"TC" // TurksAndCaicosIslands -"TV" // Tuvalu -"UG" // Uganda -"UA" // Ukraine -"AE" // UnitedArabEmirates -"GB" // UnitedKingdom -"US" // UnitedStates -"UM" // UnitedStatesMinorOutlyingIslands -"UY" // Uruguay -"UZ" // Uzbekistan -"VU" // Vanuatu -"VA" // VaticanCityState -"VE" // Venezuela -"VN" // VietNam -"VG" // BritishVirginIslands -"VI" // USVirginIslands -"WF" // WallisAndFutunaIslands -"EH" // WesternSahara -"YE" // Yemen -"YU" // Yugoslavia -"ZM" // Zambia -"ZW" // Zimbabwe -; - -static TQLocale::Language codeToLanguage(const TQString &code) -{ - if (code.length() != 2) - return TQLocale::C; - - ushort uc1 = code.unicode()[0].unicode(); - ushort uc2 = code.unicode()[1].unicode(); - - const char *c = language_code_list; - for (; *c != 0; c += 2) { - if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1]) - return (TQLocale::Language) ((c - language_code_list)/2); - } - - return TQLocale::C; -} - -static TQLocale::Country codeToCountry(const TQString &code) -{ - if (code.length() != 2) - return TQLocale::AnyCountry; - - ushort uc1 = code.unicode()[0].unicode(); - ushort uc2 = code.unicode()[1].unicode(); - - const char *c = country_code_list; - for (; *c != 0; c += 2) { - if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1]) - return (TQLocale::Country) ((c - country_code_list)/2); - } - - return TQLocale::AnyCountry; -} - -static TQString languageToCode(TQLocale::Language language) -{ - if (language == TQLocale::C) - return "C"; - - TQString code; - code.setLength(2); - const char *c = language_code_list + 2*(uint)language; - code[0] = c[0]; - code[1] = c[1]; - return code; -} - -static TQString countryToCode(TQLocale::Country country) -{ - if (country == TQLocale::AnyCountry) - return TQString::null; - - TQString code; - code.setLength(2); - const char *c = country_code_list + 2*(uint)country; - code[0] = c[0]; - code[1] = c[1]; - return code; -} - -const TQLocalePrivate *TQLocale::default_d = 0; - -TQString TQLocalePrivate::infinity() const -{ - return TQString::fromLatin1("inf"); -} - -TQString TQLocalePrivate::nan() const -{ - return TQString::fromLatin1("nan"); -} - -#if defined(Q_OS_WIN) -/* Win95 doesn't have a function to return the ISO lang/country name of the user's locale. - Instead it can return a "Windows code". This maps windows codes to ISO country names. */ - -struct WindowsToISOListElt { - int windows_code; - char iso_name[6]; -}; - -static const WindowsToISOListElt windows_to_iso_list[] = { - { 0x0401, "ar_SA" }, - { 0x0402, "bg\0 " }, - { 0x0403, "ca\0 " }, - { 0x0404, "zh_TW" }, - { 0x0405, "cs\0 " }, - { 0x0406, "da\0 " }, - { 0x0407, "de\0 " }, - { 0x0408, "el\0 " }, - { 0x0409, "en_US" }, - { 0x040a, "es\0 " }, - { 0x040b, "fi\0 " }, - { 0x040c, "fr\0 " }, - { 0x040d, "he\0 " }, - { 0x040e, "hu\0 " }, - { 0x040f, "is\0 " }, - { 0x0410, "it\0 " }, - { 0x0411, "ja\0 " }, - { 0x0412, "ko\0 " }, - { 0x0413, "nl\0 " }, - { 0x0414, "no\0 " }, - { 0x0415, "pl\0 " }, - { 0x0416, "pt_BR" }, - { 0x0418, "ro\0 " }, - { 0x0419, "ru\0 " }, - { 0x041a, "hr\0 " }, - { 0x041c, "sq\0 " }, - { 0x041d, "sv\0 " }, - { 0x041e, "th\0 " }, - { 0x041f, "tr\0 " }, - { 0x0420, "ur\0 " }, - { 0x0421, "in\0 " }, - { 0x0422, "uk\0 " }, - { 0x0423, "be\0 " }, - { 0x0425, "et\0 " }, - { 0x0426, "lv\0 " }, - { 0x0427, "lt\0 " }, - { 0x0429, "fa\0 " }, - { 0x042a, "vi\0 " }, - { 0x042d, "eu\0 " }, - { 0x042f, "mk\0 " }, - { 0x0436, "af\0 " }, - { 0x0438, "fo\0 " }, - { 0x0439, "hi\0 " }, - { 0x043e, "ms\0 " }, - { 0x0458, "mt\0 " }, - { 0x0801, "ar_IQ" }, - { 0x0804, "zh_CN" }, - { 0x0807, "de_CH" }, - { 0x0809, "en_GB" }, - { 0x080a, "es_MX" }, - { 0x080c, "fr_BE" }, - { 0x0810, "it_CH" }, - { 0x0812, "ko\0 " }, - { 0x0813, "nl_BE" }, - { 0x0814, "no\0 " }, - { 0x0816, "pt\0 " }, - { 0x081a, "sr\0 " }, - { 0x081d, "sv_FI" }, - { 0x0c01, "ar_EG" }, - { 0x0c04, "zh_HK" }, - { 0x0c07, "de_AT" }, - { 0x0c09, "en_AU" }, - { 0x0c0a, "es\0 " }, - { 0x0c0c, "fr_CA" }, - { 0x0c1a, "sr\0 " }, - { 0x1001, "ar_LY" }, - { 0x1004, "zh_SG" }, - { 0x1007, "de_LU" }, - { 0x1009, "en_CA" }, - { 0x100a, "es_GT" }, - { 0x100c, "fr_CH" }, - { 0x1401, "ar_DZ" }, - { 0x1407, "de_LI" }, - { 0x1409, "en_NZ" }, - { 0x140a, "es_CR" }, - { 0x140c, "fr_LU" }, - { 0x1801, "ar_MA" }, - { 0x1809, "en_IE" }, - { 0x180a, "es_PA" }, - { 0x1c01, "ar_TN" }, - { 0x1c09, "en_ZA" }, - { 0x1c0a, "es_DO" }, - { 0x2001, "ar_OM" }, - { 0x2009, "en_JM" }, - { 0x200a, "es_VE" }, - { 0x2401, "ar_YE" }, - { 0x2409, "en\0 " }, - { 0x240a, "es_CO" }, - { 0x2801, "ar_SY" }, - { 0x2809, "en_BZ" }, - { 0x280a, "es_PE" }, - { 0x2c01, "ar_JO" }, - { 0x2c09, "en_TT" }, - { 0x2c0a, "es_AR" }, - { 0x3001, "ar_LB" }, - { 0x300a, "es_EC" }, - { 0x3401, "ar_KW" }, - { 0x340a, "es_CL" }, - { 0x3801, "ar_AE" }, - { 0x380a, "es_UY" }, - { 0x3c01, "ar_BH" }, - { 0x3c0a, "es_PY" }, - { 0x4001, "ar_QA" }, - { 0x400a, "es_BO" }, - { 0x440a, "es_SV" }, - { 0x480a, "es_HN" }, - { 0x4c0a, "es_NI" }, - { 0x500a, "es_PR" } -}; - -static const int windows_to_iso_count - = sizeof(windows_to_iso_list)/sizeof(WindowsToISOListElt); - -static const char *winLangCodeToIsoName(int code) -{ - int cmp = code - windows_to_iso_list[0].windows_code; - if (cmp < 0) - return 0; - - if (cmp == 0) - return windows_to_iso_list[0].iso_name; - - int begin = 0; - int end = windows_to_iso_count; - - while (end - begin > 1) { - uint mid = (begin + end)/2; - - const WindowsToISOListElt *elt = windows_to_iso_list + mid; - int cmp = code - elt->windows_code; - if (cmp < 0) - end = mid; - else if (cmp > 0) - begin = mid; - else - return elt->iso_name; - } - - return 0; - -} -#endif // Q_OS_WIN - -const char* TQLocalePrivate::systemLocaleName() -{ - static TQCString lang; - lang = getenv( "LANG" ); - -#if defined( Q_OS_MAC ) - if ( !lang.isEmpty() ) - return lang; - - char mac_ret[255]; - if(!LocaleRefGetPartString(NULL, kLocaleLanguageMask | kLocaleRegionMask, 255, mac_ret)) - lang = mac_ret; -#endif - -#if defined(TQ_WS_WIN) - if ( !lang.isEmpty() ) { - long id = 0; - bool ok = false; - id = qstrtoll(lang.data(), 0, 0, &ok); - if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX ) - return lang; - else - return winLangCodeToIsoName( (int)id ); - } - - if (qWinVersion() == TQt::WV_95) { - lang = winLangCodeToIsoName(GetUserDefaultLangID()); - } else { - QT_WA( { - wchar_t out[256]; - TQString language; - TQString sublanguage; - if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME , out, 255 ) ) - language = TQString::fromUcs2( (ushort*)out ); - if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) ) - sublanguage = TQString::fromUcs2( (ushort*)out ).lower(); - lang = language; - if ( sublanguage != language && !sublanguage.isEmpty() ) - lang += "_" + sublanguage.upper(); - } , { - char out[256]; - TQString language; - TQString sublanguage; - if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, out, 255 ) ) - language = TQString::fromLocal8Bit( out ); - if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) ) - sublanguage = TQString::fromLocal8Bit( out ).lower(); - lang = language; - if ( sublanguage != language && !sublanguage.isEmpty() ) - lang += "_" + sublanguage.upper(); - } ); - } -#endif - if ( lang.isEmpty() ) - lang = "C"; - - return lang; -} - -static const TQLocalePrivate *findLocale(TQLocale::Language language, - TQLocale::Country country) -{ - unsigned language_id = (unsigned)language; - unsigned country_id = (unsigned)country; - - uint idx = locale_index[language_id]; - - const TQLocalePrivate *d = locale_data + idx; - - if (idx == 0) // default language has no associated country - return d; - - if (country == TQLocale::AnyCountry) - return d; - - Q_ASSERT(d->languageId() == language_id); - - while (d->languageId() == language_id - && d->countryId() != country_id) - ++d; - - if (d->countryId() == country_id - && d->languageId() == language_id) - return d; - - return locale_data + idx; -} - -/*! - \class TQLocale - \brief The TQLocale class converts between numbers and their - string representations in various languages. - - \reentrant - \ingroup text - - It is initialized with a country/language pair in its constructor - and offers number-to-string and string-to-number conversion - functions simmilar to those in TQString. - - \code - TQLocale egyptian(TQLocale::Arabic, TQLocale::Egypt); - TQString s1 = egyptian.toString(1.571429E+07, 'e'); - TQString s2 = egyptian.toString(10); - - double d = egyptian.toDouble(s1); - int s2 = egyptian.toInt(s2); - \endcode - - TQLocale supports the concept of a default locale, which is - determined from the system's locale settings at application - startup. The default locale can be changed by calling the - static member setDefault(). The default locale has the - following effects: - - \list - \i If a TQLocale object is constructed with the default constructor, - it will use the default locale's settings. - \i TQString::toDouble() interprets the string according to the default - locale. If this fails, it falls back on the "C" locale. - \i TQString::arg() uses the default locale to format a number when - its position specifier in the format string contains an 'L', - e.g. "%L1". - \endlist - - \code - TQLocale::setDefault(TQLocale(TQLocale::Hebrew, TQLocale::Israel)); - TQLocale hebrew; // Constructs a default TQLocale - TQString s1 = hebrew.toString(15714.3, 'e'); - - bool ok; - double d; - - TQLocale::setDefault(TQLocale::C); - d = TQString( "1234,56" ).toDouble(&ok); // ok == false - d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 - - TQLocale::setDefault(TQLocale::German); - d = TQString( "1234,56" ).toDouble(&ok); // ok == true, d == 1234.56 - d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 - - TQLocale::setDefault(TQLocale(TQLocale::English, TQLocale::UnitedStates)); - str = TQString( "%1 %L2 %L3" ) - .arg( 12345 ) - .arg( 12345 ) - .arg( 12345, 0, 16 ); - // str == "12345 12,345 3039" - \endcode - - When a language/country pair is specified in the constructor, one - of three things can happen: - - \list - \i If the language/country pair is found in the database, it is used. - \i If the language is found but the country is not, or if the country - is \c AnyCountry, the language is used with the most - appropriate available country (for example, Germany for German), - \i If neither the language nor the country are found, TQLocale - defaults to the default locale (see setDefault()). - \endlist - - The "C" locale is identical to English/UnitedStates. - - Use language() and country() to determine the actual language and - country values used. - - An alternative method for constructing a TQLocale object is by - specifying the locale name. - - \code - TQLocale korean("ko"); - TQLocale swiss("de_CH"); - \endcode - - This constructor converts the locale name to a language/country - pair; it does not use the system locale database. - - All the methods in TQLocale, with the exception of setDefault(), - are reentrant. - - \sa TQString::toDouble() TQString::arg() - - The double-to-string and string-to-double conversion functions are - covered by the following licenses: - - \legalese - - Copyright (c) 1991 by AT&T. - - Permission to use, copy, modify, and distribute this software for any - purpose without fee is hereby granted, provided that this entire notice - is included in all copies of any software which is or includes a copy - or modification of this software and in all copies of the supporting - documentation for such software. - - THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY - REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - - This product includes software developed by the University of - California, Berkeley and its contributors. -*/ - -/*! - \enum TQLocale::Language - - This enumerated type is used to specify a language. - - \value C Identical to English/UnitedStates - \value Abkhazian - \value Afan - \value Afar - \value Afrikaans - \value Albanian - \value Amharic - \value Arabic - \value Armenian - \value Assamese - \value Aymara - \value Azerbaijani - \value Bashkir - \value Basque - \value Bengali - \value Bhutani - \value Bihari - \value Bislama - \value Breton - \value Bulgarian - \value Burmese - \value Byelorussian - \value Cambodian - \value Catalan - \value Chinese - \value Corsican - \value Croatian - \value Czech - \value Danish - \value Dutch - \value English - \value Esperanto - \value Estonian - \value Faroese - \value FijiLanguage - \value Finnish - \value French - \value Frisian - \value Gaelic - \value Galician - \value Georgian - \value German - \value Greek - \value Greenlandic - \value Guarani - \value Gujarati - \value Hausa - \value Hebrew - \value Hindi - \value Hungarian - \value Icelandic - \value Indonesian - \value Interlingua - \value Interlingue - \value Inuktitut - \value Inupiak - \value Irish - \value Italian - \value Japanese - \value Javanese - \value Kannada - \value Kashmiri - \value Kazakh - \value Kinyarwanda - \value Kirghiz - \value Korean - \value Kurdish - \value Kurundi - \value Laothian - \value Latin - \value Latvian - \value Lingala - \value Lithuanian - \value Macedonian - \value Malagasy - \value Malay - \value Malayalam - \value Maltese - \value Maori - \value Marathi - \value Moldavian - \value Mongolian - \value NauruLanguage - \value Nepali - \value Norwegian - \value Occitan - \value Oriya - \value Pashto - \value Persian - \value Polish - \value Portuguese - \value Punjabi - \value Quechua - \value RhaetoRomance - \value Romanian - \value Russian - \value Samoan - \value Sangho - \value Sanskrit - \value Serbian - \value SerboCroatian - \value Sesotho - \value Setswana - \value Shona - \value Sindhi - \value Singhalese - \value Siswati - \value Slovak - \value Slovenian - \value Somali - \value Spanish - \value Sundanese - \value Swahili - \value Swedish - \value Tagalog - \value Tajik - \value Tamil - \value Tatar - \value Telugu - \value Thai - \value Tibetan - \value Tigrinya - \value TongaLanguage - \value Tsonga - \value Turkish - \value Turkmen - \value Twi - \value Uigur - \value Ukrainian - \value Urdu - \value Uzbek - \value Vietnamese - \value Volapuk - \value Welsh - \value Wolof - \value Xhosa - \value Yiddish - \value Yoruba - \value Zhuang - \value Zulu -*/ - -/*! - \enum TQLocale::Country - - This enumerated type is used to specify a country. - - \value AnyCountry - \value Afghanistan - \value Albania - \value Algeria - \value AmericanSamoa - \value Andorra - \value Angola - \value Anguilla - \value Antarctica - \value AntiguaAndBarbuda - \value Argentina - \value Armenia - \value Aruba - \value Australia - \value Austria - \value Azerbaijan - \value Bahamas - \value Bahrain - \value Bangladesh - \value Barbados - \value Belarus - \value Belgium - \value Belize - \value Benin - \value Bermuda - \value Bhutan - \value Bolivia - \value BosniaAndHerzegowina - \value Botswana - \value BouvetIsland - \value Brazil - \value BritishIndianOceanTerritory - \value BruneiDarussalam - \value Bulgaria - \value BurkinaFaso - \value Burundi - \value Cambodia - \value Cameroon - \value Canada - \value CapeVerde - \value CaymanIslands - \value CentralAfricanRepublic - \value Chad - \value Chile - \value China - \value ChristmasIsland - \value CocosIslands - \value Colombia - \value Comoros - \value DemocraticRepublicOfCongo - \value PeoplesRepublicOfCongo - \value CookIslands - \value CostaRica - \value IvoryCoast - \value Croatia - \value Cuba - \value Cyprus - \value CzechRepublic - \value Denmark - \value Djibouti - \value Dominica - \value DominicanRepublic - \value EastTimor - \value Ecuador - \value Egypt - \value ElSalvador - \value EquatorialGuinea - \value Eritrea - \value Estonia - \value Ethiopia - \value FalklandIslands - \value FaroeIslands - \value FijiCountry - \value Finland - \value France - \value MetropolitanFrance - \value FrenchGuiana - \value FrenchPolynesia - \value FrenchSouthernTerritories - \value Gabon - \value Gambia - \value Georgia - \value Germany - \value Ghana - \value Gibraltar - \value Greece - \value Greenland - \value Grenada - \value Guadeloupe - \value Guam - \value Guatemala - \value Guinea - \value GuineaBissau - \value Guyana - \value Haiti - \value HeardAndMcDonaldIslands - \value Honduras - \value HongKong - \value Hungary - \value Iceland - \value India - \value Indonesia - \value Iran - \value Iraq - \value Ireland - \value Israel - \value Italy - \value Jamaica - \value Japan - \value Jordan - \value Kazakhstan - \value Kenya - \value Kiribati - \value DemocraticRepublicOfKorea - \value RepublicOfKorea - \value Kuwait - \value Kyrgyzstan - \value Lao - \value Latvia - \value Lebanon - \value Lesotho - \value Liberia - \value LibyanArabJamahiriya - \value Liechtenstein - \value Lithuania - \value Luxembourg - \value Macau - \value Macedonia - \value Madagascar - \value Malawi - \value Malaysia - \value Maldives - \value Mali - \value Malta - \value MarshallIslands - \value Martinique - \value Mauritania - \value Mauritius - \value Mayotte - \value Mexico - \value Micronesia - \value Moldova - \value Monaco - \value Mongolia - \value Montserrat - \value Morocco - \value Mozambique - \value Myanmar - \value Namibia - \value NauruCountry - \value Nepal - \value Netherlands - \value NetherlandsAntilles - \value NewCaledonia - \value NewZealand - \value Nicaragua - \value Niger - \value Nigeria - \value Niue - \value NorfolkIsland - \value NorthernMarianaIslands - \value Norway - \value Oman - \value Pakistan - \value Palau - \value PalestinianTerritory - \value Panama - \value PapuaNewGuinea - \value Paraguay - \value Peru - \value Philippines - \value Pitcairn - \value Poland - \value Portugal - \value PuertoRico - \value Qatar - \value Reunion - \value Romania - \value RussianFederation - \value Rwanda - \value SaintKittsAndNevis - \value StLucia - \value StVincentAndTheGrenadines - \value Samoa - \value SanMarino - \value SaoTomeAndPrincipe - \value SaudiArabia - \value Senegal - \value Seychelles - \value SierraLeone - \value Singapore - \value Slovakia - \value Slovenia - \value SolomonIslands - \value Somalia - \value SouthAfrica - \value SouthGeorgiaAndTheSouthSandwichIslands - \value Spain - \value SriLanka - \value StHelena - \value StPierreAndMiquelon - \value Sudan - \value Suriname - \value SvalbardAndJanMayenIslands - \value Swaziland - \value Sweden - \value Switzerland - \value SyrianArabRepublic - \value Taiwan - \value Tajikistan - \value Tanzania - \value Thailand - \value Togo - \value Tokelau - \value TongaCountry - \value TrinidadAndTobago - \value Tunisia - \value Turkey - \value Turkmenistan - \value TurksAndCaicosIslands - \value Tuvalu - \value Uganda - \value Ukraine - \value UnitedArabEmirates - \value UnitedKingdom - \value UnitedStates - \value UnitedStatesMinorOutlyingIslands - \value Uruguay - \value Uzbekistan - \value Vanuatu - \value VaticanCityState - \value Venezuela - \value VietNam - \value BritishVirginIslands - \value USVirginIslands - \value WallisAndFutunaIslands - \value WesternSahara - \value Yemen - \value Yugoslavia - \value Zambia - \value Zimbabwe -*/ - -/*! - Constructs a TQLocale object with the specified \a name, - which has the format - "language[_country][.codeset][@modifier]" or "C", where: - - \list - \i language is a lowercase, two-letter, ISO 639 language code, - \i territory is an uppercase, two-letter, ISO 3166 country code, - \i and codeset and modifier are ignored. - \endlist - - If the string violates the locale format, or language is not - a valid ISO 369 code, the "C" locale is used instead. If country - is not present, or is not a valid ISO 3166 code, the most - appropriate country is chosen for the specified language. - - The language and country codes are converted to their respective - \c Language and \c Country enums. After this conversion is - performed the constructor behaves exactly like TQLocale(Country, - Language). - - This constructor is much slower than TQLocale(Country, Language). - - \sa name() -*/ - -TQLocale::TQLocale(const TQString &name) -{ - Language lang = C; - Country cntry = AnyCountry; - - uint l = name.length(); - - do { - if (l < 2) - break; - - const TQChar *uc = name.unicode(); - if (l > 2 - && uc[2] != '_' - && uc[2] != '.' - && uc[2] != '@') - break; - - lang = codeToLanguage(name.mid(0, 2)); - if (lang == C) - break; - - if (l == 2 || uc[2] == '.' || uc[2] == '@') - break; - - // we have uc[2] == '_' - if (l < 5) - break; - - if (l > 5 && uc[5] != '.' && uc[5] != '@') - break; - - cntry = codeToCountry(name.mid(3, 2)); - } while (FALSE); - - d = findLocale(lang, cntry); -} - -/*! - Constructs a TQLocale object initialized with the default locale. - - \sa setDefault() -*/ - -TQLocale::TQLocale() -{ - if (default_d == 0) - default_d = system().d; - - d = default_d; -} - -/*! - Constructs a TQLocale object with the specified \a language and \a - country. - - \list - \i If the language/country pair is found in the database, it is used. - \i If the language is found but the country is not, or if the country - is \c AnyCountry, the language is used with the most - appropriate available country (for example, Germany for German), - \i If neither the language nor the country are found, TQLocale - defaults to the default locale (see setDefault()). - \endlist - - The language and country that are actually used can be queried - using language() and country(). - - \sa setDefault() language() country() -*/ - -TQLocale::TQLocale(Language language, Country country) -{ - d = findLocale(language, country); - - // If not found, should default to system - if (d->languageId() == TQLocale::C && language != TQLocale::C) { - if (default_d == 0) - default_d = system().d; - - d = default_d; - } -} - -/*! - Constructs a TQLocale object as a copy of \a other. -*/ - -TQLocale::TQLocale(const TQLocale &other) -{ - d = other.d; -} - -/*! - Assigns \a other to this TQLocale object and returns a reference - to this TQLocale object. -*/ - -TQLocale &TQLocale::operator=(const TQLocale &other) -{ - d = other.d; - return *this; -} - -/*! - \nonreentrant - - Sets the global default locale to \a locale. These - values are used when a TQLocale object is constructed with - no arguments. If this function is not called, the system's - locale is used. - - \warning In a multithreaded application, the default locale - should be set at application startup, before any non-GUI threads - are created. - - \sa system() c() -*/ - -void TQLocale::setDefault(const TQLocale &locale) -{ - default_d = locale.d; -} - -/*! - Returns the language of this locale. - - \sa TQLocale() -*/ -TQLocale::Language TQLocale::language() const -{ - return (Language)d->languageId(); -} - -/*! - Returns the country of this locale. - - \sa TQLocale() -*/ -TQLocale::Country TQLocale::country() const -{ - return (Country)d->countryId(); -} - -/*! - Returns the language and country of this locale as a - string of the form "language_country", where - language is a lowercase, two-letter ISO 639 language code, - and country is an uppercase, two-letter ISO 3166 country code. - - \sa TQLocale() -*/ - -TQString TQLocale::name() const -{ - Language l = language(); - - TQString result = languageToCode(l); - - if (l == C) - return result; - - Country c = country(); - if (c == AnyCountry) - return result; - - result.append('_'); - result.append(countryToCode(c)); - - return result; -} - -/*! - Returns a TQString containing the name of \a language. -*/ - -TQString TQLocale::languageToString(Language language) -{ - if ((uint)language > (uint)TQLocale::LastLanguage) - return "Unknown"; - return language_name_list + language_name_index[(uint)language]; -} - -/*! - Returns a TQString containing the name of \a country. -*/ - -TQString TQLocale::countryToString(Country country) -{ - if ((uint)country > (uint)TQLocale::LastCountry) - return "Unknown"; - return country_name_list + country_name_index[(uint)country]; -} - -/*! - Returns the short int represented by the localized string \a s, or - 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -short TQLocale::toShort(const TQString &s, bool *ok) const -{ - TQ_LLONG i = toLongLong(s, ok); - if (i < SHRT_MIN || i > SHRT_MAX) { - if (ok != 0) - *ok = FALSE; - return 0; - } - return (short) i; -} - -/*! - Returns the unsigned short int represented by the localized string - \a s, or 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -ushort TQLocale::toUShort(const TQString &s, bool *ok) const -{ - TQ_ULLONG i = toULongLong(s, ok); - if (i > USHRT_MAX) { - if (ok != 0) - *ok = FALSE; - return 0; - } - return (ushort) i; -} - -/*! - Returns the int represented by the localized string \a s, or 0 if - the conversion failed. - - If \a ok is not 0, reports failure by setting *ok to false and - success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -int TQLocale::toInt(const TQString &s, bool *ok) const -{ - TQ_LLONG i = toLongLong(s, ok); - if (i < INT_MIN || i > INT_MAX) { - if (ok != 0) - *ok = FALSE; - return 0; - } - return (int) i; -} - -/*! - Returns the unsigned int represented by the localized string \a s, - or 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -uint TQLocale::toUInt(const TQString &s, bool *ok) const -{ - TQ_ULLONG i = toULongLong(s, ok); - if (i > UINT_MAX) { - if (ok != 0) - *ok = FALSE; - return 0; - } - return (uint) i; -} - -/*! - Returns the long int represented by the localized string \a s, or - 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -TQ_LONG TQLocale::toLong(const TQString &s, bool *ok) const -{ - TQ_LLONG i = toLongLong(s, ok); - if (i < LONG_MIN || i > LONG_MAX) { - if (ok != 0) - *ok = FALSE; - return 0; - } - return (TQ_LONG) i; -} - -/*! - Returns the unsigned long int represented by the localized string - \a s, or 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -TQ_ULONG TQLocale::toULong(const TQString &s, bool *ok) const -{ - TQ_ULLONG i = toULongLong(s, ok); - if (i > ULONG_MAX) { - if (ok != 0) - *ok = FALSE; - return 0; - } - return (TQ_ULONG) i; -} - -/*! - Returns the long long int represented by the localized string \a - s, or 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - - -TQ_LLONG TQLocale::toLongLong(const TQString &s, bool *ok) const -{ - return d->stringToLongLong(s, 0, ok, TQLocalePrivate::ParseGroupSeparators); -} - -/*! - Returns the unsigned long long int represented by the localized - string \a s, or 0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - - -TQ_ULLONG TQLocale::toULongLong(const TQString &s, bool *ok) const -{ - return d->stringToUnsLongLong(s, 0, ok, TQLocalePrivate::ParseGroupSeparators); -} - -/*! - Returns the float represented by the localized string \a s, or 0.0 - if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - This function ignores leading and trailing whitespace. - - \sa toString() -*/ - -#define QT_MAX_FLOAT 3.4028234663852886e+38 - -float TQLocale::toFloat(const TQString &s, bool *ok) const -{ - bool myOk; - double d = toDouble(s, &myOk); - if (!myOk || d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) { - if (ok != 0) - *ok = FALSE; - return 0.0; - } - if (ok != 0) - *ok = TRUE; - return (float) d; -} - -/*! - Returns the double represented by the localized string \a s, or - 0.0 if the conversion failed. - - If \a ok is not 0, reports failure by setting - *ok to false and success by setting *ok to true. - - Unlike TQString::toDouble(), this function does not fall back to - the "C" locale if the string cannot be interpreted in this - locale. - - \code - bool ok; - double d; - - TQLocale c(TQLocale::C); - d = c.toDouble( "1234.56", &ok ); // ok == true, d == 1234.56 - d = c.toDouble( "1,234.56", &ok ); // ok == true, d == 1234.56 - d = c.toDouble( "1234,56", &ok ); // ok == false - - TQLocale german(TQLocale::German); - d = german.toDouble( "1234,56", &ok ); // ok == true, d == 1234.56 - d = german.toDouble( "1.234,56", &ok ); // ok == true, d == 1234.56 - d = german.toDouble( "1234.56", &ok ); // ok == false - - d = german.toDouble( "1.234", &ok ); // ok == true, d == 1234.0 - \endcode - - Notice that the last conversion returns 1234.0, because '.' is the - thousands group separator in the German locale. - - This function ignores leading and trailing whitespace. - - \sa toString() TQString::toDouble() -*/ - -double TQLocale::toDouble(const TQString &s, bool *ok) const -{ - return d->stringToDouble(s, ok, TQLocalePrivate::ParseGroupSeparators); -} - -/*! - Returns a localized string representation of \a i. - - \sa toLongLong() -*/ - -TQString TQLocale::toString(TQ_LLONG i) const -{ - return d->longLongToString(i, -1, 10, -1, TQLocalePrivate::ThousandsGroup); -} - -/*! - \overload - - \sa toULongLong() -*/ - -TQString TQLocale::toString(TQ_ULLONG i) const -{ - return d->unsLongLongToString(i, -1, 10, -1, TQLocalePrivate::ThousandsGroup); -} - -static bool qIsUpper(char c) -{ - return c >= 'A' && c <= 'Z'; -} - -static char qToLower(char c) -{ - if (c >= 'A' && c <= 'Z') - return c - 'A' + 'a'; - else - return c; -} - -/*! - \overload - - \a f and \a prec have the same meaning as in TQString::number(double, char, int). - - \sa toDouble() -*/ - -TQString TQLocale::toString(double i, char f, int prec) const -{ - TQLocalePrivate::DoubleForm form = TQLocalePrivate::DFDecimal; - uint flags = 0; - - if (qIsUpper(f)) - flags = TQLocalePrivate::CapitalEorX; - f = qToLower(f); - - switch (f) { - case 'f': - form = TQLocalePrivate::DFDecimal; - break; - case 'e': - form = TQLocalePrivate::DFExponent; - break; - case 'g': - form = TQLocalePrivate::DFSignificantDigits; - break; - default: - break; - } - - flags |= TQLocalePrivate::ThousandsGroup; - return d->doubleToString(i, prec, form, -1, flags); -} - -/*! - \fn TQLocale TQLocale::c() - - Returns a TQLocale object initialized to the "C" locale. - - \sa system() -*/ - -/*! - Returns a TQLocale object initialized to the system locale. -*/ - -TQLocale TQLocale::system() -{ -#ifdef Q_OS_UNIX - const char *s = getenv("LC_NUMERIC"); - if (s == 0) - s = getenv("LC_ALL"); - if (s != 0) - return TQLocale(s); -#endif - return TQLocale(TQLocalePrivate::systemLocaleName()); -} - -/*! -\fn TQString TQLocale::toString(short i) const - -\overload - -\sa toShort() -*/ - -/*! -\fn TQString TQLocale::toString(ushort i) const - -\overload - -\sa toUShort() -*/ - -/*! -\fn TQString TQLocale::toString(int i) const - -\overload - -\sa toInt() -*/ - -/*! -\fn TQString TQLocale::toString(uint i) const - -\overload - -\sa toUInt() -*/ - -/*! -\fn TQString TQLocale::toString(TQ_LONG i) const - -\overload - -\sa toLong() -*/ - -/*! -\fn TQString TQLocale::toString(TQ_ULONG i) const - -\overload - -\sa toULong() -*/ - -/*! -\fn TQString TQLocale::toString(float i, char f = 'g', int prec = 6) const - -\overload - -\a f and \a prec have the same meaning as in TQString::number(double, char, int). - -\sa toDouble() -*/ - - -bool TQLocalePrivate::isDigit(TQChar d) const -{ - return zero().unicode() <= d.unicode() - && zero().unicode() + 10 > d.unicode(); -} - -static char digitToCLocale(TQChar zero, TQChar d) -{ - if (zero.unicode() <= d.unicode() - && zero.unicode() + 10 > d.unicode()) - return '0' + d.unicode() - zero.unicode(); - - tqWarning("TQLocalePrivate::digitToCLocale(): bad digit: row=%d, cell=%d", d.row(), d.cell()); - return TQChar(0); -} - -static TQString qulltoa(TQ_ULLONG l, int base, const TQLocalePrivate &locale) -{ - TQChar buff[65]; // length of MAX_ULLONG in base 2 - TQChar *p = buff + 65; - - if (base != 10 || locale.zero().unicode() == '0') { - while (l != 0) { - int c = l % base; - - --p; - - if (c < 10) - *p = '0' + c; - else - *p = c - 10 + 'a'; - - l /= base; - } - } - else { - while (l != 0) { - int c = l % base; - - *(--p) = locale.zero().unicode() + c; - - l /= base; - } - } - - return TQString(p, 65 - (p - buff)); -} - -static TQString qlltoa(TQ_LLONG l, int base, const TQLocalePrivate &locale) -{ - return qulltoa(l < 0 ? -l : l, base, locale); -} - -enum PrecisionMode { - PMDecimalDigits = 0x01, - PMSignificantDigits = 0x02, - PMChopTrailingZeros = 0x03 -}; - -static TQString &decimalForm(TQString &digits, int decpt, uint precision, - PrecisionMode pm, - bool always_show_decpt, - bool thousands_group, - const TQLocalePrivate &locale) -{ - if (decpt < 0) { - for (int i = 0; i < -decpt; ++i) - digits.prepend(locale.zero()); - decpt = 0; - } - else if ((uint)decpt > digits.length()) { - for (uint i = digits.length(); i < (uint)decpt; ++i) - digits.append(locale.zero()); - } - - if (pm == PMDecimalDigits) { - uint decimal_digits = digits.length() - decpt; - for (uint i = decimal_digits; i < precision; ++i) - digits.append(locale.zero()); - } - else if (pm == PMSignificantDigits) { - for (uint i = digits.length(); i < precision; ++i) - digits.append(locale.zero()); - } - else { // pm == PMChopTrailingZeros - } - - if (always_show_decpt || (uint)decpt < digits.length()) - digits.insert(decpt, locale.decimal()); - - if (thousands_group) { - for (int i = decpt - 3; i > 0; i -= 3) - digits.insert(i, locale.group()); - } - - if (decpt == 0) - digits.prepend(locale.zero()); - - return digits; -} - -static TQString &exponentForm(TQString &digits, int decpt, uint precision, - PrecisionMode pm, - bool always_show_decpt, - const TQLocalePrivate &locale) -{ - int exp = decpt - 1; - - if (pm == PMDecimalDigits) { - for (uint i = digits.length(); i < precision + 1; ++i) - digits.append(locale.zero()); - } - else if (pm == PMSignificantDigits) { - for (uint i = digits.length(); i < precision; ++i) - digits.append(locale.zero()); - } - else { // pm == PMChopTrailingZeros - } - - if (always_show_decpt || digits.length() > 1) - digits.insert(1, locale.decimal()); - - digits.append(locale.exponential()); - digits.append(locale.longLongToString(exp, 2, 10, - -1, TQLocalePrivate::AlwaysShowSign)); - - return digits; -} - -static bool isZero(double d) -{ - uchar *ch = (uchar *)&d; - if (ByteOrder == BigEndian) { - return !(ch[0] & 0x7F || ch[1] || ch[2] || ch[3] || ch[4] || ch[5] || ch[6] || ch[7]); - } else { - return !(ch[7] & 0x7F || ch[6] || ch[5] || ch[4] || ch[3] || ch[2] || ch[1] || ch[0]); - } -} - -TQString TQLocalePrivate::doubleToString(double d, - int precision, - DoubleForm form, - int width, - unsigned flags) const -{ - if (precision == -1) - precision = 6; - if (width == -1) - width = 0; - - bool negative = FALSE; - bool special_number = FALSE; // nan, +/-inf - TQString num_str; - -#ifdef Q_OS_WIN - // Detect special numbers (nan, +/-inf) - if (qIsInf(d)) { - num_str = infinity(); - special_number = TRUE; - negative = d < 0; - } else if (qIsNan(d)) { - num_str = nan(); - special_number = TRUE; - } -#else - // Comparing directly to INFINITY gives weird results on some systems. - double tmp_infinity = INFINITY; - - // Detect special numbers (nan, +/-inf) - if (d == tmp_infinity || d == -tmp_infinity) { - num_str = infinity(); - special_number = TRUE; - negative = d < 0; - } else if (qIsNan(d)) { - num_str = nan(); - special_number = TRUE; - } -#endif - - // Handle normal numbers - if (!special_number) { - int decpt, sign; - TQString digits; - -#ifdef QT_QLOCALE_USES_FCVT -#ifdef TQT_THREAD_SUPPORT - static bool dummy_for_mutex; - TQMutex *fcvt_mutex = tqt_global_mutexpool ? tqt_global_mutexpool->get( &dummy_for_mutex ) : 0; -# define FCVT_LOCK if (fcvt_mutex) fcvt_mutex->lock() -# define FCVT_UNLOCK if (fcvt_mutex) fcvt_mutex->unlock() -#else -# define FCVT_LOCK -# define FCVT_UNLOCK -#endif - if (form == DFDecimal) { - FCVT_LOCK; - digits = fcvt(d, precision, &decpt, &sign); - FCVT_UNLOCK; - } else { - int pr = precision; - if (form == DFExponent) - ++pr; - else if (form == DFSignificantDigits && pr == 0) - pr = 1; - FCVT_LOCK; - digits = ecvt(d, pr, &decpt, &sign); - FCVT_UNLOCK; - - // Chop trailing zeros - if (digits.length() > 0) { - int last_nonzero_idx = digits.length() - 1; - while (last_nonzero_idx > 0 - && digits.unicode()[last_nonzero_idx] == '0') - --last_nonzero_idx; - digits.truncate(last_nonzero_idx + 1); - } - - } - -#else - int mode; - if (form == DFDecimal) - mode = 3; - else - mode = 2; - - /* This next bit is a bit quirky. In DFExponent form, the precision - is the number of digits after decpt. So that would suggest using - mode=3 for qdtoa. But qdtoa behaves strangely when mode=3 and - precision=0. So we get around this by using mode=2 and reasoning - that we want precision+1 significant digits, since the decimal - point in this mode is always after the first digit. */ - int pr = precision; - if (form == DFExponent) - ++pr; - - char *rve = 0; - char *buff = 0; - digits = qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff); - if (buff != 0) - free(buff); -#endif // QT_QLOCALE_USES_FCVT - - if (zero().unicode() != '0') { - for (uint i = 0; i < digits.length(); ++i) - digits.ref(i).unicode() += zero().unicode() - '0'; - } - - bool always_show_decpt = flags & Alternate; - switch (form) { - case DFExponent: { - num_str = exponentForm(digits, decpt, precision, PMDecimalDigits, - always_show_decpt, *this); - break; - } - case DFDecimal: { - num_str = decimalForm(digits, decpt, precision, PMDecimalDigits, - always_show_decpt, flags & ThousandsGroup, - *this); - break; - } - case DFSignificantDigits: { - PrecisionMode mode = (flags & Alternate) ? - PMSignificantDigits : PMChopTrailingZeros; - - if (decpt != (int)digits.length() && (decpt <= -4 || decpt > (int)precision)) - num_str = exponentForm(digits, decpt, precision, mode, - always_show_decpt, *this); - else - num_str = decimalForm(digits, decpt, precision, mode, - always_show_decpt, flags & ThousandsGroup, - *this); - break; - } - } - - negative = sign != 0 && !isZero(d); - } - - // pad with zeros. LeftAdjusted overrides this flag). Also, we don't - // pad special numbers - if (flags & TQLocalePrivate::ZeroPadded - && !(flags & TQLocalePrivate::LeftAdjusted) - && !special_number) { - int num_pad_chars = width - (int)num_str.length(); - // leave space for the sign - if (negative - || flags & TQLocalePrivate::AlwaysShowSign - || flags & TQLocalePrivate::BlankBeforePositive) - --num_pad_chars; - - for (int i = 0; i < num_pad_chars; ++i) - num_str.prepend(zero()); - } - - // add sign - if (negative) - num_str.prepend(minus()); - else if (flags & TQLocalePrivate::AlwaysShowSign) - num_str.prepend(plus()); - else if (flags & TQLocalePrivate::BlankBeforePositive) - num_str.prepend(' '); - - if (flags & TQLocalePrivate::CapitalEorX) - num_str = num_str.upper(); - - return num_str; -} - -TQString TQLocalePrivate::longLongToString(TQ_LLONG l, int precision, - int base, int width, - unsigned flags) const -{ - bool precision_not_specified = FALSE; - if (precision == -1) { - precision_not_specified = TRUE; - precision = 1; - } - - bool negative = l < 0; - if (base != 10) { - // these are not suported by sprintf for octal and hex - flags &= ~AlwaysShowSign; - flags &= ~BlankBeforePositive; - negative = FALSE; // neither are negative numbers - } - - TQString num_str; - if (base == 10) - num_str = qlltoa(l, base, *this); - else - num_str = qulltoa(l, base, *this); - - uint cnt_thousand_sep = 0; - if (flags & ThousandsGroup && base == 10) { - for (int i = (int)num_str.length() - 3; i > 0; i -= 3) { - num_str.insert(i, group()); - ++cnt_thousand_sep; - } - } - - for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i) - num_str.prepend(base == 10 ? zero() : TQChar('0')); - - if (flags & Alternate - && base == 8 - && (num_str.isEmpty() - || num_str[0].unicode() != '0')) - num_str.prepend('0'); - - // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds - // when precision is not specified in the format string - bool zero_padded = flags & ZeroPadded - && !(flags & LeftAdjusted) - && precision_not_specified; - - if (zero_padded) { - int num_pad_chars = width - (int)num_str.length(); - - // leave space for the sign - if (negative - || flags & AlwaysShowSign - || flags & BlankBeforePositive) - --num_pad_chars; - - // leave space for optional '0x' in hex form - if (base == 16 - && flags & Alternate - && l != 0) - num_pad_chars -= 2; - - for (int i = 0; i < num_pad_chars; ++i) - num_str.prepend(base == 10 ? zero() : TQChar('0')); - } - - if (base == 16 - && flags & Alternate - && l != 0) - num_str.prepend("0x"); - - // add sign - if (negative) - num_str.prepend(minus()); - else if (flags & AlwaysShowSign) - num_str.prepend(base == 10 ? plus() : TQChar('+')); - else if (flags & BlankBeforePositive) - num_str.prepend(' '); - - if (flags & CapitalEorX) - num_str = num_str.upper(); - - return num_str; -} - -TQString TQLocalePrivate::unsLongLongToString(TQ_ULLONG l, int precision, - int base, int width, - unsigned flags) const -{ - bool precision_not_specified = FALSE; - if (precision == -1) { - precision_not_specified = TRUE; - precision = 1; - } - - TQString num_str = qulltoa(l, base, *this); - - uint cnt_thousand_sep = 0; - if (flags & ThousandsGroup && base == 10) { - for (int i = (int)num_str.length() - 3; i > 0; i -=3) { - num_str.insert(i, group()); - ++cnt_thousand_sep; - } - } - - for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i) - num_str.prepend(base == 10 ? zero() : TQChar('0')); - - if (flags & Alternate - && base == 8 - && (num_str.isEmpty() - || num_str[0].unicode() != '0')) - num_str.prepend('0'); - - // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds - // when precision is not specified in the format string - bool zero_padded = flags & ZeroPadded - && !(flags & LeftAdjusted) - && precision_not_specified; - - if (zero_padded) { - int num_pad_chars = width - (int)num_str.length(); - - // leave space for optional '0x' in hex form - if (base == 16 - && flags & Alternate - && l != 0) - num_pad_chars -= 2; - - for (int i = 0; i < num_pad_chars; ++i) - num_str.prepend(base == 10 ? zero() : TQChar('0')); - } - - if (base == 16 - && flags & Alternate - && l != 0) - num_str.prepend("0x"); - - if (flags & CapitalEorX) - num_str = num_str.upper(); - - return num_str; -} - -static inline bool isLatin1Digit(const TQChar &c) -{ - return c.unicode() >= '0' && c.unicode() <= '9'; -} - -// Removes thousand-group separators, ie. the ',' in "1,234,567.89e-5" -bool TQLocalePrivate::removeGroupSeparators(TQString &num_str) const -{ - int group_cnt = 0; // counts number of group chars - int decpt_idx = -1; - - // Find the decimal point and check if there are any group chars - uint i = 0; - for (; i < num_str.length(); ++i) { - TQChar c = num_str.unicode()[i]; - - if (c.unicode() == ',') { - // check that there are digits before and after the separator - if (i == 0 || !isLatin1Digit(num_str.unicode()[i - 1])) - return FALSE; - if (i == num_str.length() + 1 || !isLatin1Digit(num_str.unicode()[i + 1])) - return FALSE; - ++group_cnt; - } - else if (c.unicode() == '.') { - // Fail if more than one decimal points - if (decpt_idx != -1) - return FALSE; - decpt_idx = i; - } else if (c.unicode() == 'e' || c.unicode() == 'E') { - // an 'e' or 'E' - if we have not encountered a decimal - // point, this is where it "is". - if (decpt_idx == -1) - decpt_idx = i; - } - } - - // If no group chars, we're done - if (group_cnt == 0) - return TRUE; - - // No decimal point means that it "is" at the end of the string - if (decpt_idx == -1) - decpt_idx = num_str.length(); - - i = 0; - while (i < num_str.length() && group_cnt > 0) { - TQChar c = num_str.unicode()[i]; - - if (c.unicode() == ',') { - // Don't allow group chars after the decimal point - if ((int)i > decpt_idx) - return FALSE; - - // Check that it is placed correctly relative to the decpt - if ((decpt_idx - i) % 4 != 0) - return FALSE; - - // Remove it - num_str.remove(i, 1); - - --group_cnt; - --decpt_idx; // adjust decpt_idx - } else { - // Check that we are not missing a separator - if ((int)i < decpt_idx && (decpt_idx - i) % 4 == 0) - return FALSE; - ++i; - } - } - - return TRUE; -} - -static void stripWhiteSpaceInPlace(TQString &s) -{ - uint i = 0; - while (i < s.length() && s.unicode()[i].isSpace()) - ++i; - if (i > 0) - s.remove(0, i); - - i = s.length(); - - if (i == 0) - return; - --i; - while (i > 0 && s.unicode()[i].isSpace()) - --i; - if (i + 1 < s.length()) - s.truncate(i + 1); -} - -/* - Converts a number in locale to its representation in the C locale. - Only has to guarantee that a string that is a correct representation of - a number will be converted. If junk is passed in, junk will be passed - out and the error will be detected during the actual conversion to a - number. We can't detect junk here, since we don't even know the base - of the number. -*/ -bool TQLocalePrivate::numberToCLocale(TQString &l_num, - GroupSeparatorMode group_sep_mode) const -{ - stripWhiteSpaceInPlace(l_num); - - if (l_num.isEmpty()) - return FALSE; - - for (uint idx = 0; idx < l_num.length(); ++idx) { - TQChar &c = l_num.ref(idx); - - if (isDigit(c)) - c = digitToCLocale(zero(), c); - else if (c == plus()) - c = '+'; - else if (c == minus()) - c = '-'; - else if (c == decimal()) - c = '.'; - else if (c == group()) - c = ','; - // In several languages group() is the char 0xA0, which looks like a space. - // People use a regular space instead of it and complain it doesn't work. - else if (group().unicode() == 0xA0 && c.unicode() == ' ') - c = ','; - else if (c == exponential() || c == exponential().upper()) - c = 'e'; - else if (c == list()) - c = ';'; - else if (c == percent()) - c = '%'; - else if (c.unicode() >= 'A' && c.unicode() <= 'Z') - c = c.lower(); - else if (c.unicode() >= 'a' && c.unicode() <= 'z') - ; // do nothing - else - return FALSE; - } - - if (group_sep_mode == ParseGroupSeparators - && !removeGroupSeparators(l_num)) - return FALSE; - - return TRUE; -} - -double TQLocalePrivate::stringToDouble(TQString num, - bool *ok, - GroupSeparatorMode group_sep_mode) const -{ - if (!numberToCLocale(num, group_sep_mode)) { - if (ok != 0) - *ok = FALSE; - return 0.0; - } - - if (ok != 0) - *ok = TRUE; - - if (num == "nan") - return NAN; - - if (num == "+inf" - || num == "inf") - return INFINITY; - - if (num == "-inf") - return -INFINITY; - - bool _ok; - const char *num_buff = num.latin1(); - -#ifdef QT_QLOCALE_USES_FCVT - char *endptr; - double d = strtod(num_buff, &endptr); - _ok = TRUE; -#else - const char *endptr; - double d = qstrtod(num_buff, &endptr, &_ok); -#endif - - if (!_ok || *endptr != '\0') { - if (ok != 0) - *ok = FALSE; - return 0.0; - } - else - return d; -} - -TQ_LLONG TQLocalePrivate::stringToLongLong(TQString num, int base, - bool *ok, - GroupSeparatorMode group_sep_mode) const -{ - if (!numberToCLocale(num, group_sep_mode)) { - if (ok != 0) - *ok = FALSE; - return 0; - } - - bool _ok; - const char *endptr; - const char *num_buff = num.latin1(); - TQ_LLONG l = qstrtoll(num_buff, &endptr, base, &_ok); - - if (!_ok || *endptr != '\0') { - if (ok != 0) - *ok = FALSE; - return 0; - } - - if (ok != 0) - *ok = TRUE; - return l; -} - -TQ_ULLONG TQLocalePrivate::stringToUnsLongLong(TQString num, int base, - bool *ok, - GroupSeparatorMode group_sep_mode) const -{ - if (!numberToCLocale(num, group_sep_mode)) { - if (ok != 0) - *ok = FALSE; - return 0; - } - - bool _ok; - const char *endptr; - const char *num_buff = num.latin1(); - TQ_ULLONG l = qstrtoull(num_buff, &endptr, base, &_ok); - - if (!_ok || *endptr != '\0') { - if (ok != 0) - *ok = FALSE; - return 0; - } - - if (ok != 0) - *ok = TRUE; - return l; -} - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -// static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; -// "$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $"; - -/* - * Convert a string to an TQ_ULLONG integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -static TQ_ULLONG qstrtoull(const char *nptr, const char **endptr, int base, bool *ok) -{ - const char *s = nptr; - TQ_ULLONG acc; - unsigned char c; - TQ_ULLONG qbase, cutoff; - int neg, any, cutlim; - - if (ok != 0) - *ok = TRUE; - - /* - * See strtoq for comments as to the logic used. - */ - s = nptr; - do { - c = *s++; - } while (isspace(c)); - if (c == '-') { - if (ok != 0) - *ok = FALSE; - if (endptr != 0) - *endptr = s - 1; - return 0; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - qbase = (unsigned)base; - cutoff = (TQ_ULLONG)ULLONG_MAX / qbase; - cutlim = (TQ_ULLONG)ULLONG_MAX % qbase; - for (acc = 0, any = 0;; c = *s++) { - if (!isascii(c)) - break; - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= qbase; - acc += c; - } - } - if (any < 0) { - acc = ULLONG_MAX; - if (ok != 0) - *ok = FALSE; - } - else if (neg) - acc = (~acc) + 1; - if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} - - -// "$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $"; - - -/* - * Convert a string to a TQ_LLONG integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -static TQ_LLONG qstrtoll(const char *nptr, const char **endptr, int base, bool *ok) -{ - const char *s; - TQ_ULLONG acc; - unsigned char c; - TQ_ULLONG qbase, cutoff; - int neg, any, cutlim; - - if (ok != 0) - *ok = TRUE; - - /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ - s = nptr; - do { - c = *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - - /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for quads is - * [-9223372036854775808..9223372036854775807] and the input base - * is 10, cutoff will be set to 922337203685477580 and cutlim to - * either 7 (neg==0) or 8 (neg==1), meaning that if we have - * accumulated a value > 922337203685477580, or equal but the - * next digit is > 7 (or 8), the number is too big, and we will - * return a range error. - * - * Set any if any `digits' consumed; make it negative to indicate - * overflow. - */ - qbase = (unsigned)base; - cutoff = neg ? (TQ_ULLONG)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX - : LLONG_MAX; - cutlim = cutoff % qbase; - cutoff /= qbase; - for (acc = 0, any = 0;; c = *s++) { - if (!isascii(c)) - break; - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= qbase; - acc += c; - } - } - if (any < 0) { - acc = neg ? LLONG_MIN : LLONG_MAX; - if (ok != 0) - *ok = FALSE; - } else if (neg) { - acc = (~acc) + 1; - } - if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} - -#ifndef QT_QLOCALE_USES_FCVT - -/* From: NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp */ -/* $FreeBSD: src/lib/libc/stdlib/netbsd_strtod.c,v 1.2.2.2 2001/03/02 17:14:15 tegge Exp $ */ - -/* Please send bug reports to - David M. Gay - AT&T Bell Laboratories, Room 2C-463 - 600 Mountain Avenue - Murray Hill, NJ 07974-2070 - U.S.A. - dmg@research.att.com or research!dmg - */ - -/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. - * - * This strtod returns a nearest machine number to the input decimal - * string (or sets errno to ERANGE). With IEEE arithmetic, ties are - * broken by the IEEE round-even rule. Otherwise ties are broken by - * biased rounding (add half and chop). - * - * Inspired loosely by William D. Clinger's paper "How to Read Floating - * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * - * 1. We only require IEEE, IBM, or VAX double-precision - * arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). - */ - -/* - * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least - * significant byte has the lowest address. - * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most - * significant byte has the lowest address. - * #define Long int on machines with 32-bit ints and 64-bit longs. - * #define Sudden_Underflow for IEEE-format machines without gradual - * underflow (i.e., that flush to zero on underflow). - * #define IBM for IBM mainframe-style floating-point arithmetic. - * #define VAX for VAX-style floating-point arithmetic. - * #define Unsigned_Shifts if >> does treats its left operand as unsigned. - * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. - * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. - * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines - * that use extended-precision instructions to compute rounded - * products and quotients) with IBM. - * #define ROUND_BIASED for IEEE-format with biased rounding. - * #define Inaccurate_Divide for IEEE-format with correctly rounded - * products but inaccurate quotients, e.g., for Intel i860. - * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision - * integer arithmetic. Whether this speeds things up or slows things - * down depends on the machine and the number being converted. - * #define KR_headers for old-style C function headers. - * #define Bad_float_h if your system lacks a float.h or if it does not - * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, - * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. - * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) - * if memory is available and otherwise does something you deem - * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp $"); -#endif /* LIBC_SCCS and not lint */ - -/* -#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ - defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \ - defined(__powerpc__) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_MACX) || \ - defined(mips) || defined(Q_OS_AIX) || defined(Q_OS_SOLARIS) -# define IEEE_BIG_OR_LITTLE_ENDIAN 1 -#endif -*/ - -// *All* of our architectures have IEEE arithmetic, don't they? -#define IEEE_BIG_OR_LITTLE_ENDIAN 1 - -#ifdef __arm32__ -/* - * Although the CPU is little endian the FP has different - * byte and word endianness. The byte order is still little endian - * but the word order is big endian. - */ -#define IEEE_BIG_OR_LITTLE_ENDIAN -#endif - -#ifdef vax -#define VAX -#endif - -#define Long TQ_INT32 -#define ULong TQ_UINT32 - -#define MALLOC malloc -#define CONST const - -#ifdef BSD_QDTOA_DEBUG -#include -#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} -#endif - -#ifdef Unsigned_Shifts -#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; -#else -#define Sign_Extend(a,b) /*no-op*/ -#endif - -#if (defined(IEEE_BIG_OR_LITTLE_ENDIAN) + defined(VAX) + defined(IBM)) != 1 -#error Exactly one of IEEE_BIG_OR_LITTLE_ENDIAN, VAX, or IBM should be defined. -#endif - -inline ULong getWord0(const NEEDS_VOLATILE double x) -{ - const NEEDS_VOLATILE uchar *ptr = reinterpret_cast(&x); - if (ByteOrder == BigEndian) { - return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3]; - } else { - return (ptr[7]<<24) + (ptr[6]<<16) + (ptr[5]<<8) + ptr[4]; - } -} - -inline void setWord0(NEEDS_VOLATILE double *x, ULong l) -{ - NEEDS_VOLATILE uchar *ptr = reinterpret_cast(x); - if (ByteOrder == BigEndian) { - ptr[0] = (uchar)(l>>24); - ptr[1] = (uchar)(l>>16); - ptr[2] = (uchar)(l>>8); - ptr[3] = (uchar)l; - } else { - ptr[7] = (uchar)(l>>24); - ptr[6] = (uchar)(l>>16); - ptr[5] = (uchar)(l>>8); - ptr[4] = (uchar)l; - } -} - -inline ULong getWord1(const NEEDS_VOLATILE double x) -{ - const NEEDS_VOLATILE uchar *ptr = reinterpret_cast(&x); - if (ByteOrder == BigEndian) { - return (ptr[4]<<24) + (ptr[5]<<16) + (ptr[6]<<8) + ptr[7]; - } else { - return (ptr[3]<<24) + (ptr[2]<<16) + (ptr[1]<<8) + ptr[0]; - } -} -inline void setWord1(NEEDS_VOLATILE double *x, ULong l) -{ - NEEDS_VOLATILE uchar *ptr = reinterpret_cast(x); - if (ByteOrder == BigEndian) { - ptr[4] = (uchar)(l>>24); - ptr[5] = (uchar)(l>>16); - ptr[6] = (uchar)(l>>8); - ptr[7] = (uchar)l; - } else { - ptr[3] = (uchar)(l>>24); - ptr[2] = (uchar)(l>>16); - ptr[1] = (uchar)(l>>8); - ptr[0] = (uchar)l; - } -} - -static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c) -{ - - *a = (((unsigned short)b) << 16) | ((unsigned short)c); - ++a; -} - -/* #define P DBL_MANT_DIG */ -/* Ten_pmax = floor(P*log(2)/log(5)) */ -/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ -/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ -/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ - -#if defined(IEEE_BIG_OR_LITTLE_ENDIAN) -#define Exp_shift 20 -#define Exp_shift1 20 -#define Exp_msk1 0x100000 -#define Exp_msk11 0x100000 -#define Exp_mask 0x7ff00000 -#define P 53 -#define Bias 1023 -#define IEEE_Arith -#define Emin (-1022) -#define Exp_1 0x3ff00000 -#define Exp_11 0x3ff00000 -#define Ebits 11 -#define Frac_mask 0xfffff -#define Frac_mask1 0xfffff -#define Ten_pmax 22 -#define Bletch 0x10 -#define Bndry_mask 0xfffff -#define Bndry_mask1 0xfffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 1 -#define Tiny0 0 -#define Tiny1 1 -#define Quick_max 14 -#define Int_max 14 -#define Infinite(x) (getWord0(x) == 0x7ff00000) /* sufficient test for here */ -#else -#undef Sudden_Underflow -#define Sudden_Underflow -#ifdef IBM -#define Exp_shift 24 -#define Exp_shift1 24 -#define Exp_msk1 0x1000000 -#define Exp_msk11 0x1000000 -#define Exp_mask 0x7f000000 -#define P 14 -#define Bias 65 -#define Exp_1 0x41000000 -#define Exp_11 0x41000000 -#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ -#define Frac_mask 0xffffff -#define Frac_mask1 0xffffff -#define Bletch 4 -#define Ten_pmax 22 -#define Bndry_mask 0xefffff -#define Bndry_mask1 0xffffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 4 -#define Tiny0 0x100000 -#define Tiny1 0 -#define Quick_max 14 -#define Int_max 15 -#else /* VAX */ -#define Exp_shift 23 -#define Exp_shift1 7 -#define Exp_msk1 0x80 -#define Exp_msk11 0x800000 -#define Exp_mask 0x7f80 -#define P 56 -#define Bias 129 -#define Exp_1 0x40800000 -#define Exp_11 0x4080 -#define Ebits 8 -#define Frac_mask 0x7fffff -#define Frac_mask1 0xffff007f -#define Ten_pmax 24 -#define Bletch 2 -#define Bndry_mask 0xffff007f -#define Bndry_mask1 0xffff007f -#define LSB 0x10000 -#define Sign_bit 0x8000 -#define Log2P 1 -#define Tiny0 0x80 -#define Tiny1 0 -#define Quick_max 15 -#define Int_max 15 -#endif -#endif - -#ifndef IEEE_Arith -#define ROUND_BIASED -#endif - -#ifdef RND_PRODQUOT -#define rounded_product(a,b) a = rnd_prod(a, b) -#define rounded_quotient(a,b) a = rnd_quot(a, b) -extern double rnd_prod(double, double), rnd_quot(double, double); -#else -#define rounded_product(a,b) a *= b -#define rounded_quotient(a,b) a /= b -#endif - -#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) -#define Big1 0xffffffff - -#ifndef Just_16 -/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. - * This makes some inner loops simpler and sometimes saves work - * during multiplications, but it often seems to make things slightly - * slower. Hence the default is now to store 32 bits per Long. - */ -#ifndef Pack_32 -#define Pack_32 -#endif -#endif - -#define Kmax 15 - -struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; -}; - - typedef struct Bigint Bigint; - -static Bigint *Balloc(int k) -{ - int x; - Bigint *rv; - - x = 1 << k; - rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)); - rv->k = k; - rv->maxwds = x; - rv->sign = rv->wds = 0; - return rv; -} - -static void Bfree(Bigint *v) -{ - free(v); -} - -#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ -y->wds*sizeof(Long) + 2*sizeof(int)) - -/* multiply by m and add a */ -static Bigint *multadd(Bigint *b, int m, int a) -{ - int i, wds; - ULong *x, y; -#ifdef Pack_32 - ULong xi, z; -#endif - Bigint *b1; - - wds = b->wds; - x = b->x; - i = 0; - do { -#ifdef Pack_32 - xi = *x; - y = (xi & 0xffff) * m + a; - z = (xi >> 16) * m + (y >> 16); - a = (int)(z >> 16); - *x++ = (z << 16) + (y & 0xffff); -#else - y = *x * m + a; - a = (int)(y >> 16); - *x++ = y & 0xffff; -#endif - } - while(++i < wds); - if (a) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = a; - b->wds = wds; - } - return b; -} - -static Bigint *s2b(CONST char *s, int nd0, int nd, ULong y9) -{ - Bigint *b; - int i, k; - Long x, y; - - x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; -#ifdef Pack_32 - b = Balloc(k); - b->x[0] = y9; - b->wds = 1; -#else - b = Balloc(k+1); - b->x[0] = y9 & 0xffff; - b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; -#endif - - i = 9; - if (9 < nd0) { - s += 9; - do b = multadd(b, 10, *s++ - '0'); - while(++i < nd0); - s++; - } - else - s += 10; - for(; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; -} - -static int hi0bits(ULong x) -{ - int k = 0; - - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; -} - -static int lo0bits(ULong *y) -{ - int k; - ULong x = *y; - - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!x & 1) - return 32; - } - *y = x; - return k; -} - -static Bigint *i2b(int i) -{ - Bigint *b; - - b = Balloc(1); - b->x[0] = i; - b->wds = 1; - return b; -} - -static Bigint *mult(Bigint *a, Bigint *b) -{ - Bigint *c; - int k, wa, wb, wc; - ULong carry, y, z; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; -#ifdef Pack_32 - ULong z2; -#endif - - if (a->wds < b->wds) { - c = a; - a = b; - b = c; - } - k = a->k; - wa = a->wds; - wb = b->wds; - wc = wa + wb; - if (wc > a->maxwds) - k++; - c = Balloc(k); - for(x = c->x, xa = x + wc; x < xa; x++) - *x = 0; - xa = a->x; - xae = xa + wa; - xb = b->x; - xbe = xb + wb; - xc0 = c->x; -#ifdef Pack_32 - for(; xb < xbe; xb++, xc0++) { - if ((y = *xb & 0xffff) != 0) { - x = xa; - xc = xc0; - carry = 0; - do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; - carry = z >> 16; - z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; - carry = z2 >> 16; - Storeinc(xc, z2, z); - } - while(x < xae); - *xc = carry; - } - if ((y = *xb >> 16) != 0) { - x = xa; - xc = xc0; - carry = 0; - z2 = *xc; - do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; - carry = z >> 16; - Storeinc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; - carry = z2 >> 16; - } - while(x < xae); - *xc = z2; - } - } -#else - for(; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } - while(x < xae); - *xc = carry; - } - } -#endif - for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; -} - -static Bigint *p5s; - -static Bigint *pow5mult(Bigint *b, int k) -{ - Bigint *b1, *p5, *p51; - int i; - static const int p05[3] = { 5, 25, 125 }; - - if ((i = k & 3) != 0) - b = multadd(b, p05[i-1], 0); - - if (!(k >>= 2)) - return b; - if (!(p5 = p5s)) { - /* first time */ - p5 = p5s = i2b(625); - p5->next = 0; - } - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - } - if (!(k >>= 1)) - break; - if (!(p51 = p5->next)) { - p51 = p5->next = mult(p5,p5); - p51->next = 0; - } - p5 = p51; - } - return b; -} - -static Bigint *lshift(Bigint *b, int k) -{ - int i, k1, n, n1; - Bigint *b1; - ULong *x, *x1, *xe, z; - -#ifdef Pack_32 - n = k >> 5; -#else - n = k >> 4; -#endif - k1 = b->k; - n1 = n + b->wds + 1; - for(i = b->maxwds; n1 > i; i <<= 1) - k1++; - b1 = Balloc(k1); - x1 = b1->x; - for(i = 0; i < n; i++) - *x1++ = 0; - x = b->x; - xe = x + b->wds; -#ifdef Pack_32 - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } - while(x < xe); - if ((*x1 = z) != 0) - ++n1; - } -#else - if (k &= 0xf) { - k1 = 16 - k; - z = 0; - do { - *x1++ = *x << k & 0xffff | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#endif - else do - *x1++ = *x++; - while(x < xe); - b1->wds = n1 - 1; - Bfree(b); - return b1; -} - -static int cmp(Bigint *a, Bigint *b) -{ - ULong *xa, *xa0, *xb, *xb0; - int i, j; - - i = a->wds; - j = b->wds; -#ifdef BSD_QDTOA_DEBUG - if (i > 1 && !a->x[i-1]) - Bug("cmp called with a->x[a->wds-1] == 0"); - if (j > 1 && !b->x[j-1]) - Bug("cmp called with b->x[b->wds-1] == 0"); -#endif - if (i -= j) - return i; - xa0 = a->x; - xa = xa0 + j; - xb0 = b->x; - xb = xb0 + j; - for(;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; -} - -static Bigint *diff(Bigint *a, Bigint *b) -{ - Bigint *c; - int i, wa, wb; - Long borrow, y; /* We need signed shifts here. */ - ULong *xa, *xae, *xb, *xbe, *xc; -#ifdef Pack_32 - Long z; -#endif - - i = cmp(a,b); - if (!i) { - c = Balloc(0); - c->wds = 1; - c->x[0] = 0; - return c; - } - if (i < 0) { - c = a; - a = b; - b = c; - i = 1; - } - else - i = 0; - c = Balloc(a->k); - c->sign = i; - wa = a->wds; - xa = a->x; - xae = xa + wa; - wb = b->wds; - xb = b->x; - xbe = xb + wb; - xc = c->x; - borrow = 0; -#ifdef Pack_32 - do { - y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(xc, z, y); - } - while(xb < xbe); - while(xa < xae) { - y = (*xa & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*xa++ >> 16) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(xc, z, y); - } -#else - do { - y = *xa++ - *xb++ + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *xc++ = y & 0xffff; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *xc++ = y & 0xffff; - } -#endif - while(!*--xc) - wa--; - c->wds = wa; - return c; -} - -static double ulp(double x) -{ - Long L; - double a; - - L = (getWord0(x) & Exp_mask) - (P-1)*Exp_msk1; -#ifndef Sudden_Underflow - if (L > 0) { -#endif -#ifdef IBM - L |= Exp_msk1 >> 4; -#endif - setWord0(&a, L); - setWord1(&a, 0); -#ifndef Sudden_Underflow - } - else { - L = -L >> Exp_shift; - if (L < Exp_shift) { - setWord0(&a, 0x80000 >> L); - setWord1(&a, 0); - } - else { - setWord0(&a, 0); - L -= Exp_shift; - setWord1(&a, L >= 31 ? 1U : 1U << (31 - L)); - } - } -#endif - return a; -} - -static double b2d(Bigint *a, int *e) -{ - ULong *xa, *xa0, w, y, z; - int k; - double d; - - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; -#ifdef BSD_QDTOA_DEBUG - if (!y) Bug("zero y in b2d"); -#endif - k = hi0bits(y); - *e = 32 - k; -#ifdef Pack_32 - if (k < Ebits) { - setWord0(&d, Exp_1 | y >> (Ebits - k)); - w = xa > xa0 ? *--xa : 0; - setWord1(&d, y << ((32-Ebits) + k) | w >> (Ebits - k)); - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - setWord0(&d, Exp_1 | y << k | z >> (32 - k)); - y = xa > xa0 ? *--xa : 0; - setWord1(&d, z << k | y >> (32 - k)); - } - else { - setWord0(&d, Exp_1 | y); - setWord1(&d, z); - } -#else - if (k < Ebits + 16) { - z = xa > xa0 ? *--xa : 0; - setWord0(&d, Exp_1 | y << k - Ebits | z >> Ebits + 16 - k); - w = xa > xa0 ? *--xa : 0; - y = xa > xa0 ? *--xa : 0; - setWord1(&d, z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k); - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - w = xa > xa0 ? *--xa : 0; - k -= Ebits + 16; - setWord0(&d, Exp_1 | y << k + 16 | z << k | w >> 16 - k); - y = xa > xa0 ? *--xa : 0; - setWord1(&d, w << k + 16 | y << k); -#endif - ret_d: - return d; -} - -static Bigint *d2b(double d, int *e, int *bits) -{ - Bigint *b; - int de, i, k; - ULong *x, y, z; - -#ifdef Pack_32 - b = Balloc(1); -#else - b = Balloc(2); -#endif - x = b->x; - - z = getWord0(d) & Frac_mask; - setWord0(&d, getWord0(d) & 0x7fffffff); /* clear sign bit, which we ignore */ -#ifdef Sudden_Underflow - de = (int)(getWord0(d) >> Exp_shift); -#ifndef IBM - z |= Exp_msk11; -#endif -#else - if ((de = (int)(getWord0(d) >> Exp_shift)) != 0) - z |= Exp_msk1; -#endif -#ifdef Pack_32 - if ((y = getWord1(d)) != 0) { - if ((k = lo0bits(&y)) != 0) { - x[0] = y | z << (32 - k); - z >>= k; - } - else - x[0] = y; - i = b->wds = (x[1] = z) ? 2 : 1; - } - else { -#ifdef BSD_QDTOA_DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - x[0] = z; - i = b->wds = 1; - k += 32; - } -#else - if (y = getWord1(d)) { - if (k = lo0bits(&y)) - if (k >= 16) { - x[0] = y | z << 32 - k & 0xffff; - x[1] = z >> k - 16 & 0xffff; - x[2] = z >> k; - i = 2; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16 | z << 16 - k & 0xffff; - x[2] = z >> k & 0xffff; - x[3] = z >> k+16; - i = 3; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16; - x[2] = z & 0xffff; - x[3] = z >> 16; - i = 3; - } - } - else { -#ifdef BSD_QDTOA_DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - if (k >= 16) { - x[0] = z; - i = 0; - } - else { - x[0] = z & 0xffff; - x[1] = z >> 16; - i = 1; - } - k += 32; - } - while(!x[i]) - --i; - b->wds = i + 1; -#endif -#ifndef Sudden_Underflow - if (de) { -#endif -#ifdef IBM - *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(getWord0(d) & Frac_mask); -#else - *e = de - Bias - (P-1) + k; - *bits = P - k; -#endif -#ifndef Sudden_Underflow - } - else { - *e = de - Bias - (P-1) + 1 + k; -#ifdef Pack_32 - *bits = 32*i - hi0bits(x[i-1]); -#else - *bits = (i+2)*16 - hi0bits(x[i]); -#endif - } -#endif - return b; -} - -static double ratio(Bigint *a, Bigint *b) -{ - double da, db; - int k, ka, kb; - - da = b2d(a, &ka); - db = b2d(b, &kb); -#ifdef Pack_32 - k = ka - kb + 32*(a->wds - b->wds); -#else - k = ka - kb + 16*(a->wds - b->wds); -#endif -#ifdef IBM - if (k > 0) { - setWord0(&da, getWord0(da) + (k >> 2)*Exp_msk1); - if (k &= 3) - da *= 1 << k; - } - else { - k = -k; - setWord0(&db, getWord0(db) + (k >> 2)*Exp_msk1); - if (k &= 3) - db *= 1 << k; - } -#else - if (k > 0) - setWord0(&da, getWord0(da) + k*Exp_msk1); - else { - k = -k; - setWord0(&db, getWord0(db) + k*Exp_msk1); - } -#endif - return da / db; -} - -static CONST double tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 -#ifdef VAX - , 1e23, 1e24 -#endif -}; - -#ifdef IEEE_Arith -static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; -#define n_bigtens 5 -#else -#ifdef IBM -static CONST double bigtens[] = { 1e16, 1e32, 1e64 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; -#define n_bigtens 3 -#else -static CONST double bigtens[] = { 1e16, 1e32 }; -static CONST double tinytens[] = { 1e-16, 1e-32 }; -#define n_bigtens 2 -#endif -#endif - -/* - The pre-release gcc3.3 shipped with SuSE 8.2 has a bug which causes - the comparison 1e-100 == 0.0 to return true. As a workaround, we - compare it to a global variable containing 0.0, which produces - correct assembler output. - - ### consider detecting the broken compilers and using the static - ### double for these, and use a #define for all working compilers -*/ -static double g_double_zero = 0.0; - -static double qstrtod(CONST char *s00, CONST char **se, bool *ok) -{ - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, - e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; - CONST char *s, *s0, *s1; - double aadj, aadj1, adj, rv, rv0; - Long L; - ULong y, z; - Bigint *bb1, *bd0; - Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */ - - /* - #ifndef KR_headers - CONST char decimal_point = localeconv()->decimal_point[0]; - #else - CONST char decimal_point = '.'; - #endif */ - if (ok != 0) - *ok = TRUE; - - CONST char decimal_point = '.'; - - sign = nz0 = nz = 0; - rv = 0.; - - - for(s = s00; isspace((unsigned char) *s); s++) - ; - - if (*s == '-') { - sign = 1; - s++; - } else if (*s == '+') { - s++; - } - - if (*s == '\0') { - s = s00; - goto ret; - } - - if (*s == '0') { - nz0 = 1; - while(*++s == '0') ; - if (!*s) - goto ret; - } - s0 = s; - y = z = 0; - for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) - if (nd < 9) - y = 10*y + c - '0'; - else if (nd < 16) - z = 10*z + c - '0'; - nd0 = nd; - if (c == decimal_point) { - c = *++s; - if (!nd) { - for(; c == '0'; c = *++s) - nz++; - if (c > '0' && c <= '9') { - s0 = s; - nf += nz; - nz = 0; - goto have_dig; - } - goto dig_done; - } - for(; c >= '0' && c <= '9'; c = *++s) { - have_dig: - nz++; - if (c -= '0') { - nf += nz; - for(i = 1; i < nz; i++) - if (nd++ < 9) - y *= 10; - else if (nd <= DBL_DIG + 1) - z *= 10; - if (nd++ < 9) - y = 10*y + c; - else if (nd <= DBL_DIG + 1) - z = 10*z + c; - nz = 0; - } - } - } - dig_done: - e = 0; - if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) { - s = s00; - goto ret; - } - s00 = s; - esign = 0; - switch(c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; - } - if (c >= '0' && c <= '9') { - while(c == '0') - c = *++s; - if (c > '0' && c <= '9') { - L = c - '0'; - s1 = s; - while((c = *++s) >= '0' && c <= '9') - L = 10*L + c - '0'; - if (s - s1 > 8 || L > 19999) - /* Avoid confusion from exponents - * so large that e might overflow. - */ - e = 19999; /* safe for 16 bit ints */ - else - e = (int)L; - if (esign) - e = -e; - } - else - e = 0; - } - else - s = s00; - } - if (!nd) { - if (!nz && !nz0) - s = s00; - goto ret; - } - e1 = e -= nf; - - /* Now we have nd0 digits, starting at s0, followed by a - * decimal point, followed by nd-nd0 digits. The number we're - * after is the integer represented by those digits times - * 10**e */ - - if (!nd0) - nd0 = nd; - k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - rv = y; - if (k > 9) - rv = tens[k - 9] * rv + z; - bd0 = 0; - if (nd <= DBL_DIG -#ifndef RND_PRODQUOT - && FLT_ROUNDS == 1 -#endif - ) { - if (!e) - goto ret; - if (e > 0) { - if (e <= Ten_pmax) { -#ifdef VAX - goto vax_ovfl_check; -#else - /* rv = */ rounded_product(rv, tens[e]); - goto ret; -#endif - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ - e -= i; - rv *= tens[i]; -#ifdef VAX - /* VAX exponent range is so narrow we must - * worry about overflow here... - */ - vax_ovfl_check: - setWord0(&rv, getWord0(rv) - P*Exp_msk1); - /* rv = */ rounded_product(rv, tens[e]); - if ((getWord0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) - goto ovfl; - setWord0(&rv, getWord0(rv) + P*Exp_msk1); -#else - /* rv = */ rounded_product(rv, tens[e]); -#endif - goto ret; - } - } -#ifndef Inaccurate_Divide - else if (e >= -Ten_pmax) { - /* rv = */ rounded_quotient(rv, tens[-e]); - goto ret; - } -#endif - } - e1 += nd - k; - - /* Get starting approximation = rv * 10**e1 */ - - if (e1 > 0) { - if ((i = e1 & 15) != 0) - rv *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { - ovfl: - // errno = ERANGE; - if (ok != 0) - *ok = FALSE; -#ifdef __STDC__ - rv = HUGE_VAL; -#else - /* Can't trust HUGE_VAL */ -#ifdef IEEE_Arith - setWord0(&rv, Exp_mask); - setWord1(&rv, 0); -#else - setWord0(&rv, Big0); - setWord1(&rv, Big1); -#endif -#endif - if (bd0) - goto retfree; - goto ret; - } - if (e1 >>= 4) { - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - rv *= bigtens[j]; - /* The last multiplication could overflow. */ - setWord0(&rv, getWord0(rv) - P*Exp_msk1); - rv *= bigtens[j]; - if ((z = getWord0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-P)) - goto ovfl; - if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - setWord0(&rv, Big0); - setWord1(&rv, Big1); - } - else - setWord0(&rv, getWord0(rv) + P*Exp_msk1); - } - - } - } - else if (e1 < 0) { - e1 = -e1; - if ((i = e1 & 15) != 0) - rv /= tens[i]; - if (e1 &= ~15) { - e1 >>= 4; - if (e1 >= 1 << n_bigtens) - goto undfl; - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - rv *= tinytens[j]; - /* The last multiplication could underflow. */ - rv0 = rv; - rv *= tinytens[j]; - if (rv == g_double_zero) - { - rv = 2.*rv0; - rv *= tinytens[j]; - if (rv == g_double_zero) - { - undfl: - rv = 0.; - // errno = ERANGE; - if (ok != 0) - *ok = FALSE; - if (bd0) - goto retfree; - goto ret; - } - setWord0(&rv, Tiny0); - setWord1(&rv, Tiny1); - /* The refinement below will clean - * this approximation up. - */ - } - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - bd0 = s2b(s0, nd0, nd, y); - - for(;;) { - bd = Balloc(bd0->k); - Bcopy(bd, bd0); - bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ - bs = i2b(1); - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } - else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; -#ifdef Sudden_Underflow -#ifdef IBM - j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); -#else - j = P + 1 - bbbits; -#endif -#else - i = bbe + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j = bbe + (P-Emin); - else - j = P + 1 - bbbits; -#endif - bb2 += j; - bd2 += j; - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - if (bb5 > 0) { - bs = pow5mult(bs, bb5); - bb1 = mult(bs, bb); - Bfree(bb); - bb = bb1; - } - if (bb2 > 0) - bb = lshift(bb, bb2); - if (bd5 > 0) - bd = pow5mult(bd, bd5); - if (bd2 > 0) - bd = lshift(bd, bd2); - if (bs2 > 0) - bs = lshift(bs, bs2); - delta = diff(bb, bd); - dsign = delta->sign; - delta->sign = 0; - i = cmp(delta, bs); - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask) - break; - delta = lshift(delta,Log2P); - if (cmp(delta, bs) > 0) - goto drop_down; - break; - } - if (i == 0) { - /* exactly half-way between */ - if (dsign) { - if ((getWord0(rv) & Bndry_mask1) == Bndry_mask1 - && getWord1(rv) == 0xffffffff) { - /*boundary case -- increment exponent*/ - setWord0(&rv, (getWord0(rv) & Exp_mask) - + Exp_msk1 -#ifdef IBM - | Exp_msk1 >> 4 -#endif - ); - setWord1(&rv, 0); - break; - } - } - else if (!(getWord0(rv) & Bndry_mask) && !getWord1(rv)) { - drop_down: - /* boundary case -- decrement exponent */ -#ifdef Sudden_Underflow - L = getWord0(rv) & Exp_mask; -#ifdef IBM - if (L < Exp_msk1) -#else - if (L <= Exp_msk1) -#endif - goto undfl; - L -= Exp_msk1; -#else - L = (getWord0(rv) & Exp_mask) - Exp_msk1; -#endif - setWord0(&rv, L | Bndry_mask1); - setWord1(&rv, 0xffffffff); -#ifdef IBM - goto cont; -#else - break; -#endif - } -#ifndef ROUND_BIASED - if (!(getWord1(rv) & LSB)) - break; -#endif - if (dsign) - rv += ulp(rv); -#ifndef ROUND_BIASED - else { - rv -= ulp(rv); -#ifndef Sudden_Underflow - if (rv == g_double_zero) - goto undfl; -#endif - } -#endif - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (dsign) - aadj = aadj1 = 1.; - else if (getWord1(rv) || getWord0(rv) & Bndry_mask) { -#ifndef Sudden_Underflow - if (getWord1(rv) == Tiny1 && !getWord0(rv)) - goto undfl; -#endif - aadj = 1.; - aadj1 = -1.; - } - else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2./FLT_RADIX) - aadj = 1./FLT_RADIX; - else - aadj *= 0.5; - aadj1 = -aadj; - } - } - else { - aadj *= 0.5; - aadj1 = dsign ? aadj : -aadj; -#ifdef Check_FLT_ROUNDS - switch(FLT_ROUNDS) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; - } -#else - if (FLT_ROUNDS == 0) - aadj1 += 0.5; -#endif - } - y = getWord0(rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - rv0 = rv; - setWord0(&rv, getWord0(rv) - P*Exp_msk1); - adj = aadj1 * ulp(rv); - rv += adj; - if ((getWord0(rv) & Exp_mask) >= - Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (getWord0(rv0) == Big0 && getWord1(rv0) == Big1) - goto ovfl; - setWord0(&rv, Big0); - setWord1(&rv, Big1); - goto cont; - } - else - setWord0(&rv, getWord0(rv) + P*Exp_msk1); - } - else { -#ifdef Sudden_Underflow - if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1) { - rv0 = rv; - setWord0(&rv, getWord0(rv) + P*Exp_msk1); - adj = aadj1 * ulp(rv); - rv += adj; -#ifdef IBM - if ((getWord0(rv) & Exp_mask) < P*Exp_msk1) -#else - if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1) -#endif - { - if (getWord0(rv0) == Tiny0 - && getWord1(rv0) == Tiny1) - goto undfl; - setWord0(&rv, Tiny0); - setWord1(&rv, Tiny1); - goto cont; - } - else - setWord0(&rv, getWord0(rv) - P*Exp_msk1); - } - else { - adj = aadj1 * ulp(rv); - rv += adj; - } -#else - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., - * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid - * trouble from bits lost to denormalization; - * example: 1.2e-307 . - */ - if (y <= (P-1)*Exp_msk1 && aadj >= 1.) { - aadj1 = (double)(int)(aadj + 0.5); - if (!dsign) - aadj1 = -aadj1; - } - adj = aadj1 * ulp(rv); - rv += adj; -#endif - } - z = getWord0(rv) & Exp_mask; - if (y == z) { - /* Can we stop now? */ - L = (Long) aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } - else if (aadj < .4999999/FLT_RADIX) - break; - } - cont: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(delta); - } - retfree: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); - ret: - if (se) - *se = (char *)s; - return sign ? -rv : rv; -} - -static int quorem(Bigint *b, Bigint *S) -{ - int n; - Long borrow, y; - ULong carry, q, ys; - ULong *bx, *bxe, *sx, *sxe; -#ifdef Pack_32 - Long z; - ULong si, zs; -#endif - - n = S->wds; -#ifdef BSD_QDTOA_DEBUG - /*debug*/ if (b->wds > n) - /*debug*/ Bug("oversize b in quorem"); -#endif - if (b->wds < n) - return 0; - sx = S->x; - sxe = sx + --n; - bx = b->x; - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ -#ifdef BSD_QDTOA_DEBUG - /*debug*/ if (q > 9) - /*debug*/ Bug("oversized quotient in quorem"); -#endif - if (q) { - borrow = 0; - carry = 0; - do { -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*bx >> 16) - (zs & 0xffff) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *bx++ = y & 0xffff; -#endif - } - while(sx <= sxe); - if (!*bxe) { - bx = b->x; - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; - do { -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*bx >> 16) - (zs & 0xffff) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *bx++ = y & 0xffff; -#endif - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; -} - -/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. - * - * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. - */ - - -/* This actually sometimes returns a pointer to a string literal - cast to a char*. Do NOT try to modify the return value. */ - -static char *qdtoa ( double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp) -{ - // Some values of the floating-point control word can cause _qdtoa to crash with an underflow. - // We set a safe value here. -#ifdef Q_OS_WIN -#ifndef Q_CC_BOR - unsigned int oldbits = _control87(0, 0); -#ifndef _M_X64 //x64 does not support precition control - _control87(0x9001F, 0xFFFFF); -#else - _control87(0x9001F, _MCW_DN|_MCW_EM|_MCW_RC); -#endif //_M_X64 -#endif -#endif - -#ifdef Q_OS_LINUX - fenv_t envp; - feholdexcept(&envp); -#endif - - char *s = _qdtoa(d, mode, ndigits, decpt, sign, rve, resultp); - -#ifdef Q_OS_WIN -#ifndef Q_CC_BOR - _clear87(); -#ifndef _M_X64 - _control87(oldbits, 0xFFFFF); -#else - _control87(oldbits, _MCW_DN|_MCW_EM|_MCW_RC); -#endif //_M_X64 -#endif -#endif - -#ifdef Q_OS_LINUX - fesetenv(&envp); -#endif - - return s; -} - -static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp) -{ - /* - Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4-9 should give the same return values as 2-3, i.e., - 4 <= mode <= 9 ==> same return as mode - 2 + (mode & 1). These modes are mainly for - debugging; often they run slower but sometimes - faster than modes 2-3. - 4,5,8,9 ==> left-to-right digit generation. - 6-9 ==> don't try fast floating-point estimate - (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int bbits, b2, b5, be, dig, i, ieps, ilim0, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - try_quick; - int ilim = 0, ilim1 = 0, spec_case = 0; /* pacify gcc */ - Long L; -#ifndef Sudden_Underflow - int denorm; - ULong x; -#endif - Bigint *b, *b1, *delta, *mhi, *S; - Bigint *mlo = NULL; /* pacify gcc */ - double d2; - double ds, eps; - char *s, *s0; - - if (getWord0(d) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - setWord0(&d, getWord0(d) & ~Sign_bit); /* clear sign bit */ - } - else - *sign = 0; - -#if defined(IEEE_Arith) + defined(VAX) -#ifdef IEEE_Arith - if ((getWord0(d) & Exp_mask) == Exp_mask) -#else - if (getWord0(d) == 0x8000) -#endif - { - /* Infinity or NaN */ - *decpt = 9999; - s = -#ifdef IEEE_Arith - !getWord1(d) && !(getWord0(d) & 0xfffff) ? (char*)"Infinity" : -#endif - (char*)"NaN"; - if (rve) - *rve = -#ifdef IEEE_Arith - s[3] ? s + 8 : -#endif - s + 3; - return s; - } -#endif -#ifdef IBM - d += 0; /* normalize */ -#endif - if (d == g_double_zero) - { - *decpt = 1; - s = (char*) "0"; - if (rve) - *rve = s + 1; - return s; - } - - b = d2b(d, &be, &bbits); -#ifdef Sudden_Underflow - i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); -#else - if ((i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { -#endif - d2 = d; - setWord0(&d2, getWord0(d2) & Frac_mask1); - setWord0(&d2, getWord0(d2) | Exp_11); -#ifdef IBM - if (j = 11 - hi0bits(getWord0(d2) & Frac_mask)) - d2 /= 1 << j; -#endif - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; -#ifdef IBM - i <<= 2; - i += j; -#endif -#ifndef Sudden_Underflow - denorm = 0; - } - else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? getWord0(d) << (64 - i) | getWord1(d) >> (i - 32) - : getWord1(d) << (32 - i); - d2 = x; - setWord0(&d2, getWord0(d2) - 31*Exp_msk1); /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } -#endif - ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (d < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - if (mode < 0 || mode > 9) - mode = 0; - try_quick = 1; - if (mode > 5) { - mode -= 4; - try_quick = 0; - } - leftright = 1; - switch(mode) { - case 0: - case 1: - ilim = ilim1 = -1; - i = 18; - ndigits = 0; - break; - case 2: - leftright = 0; - /* no break */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = 0; - /* no break */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - *resultp = (char *) malloc(i + 1); - s = s0 = *resultp; - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - d2 = d; - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - d /= bigtens[n_bigtens-1]; - ieps++; - } - for(; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - d /= ds; - } - else if ((j1 = -k) != 0) { - d *= tens[j1 & 0xf]; - for(j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - d *= bigtens[i]; - } - } - if (k_check && d < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - d *= 10.; - ieps++; - } - eps = ieps*d + 7.; - setWord0(&eps, getWord0(eps) - (P-1)*Exp_msk1); - if (ilim == 0) { - S = mhi = 0; - d -= 5.; - if (d > eps) - goto one_digit; - if (d < -eps) - goto no_digits; - goto fast_failed; - } -#ifndef No_leftright - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - eps = 0.5/tens[ilim-1] - eps; - for(i = 0;;) { - L = (Long)d; - d -= L; - *s++ = '0' + (int)L; - if (d < eps) - goto ret1; - if (1. - d < eps) - goto bump_up; - if (++i >= ilim) - break; - eps *= 10.; - d *= 10.; - } - } - else { -#endif - /* Generate ilim digits, then fix them up. */ - eps *= tens[ilim-1]; - for(i = 1;; i++, d *= 10.) { - L = (Long)d; - d -= L; - *s++ = '0' + (int)L; - if (i == ilim) { - if (d > 0.5 + eps) - goto bump_up; - else if (d < 0.5 - eps) { - while(*--s == '0'); - s++; - goto ret1; - } - break; - } - } -#ifndef No_leftright - } -#endif - fast_failed: - s = s0; - d = d2; - k = k0; - ilim = ilim0; - } - - /* Do we have a "small" integer? */ - - if (be >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = 0; - if (ilim < 0 || d <= 5*ds) - goto no_digits; - goto one_digit; - } - for(i = 1;; i++) { - L = (Long)(d / ds); - d -= L*ds; -#ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (d < 0) { - L--; - d += ds; - } -#endif - *s++ = '0' + (int)L; - if (i == ilim) { - d += d; - if (d > ds || (d == ds && L & 1)) { - bump_up: - while(*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - if ((d *= 10.) == g_double_zero) - break; - } - goto ret1; - } - - m2 = b2; - m5 = b5; - mhi = mlo = 0; - if (leftright) { - if (mode < 2) { - i = -#ifndef Sudden_Underflow - denorm ? be + (Bias + (P-1) - 1 + 1) : -#endif -#ifdef IBM - 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); -#else - 1 + P - bbits; -#endif - } - else { - j = ilim - 1; - if (m5 >= j) - m5 -= j; - else { - s5 += j -= m5; - b5 += j; - m5 = 0; - } - if ((i = ilim) < 0) { - m2 -= i; - i = 0; - } - } - b2 += i; - s2 += i; - mhi = i2b(1); - } - if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - b1 = mult(mhi, b); - Bfree(b); - b = b1; - } - if ((j = b5 - m5) != 0) - b = pow5mult(b, j); - } - else - b = pow5mult(b, b5); - } - S = i2b(1); - if (s5 > 0) - S = pow5mult(S, s5); - - /* Check for special case that d is a normalized power of 2. */ - - if (mode < 2) { - if (!getWord1(d) && !(getWord0(d) & Bndry_mask) -#ifndef Sudden_Underflow - && getWord0(d) & Exp_mask -#endif - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - else - spec_case = 0; - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ -#ifdef Pack_32 - if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0) - i = 32 - i; -#else - if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) - i = 16 - i; -#endif - if (i > 4) { - i -= 4; - b2 += i; - m2 += i; - s2 += i; - } - else if (i < 4) { - i += 28; - b2 += i; - m2 += i; - s2 += i; - } - if (b2 > 0) - b = lshift(b, b2); - if (s2 > 0) - S = lshift(S, s2); - if (k_check) { - if (cmp(b,S) < 0) { - k--; - b = multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) - mhi = multadd(mhi, 10, 0); - ilim = ilim1; - } - } - if (ilim <= 0 && mode > 2) { - if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { - /* no digits, fcvt style */ - no_digits: - k = -1 - ndigits; - goto ret; - } - one_digit: - *s++ = '1'; - k++; - goto ret; - } - if (leftright) { - if (m2 > 0) - mhi = lshift(mhi, m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = Balloc(mhi->k); - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); - } - - for(i = 1;;i++) { - dig = quorem(b,S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - delta = diff(S, mhi); - j1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); -#ifndef ROUND_BIASED - if (j1 == 0 && !mode && !(getWord1(d) & 1)) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; - *s++ = dig; - goto ret; - } -#endif - if (j < 0 || (j == 0 && !mode -#ifndef ROUND_BIASED - && !(getWord1(d) & 1) -#endif - )) { - if (j1 > 0) { - b = lshift(b, 1); - j1 = cmp(b, S); - if ((j1 > 0 || (j1 == 0 && dig & 1)) - && dig++ == '9') - goto round_9_up; - } - *s++ = dig; - goto ret; - } - if (j1 > 0) { - if (dig == '9') { /* possible if i == 1 */ - round_9_up: - *s++ = '9'; - goto roundoff; - } - *s++ = dig + 1; - goto ret; - } - *s++ = dig; - if (i == ilim) - break; - b = multadd(b, 10, 0); - if (mlo == mhi) - mlo = mhi = multadd(mhi, 10, 0); - else { - mlo = multadd(mlo, 10, 0); - mhi = multadd(mhi, 10, 0); - } - } - } - else - for(i = 1;; i++) { - *s++ = dig = quorem(b,S) + '0'; - if (i >= ilim) - break; - b = multadd(b, 10, 0); - } - - /* Round off last digit */ - - b = lshift(b, 1); - j = cmp(b, S); - if (j > 0 || (j == 0 && dig & 1)) { - roundoff: - while(*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - ++*s++; - } - else { - while(*--s == '0'); - s++; - } - ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } - ret1: - Bfree(b); - if (s == s0) { /* don't return empty string */ - *s++ = '0'; - k = 0; - } - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; -} - -#endif // QT_QLOCALE_USES_FCVT diff --git a/src/tools/qlocale_p.h b/src/tools/qlocale_p.h deleted file mode 100644 index 8d562d22c..000000000 --- a/src/tools/qlocale_p.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Declaration of the TQLocalePrivate class -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the widgets module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#ifndef TQLOCALE_P_H -#define TQLOCALE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the TQt API. It exists for the convenience -// of internal files. This header file may change from version to version -// without notice, or even be removed. -// -// We mean it. -// -// - -#include - -struct TQLocalePrivate -{ -public: - const TQChar &decimal() const { return (TQChar&)m_decimal; } - const TQChar &group() const { return (TQChar&)m_group; } - const TQChar &list() const { return (TQChar&)m_list; } - const TQChar &percent() const { return (TQChar&)m_percent; } - const TQChar &zero() const { return (TQChar&)m_zero; } - TQChar plus() const { return TQChar('+'); } - const TQChar &minus() const { return (TQChar&)m_minus; } - const TQChar &exponential() const { return (TQChar&)m_exponential; } - TQString infinity() const; - TQString nan() const; - - TQ_UINT32 languageId() const { return m_language_id; } - TQ_UINT32 countryId() const { return m_country_id; } - - bool isDigit(TQChar d) const; - - enum GroupSeparatorMode { - FailOnGroupSeparators, - ParseGroupSeparators - }; - - enum DoubleForm { - DFExponent = 0, // %e or %E - DFDecimal, // %f or %F - DFSignificantDigits, // %g or %G - _DFMax = DFSignificantDigits - }; - - enum Flags { - NoFlags = 0, - - // These correspond to the options in a printf format string - Alternate = 0x01, - ZeroPadded = 0x02, - LeftAdjusted = 0x04, - BlankBeforePositive = 0x08, - AlwaysShowSign = 0x10, - ThousandsGroup = 0x20, - CapitalEorX = 0x40 // %x, %e, %f, %g vs. %X, %E, %F, %G - }; - - TQString doubleToString(double d, - int precision = -1, - DoubleForm form = DFSignificantDigits, - int width = -1, - unsigned flags = NoFlags) const; - TQString longLongToString(TQ_LLONG l, int precision = -1, - int base = 10, - int width = -1, - unsigned flags = NoFlags) const; - TQString unsLongLongToString(TQ_ULLONG l, int precision = -1, - int base = 10, - int width = -1, - unsigned flags = NoFlags) const; - double stringToDouble(TQString num, bool *ok, GroupSeparatorMode group_sep_mode) const; - TQ_LLONG stringToLongLong(TQString num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const; - TQ_ULLONG stringToUnsLongLong(TQString num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const; - bool removeGroupSeparators(TQString &num_str) const; - bool numberToCLocale(TQString &locale_num, GroupSeparatorMode group_sep_mode) const; - - TQ_UINT32 m_language_id, m_country_id; - - TQ_UINT16 m_decimal, m_group, m_list, m_percent, - m_zero, m_minus, m_exponential; - - static const TQString m_infinity; - static const TQString m_nan; - static const TQChar m_plus; - - static const char *systemLocaleName(); -}; - -#endif diff --git a/src/tools/qt_tools.pri b/src/tools/qt_tools.pri index c4cced519..5eb816580 100644 --- a/src/tools/qt_tools.pri +++ b/src/tools/qt_tools.pri @@ -34,8 +34,8 @@ tools { $$TOOLS_H/tqiodevice.h \ $$TOOLS_H/ntqlibrary.h \ $$TOOLS_P/qlibrary_p.h \ - $$TOOLS_H/ntqlocale.h \ - $$TOOLS_P/qlocale_p.h \ + $$TOOLS_H/tqlocale.h \ + $$TOOLS_P/tqlocale_p.h \ $$TOOLS_H/tqptrlist.h \ $$TOOLS_H/tqmap.h \ $$TOOLS_H/tqmutex.h \ @@ -126,7 +126,7 @@ tools { $$TOOLS_CPP/qgvector.cpp \ $$TOOLS_CPP/tqiodevice.cpp \ $$TOOLS_CPP/qlibrary.cpp \ - $$TOOLS_CPP/qlocale.cpp \ + $$TOOLS_CPP/tqlocale.cpp \ $$TOOLS_CPP/tqmap.cpp \ $$TOOLS_CPP/tqmutexpool.cpp \ $$TOOLS_CPP/tqptrcollection.cpp \ @@ -143,7 +143,7 @@ tools { irix-cc* { CXXFLAGS_PRELINK = $$QMAKE_CXXFLAGS CXXFLAGS_PRELINK -= -O2 - QMAKE_PRE_LINK = $(CXX) -c $$CXXFLAGS_PRELINK -O1 $(INCPATH) -o $(OBJECTS_DIR)/qlocale.o tools/qlocale.cpp + QMAKE_PRE_LINK = $(CXX) -c $$CXXFLAGS_PRELINK -O1 $(INCPATH) -o $(OBJECTS_DIR)/tqlocale.o tools/tqlocale.cpp } } diff --git a/src/tools/tqlocale.cpp b/src/tools/tqlocale.cpp new file mode 100644 index 000000000..57ddcfb3f --- /dev/null +++ b/src/tools/tqlocale.cpp @@ -0,0 +1,6322 @@ +/**************************************************************************** +** +** Implementation of the TQLocale class +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the tools module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "tqlocale.h" +#include "tqlocale_p.h" +#include "ntqnamespace.h" + +#ifdef QT_QLOCALE_USES_FCVT +# include +# include +#endif + +#if defined (Q_OS_WIN) +# include +# undef NAN // we want to use our fallback on Windows +# undef INFINITY +#endif + +#ifdef Q_OS_LINUX +# include +#endif + +#if defined( Q_OS_MAC ) +# include +#endif + +#if defined (Q_OS_SOLARIS) +# include +#endif + +#if defined (Q_OS_OSF) && (defined(__DECC) || defined(__DECCXX)) +# define INFINITY DBL_INFINITY +# define NAN DBL_QNAN +#endif + +#if (defined(Q_CC_GNU) && defined(Q_OS_WIN)) || __GNUC__ == 4 || defined(QT_QLOCALE_NEEDS_VOLATILE) +# define NEEDS_VOLATILE volatile +#else +# define NEEDS_VOLATILE +#endif + +enum { + LittleEndian, + BigEndian + +#ifdef TQ_BYTE_ORDER +# if TQ_BYTE_ORDER == TQ_BIG_ENDIAN + , ByteOrder = BigEndian +# elif TQ_BYTE_ORDER == TQ_LITTLE_ENDIAN + , ByteOrder = LittleEndian +# else +# error "undefined byte order" +# endif +}; +#else +}; +static const unsigned int one = 1; +static const bool ByteOrder = ((*((unsigned char *) &one) == 0) ? BigEndian : LittleEndian); +#endif + +#if !defined(INFINITY) +static const unsigned char be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }; +static const unsigned char le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; +static inline double inf() +{ + return (ByteOrder == BigEndian ? + *((const double *) be_inf_bytes) : + *((const double *) le_inf_bytes)); +} +# define INFINITY (::inf()) +#endif + +#if !defined(NAN) +static const unsigned char be_nan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }; +static const unsigned char le_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; +static inline double nan() +{ + return (ByteOrder == BigEndian ? + *((const double *) be_nan_bytes) : + *((const double *) le_nan_bytes)); +} +# define NAN (::nan()) +#endif + +// We can't rely on -NAN, since all operations on a NAN should return a NAN. +static double be_neg_nan; +static double le_neg_nan; +static const unsigned char be_neg_nan_bytes[] = { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 }; +static const unsigned char le_neg_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0xff }; +static bool neg_nan_init = false; + +static inline double negNan() +{ + if (!neg_nan_init) + { + memcpy(&be_neg_nan,be_neg_nan_bytes,sizeof(be_neg_nan_bytes)); + memcpy(&le_neg_nan,le_neg_nan_bytes,sizeof(le_neg_nan_bytes)); + neg_nan_init = true; + } + return (ByteOrder == BigEndian ? + be_neg_nan : + le_neg_nan); + +} + +// Sizes as defined by the ISO C99 standard - fallback +#ifndef LLONG_MAX +# define LLONG_MAX TQ_INT64_C(9223372036854775807) +#endif +#ifndef LLONG_MIN +# define LLONG_MIN (-LLONG_MAX - TQ_INT64_C(1)) +#endif +#ifndef ULLONG_MAX +# define ULLONG_MAX TQ_UINT64_C(0xffffffffffffffff) +#endif + +#ifndef QT_QLOCALE_USES_FCVT +static char *qdtoa(double d, int mode, int ndigits, int *decpt, + int *sign, char **rve, char **digits_str); +static char *_qdtoa(double d, int mode, int ndigits, int *decpt, + int *sign, char **rve, char **digits_str); +static double qstrtod(const char *s00, char const **se, bool *ok); +#endif +static TQ_LLONG qstrtoll(const char *nptr, const char **endptr, int base, bool *ok); +static TQ_ULLONG qstrtoull(const char *nptr, const char **endptr, int base, bool *ok); + +static inline bool compareBits(double d1, double d2) +{ + return memcmp((const char*)&d1, (const char*)&d2, sizeof(double)) == 0; +} + +static inline bool qIsInf(double d) +{ + return compareBits(d, INFINITY) || compareBits(d, -INFINITY); +} + +static inline bool qIsNan(double d) +{ + return compareBits(d, NAN) || compareBits(d, negNan()); +} + +static const uint locale_index[] = { + 0, // unused + 0, // C + 0, // Abkhazian + 0, // Afan + 0, // Afar + 1, // Afrikaans + 2, // Albanian + 0, // Amharic + 3, // Arabic + 19, // Armenian + 0, // Assamese + 0, // Aymara + 20, // Azerbaijani + 0, // Bashkir + 21, // Basque + 22, // Bengali + 0, // Bhutani + 0, // Bihari + 0, // Bislama + 0, // Breton + 23, // Bulgarian + 0, // Burmese + 24, // Byelorussian + 0, // Cambodian + 25, // Catalan + 26, // Chinese + 0, // Corsican + 31, // Croatian + 32, // Czech + 33, // Danish + 34, // Dutch + 36, // English + 0, // Esperanto + 48, // Estonian + 49, // Faroese + 0, // Fiji + 50, // Finnish + 51, // French + 0, // Frisian + 0, // Gaelic + 57, // Galician + 58, // Georgian + 59, // German + 64, // Greek + 0, // Greenlandic + 0, // Guarani + 65, // Gujarati + 0, // Hausa + 66, // Hebrew + 67, // Hindi + 68, // Hungarian + 69, // Icelandic + 70, // Indonesian + 0, // Interlingua + 0, // Interlingue + 0, // Inuktitut + 0, // Inupiak + 0, // Irish + 71, // Italian + 73, // Japanese + 0, // Javanese + 74, // Kannada + 0, // Kashmiri + 75, // Kazakh + 0, // Kinyarwanda + 76, // Kirghiz + 77, // Korean + 0, // Kurdish + 0, // Kurundi + 0, // Laothian + 0, // Latin + 78, // Latvian + 0, // Lingala + 79, // Lithuanian + 80, // Macedonian + 0, // Malagasy + 81, // Malay + 0, // Malayalam + 0, // Maltese + 0, // Maori + 83, // Marathi + 0, // Moldavian + 84, // Mongolian + 0, // Nauru + 0, // Nepali + 85, // Norwegian + 0, // Occitan + 0, // Oriya + 0, // Pashto + 86, // Persian + 87, // Polish + 88, // Portuguese + 90, // Punjabi + 0, // Quechua + 0, // RhaetoRomance + 91, // Romanian + 92, // Russian + 0, // Samoan + 0, // Sangho + 93, // Sanskrit + 0, // Serbian + 0, // SerboCroatian + 0, // Sesotho + 0, // Setswana + 0, // Shona + 0, // Sindhi + 0, // Singhalese + 0, // Siswati + 94, // Slovak + 95, // Slovenian + 0, // Somali + 96, // Spanish + 0, // Sundanese + 115, // Swahili + 116, // Swedish + 0, // Tagalog + 0, // Tajik + 118, // Tamil + 0, // Tatar + 119, // Telugu + 120, // Thai + 0, // Tibetan + 0, // Tigrinya + 0, // Tonga + 0, // Tsonga + 121, // Turkish + 0, // Turkmen + 0, // Twi + 0, // Uigur + 122, // Ukrainian + 123, // Urdu + 124, // Uzbek + 125, // Vietnamese + 0, // Volapuk + 0, // Welsh + 0, // Wolof + 0, // Xhosa + 0, // Yiddish + 0, // Yoruba + 0, // Zhuang + 0, // Zulu + 0 // trailing 0 +}; + +static const TQLocalePrivate locale_data[] = { +// lang terr dec group list prcnt zero minus exp + { 1, 0, 46, 44, 59, 37, 48, 45, 101 }, // C/AnyCountry + { 5, 195, 46, 44, 44, 37, 48, 45, 101 }, // Afrikaans/SouthAfrica + { 6, 2, 44, 46, 59, 37, 48, 45, 101 }, // Albanian/Albania + { 8, 186, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/SaudiArabia + { 8, 3, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Algeria + { 8, 17, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Bahrain + { 8, 64, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Egypt + { 8, 103, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Iraq + { 8, 109, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Jordan + { 8, 115, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Kuwait + { 8, 119, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Lebanon + { 8, 122, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/LibyanArabJamahiriya + { 8, 145, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Morocco + { 8, 162, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Oman + { 8, 175, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Qatar + { 8, 207, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/SyrianArabRepublic + { 8, 216, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Tunisia + { 8, 223, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/UnitedArabEmirates + { 8, 237, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Yemen + { 9, 11, 46, 44, 44, 37, 48, 45, 101 }, // Armenian/Armenia + { 12, 15, 44, 160, 59, 37, 48, 45, 101 }, // Azerbaijani/Azerbaijan + { 14, 197, 44, 46, 59, 37, 48, 45, 101 }, // Basque/Spain + { 15, 100, 46, 44, 59, 37, 48, 45, 101 }, // Bengali/India + { 20, 33, 44, 160, 59, 37, 48, 45, 101 }, // Bulgarian/Bulgaria + { 22, 20, 44, 160, 59, 37, 48, 45, 101 }, // Byelorussian/Belarus + { 24, 197, 44, 46, 59, 37, 48, 45, 101 }, // Catalan/Spain + { 25, 44, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/China + { 25, 97, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/HongKong + { 25, 126, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Macau + { 25, 190, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Singapore + { 25, 208, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Taiwan + { 27, 54, 44, 46, 59, 37, 48, 45, 101 }, // Croatian/Croatia + { 28, 57, 44, 160, 59, 37, 48, 45, 101 }, // Czech/CzechRepublic + { 29, 58, 44, 46, 59, 37, 48, 45, 101 }, // Danish/Denmark + { 30, 151, 44, 46, 59, 37, 48, 45, 101 }, // Dutch/Netherlands + { 30, 21, 44, 46, 59, 37, 48, 45, 101 }, // Dutch/Belgium + { 31, 225, 46, 44, 44, 37, 48, 45, 101 }, // English/UnitedStates + { 31, 13, 46, 44, 44, 37, 48, 45, 101 }, // English/Australia + { 31, 22, 46, 44, 59, 37, 48, 45, 101 }, // English/Belize + { 31, 38, 46, 44, 44, 37, 48, 45, 101 }, // English/Canada + { 31, 104, 46, 44, 44, 37, 48, 45, 101 }, // English/Ireland + { 31, 107, 46, 44, 44, 37, 48, 45, 101 }, // English/Jamaica + { 31, 154, 46, 44, 44, 37, 48, 45, 101 }, // English/NewZealand + { 31, 170, 46, 44, 44, 37, 48, 45, 101 }, // English/Philippines + { 31, 195, 46, 44, 44, 37, 48, 45, 101 }, // English/SouthAfrica + { 31, 215, 46, 44, 59, 37, 48, 45, 101 }, // English/TrinidadAndTobago + { 31, 224, 46, 44, 44, 37, 48, 45, 101 }, // English/UnitedKingdom + { 31, 240, 46, 44, 44, 37, 48, 45, 101 }, // English/Zimbabwe + { 33, 68, 44, 160, 59, 37, 48, 45, 101 }, // Estonian/Estonia + { 34, 71, 44, 46, 59, 37, 48, 45, 101 }, // Faroese/FaroeIslands + { 36, 73, 44, 160, 59, 37, 48, 45, 101 }, // Finnish/Finland + { 37, 74, 44, 160, 59, 37, 48, 45, 101 }, // French/France + { 37, 21, 44, 46, 59, 37, 48, 45, 101 }, // French/Belgium + { 37, 38, 44, 160, 59, 37, 48, 45, 101 }, // French/Canada + { 37, 125, 44, 160, 59, 37, 48, 45, 101 }, // French/Luxembourg + { 37, 142, 44, 160, 59, 37, 48, 45, 101 }, // French/Monaco + { 37, 206, 46, 39, 59, 37, 48, 45, 101 }, // French/Switzerland + { 40, 197, 44, 46, 44, 37, 48, 45, 101 }, // Galician/Spain + { 41, 81, 44, 160, 59, 37, 48, 45, 101 }, // Georgian/Georgia + { 42, 82, 44, 46, 59, 37, 48, 45, 101 }, // German/Germany + { 42, 14, 44, 46, 59, 37, 48, 45, 101 }, // German/Austria + { 42, 123, 46, 39, 59, 37, 48, 45, 101 }, // German/Liechtenstein + { 42, 125, 44, 46, 59, 37, 48, 45, 101 }, // German/Luxembourg + { 42, 206, 46, 39, 59, 37, 48, 45, 101 }, // German/Switzerland + { 43, 85, 44, 46, 59, 37, 48, 45, 101 }, // Greek/Greece + { 46, 100, 46, 44, 44, 37, 2790, 45, 101 }, // Gujarati/India + { 48, 105, 46, 44, 44, 37, 48, 45, 101 }, // Hebrew/Israel + { 49, 100, 46, 44, 44, 37, 48, 45, 101 }, // Hindi/India + { 50, 98, 44, 160, 59, 37, 48, 45, 101 }, // Hungarian/Hungary + { 51, 99, 44, 46, 59, 37, 48, 45, 101 }, // Icelandic/Iceland + { 52, 101, 44, 46, 59, 37, 48, 45, 101 }, // Indonesian/Indonesia + { 58, 106, 44, 46, 59, 37, 48, 45, 101 }, // Italian/Italy + { 58, 206, 46, 39, 59, 37, 48, 45, 101 }, // Italian/Switzerland + { 59, 108, 46, 44, 44, 37, 48, 45, 101 }, // Japanese/Japan + { 61, 100, 46, 44, 44, 37, 3302, 45, 101 }, // Kannada/India + { 63, 110, 44, 160, 59, 37, 48, 45, 101 }, // Kazakh/Kazakhstan + { 65, 116, 44, 160, 59, 37, 48, 45, 101 }, // Kirghiz/Kyrgyzstan + { 66, 114, 46, 44, 44, 37, 48, 45, 101 }, // Korean/RepublicOfKorea + { 71, 118, 44, 160, 59, 37, 48, 45, 101 }, // Latvian/Latvia + { 73, 124, 44, 46, 59, 37, 48, 45, 101 }, // Lithuanian/Lithuania + { 74, 127, 44, 46, 59, 37, 48, 45, 101 }, // Macedonian/Macedonia + { 76, 130, 44, 46, 59, 37, 48, 45, 101 }, // Malay/Malaysia + { 76, 32, 44, 46, 59, 37, 48, 45, 101 }, // Malay/BruneiDarussalam + { 80, 100, 46, 44, 44, 37, 2406, 45, 101 }, // Marathi/India + { 82, 143, 44, 160, 59, 37, 48, 45, 101 }, // Mongolian/Mongolia + { 85, 161, 44, 160, 59, 37, 48, 45, 101 }, // Norwegian/Norway + { 89, 102, 46, 44, 59, 37, 1776, 45, 101 }, // Persian/Iran + { 90, 172, 44, 160, 59, 37, 48, 45, 101 }, // Polish/Poland + { 91, 173, 44, 46, 59, 37, 48, 45, 101 }, // Portuguese/Portugal + { 91, 30, 44, 46, 59, 37, 48, 45, 101 }, // Portuguese/Brazil + { 92, 100, 46, 44, 44, 37, 2662, 45, 101 }, // Punjabi/India + { 95, 177, 44, 46, 59, 37, 48, 45, 101 }, // Romanian/Romania + { 96, 178, 44, 160, 59, 37, 48, 45, 101 }, // Russian/RussianFederation + { 99, 100, 46, 44, 44, 37, 2406, 45, 101 }, // Sanskrit/India + { 108, 191, 44, 160, 59, 37, 48, 45, 101 }, // Slovak/Slovakia + { 109, 192, 44, 46, 59, 37, 48, 45, 101 }, // Slovenian/Slovenia + { 111, 197, 44, 46, 59, 37, 48, 45, 101 }, // Spanish/Spain + { 111, 10, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Argentina + { 111, 26, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Bolivia + { 111, 43, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Chile + { 111, 47, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Colombia + { 111, 52, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/CostaRica + { 111, 61, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/DominicanRepublic + { 111, 63, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Ecuador + { 111, 65, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/ElSalvador + { 111, 90, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Guatemala + { 111, 96, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Honduras + { 111, 139, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Mexico + { 111, 155, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Nicaragua + { 111, 166, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Panama + { 111, 168, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Paraguay + { 111, 169, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Peru + { 111, 174, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/PuertoRico + { 111, 227, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Uruguay + { 111, 231, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Venezuela + { 113, 111, 46, 44, 44, 37, 48, 45, 101 }, // Swahili/Kenya + { 114, 205, 44, 160, 59, 37, 48, 45, 101 }, // Swedish/Sweden + { 114, 73, 44, 160, 59, 37, 48, 45, 101 }, // Swedish/Finland + { 117, 100, 46, 44, 44, 37, 48, 45, 101 }, // Tamil/India + { 119, 100, 46, 44, 44, 37, 3174, 45, 101 }, // Telugu/India + { 120, 211, 46, 44, 44, 37, 3664, 45, 101 }, // Thai/Thailand + { 125, 217, 44, 46, 59, 37, 48, 45, 101 }, // Turkish/Turkey + { 129, 222, 44, 160, 59, 37, 48, 45, 101 }, // Ukrainian/Ukraine + { 130, 163, 46, 44, 59, 37, 1776, 45, 101 }, // Urdu/Pakistan + { 131, 228, 44, 160, 59, 37, 48, 45, 101 }, // Uzbek/Uzbekistan + { 132, 232, 44, 46, 44, 37, 48, 45, 101 }, // Vietnamese/VietNam + { 0, 0, 0, 0, 0, 0, 0, 0, 0 } // trailing 0s +}; + +static const char language_name_list[] = +"Default\0" +"C\0" +"Abkhazian\0" +"Afan\0" +"Afar\0" +"Afrikaans\0" +"Albanian\0" +"Amharic\0" +"Arabic\0" +"Armenian\0" +"Assamese\0" +"Aymara\0" +"Azerbaijani\0" +"Bashkir\0" +"Basque\0" +"Bengali\0" +"Bhutani\0" +"Bihari\0" +"Bislama\0" +"Breton\0" +"Bulgarian\0" +"Burmese\0" +"Byelorussian\0" +"Cambodian\0" +"Catalan\0" +"Chinese\0" +"Corsican\0" +"Croatian\0" +"Czech\0" +"Danish\0" +"Dutch\0" +"English\0" +"Esperanto\0" +"Estonian\0" +"Faroese\0" +"Fiji\0" +"Finnish\0" +"French\0" +"Frisian\0" +"Gaelic\0" +"Galician\0" +"Georgian\0" +"German\0" +"Greek\0" +"Greenlandic\0" +"Guarani\0" +"Gujarati\0" +"Hausa\0" +"Hebrew\0" +"Hindi\0" +"Hungarian\0" +"Icelandic\0" +"Indonesian\0" +"Interlingua\0" +"Interlingue\0" +"Inuktitut\0" +"Inupiak\0" +"Irish\0" +"Italian\0" +"Japanese\0" +"Javanese\0" +"Kannada\0" +"Kashmiri\0" +"Kazakh\0" +"Kinyarwanda\0" +"Kirghiz\0" +"Korean\0" +"Kurdish\0" +"Kurundi\0" +"Laothian\0" +"Latin\0" +"Latvian\0" +"Lingala\0" +"Lithuanian\0" +"Macedonian\0" +"Malagasy\0" +"Malay\0" +"Malayalam\0" +"Maltese\0" +"Maori\0" +"Marathi\0" +"Moldavian\0" +"Mongolian\0" +"Nauru\0" +"Nepali\0" +"Norwegian\0" +"Occitan\0" +"Oriya\0" +"Pashto\0" +"Persian\0" +"Polish\0" +"Portuguese\0" +"Punjabi\0" +"Quechua\0" +"RhaetoRomance\0" +"Romanian\0" +"Russian\0" +"Samoan\0" +"Sangho\0" +"Sanskrit\0" +"Serbian\0" +"SerboCroatian\0" +"Sesotho\0" +"Setswana\0" +"Shona\0" +"Sindhi\0" +"Singhalese\0" +"Siswati\0" +"Slovak\0" +"Slovenian\0" +"Somali\0" +"Spanish\0" +"Sundanese\0" +"Swahili\0" +"Swedish\0" +"Tagalog\0" +"Tajik\0" +"Tamil\0" +"Tatar\0" +"Telugu\0" +"Thai\0" +"Tibetan\0" +"Tigrinya\0" +"Tonga\0" +"Tsonga\0" +"Turkish\0" +"Turkmen\0" +"Twi\0" +"Uigur\0" +"Ukrainian\0" +"Urdu\0" +"Uzbek\0" +"Vietnamese\0" +"Volapuk\0" +"Welsh\0" +"Wolof\0" +"Xhosa\0" +"Yiddish\0" +"Yoruba\0" +"Zhuang\0" +"Zulu\0"; + +static const uint language_name_index[] = { + 0,// Unused + 8,// C + 10,// Abkhazian + 20,// Afan + 25,// Afar + 30,// Afrikaans + 40,// Albanian + 49,// Amharic + 57,// Arabic + 64,// Armenian + 73,// Assamese + 82,// Aymara + 89,// Azerbaijani + 101,// Bashkir + 109,// Basque + 116,// Bengali + 124,// Bhutani + 132,// Bihari + 139,// Bislama + 147,// Breton + 154,// Bulgarian + 164,// Burmese + 172,// Byelorussian + 185,// Cambodian + 195,// Catalan + 203,// Chinese + 211,// Corsican + 220,// Croatian + 229,// Czech + 235,// Danish + 242,// Dutch + 248,// English + 256,// Esperanto + 266,// Estonian + 275,// Faroese + 283,// Fiji + 288,// Finnish + 296,// French + 303,// Frisian + 311,// Gaelic + 318,// Galician + 327,// Georgian + 336,// German + 343,// Greek + 349,// Greenlandic + 361,// Guarani + 369,// Gujarati + 378,// Hausa + 384,// Hebrew + 391,// Hindi + 397,// Hungarian + 407,// Icelandic + 417,// Indonesian + 428,// Interlingua + 440,// Interlingue + 452,// Inuktitut + 462,// Inupiak + 470,// Irish + 476,// Italian + 484,// Japanese + 493,// Javanese + 502,// Kannada + 510,// Kashmiri + 519,// Kazakh + 526,// Kinyarwanda + 538,// Kirghiz + 546,// Korean + 553,// Kurdish + 561,// Kurundi + 569,// Laothian + 578,// Latin + 584,// Latvian + 592,// Lingala + 600,// Lithuanian + 611,// Macedonian + 622,// Malagasy + 631,// Malay + 637,// Malayalam + 647,// Maltese + 655,// Maori + 661,// Marathi + 669,// Moldavian + 679,// Mongolian + 689,// Nauru + 695,// Nepali + 702,// Norwegian + 712,// Occitan + 720,// Oriya + 726,// Pashto + 733,// Persian + 741,// Polish + 748,// Portuguese + 759,// Punjabi + 767,// Quechua + 775,// RhaetoRomance + 789,// Romanian + 798,// Russian + 806,// Samoan + 813,// Sangho + 820,// Sanskrit + 829,// Serbian + 837,// SerboCroatian + 851,// Sesotho + 859,// Setswana + 868,// Shona + 874,// Sindhi + 881,// Singhalese + 892,// Siswati + 900,// Slovak + 907,// Slovenian + 917,// Somali + 924,// Spanish + 932,// Sundanese + 942,// Swahili + 950,// Swedish + 958,// Tagalog + 966,// Tajik + 972,// Tamil + 978,// Tatar + 984,// Telugu + 991,// Thai + 996,// Tibetan + 1004,// Tigrinya + 1013,// Tonga + 1019,// Tsonga + 1026,// Turkish + 1034,// Turkmen + 1042,// Twi + 1046,// Uigur + 1052,// Ukrainian + 1062,// Urdu + 1067,// Uzbek + 1073,// Vietnamese + 1084,// Volapuk + 1092,// Welsh + 1098,// Wolof + 1104,// Xhosa + 1110,// Yiddish + 1118,// Yoruba + 1125,// Zhuang + 1132// Zulu +}; + +static const char country_name_list[] = +"Default\0" +"Afghanistan\0" +"Albania\0" +"Algeria\0" +"AmericanSamoa\0" +"Andorra\0" +"Angola\0" +"Anguilla\0" +"Antarctica\0" +"AntiguaAndBarbuda\0" +"Argentina\0" +"Armenia\0" +"Aruba\0" +"Australia\0" +"Austria\0" +"Azerbaijan\0" +"Bahamas\0" +"Bahrain\0" +"Bangladesh\0" +"Barbados\0" +"Belarus\0" +"Belgium\0" +"Belize\0" +"Benin\0" +"Bermuda\0" +"Bhutan\0" +"Bolivia\0" +"BosniaAndHerzegowina\0" +"Botswana\0" +"BouvetIsland\0" +"Brazil\0" +"BritishIndianOceanTerritory\0" +"BruneiDarussalam\0" +"Bulgaria\0" +"BurkinaFaso\0" +"Burundi\0" +"Cambodia\0" +"Cameroon\0" +"Canada\0" +"CapeVerde\0" +"CaymanIslands\0" +"CentralAfricanRepublic\0" +"Chad\0" +"Chile\0" +"China\0" +"ChristmasIsland\0" +"CocosIslands\0" +"Colombia\0" +"Comoros\0" +"DemocraticRepublicOfCongo\0" +"PeoplesRepublicOfCongo\0" +"CookIslands\0" +"CostaRica\0" +"IvoryCoast\0" +"Croatia\0" +"Cuba\0" +"Cyprus\0" +"CzechRepublic\0" +"Denmark\0" +"Djibouti\0" +"Dominica\0" +"DominicanRepublic\0" +"EastTimor\0" +"Ecuador\0" +"Egypt\0" +"ElSalvador\0" +"EquatorialGuinea\0" +"Eritrea\0" +"Estonia\0" +"Ethiopia\0" +"FalklandIslands\0" +"FaroeIslands\0" +"Fiji\0" +"Finland\0" +"France\0" +"MetropolitanFrance\0" +"FrenchGuiana\0" +"FrenchPolynesia\0" +"FrenchSouthernTerritories\0" +"Gabon\0" +"Gambia\0" +"Georgia\0" +"Germany\0" +"Ghana\0" +"Gibraltar\0" +"Greece\0" +"Greenland\0" +"Grenada\0" +"Guadeloupe\0" +"Guam\0" +"Guatemala\0" +"Guinea\0" +"GuineaBissau\0" +"Guyana\0" +"Haiti\0" +"HeardAndMcDonaldIslands\0" +"Honduras\0" +"HongKong\0" +"Hungary\0" +"Iceland\0" +"India\0" +"Indonesia\0" +"Iran\0" +"Iraq\0" +"Ireland\0" +"Israel\0" +"Italy\0" +"Jamaica\0" +"Japan\0" +"Jordan\0" +"Kazakhstan\0" +"Kenya\0" +"Kiribati\0" +"DemocraticRepublicOfKorea\0" +"RepublicOfKorea\0" +"Kuwait\0" +"Kyrgyzstan\0" +"Lao\0" +"Latvia\0" +"Lebanon\0" +"Lesotho\0" +"Liberia\0" +"LibyanArabJamahiriya\0" +"Liechtenstein\0" +"Lithuania\0" +"Luxembourg\0" +"Macau\0" +"Macedonia\0" +"Madagascar\0" +"Malawi\0" +"Malaysia\0" +"Maldives\0" +"Mali\0" +"Malta\0" +"MarshallIslands\0" +"Martinique\0" +"Mauritania\0" +"Mauritius\0" +"Mayotte\0" +"Mexico\0" +"Micronesia\0" +"Moldova\0" +"Monaco\0" +"Mongolia\0" +"Montserrat\0" +"Morocco\0" +"Mozambique\0" +"Myanmar\0" +"Namibia\0" +"Nauru\0" +"Nepal\0" +"Netherlands\0" +"NetherlandsAntilles\0" +"NewCaledonia\0" +"NewZealand\0" +"Nicaragua\0" +"Niger\0" +"Nigeria\0" +"Niue\0" +"NorfolkIsland\0" +"NorthernMarianaIslands\0" +"Norway\0" +"Oman\0" +"Pakistan\0" +"Palau\0" +"PalestinianTerritory\0" +"Panama\0" +"PapuaNewGuinea\0" +"Paraguay\0" +"Peru\0" +"Philippines\0" +"Pitcairn\0" +"Poland\0" +"Portugal\0" +"PuertoRico\0" +"Qatar\0" +"Reunion\0" +"Romania\0" +"RussianFederation\0" +"Rwanda\0" +"SaintKittsAndNevis\0" +"StLucia\0" +"StVincentAndTheGrenadines\0" +"Samoa\0" +"SanMarino\0" +"SaoTomeAndPrincipe\0" +"SaudiArabia\0" +"Senegal\0" +"Seychelles\0" +"SierraLeone\0" +"Singapore\0" +"Slovakia\0" +"Slovenia\0" +"SolomonIslands\0" +"Somalia\0" +"SouthAfrica\0" +"SouthGeorgiaAndTheSouthSandwichIslands\0" +"Spain\0" +"SriLanka\0" +"StHelena\0" +"StPierreAndMiquelon\0" +"Sudan\0" +"Suriname\0" +"SvalbardAndJanMayenIslands\0" +"Swaziland\0" +"Sweden\0" +"Switzerland\0" +"SyrianArabRepublic\0" +"Taiwan\0" +"Tajikistan\0" +"Tanzania\0" +"Thailand\0" +"Togo\0" +"Tokelau\0" +"Tonga\0" +"TrinidadAndTobago\0" +"Tunisia\0" +"Turkey\0" +"Turkmenistan\0" +"TurksAndCaicosIslands\0" +"Tuvalu\0" +"Uganda\0" +"Ukraine\0" +"UnitedArabEmirates\0" +"UnitedKingdom\0" +"UnitedStates\0" +"UnitedStatesMinorOutlyingIslands\0" +"Uruguay\0" +"Uzbekistan\0" +"Vanuatu\0" +"VaticanCityState\0" +"Venezuela\0" +"VietNam\0" +"BritishVirginIslands\0" +"USVirginIslands\0" +"WallisAndFutunaIslands\0" +"WesternSahara\0" +"Yemen\0" +"Yugoslavia\0" +"Zambia\0" +"Zimbabwe\0"; + +static const uint country_name_index[] = { + 0,// AnyCountry + 8,// Afghanistan + 20,// Albania + 28,// Algeria + 36,// AmericanSamoa + 50,// Andorra + 58,// Angola + 65,// Anguilla + 74,// Antarctica + 85,// AntiguaAndBarbuda + 103,// Argentina + 113,// Armenia + 121,// Aruba + 127,// Australia + 137,// Austria + 145,// Azerbaijan + 156,// Bahamas + 164,// Bahrain + 172,// Bangladesh + 183,// Barbados + 192,// Belarus + 200,// Belgium + 208,// Belize + 215,// Benin + 221,// Bermuda + 229,// Bhutan + 236,// Bolivia + 244,// BosniaAndHerzegowina + 265,// Botswana + 274,// BouvetIsland + 287,// Brazil + 294,// BritishIndianOceanTerritory + 322,// BruneiDarussalam + 339,// Bulgaria + 348,// BurkinaFaso + 360,// Burundi + 368,// Cambodia + 377,// Cameroon + 386,// Canada + 393,// CapeVerde + 403,// CaymanIslands + 417,// CentralAfricanRepublic + 440,// Chad + 445,// Chile + 451,// China + 457,// ChristmasIsland + 473,// CocosIslands + 486,// Colombia + 495,// Comoros + 503,// DemocraticRepublicOfCongo + 529,// PeoplesRepublicOfCongo + 552,// CookIslands + 564,// CostaRica + 574,// IvoryCoast + 585,// Croatia + 593,// Cuba + 598,// Cyprus + 605,// CzechRepublic + 619,// Denmark + 627,// Djibouti + 636,// Dominica + 645,// DominicanRepublic + 663,// EastTimor + 673,// Ecuador + 681,// Egypt + 687,// ElSalvador + 698,// EquatorialGuinea + 715,// Eritrea + 723,// Estonia + 731,// Ethiopia + 740,// FalklandIslands + 756,// FaroeIslands + 769,// Fiji + 774,// Finland + 782,// France + 789,// MetropolitanFrance + 808,// FrenchGuiana + 821,// FrenchPolynesia + 837,// FrenchSouthernTerritories + 863,// Gabon + 869,// Gambia + 876,// Georgia + 884,// Germany + 892,// Ghana + 898,// Gibraltar + 908,// Greece + 915,// Greenland + 925,// Grenada + 933,// Guadeloupe + 944,// Guam + 949,// Guatemala + 959,// Guinea + 966,// GuineaBissau + 979,// Guyana + 986,// Haiti + 992,// HeardAndMcDonaldIslands + 1016,// Honduras + 1025,// HongKong + 1034,// Hungary + 1042,// Iceland + 1050,// India + 1056,// Indonesia + 1066,// Iran + 1071,// Iraq + 1076,// Ireland + 1084,// Israel + 1091,// Italy + 1097,// Jamaica + 1105,// Japan + 1111,// Jordan + 1118,// Kazakhstan + 1129,// Kenya + 1135,// Kiribati + 1144,// DemocraticRepublicOfKorea + 1170,// RepublicOfKorea + 1186,// Kuwait + 1193,// Kyrgyzstan + 1204,// Lao + 1208,// Latvia + 1215,// Lebanon + 1223,// Lesotho + 1231,// Liberia + 1239,// LibyanArabJamahiriya + 1260,// Liechtenstein + 1274,// Lithuania + 1284,// Luxembourg + 1295,// Macau + 1301,// Macedonia + 1311,// Madagascar + 1322,// Malawi + 1329,// Malaysia + 1338,// Maldives + 1347,// Mali + 1352,// Malta + 1358,// MarshallIslands + 1374,// Martinique + 1385,// Mauritania + 1396,// Mauritius + 1406,// Mayotte + 1414,// Mexico + 1421,// Micronesia + 1432,// Moldova + 1440,// Monaco + 1447,// Mongolia + 1456,// Montserrat + 1467,// Morocco + 1475,// Mozambique + 1486,// Myanmar + 1494,// Namibia + 1502,// Nauru + 1508,// Nepal + 1514,// Netherlands + 1526,// NetherlandsAntilles + 1546,// NewCaledonia + 1559,// NewZealand + 1570,// Nicaragua + 1580,// Niger + 1586,// Nigeria + 1594,// Niue + 1599,// NorfolkIsland + 1613,// NorthernMarianaIslands + 1636,// Norway + 1643,// Oman + 1648,// Pakistan + 1657,// Palau + 1663,// PalestinianTerritory + 1684,// Panama + 1691,// PapuaNewGuinea + 1706,// Paraguay + 1715,// Peru + 1720,// Philippines + 1732,// Pitcairn + 1741,// Poland + 1748,// Portugal + 1757,// PuertoRico + 1768,// Qatar + 1774,// Reunion + 1782,// Romania + 1790,// RussianFederation + 1808,// Rwanda + 1815,// SaintKittsAndNevis + 1834,// StLucia + 1842,// StVincentAndTheGrenadines + 1868,// Samoa + 1874,// SanMarino + 1884,// SaoTomeAndPrincipe + 1903,// SaudiArabia + 1915,// Senegal + 1923,// Seychelles + 1934,// SierraLeone + 1946,// Singapore + 1956,// Slovakia + 1965,// Slovenia + 1974,// SolomonIslands + 1989,// Somalia + 1997,// SouthAfrica + 2009,// SouthGeorgiaAndTheSouthSandwichIslands + 2048,// Spain + 2054,// SriLanka + 2063,// StHelena + 2072,// StPierreAndMiquelon + 2092,// Sudan + 2098,// Suriname + 2107,// SvalbardAndJanMayenIslands + 2134,// Swaziland + 2144,// Sweden + 2151,// Switzerland + 2163,// SyrianArabRepublic + 2182,// Taiwan + 2189,// Tajikistan + 2200,// Tanzania + 2209,// Thailand + 2218,// Togo + 2223,// Tokelau + 2231,// Tonga + 2237,// TrinidadAndTobago + 2255,// Tunisia + 2263,// Turkey + 2270,// Turkmenistan + 2283,// TurksAndCaicosIslands + 2305,// Tuvalu + 2312,// Uganda + 2319,// Ukraine + 2327,// UnitedArabEmirates + 2346,// UnitedKingdom + 2360,// UnitedStates + 2373,// UnitedStatesMinorOutlyingIslands + 2406,// Uruguay + 2414,// Uzbekistan + 2425,// Vanuatu + 2433,// VaticanCityState + 2450,// Venezuela + 2460,// VietNam + 2468,// BritishVirginIslands + 2489,// USVirginIslands + 2505,// WallisAndFutunaIslands + 2528,// WesternSahara + 2542,// Yemen + 2548,// Yugoslavia + 2559,// Zambia + 2566// Zimbabwe +}; + +static const char language_code_list[] = +" " // Unused +" " // C +"ab" // Abkhazian +"om" // Afan +"aa" // Afar +"af" // Afrikaans +"sq" // Albanian +"am" // Amharic +"ar" // Arabic +"hy" // Armenian +"as" // Assamese +"ay" // Aymara +"az" // Azerbaijani +"ba" // Bashkir +"eu" // Basque +"bn" // Bengali +"dz" // Bhutani +"bh" // Bihari +"bi" // Bislama +"br" // Breton +"bg" // Bulgarian +"my" // Burmese +"be" // Byelorussian +"km" // Cambodian +"ca" // Catalan +"zh" // Chinese +"co" // Corsican +"hr" // Croatian +"cs" // Czech +"da" // Danish +"nl" // Dutch +"en" // English +"eo" // Esperanto +"et" // Estonian +"fo" // Faroese +"fj" // Fiji +"fi" // Finnish +"fr" // French +"fy" // Frisian +"gd" // Gaelic +"gl" // Galician +"ka" // Georgian +"de" // German +"el" // Greek +"kl" // Greenlandic +"gn" // Guarani +"gu" // Gujarati +"ha" // Hausa +"he" // Hebrew +"hi" // Hindi +"hu" // Hungarian +"is" // Icelandic +"id" // Indonesian +"ia" // Interlingua +"ie" // Interlingue +"iu" // Inuktitut +"ik" // Inupiak +"ga" // Irish +"it" // Italian +"ja" // Japanese +"jv" // Javanese +"kn" // Kannada +"ks" // Kashmiri +"kk" // Kazakh +"rw" // Kinyarwanda +"ky" // Kirghiz +"ko" // Korean +"ku" // Kurdish +"rn" // Kurundi +"lo" // Laothian +"la" // Latin +"lv" // Latvian +"ln" // Lingala +"lt" // Lithuanian +"mk" // Macedonian +"mg" // Malagasy +"ms" // Malay +"ml" // Malayalam +"mt" // Maltese +"mi" // Maori +"mr" // Marathi +"mo" // Moldavian +"mn" // Mongolian +"na" // Nauru +"ne" // Nepali +"no" // Norwegian +"oc" // Occitan +"or" // Oriya +"ps" // Pashto +"fa" // Persian +"pl" // Polish +"pt" // Portuguese +"pa" // Punjabi +"qu" // Quechua +"rm" // RhaetoRomance +"ro" // Romanian +"ru" // Russian +"sm" // Samoan +"sg" // Sangho +"sa" // Sanskrit +"sr" // Serbian +"sh" // SerboCroatian +"st" // Sesotho +"tn" // Setswana +"sn" // Shona +"sd" // Sindhi +"si" // Singhalese +"ss" // Siswati +"sk" // Slovak +"sl" // Slovenian +"so" // Somali +"es" // Spanish +"su" // Sundanese +"sw" // Swahili +"sv" // Swedish +"tl" // Tagalog +"tg" // Tajik +"ta" // Tamil +"tt" // Tatar +"te" // Telugu +"th" // Thai +"bo" // Tibetan +"ti" // Tigrinya +"to" // Tonga +"ts" // Tsonga +"tr" // Turkish +"tk" // Turkmen +"tw" // Twi +"ug" // Uigur +"uk" // Ukrainian +"ur" // Urdu +"uz" // Uzbek +"vi" // Vietnamese +"vo" // Volapuk +"cy" // Welsh +"wo" // Wolof +"xh" // Xhosa +"yi" // Yiddish +"yo" // Yoruba +"za" // Zhuang +"zu" // Zulu +; + +static const char country_code_list[] = +" " // AnyLanguage +"AF" // Afghanistan +"AL" // Albania +"DZ" // Algeria +"AS" // AmericanSamoa +"AD" // Andorra +"AO" // Angola +"AI" // Anguilla +"AQ" // Antarctica +"AG" // AntiguaAndBarbuda +"AR" // Argentina +"AM" // Armenia +"AW" // Aruba +"AU" // Australia +"AT" // Austria +"AZ" // Azerbaijan +"BS" // Bahamas +"BH" // Bahrain +"BD" // Bangladesh +"BB" // Barbados +"BY" // Belarus +"BE" // Belgium +"BZ" // Belize +"BJ" // Benin +"BM" // Bermuda +"BT" // Bhutan +"BO" // Bolivia +"BA" // BosniaAndHerzegowina +"BW" // Botswana +"BV" // BouvetIsland +"BR" // Brazil +"IO" // BritishIndianOceanTerritory +"BN" // BruneiDarussalam +"BG" // Bulgaria +"BF" // BurkinaFaso +"BI" // Burundi +"KH" // Cambodia +"CM" // Cameroon +"CA" // Canada +"CV" // CapeVerde +"KY" // CaymanIslands +"CF" // CentralAfricanRepublic +"TD" // Chad +"CL" // Chile +"CN" // China +"CX" // ChristmasIsland +"CC" // CocosIslands +"CO" // Colombia +"KM" // Comoros +"CD" // DemocraticRepublicOfCongo +"CG" // PeoplesRepublicOfCongo +"CK" // CookIslands +"CR" // CostaRica +"CI" // IvoryCoast +"HR" // Croatia +"CU" // Cuba +"CY" // Cyprus +"CZ" // CzechRepublic +"DK" // Denmark +"DJ" // Djibouti +"DM" // Dominica +"DO" // DominicanRepublic +"TL" // EastTimor +"EC" // Ecuador +"EG" // Egypt +"SV" // ElSalvador +"GQ" // EquatorialGuinea +"ER" // Eritrea +"EE" // Estonia +"ET" // Ethiopia +"FK" // FalklandIslands +"FO" // FaroeIslands +"FJ" // Fiji +"FI" // Finland +"FR" // France +"FX" // MetropolitanFrance +"GF" // FrenchGuiana +"PF" // FrenchPolynesia +"TF" // FrenchSouthernTerritories +"GA" // Gabon +"GM" // Gambia +"GE" // Georgia +"DE" // Germany +"GH" // Ghana +"GI" // Gibraltar +"GR" // Greece +"GL" // Greenland +"GD" // Grenada +"GP" // Guadeloupe +"GU" // Guam +"GT" // Guatemala +"GN" // Guinea +"GW" // GuineaBissau +"GY" // Guyana +"HT" // Haiti +"HM" // HeardAndMcDonaldIslands +"HN" // Honduras +"HK" // HongKong +"HU" // Hungary +"IS" // Iceland +"IN" // India +"ID" // Indonesia +"IR" // Iran +"IQ" // Iraq +"IE" // Ireland +"IL" // Israel +"IT" // Italy +"JM" // Jamaica +"JP" // Japan +"JO" // Jordan +"KZ" // Kazakhstan +"KE" // Kenya +"KI" // Kiribati +"KP" // DemocraticRepublicOfKorea +"KR" // RepublicOfKorea +"KW" // Kuwait +"KG" // Kyrgyzstan +"LA" // Lao +"LV" // Latvia +"LB" // Lebanon +"LS" // Lesotho +"LR" // Liberia +"LY" // LibyanArabJamahiriya +"LI" // Liechtenstein +"LT" // Lithuania +"LU" // Luxembourg +"MO" // Macau +"MK" // Macedonia +"MG" // Madagascar +"MW" // Malawi +"MY" // Malaysia +"MV" // Maldives +"ML" // Mali +"MT" // Malta +"MH" // MarshallIslands +"MQ" // Martinique +"MR" // Mauritania +"MU" // Mauritius +"YT" // Mayotte +"MX" // Mexico +"FM" // Micronesia +"MD" // Moldova +"MC" // Monaco +"MN" // Mongolia +"MS" // Montserrat +"MA" // Morocco +"MZ" // Mozambique +"MM" // Myanmar +"NA" // Namibia +"NR" // Nauru +"NP" // Nepal +"NL" // Netherlands +"AN" // NetherlandsAntilles +"NC" // NewCaledonia +"NZ" // NewZealand +"NI" // Nicaragua +"NE" // Niger +"NG" // Nigeria +"NU" // Niue +"NF" // NorfolkIsland +"MP" // NorthernMarianaIslands +"NO" // Norway +"OM" // Oman +"PK" // Pakistan +"PW" // Palau +"PS" // PalestinianTerritory +"PA" // Panama +"PG" // PapuaNewGuinea +"PY" // Paraguay +"PE" // Peru +"PH" // Philippines +"PN" // Pitcairn +"PL" // Poland +"PT" // Portugal +"PR" // PuertoRico +"QA" // Qatar +"RE" // Reunion +"RO" // Romania +"RU" // RussianFederation +"RW" // Rwanda +"KN" // SaintKittsAndNevis +"LC" // StLucia +"VC" // StVincentAndTheGrenadines +"WS" // Samoa +"SM" // SanMarino +"ST" // SaoTomeAndPrincipe +"SA" // SaudiArabia +"SN" // Senegal +"SC" // Seychelles +"SL" // SierraLeone +"SG" // Singapore +"SK" // Slovakia +"SI" // Slovenia +"SB" // SolomonIslands +"SO" // Somalia +"ZA" // SouthAfrica +"GS" // SouthGeorgiaAndTheSouthSandwichIslands +"ES" // Spain +"LK" // SriLanka +"SH" // StHelena +"PM" // StPierreAndMiquelon +"SD" // Sudan +"SR" // Suriname +"SJ" // SvalbardAndJanMayenIslands +"SZ" // Swaziland +"SE" // Sweden +"CH" // Switzerland +"SY" // SyrianArabRepublic +"TW" // Taiwan +"TJ" // Tajikistan +"TZ" // Tanzania +"TH" // Thailand +"TG" // Togo +"TK" // Tokelau +"TO" // Tonga +"TT" // TrinidadAndTobago +"TN" // Tunisia +"TR" // Turkey +"TM" // Turkmenistan +"TC" // TurksAndCaicosIslands +"TV" // Tuvalu +"UG" // Uganda +"UA" // Ukraine +"AE" // UnitedArabEmirates +"GB" // UnitedKingdom +"US" // UnitedStates +"UM" // UnitedStatesMinorOutlyingIslands +"UY" // Uruguay +"UZ" // Uzbekistan +"VU" // Vanuatu +"VA" // VaticanCityState +"VE" // Venezuela +"VN" // VietNam +"VG" // BritishVirginIslands +"VI" // USVirginIslands +"WF" // WallisAndFutunaIslands +"EH" // WesternSahara +"YE" // Yemen +"YU" // Yugoslavia +"ZM" // Zambia +"ZW" // Zimbabwe +; + +static TQLocale::Language codeToLanguage(const TQString &code) +{ + if (code.length() != 2) + return TQLocale::C; + + ushort uc1 = code.unicode()[0].unicode(); + ushort uc2 = code.unicode()[1].unicode(); + + const char *c = language_code_list; + for (; *c != 0; c += 2) { + if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1]) + return (TQLocale::Language) ((c - language_code_list)/2); + } + + return TQLocale::C; +} + +static TQLocale::Country codeToCountry(const TQString &code) +{ + if (code.length() != 2) + return TQLocale::AnyCountry; + + ushort uc1 = code.unicode()[0].unicode(); + ushort uc2 = code.unicode()[1].unicode(); + + const char *c = country_code_list; + for (; *c != 0; c += 2) { + if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1]) + return (TQLocale::Country) ((c - country_code_list)/2); + } + + return TQLocale::AnyCountry; +} + +static TQString languageToCode(TQLocale::Language language) +{ + if (language == TQLocale::C) + return "C"; + + TQString code; + code.setLength(2); + const char *c = language_code_list + 2*(uint)language; + code[0] = c[0]; + code[1] = c[1]; + return code; +} + +static TQString countryToCode(TQLocale::Country country) +{ + if (country == TQLocale::AnyCountry) + return TQString::null; + + TQString code; + code.setLength(2); + const char *c = country_code_list + 2*(uint)country; + code[0] = c[0]; + code[1] = c[1]; + return code; +} + +const TQLocalePrivate *TQLocale::default_d = 0; + +TQString TQLocalePrivate::infinity() const +{ + return TQString::fromLatin1("inf"); +} + +TQString TQLocalePrivate::nan() const +{ + return TQString::fromLatin1("nan"); +} + +#if defined(Q_OS_WIN) +/* Win95 doesn't have a function to return the ISO lang/country name of the user's locale. + Instead it can return a "Windows code". This maps windows codes to ISO country names. */ + +struct WindowsToISOListElt { + int windows_code; + char iso_name[6]; +}; + +static const WindowsToISOListElt windows_to_iso_list[] = { + { 0x0401, "ar_SA" }, + { 0x0402, "bg\0 " }, + { 0x0403, "ca\0 " }, + { 0x0404, "zh_TW" }, + { 0x0405, "cs\0 " }, + { 0x0406, "da\0 " }, + { 0x0407, "de\0 " }, + { 0x0408, "el\0 " }, + { 0x0409, "en_US" }, + { 0x040a, "es\0 " }, + { 0x040b, "fi\0 " }, + { 0x040c, "fr\0 " }, + { 0x040d, "he\0 " }, + { 0x040e, "hu\0 " }, + { 0x040f, "is\0 " }, + { 0x0410, "it\0 " }, + { 0x0411, "ja\0 " }, + { 0x0412, "ko\0 " }, + { 0x0413, "nl\0 " }, + { 0x0414, "no\0 " }, + { 0x0415, "pl\0 " }, + { 0x0416, "pt_BR" }, + { 0x0418, "ro\0 " }, + { 0x0419, "ru\0 " }, + { 0x041a, "hr\0 " }, + { 0x041c, "sq\0 " }, + { 0x041d, "sv\0 " }, + { 0x041e, "th\0 " }, + { 0x041f, "tr\0 " }, + { 0x0420, "ur\0 " }, + { 0x0421, "in\0 " }, + { 0x0422, "uk\0 " }, + { 0x0423, "be\0 " }, + { 0x0425, "et\0 " }, + { 0x0426, "lv\0 " }, + { 0x0427, "lt\0 " }, + { 0x0429, "fa\0 " }, + { 0x042a, "vi\0 " }, + { 0x042d, "eu\0 " }, + { 0x042f, "mk\0 " }, + { 0x0436, "af\0 " }, + { 0x0438, "fo\0 " }, + { 0x0439, "hi\0 " }, + { 0x043e, "ms\0 " }, + { 0x0458, "mt\0 " }, + { 0x0801, "ar_IQ" }, + { 0x0804, "zh_CN" }, + { 0x0807, "de_CH" }, + { 0x0809, "en_GB" }, + { 0x080a, "es_MX" }, + { 0x080c, "fr_BE" }, + { 0x0810, "it_CH" }, + { 0x0812, "ko\0 " }, + { 0x0813, "nl_BE" }, + { 0x0814, "no\0 " }, + { 0x0816, "pt\0 " }, + { 0x081a, "sr\0 " }, + { 0x081d, "sv_FI" }, + { 0x0c01, "ar_EG" }, + { 0x0c04, "zh_HK" }, + { 0x0c07, "de_AT" }, + { 0x0c09, "en_AU" }, + { 0x0c0a, "es\0 " }, + { 0x0c0c, "fr_CA" }, + { 0x0c1a, "sr\0 " }, + { 0x1001, "ar_LY" }, + { 0x1004, "zh_SG" }, + { 0x1007, "de_LU" }, + { 0x1009, "en_CA" }, + { 0x100a, "es_GT" }, + { 0x100c, "fr_CH" }, + { 0x1401, "ar_DZ" }, + { 0x1407, "de_LI" }, + { 0x1409, "en_NZ" }, + { 0x140a, "es_CR" }, + { 0x140c, "fr_LU" }, + { 0x1801, "ar_MA" }, + { 0x1809, "en_IE" }, + { 0x180a, "es_PA" }, + { 0x1c01, "ar_TN" }, + { 0x1c09, "en_ZA" }, + { 0x1c0a, "es_DO" }, + { 0x2001, "ar_OM" }, + { 0x2009, "en_JM" }, + { 0x200a, "es_VE" }, + { 0x2401, "ar_YE" }, + { 0x2409, "en\0 " }, + { 0x240a, "es_CO" }, + { 0x2801, "ar_SY" }, + { 0x2809, "en_BZ" }, + { 0x280a, "es_PE" }, + { 0x2c01, "ar_JO" }, + { 0x2c09, "en_TT" }, + { 0x2c0a, "es_AR" }, + { 0x3001, "ar_LB" }, + { 0x300a, "es_EC" }, + { 0x3401, "ar_KW" }, + { 0x340a, "es_CL" }, + { 0x3801, "ar_AE" }, + { 0x380a, "es_UY" }, + { 0x3c01, "ar_BH" }, + { 0x3c0a, "es_PY" }, + { 0x4001, "ar_QA" }, + { 0x400a, "es_BO" }, + { 0x440a, "es_SV" }, + { 0x480a, "es_HN" }, + { 0x4c0a, "es_NI" }, + { 0x500a, "es_PR" } +}; + +static const int windows_to_iso_count + = sizeof(windows_to_iso_list)/sizeof(WindowsToISOListElt); + +static const char *winLangCodeToIsoName(int code) +{ + int cmp = code - windows_to_iso_list[0].windows_code; + if (cmp < 0) + return 0; + + if (cmp == 0) + return windows_to_iso_list[0].iso_name; + + int begin = 0; + int end = windows_to_iso_count; + + while (end - begin > 1) { + uint mid = (begin + end)/2; + + const WindowsToISOListElt *elt = windows_to_iso_list + mid; + int cmp = code - elt->windows_code; + if (cmp < 0) + end = mid; + else if (cmp > 0) + begin = mid; + else + return elt->iso_name; + } + + return 0; + +} +#endif // Q_OS_WIN + +const char* TQLocalePrivate::systemLocaleName() +{ + static TQCString lang; + lang = getenv( "LANG" ); + +#if defined( Q_OS_MAC ) + if ( !lang.isEmpty() ) + return lang; + + char mac_ret[255]; + if(!LocaleRefGetPartString(NULL, kLocaleLanguageMask | kLocaleRegionMask, 255, mac_ret)) + lang = mac_ret; +#endif + +#if defined(TQ_WS_WIN) + if ( !lang.isEmpty() ) { + long id = 0; + bool ok = false; + id = qstrtoll(lang.data(), 0, 0, &ok); + if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX ) + return lang; + else + return winLangCodeToIsoName( (int)id ); + } + + if (qWinVersion() == TQt::WV_95) { + lang = winLangCodeToIsoName(GetUserDefaultLangID()); + } else { + QT_WA( { + wchar_t out[256]; + TQString language; + TQString sublanguage; + if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME , out, 255 ) ) + language = TQString::fromUcs2( (ushort*)out ); + if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) ) + sublanguage = TQString::fromUcs2( (ushort*)out ).lower(); + lang = language; + if ( sublanguage != language && !sublanguage.isEmpty() ) + lang += "_" + sublanguage.upper(); + } , { + char out[256]; + TQString language; + TQString sublanguage; + if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, out, 255 ) ) + language = TQString::fromLocal8Bit( out ); + if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) ) + sublanguage = TQString::fromLocal8Bit( out ).lower(); + lang = language; + if ( sublanguage != language && !sublanguage.isEmpty() ) + lang += "_" + sublanguage.upper(); + } ); + } +#endif + if ( lang.isEmpty() ) + lang = "C"; + + return lang; +} + +static const TQLocalePrivate *findLocale(TQLocale::Language language, + TQLocale::Country country) +{ + unsigned language_id = (unsigned)language; + unsigned country_id = (unsigned)country; + + uint idx = locale_index[language_id]; + + const TQLocalePrivate *d = locale_data + idx; + + if (idx == 0) // default language has no associated country + return d; + + if (country == TQLocale::AnyCountry) + return d; + + Q_ASSERT(d->languageId() == language_id); + + while (d->languageId() == language_id + && d->countryId() != country_id) + ++d; + + if (d->countryId() == country_id + && d->languageId() == language_id) + return d; + + return locale_data + idx; +} + +/*! + \class TQLocale + \brief The TQLocale class converts between numbers and their + string representations in various languages. + + \reentrant + \ingroup text + + It is initialized with a country/language pair in its constructor + and offers number-to-string and string-to-number conversion + functions simmilar to those in TQString. + + \code + TQLocale egyptian(TQLocale::Arabic, TQLocale::Egypt); + TQString s1 = egyptian.toString(1.571429E+07, 'e'); + TQString s2 = egyptian.toString(10); + + double d = egyptian.toDouble(s1); + int s2 = egyptian.toInt(s2); + \endcode + + TQLocale supports the concept of a default locale, which is + determined from the system's locale settings at application + startup. The default locale can be changed by calling the + static member setDefault(). The default locale has the + following effects: + + \list + \i If a TQLocale object is constructed with the default constructor, + it will use the default locale's settings. + \i TQString::toDouble() interprets the string according to the default + locale. If this fails, it falls back on the "C" locale. + \i TQString::arg() uses the default locale to format a number when + its position specifier in the format string contains an 'L', + e.g. "%L1". + \endlist + + \code + TQLocale::setDefault(TQLocale(TQLocale::Hebrew, TQLocale::Israel)); + TQLocale hebrew; // Constructs a default TQLocale + TQString s1 = hebrew.toString(15714.3, 'e'); + + bool ok; + double d; + + TQLocale::setDefault(TQLocale::C); + d = TQString( "1234,56" ).toDouble(&ok); // ok == false + d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 + + TQLocale::setDefault(TQLocale::German); + d = TQString( "1234,56" ).toDouble(&ok); // ok == true, d == 1234.56 + d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 + + TQLocale::setDefault(TQLocale(TQLocale::English, TQLocale::UnitedStates)); + str = TQString( "%1 %L2 %L3" ) + .arg( 12345 ) + .arg( 12345 ) + .arg( 12345, 0, 16 ); + // str == "12345 12,345 3039" + \endcode + + When a language/country pair is specified in the constructor, one + of three things can happen: + + \list + \i If the language/country pair is found in the database, it is used. + \i If the language is found but the country is not, or if the country + is \c AnyCountry, the language is used with the most + appropriate available country (for example, Germany for German), + \i If neither the language nor the country are found, TQLocale + defaults to the default locale (see setDefault()). + \endlist + + The "C" locale is identical to English/UnitedStates. + + Use language() and country() to determine the actual language and + country values used. + + An alternative method for constructing a TQLocale object is by + specifying the locale name. + + \code + TQLocale korean("ko"); + TQLocale swiss("de_CH"); + \endcode + + This constructor converts the locale name to a language/country + pair; it does not use the system locale database. + + All the methods in TQLocale, with the exception of setDefault(), + are reentrant. + + \sa TQString::toDouble() TQString::arg() + + The double-to-string and string-to-double conversion functions are + covered by the following licenses: + + \legalese + + Copyright (c) 1991 by AT&T. + + Permission to use, copy, modify, and distribute this software for any + purpose without fee is hereby granted, provided that this entire notice + is included in all copies of any software which is or includes a copy + or modification of this software and in all copies of the supporting + documentation for such software. + + THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY + REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + + This product includes software developed by the University of + California, Berkeley and its contributors. +*/ + +/*! + \enum TQLocale::Language + + This enumerated type is used to specify a language. + + \value C Identical to English/UnitedStates + \value Abkhazian + \value Afan + \value Afar + \value Afrikaans + \value Albanian + \value Amharic + \value Arabic + \value Armenian + \value Assamese + \value Aymara + \value Azerbaijani + \value Bashkir + \value Basque + \value Bengali + \value Bhutani + \value Bihari + \value Bislama + \value Breton + \value Bulgarian + \value Burmese + \value Byelorussian + \value Cambodian + \value Catalan + \value Chinese + \value Corsican + \value Croatian + \value Czech + \value Danish + \value Dutch + \value English + \value Esperanto + \value Estonian + \value Faroese + \value FijiLanguage + \value Finnish + \value French + \value Frisian + \value Gaelic + \value Galician + \value Georgian + \value German + \value Greek + \value Greenlandic + \value Guarani + \value Gujarati + \value Hausa + \value Hebrew + \value Hindi + \value Hungarian + \value Icelandic + \value Indonesian + \value Interlingua + \value Interlingue + \value Inuktitut + \value Inupiak + \value Irish + \value Italian + \value Japanese + \value Javanese + \value Kannada + \value Kashmiri + \value Kazakh + \value Kinyarwanda + \value Kirghiz + \value Korean + \value Kurdish + \value Kurundi + \value Laothian + \value Latin + \value Latvian + \value Lingala + \value Lithuanian + \value Macedonian + \value Malagasy + \value Malay + \value Malayalam + \value Maltese + \value Maori + \value Marathi + \value Moldavian + \value Mongolian + \value NauruLanguage + \value Nepali + \value Norwegian + \value Occitan + \value Oriya + \value Pashto + \value Persian + \value Polish + \value Portuguese + \value Punjabi + \value Quechua + \value RhaetoRomance + \value Romanian + \value Russian + \value Samoan + \value Sangho + \value Sanskrit + \value Serbian + \value SerboCroatian + \value Sesotho + \value Setswana + \value Shona + \value Sindhi + \value Singhalese + \value Siswati + \value Slovak + \value Slovenian + \value Somali + \value Spanish + \value Sundanese + \value Swahili + \value Swedish + \value Tagalog + \value Tajik + \value Tamil + \value Tatar + \value Telugu + \value Thai + \value Tibetan + \value Tigrinya + \value TongaLanguage + \value Tsonga + \value Turkish + \value Turkmen + \value Twi + \value Uigur + \value Ukrainian + \value Urdu + \value Uzbek + \value Vietnamese + \value Volapuk + \value Welsh + \value Wolof + \value Xhosa + \value Yiddish + \value Yoruba + \value Zhuang + \value Zulu +*/ + +/*! + \enum TQLocale::Country + + This enumerated type is used to specify a country. + + \value AnyCountry + \value Afghanistan + \value Albania + \value Algeria + \value AmericanSamoa + \value Andorra + \value Angola + \value Anguilla + \value Antarctica + \value AntiguaAndBarbuda + \value Argentina + \value Armenia + \value Aruba + \value Australia + \value Austria + \value Azerbaijan + \value Bahamas + \value Bahrain + \value Bangladesh + \value Barbados + \value Belarus + \value Belgium + \value Belize + \value Benin + \value Bermuda + \value Bhutan + \value Bolivia + \value BosniaAndHerzegowina + \value Botswana + \value BouvetIsland + \value Brazil + \value BritishIndianOceanTerritory + \value BruneiDarussalam + \value Bulgaria + \value BurkinaFaso + \value Burundi + \value Cambodia + \value Cameroon + \value Canada + \value CapeVerde + \value CaymanIslands + \value CentralAfricanRepublic + \value Chad + \value Chile + \value China + \value ChristmasIsland + \value CocosIslands + \value Colombia + \value Comoros + \value DemocraticRepublicOfCongo + \value PeoplesRepublicOfCongo + \value CookIslands + \value CostaRica + \value IvoryCoast + \value Croatia + \value Cuba + \value Cyprus + \value CzechRepublic + \value Denmark + \value Djibouti + \value Dominica + \value DominicanRepublic + \value EastTimor + \value Ecuador + \value Egypt + \value ElSalvador + \value EquatorialGuinea + \value Eritrea + \value Estonia + \value Ethiopia + \value FalklandIslands + \value FaroeIslands + \value FijiCountry + \value Finland + \value France + \value MetropolitanFrance + \value FrenchGuiana + \value FrenchPolynesia + \value FrenchSouthernTerritories + \value Gabon + \value Gambia + \value Georgia + \value Germany + \value Ghana + \value Gibraltar + \value Greece + \value Greenland + \value Grenada + \value Guadeloupe + \value Guam + \value Guatemala + \value Guinea + \value GuineaBissau + \value Guyana + \value Haiti + \value HeardAndMcDonaldIslands + \value Honduras + \value HongKong + \value Hungary + \value Iceland + \value India + \value Indonesia + \value Iran + \value Iraq + \value Ireland + \value Israel + \value Italy + \value Jamaica + \value Japan + \value Jordan + \value Kazakhstan + \value Kenya + \value Kiribati + \value DemocraticRepublicOfKorea + \value RepublicOfKorea + \value Kuwait + \value Kyrgyzstan + \value Lao + \value Latvia + \value Lebanon + \value Lesotho + \value Liberia + \value LibyanArabJamahiriya + \value Liechtenstein + \value Lithuania + \value Luxembourg + \value Macau + \value Macedonia + \value Madagascar + \value Malawi + \value Malaysia + \value Maldives + \value Mali + \value Malta + \value MarshallIslands + \value Martinique + \value Mauritania + \value Mauritius + \value Mayotte + \value Mexico + \value Micronesia + \value Moldova + \value Monaco + \value Mongolia + \value Montserrat + \value Morocco + \value Mozambique + \value Myanmar + \value Namibia + \value NauruCountry + \value Nepal + \value Netherlands + \value NetherlandsAntilles + \value NewCaledonia + \value NewZealand + \value Nicaragua + \value Niger + \value Nigeria + \value Niue + \value NorfolkIsland + \value NorthernMarianaIslands + \value Norway + \value Oman + \value Pakistan + \value Palau + \value PalestinianTerritory + \value Panama + \value PapuaNewGuinea + \value Paraguay + \value Peru + \value Philippines + \value Pitcairn + \value Poland + \value Portugal + \value PuertoRico + \value Qatar + \value Reunion + \value Romania + \value RussianFederation + \value Rwanda + \value SaintKittsAndNevis + \value StLucia + \value StVincentAndTheGrenadines + \value Samoa + \value SanMarino + \value SaoTomeAndPrincipe + \value SaudiArabia + \value Senegal + \value Seychelles + \value SierraLeone + \value Singapore + \value Slovakia + \value Slovenia + \value SolomonIslands + \value Somalia + \value SouthAfrica + \value SouthGeorgiaAndTheSouthSandwichIslands + \value Spain + \value SriLanka + \value StHelena + \value StPierreAndMiquelon + \value Sudan + \value Suriname + \value SvalbardAndJanMayenIslands + \value Swaziland + \value Sweden + \value Switzerland + \value SyrianArabRepublic + \value Taiwan + \value Tajikistan + \value Tanzania + \value Thailand + \value Togo + \value Tokelau + \value TongaCountry + \value TrinidadAndTobago + \value Tunisia + \value Turkey + \value Turkmenistan + \value TurksAndCaicosIslands + \value Tuvalu + \value Uganda + \value Ukraine + \value UnitedArabEmirates + \value UnitedKingdom + \value UnitedStates + \value UnitedStatesMinorOutlyingIslands + \value Uruguay + \value Uzbekistan + \value Vanuatu + \value VaticanCityState + \value Venezuela + \value VietNam + \value BritishVirginIslands + \value USVirginIslands + \value WallisAndFutunaIslands + \value WesternSahara + \value Yemen + \value Yugoslavia + \value Zambia + \value Zimbabwe +*/ + +/*! + Constructs a TQLocale object with the specified \a name, + which has the format + "language[_country][.codeset][@modifier]" or "C", where: + + \list + \i language is a lowercase, two-letter, ISO 639 language code, + \i territory is an uppercase, two-letter, ISO 3166 country code, + \i and codeset and modifier are ignored. + \endlist + + If the string violates the locale format, or language is not + a valid ISO 369 code, the "C" locale is used instead. If country + is not present, or is not a valid ISO 3166 code, the most + appropriate country is chosen for the specified language. + + The language and country codes are converted to their respective + \c Language and \c Country enums. After this conversion is + performed the constructor behaves exactly like TQLocale(Country, + Language). + + This constructor is much slower than TQLocale(Country, Language). + + \sa name() +*/ + +TQLocale::TQLocale(const TQString &name) +{ + Language lang = C; + Country cntry = AnyCountry; + + uint l = name.length(); + + do { + if (l < 2) + break; + + const TQChar *uc = name.unicode(); + if (l > 2 + && uc[2] != '_' + && uc[2] != '.' + && uc[2] != '@') + break; + + lang = codeToLanguage(name.mid(0, 2)); + if (lang == C) + break; + + if (l == 2 || uc[2] == '.' || uc[2] == '@') + break; + + // we have uc[2] == '_' + if (l < 5) + break; + + if (l > 5 && uc[5] != '.' && uc[5] != '@') + break; + + cntry = codeToCountry(name.mid(3, 2)); + } while (FALSE); + + d = findLocale(lang, cntry); +} + +/*! + Constructs a TQLocale object initialized with the default locale. + + \sa setDefault() +*/ + +TQLocale::TQLocale() +{ + if (default_d == 0) + default_d = system().d; + + d = default_d; +} + +/*! + Constructs a TQLocale object with the specified \a language and \a + country. + + \list + \i If the language/country pair is found in the database, it is used. + \i If the language is found but the country is not, or if the country + is \c AnyCountry, the language is used with the most + appropriate available country (for example, Germany for German), + \i If neither the language nor the country are found, TQLocale + defaults to the default locale (see setDefault()). + \endlist + + The language and country that are actually used can be queried + using language() and country(). + + \sa setDefault() language() country() +*/ + +TQLocale::TQLocale(Language language, Country country) +{ + d = findLocale(language, country); + + // If not found, should default to system + if (d->languageId() == TQLocale::C && language != TQLocale::C) { + if (default_d == 0) + default_d = system().d; + + d = default_d; + } +} + +/*! + Constructs a TQLocale object as a copy of \a other. +*/ + +TQLocale::TQLocale(const TQLocale &other) +{ + d = other.d; +} + +/*! + Assigns \a other to this TQLocale object and returns a reference + to this TQLocale object. +*/ + +TQLocale &TQLocale::operator=(const TQLocale &other) +{ + d = other.d; + return *this; +} + +/*! + \nonreentrant + + Sets the global default locale to \a locale. These + values are used when a TQLocale object is constructed with + no arguments. If this function is not called, the system's + locale is used. + + \warning In a multithreaded application, the default locale + should be set at application startup, before any non-GUI threads + are created. + + \sa system() c() +*/ + +void TQLocale::setDefault(const TQLocale &locale) +{ + default_d = locale.d; +} + +/*! + Returns the language of this locale. + + \sa TQLocale() +*/ +TQLocale::Language TQLocale::language() const +{ + return (Language)d->languageId(); +} + +/*! + Returns the country of this locale. + + \sa TQLocale() +*/ +TQLocale::Country TQLocale::country() const +{ + return (Country)d->countryId(); +} + +/*! + Returns the language and country of this locale as a + string of the form "language_country", where + language is a lowercase, two-letter ISO 639 language code, + and country is an uppercase, two-letter ISO 3166 country code. + + \sa TQLocale() +*/ + +TQString TQLocale::name() const +{ + Language l = language(); + + TQString result = languageToCode(l); + + if (l == C) + return result; + + Country c = country(); + if (c == AnyCountry) + return result; + + result.append('_'); + result.append(countryToCode(c)); + + return result; +} + +/*! + Returns a TQString containing the name of \a language. +*/ + +TQString TQLocale::languageToString(Language language) +{ + if ((uint)language > (uint)TQLocale::LastLanguage) + return "Unknown"; + return language_name_list + language_name_index[(uint)language]; +} + +/*! + Returns a TQString containing the name of \a country. +*/ + +TQString TQLocale::countryToString(Country country) +{ + if ((uint)country > (uint)TQLocale::LastCountry) + return "Unknown"; + return country_name_list + country_name_index[(uint)country]; +} + +/*! + Returns the short int represented by the localized string \a s, or + 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +short TQLocale::toShort(const TQString &s, bool *ok) const +{ + TQ_LLONG i = toLongLong(s, ok); + if (i < SHRT_MIN || i > SHRT_MAX) { + if (ok != 0) + *ok = FALSE; + return 0; + } + return (short) i; +} + +/*! + Returns the unsigned short int represented by the localized string + \a s, or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +ushort TQLocale::toUShort(const TQString &s, bool *ok) const +{ + TQ_ULLONG i = toULongLong(s, ok); + if (i > USHRT_MAX) { + if (ok != 0) + *ok = FALSE; + return 0; + } + return (ushort) i; +} + +/*! + Returns the int represented by the localized string \a s, or 0 if + the conversion failed. + + If \a ok is not 0, reports failure by setting *ok to false and + success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +int TQLocale::toInt(const TQString &s, bool *ok) const +{ + TQ_LLONG i = toLongLong(s, ok); + if (i < INT_MIN || i > INT_MAX) { + if (ok != 0) + *ok = FALSE; + return 0; + } + return (int) i; +} + +/*! + Returns the unsigned int represented by the localized string \a s, + or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +uint TQLocale::toUInt(const TQString &s, bool *ok) const +{ + TQ_ULLONG i = toULongLong(s, ok); + if (i > UINT_MAX) { + if (ok != 0) + *ok = FALSE; + return 0; + } + return (uint) i; +} + +/*! + Returns the long int represented by the localized string \a s, or + 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +TQ_LONG TQLocale::toLong(const TQString &s, bool *ok) const +{ + TQ_LLONG i = toLongLong(s, ok); + if (i < LONG_MIN || i > LONG_MAX) { + if (ok != 0) + *ok = FALSE; + return 0; + } + return (TQ_LONG) i; +} + +/*! + Returns the unsigned long int represented by the localized string + \a s, or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +TQ_ULONG TQLocale::toULong(const TQString &s, bool *ok) const +{ + TQ_ULLONG i = toULongLong(s, ok); + if (i > ULONG_MAX) { + if (ok != 0) + *ok = FALSE; + return 0; + } + return (TQ_ULONG) i; +} + +/*! + Returns the long long int represented by the localized string \a + s, or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + + +TQ_LLONG TQLocale::toLongLong(const TQString &s, bool *ok) const +{ + return d->stringToLongLong(s, 0, ok, TQLocalePrivate::ParseGroupSeparators); +} + +/*! + Returns the unsigned long long int represented by the localized + string \a s, or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + + +TQ_ULLONG TQLocale::toULongLong(const TQString &s, bool *ok) const +{ + return d->stringToUnsLongLong(s, 0, ok, TQLocalePrivate::ParseGroupSeparators); +} + +/*! + Returns the float represented by the localized string \a s, or 0.0 + if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +#define QT_MAX_FLOAT 3.4028234663852886e+38 + +float TQLocale::toFloat(const TQString &s, bool *ok) const +{ + bool myOk; + double d = toDouble(s, &myOk); + if (!myOk || d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) { + if (ok != 0) + *ok = FALSE; + return 0.0; + } + if (ok != 0) + *ok = TRUE; + return (float) d; +} + +/*! + Returns the double represented by the localized string \a s, or + 0.0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + Unlike TQString::toDouble(), this function does not fall back to + the "C" locale if the string cannot be interpreted in this + locale. + + \code + bool ok; + double d; + + TQLocale c(TQLocale::C); + d = c.toDouble( "1234.56", &ok ); // ok == true, d == 1234.56 + d = c.toDouble( "1,234.56", &ok ); // ok == true, d == 1234.56 + d = c.toDouble( "1234,56", &ok ); // ok == false + + TQLocale german(TQLocale::German); + d = german.toDouble( "1234,56", &ok ); // ok == true, d == 1234.56 + d = german.toDouble( "1.234,56", &ok ); // ok == true, d == 1234.56 + d = german.toDouble( "1234.56", &ok ); // ok == false + + d = german.toDouble( "1.234", &ok ); // ok == true, d == 1234.0 + \endcode + + Notice that the last conversion returns 1234.0, because '.' is the + thousands group separator in the German locale. + + This function ignores leading and trailing whitespace. + + \sa toString() TQString::toDouble() +*/ + +double TQLocale::toDouble(const TQString &s, bool *ok) const +{ + return d->stringToDouble(s, ok, TQLocalePrivate::ParseGroupSeparators); +} + +/*! + Returns a localized string representation of \a i. + + \sa toLongLong() +*/ + +TQString TQLocale::toString(TQ_LLONG i) const +{ + return d->longLongToString(i, -1, 10, -1, TQLocalePrivate::ThousandsGroup); +} + +/*! + \overload + + \sa toULongLong() +*/ + +TQString TQLocale::toString(TQ_ULLONG i) const +{ + return d->unsLongLongToString(i, -1, 10, -1, TQLocalePrivate::ThousandsGroup); +} + +static bool qIsUpper(char c) +{ + return c >= 'A' && c <= 'Z'; +} + +static char qToLower(char c) +{ + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + else + return c; +} + +/*! + \overload + + \a f and \a prec have the same meaning as in TQString::number(double, char, int). + + \sa toDouble() +*/ + +TQString TQLocale::toString(double i, char f, int prec) const +{ + TQLocalePrivate::DoubleForm form = TQLocalePrivate::DFDecimal; + uint flags = 0; + + if (qIsUpper(f)) + flags = TQLocalePrivate::CapitalEorX; + f = qToLower(f); + + switch (f) { + case 'f': + form = TQLocalePrivate::DFDecimal; + break; + case 'e': + form = TQLocalePrivate::DFExponent; + break; + case 'g': + form = TQLocalePrivate::DFSignificantDigits; + break; + default: + break; + } + + flags |= TQLocalePrivate::ThousandsGroup; + return d->doubleToString(i, prec, form, -1, flags); +} + +/*! + \fn TQLocale TQLocale::c() + + Returns a TQLocale object initialized to the "C" locale. + + \sa system() +*/ + +/*! + Returns a TQLocale object initialized to the system locale. +*/ + +TQLocale TQLocale::system() +{ +#ifdef Q_OS_UNIX + const char *s = getenv("LC_NUMERIC"); + if (s == 0) + s = getenv("LC_ALL"); + if (s != 0) + return TQLocale(s); +#endif + return TQLocale(TQLocalePrivate::systemLocaleName()); +} + +/*! +\fn TQString TQLocale::toString(short i) const + +\overload + +\sa toShort() +*/ + +/*! +\fn TQString TQLocale::toString(ushort i) const + +\overload + +\sa toUShort() +*/ + +/*! +\fn TQString TQLocale::toString(int i) const + +\overload + +\sa toInt() +*/ + +/*! +\fn TQString TQLocale::toString(uint i) const + +\overload + +\sa toUInt() +*/ + +/*! +\fn TQString TQLocale::toString(TQ_LONG i) const + +\overload + +\sa toLong() +*/ + +/*! +\fn TQString TQLocale::toString(TQ_ULONG i) const + +\overload + +\sa toULong() +*/ + +/*! +\fn TQString TQLocale::toString(float i, char f = 'g', int prec = 6) const + +\overload + +\a f and \a prec have the same meaning as in TQString::number(double, char, int). + +\sa toDouble() +*/ + + +bool TQLocalePrivate::isDigit(TQChar d) const +{ + return zero().unicode() <= d.unicode() + && zero().unicode() + 10 > d.unicode(); +} + +static char digitToCLocale(TQChar zero, TQChar d) +{ + if (zero.unicode() <= d.unicode() + && zero.unicode() + 10 > d.unicode()) + return '0' + d.unicode() - zero.unicode(); + + tqWarning("TQLocalePrivate::digitToCLocale(): bad digit: row=%d, cell=%d", d.row(), d.cell()); + return TQChar(0); +} + +static TQString qulltoa(TQ_ULLONG l, int base, const TQLocalePrivate &locale) +{ + TQChar buff[65]; // length of MAX_ULLONG in base 2 + TQChar *p = buff + 65; + + if (base != 10 || locale.zero().unicode() == '0') { + while (l != 0) { + int c = l % base; + + --p; + + if (c < 10) + *p = '0' + c; + else + *p = c - 10 + 'a'; + + l /= base; + } + } + else { + while (l != 0) { + int c = l % base; + + *(--p) = locale.zero().unicode() + c; + + l /= base; + } + } + + return TQString(p, 65 - (p - buff)); +} + +static TQString qlltoa(TQ_LLONG l, int base, const TQLocalePrivate &locale) +{ + return qulltoa(l < 0 ? -l : l, base, locale); +} + +enum PrecisionMode { + PMDecimalDigits = 0x01, + PMSignificantDigits = 0x02, + PMChopTrailingZeros = 0x03 +}; + +static TQString &decimalForm(TQString &digits, int decpt, uint precision, + PrecisionMode pm, + bool always_show_decpt, + bool thousands_group, + const TQLocalePrivate &locale) +{ + if (decpt < 0) { + for (int i = 0; i < -decpt; ++i) + digits.prepend(locale.zero()); + decpt = 0; + } + else if ((uint)decpt > digits.length()) { + for (uint i = digits.length(); i < (uint)decpt; ++i) + digits.append(locale.zero()); + } + + if (pm == PMDecimalDigits) { + uint decimal_digits = digits.length() - decpt; + for (uint i = decimal_digits; i < precision; ++i) + digits.append(locale.zero()); + } + else if (pm == PMSignificantDigits) { + for (uint i = digits.length(); i < precision; ++i) + digits.append(locale.zero()); + } + else { // pm == PMChopTrailingZeros + } + + if (always_show_decpt || (uint)decpt < digits.length()) + digits.insert(decpt, locale.decimal()); + + if (thousands_group) { + for (int i = decpt - 3; i > 0; i -= 3) + digits.insert(i, locale.group()); + } + + if (decpt == 0) + digits.prepend(locale.zero()); + + return digits; +} + +static TQString &exponentForm(TQString &digits, int decpt, uint precision, + PrecisionMode pm, + bool always_show_decpt, + const TQLocalePrivate &locale) +{ + int exp = decpt - 1; + + if (pm == PMDecimalDigits) { + for (uint i = digits.length(); i < precision + 1; ++i) + digits.append(locale.zero()); + } + else if (pm == PMSignificantDigits) { + for (uint i = digits.length(); i < precision; ++i) + digits.append(locale.zero()); + } + else { // pm == PMChopTrailingZeros + } + + if (always_show_decpt || digits.length() > 1) + digits.insert(1, locale.decimal()); + + digits.append(locale.exponential()); + digits.append(locale.longLongToString(exp, 2, 10, + -1, TQLocalePrivate::AlwaysShowSign)); + + return digits; +} + +static bool isZero(double d) +{ + uchar *ch = (uchar *)&d; + if (ByteOrder == BigEndian) { + return !(ch[0] & 0x7F || ch[1] || ch[2] || ch[3] || ch[4] || ch[5] || ch[6] || ch[7]); + } else { + return !(ch[7] & 0x7F || ch[6] || ch[5] || ch[4] || ch[3] || ch[2] || ch[1] || ch[0]); + } +} + +TQString TQLocalePrivate::doubleToString(double d, + int precision, + DoubleForm form, + int width, + unsigned flags) const +{ + if (precision == -1) + precision = 6; + if (width == -1) + width = 0; + + bool negative = FALSE; + bool special_number = FALSE; // nan, +/-inf + TQString num_str; + +#ifdef Q_OS_WIN + // Detect special numbers (nan, +/-inf) + if (qIsInf(d)) { + num_str = infinity(); + special_number = TRUE; + negative = d < 0; + } else if (qIsNan(d)) { + num_str = nan(); + special_number = TRUE; + } +#else + // Comparing directly to INFINITY gives weird results on some systems. + double tmp_infinity = INFINITY; + + // Detect special numbers (nan, +/-inf) + if (d == tmp_infinity || d == -tmp_infinity) { + num_str = infinity(); + special_number = TRUE; + negative = d < 0; + } else if (qIsNan(d)) { + num_str = nan(); + special_number = TRUE; + } +#endif + + // Handle normal numbers + if (!special_number) { + int decpt, sign; + TQString digits; + +#ifdef QT_QLOCALE_USES_FCVT +#ifdef TQT_THREAD_SUPPORT + static bool dummy_for_mutex; + TQMutex *fcvt_mutex = tqt_global_mutexpool ? tqt_global_mutexpool->get( &dummy_for_mutex ) : 0; +# define FCVT_LOCK if (fcvt_mutex) fcvt_mutex->lock() +# define FCVT_UNLOCK if (fcvt_mutex) fcvt_mutex->unlock() +#else +# define FCVT_LOCK +# define FCVT_UNLOCK +#endif + if (form == DFDecimal) { + FCVT_LOCK; + digits = fcvt(d, precision, &decpt, &sign); + FCVT_UNLOCK; + } else { + int pr = precision; + if (form == DFExponent) + ++pr; + else if (form == DFSignificantDigits && pr == 0) + pr = 1; + FCVT_LOCK; + digits = ecvt(d, pr, &decpt, &sign); + FCVT_UNLOCK; + + // Chop trailing zeros + if (digits.length() > 0) { + int last_nonzero_idx = digits.length() - 1; + while (last_nonzero_idx > 0 + && digits.unicode()[last_nonzero_idx] == '0') + --last_nonzero_idx; + digits.truncate(last_nonzero_idx + 1); + } + + } + +#else + int mode; + if (form == DFDecimal) + mode = 3; + else + mode = 2; + + /* This next bit is a bit quirky. In DFExponent form, the precision + is the number of digits after decpt. So that would suggest using + mode=3 for qdtoa. But qdtoa behaves strangely when mode=3 and + precision=0. So we get around this by using mode=2 and reasoning + that we want precision+1 significant digits, since the decimal + point in this mode is always after the first digit. */ + int pr = precision; + if (form == DFExponent) + ++pr; + + char *rve = 0; + char *buff = 0; + digits = qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff); + if (buff != 0) + free(buff); +#endif // QT_QLOCALE_USES_FCVT + + if (zero().unicode() != '0') { + for (uint i = 0; i < digits.length(); ++i) + digits.ref(i).unicode() += zero().unicode() - '0'; + } + + bool always_show_decpt = flags & Alternate; + switch (form) { + case DFExponent: { + num_str = exponentForm(digits, decpt, precision, PMDecimalDigits, + always_show_decpt, *this); + break; + } + case DFDecimal: { + num_str = decimalForm(digits, decpt, precision, PMDecimalDigits, + always_show_decpt, flags & ThousandsGroup, + *this); + break; + } + case DFSignificantDigits: { + PrecisionMode mode = (flags & Alternate) ? + PMSignificantDigits : PMChopTrailingZeros; + + if (decpt != (int)digits.length() && (decpt <= -4 || decpt > (int)precision)) + num_str = exponentForm(digits, decpt, precision, mode, + always_show_decpt, *this); + else + num_str = decimalForm(digits, decpt, precision, mode, + always_show_decpt, flags & ThousandsGroup, + *this); + break; + } + } + + negative = sign != 0 && !isZero(d); + } + + // pad with zeros. LeftAdjusted overrides this flag). Also, we don't + // pad special numbers + if (flags & TQLocalePrivate::ZeroPadded + && !(flags & TQLocalePrivate::LeftAdjusted) + && !special_number) { + int num_pad_chars = width - (int)num_str.length(); + // leave space for the sign + if (negative + || flags & TQLocalePrivate::AlwaysShowSign + || flags & TQLocalePrivate::BlankBeforePositive) + --num_pad_chars; + + for (int i = 0; i < num_pad_chars; ++i) + num_str.prepend(zero()); + } + + // add sign + if (negative) + num_str.prepend(minus()); + else if (flags & TQLocalePrivate::AlwaysShowSign) + num_str.prepend(plus()); + else if (flags & TQLocalePrivate::BlankBeforePositive) + num_str.prepend(' '); + + if (flags & TQLocalePrivate::CapitalEorX) + num_str = num_str.upper(); + + return num_str; +} + +TQString TQLocalePrivate::longLongToString(TQ_LLONG l, int precision, + int base, int width, + unsigned flags) const +{ + bool precision_not_specified = FALSE; + if (precision == -1) { + precision_not_specified = TRUE; + precision = 1; + } + + bool negative = l < 0; + if (base != 10) { + // these are not suported by sprintf for octal and hex + flags &= ~AlwaysShowSign; + flags &= ~BlankBeforePositive; + negative = FALSE; // neither are negative numbers + } + + TQString num_str; + if (base == 10) + num_str = qlltoa(l, base, *this); + else + num_str = qulltoa(l, base, *this); + + uint cnt_thousand_sep = 0; + if (flags & ThousandsGroup && base == 10) { + for (int i = (int)num_str.length() - 3; i > 0; i -= 3) { + num_str.insert(i, group()); + ++cnt_thousand_sep; + } + } + + for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i) + num_str.prepend(base == 10 ? zero() : TQChar('0')); + + if (flags & Alternate + && base == 8 + && (num_str.isEmpty() + || num_str[0].unicode() != '0')) + num_str.prepend('0'); + + // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds + // when precision is not specified in the format string + bool zero_padded = flags & ZeroPadded + && !(flags & LeftAdjusted) + && precision_not_specified; + + if (zero_padded) { + int num_pad_chars = width - (int)num_str.length(); + + // leave space for the sign + if (negative + || flags & AlwaysShowSign + || flags & BlankBeforePositive) + --num_pad_chars; + + // leave space for optional '0x' in hex form + if (base == 16 + && flags & Alternate + && l != 0) + num_pad_chars -= 2; + + for (int i = 0; i < num_pad_chars; ++i) + num_str.prepend(base == 10 ? zero() : TQChar('0')); + } + + if (base == 16 + && flags & Alternate + && l != 0) + num_str.prepend("0x"); + + // add sign + if (negative) + num_str.prepend(minus()); + else if (flags & AlwaysShowSign) + num_str.prepend(base == 10 ? plus() : TQChar('+')); + else if (flags & BlankBeforePositive) + num_str.prepend(' '); + + if (flags & CapitalEorX) + num_str = num_str.upper(); + + return num_str; +} + +TQString TQLocalePrivate::unsLongLongToString(TQ_ULLONG l, int precision, + int base, int width, + unsigned flags) const +{ + bool precision_not_specified = FALSE; + if (precision == -1) { + precision_not_specified = TRUE; + precision = 1; + } + + TQString num_str = qulltoa(l, base, *this); + + uint cnt_thousand_sep = 0; + if (flags & ThousandsGroup && base == 10) { + for (int i = (int)num_str.length() - 3; i > 0; i -=3) { + num_str.insert(i, group()); + ++cnt_thousand_sep; + } + } + + for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i) + num_str.prepend(base == 10 ? zero() : TQChar('0')); + + if (flags & Alternate + && base == 8 + && (num_str.isEmpty() + || num_str[0].unicode() != '0')) + num_str.prepend('0'); + + // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds + // when precision is not specified in the format string + bool zero_padded = flags & ZeroPadded + && !(flags & LeftAdjusted) + && precision_not_specified; + + if (zero_padded) { + int num_pad_chars = width - (int)num_str.length(); + + // leave space for optional '0x' in hex form + if (base == 16 + && flags & Alternate + && l != 0) + num_pad_chars -= 2; + + for (int i = 0; i < num_pad_chars; ++i) + num_str.prepend(base == 10 ? zero() : TQChar('0')); + } + + if (base == 16 + && flags & Alternate + && l != 0) + num_str.prepend("0x"); + + if (flags & CapitalEorX) + num_str = num_str.upper(); + + return num_str; +} + +static inline bool isLatin1Digit(const TQChar &c) +{ + return c.unicode() >= '0' && c.unicode() <= '9'; +} + +// Removes thousand-group separators, ie. the ',' in "1,234,567.89e-5" +bool TQLocalePrivate::removeGroupSeparators(TQString &num_str) const +{ + int group_cnt = 0; // counts number of group chars + int decpt_idx = -1; + + // Find the decimal point and check if there are any group chars + uint i = 0; + for (; i < num_str.length(); ++i) { + TQChar c = num_str.unicode()[i]; + + if (c.unicode() == ',') { + // check that there are digits before and after the separator + if (i == 0 || !isLatin1Digit(num_str.unicode()[i - 1])) + return FALSE; + if (i == num_str.length() + 1 || !isLatin1Digit(num_str.unicode()[i + 1])) + return FALSE; + ++group_cnt; + } + else if (c.unicode() == '.') { + // Fail if more than one decimal points + if (decpt_idx != -1) + return FALSE; + decpt_idx = i; + } else if (c.unicode() == 'e' || c.unicode() == 'E') { + // an 'e' or 'E' - if we have not encountered a decimal + // point, this is where it "is". + if (decpt_idx == -1) + decpt_idx = i; + } + } + + // If no group chars, we're done + if (group_cnt == 0) + return TRUE; + + // No decimal point means that it "is" at the end of the string + if (decpt_idx == -1) + decpt_idx = num_str.length(); + + i = 0; + while (i < num_str.length() && group_cnt > 0) { + TQChar c = num_str.unicode()[i]; + + if (c.unicode() == ',') { + // Don't allow group chars after the decimal point + if ((int)i > decpt_idx) + return FALSE; + + // Check that it is placed correctly relative to the decpt + if ((decpt_idx - i) % 4 != 0) + return FALSE; + + // Remove it + num_str.remove(i, 1); + + --group_cnt; + --decpt_idx; // adjust decpt_idx + } else { + // Check that we are not missing a separator + if ((int)i < decpt_idx && (decpt_idx - i) % 4 == 0) + return FALSE; + ++i; + } + } + + return TRUE; +} + +static void stripWhiteSpaceInPlace(TQString &s) +{ + uint i = 0; + while (i < s.length() && s.unicode()[i].isSpace()) + ++i; + if (i > 0) + s.remove(0, i); + + i = s.length(); + + if (i == 0) + return; + --i; + while (i > 0 && s.unicode()[i].isSpace()) + --i; + if (i + 1 < s.length()) + s.truncate(i + 1); +} + +/* + Converts a number in locale to its representation in the C locale. + Only has to guarantee that a string that is a correct representation of + a number will be converted. If junk is passed in, junk will be passed + out and the error will be detected during the actual conversion to a + number. We can't detect junk here, since we don't even know the base + of the number. +*/ +bool TQLocalePrivate::numberToCLocale(TQString &l_num, + GroupSeparatorMode group_sep_mode) const +{ + stripWhiteSpaceInPlace(l_num); + + if (l_num.isEmpty()) + return FALSE; + + for (uint idx = 0; idx < l_num.length(); ++idx) { + TQChar &c = l_num.ref(idx); + + if (isDigit(c)) + c = digitToCLocale(zero(), c); + else if (c == plus()) + c = '+'; + else if (c == minus()) + c = '-'; + else if (c == decimal()) + c = '.'; + else if (c == group()) + c = ','; + // In several languages group() is the char 0xA0, which looks like a space. + // People use a regular space instead of it and complain it doesn't work. + else if (group().unicode() == 0xA0 && c.unicode() == ' ') + c = ','; + else if (c == exponential() || c == exponential().upper()) + c = 'e'; + else if (c == list()) + c = ';'; + else if (c == percent()) + c = '%'; + else if (c.unicode() >= 'A' && c.unicode() <= 'Z') + c = c.lower(); + else if (c.unicode() >= 'a' && c.unicode() <= 'z') + ; // do nothing + else + return FALSE; + } + + if (group_sep_mode == ParseGroupSeparators + && !removeGroupSeparators(l_num)) + return FALSE; + + return TRUE; +} + +double TQLocalePrivate::stringToDouble(TQString num, + bool *ok, + GroupSeparatorMode group_sep_mode) const +{ + if (!numberToCLocale(num, group_sep_mode)) { + if (ok != 0) + *ok = FALSE; + return 0.0; + } + + if (ok != 0) + *ok = TRUE; + + if (num == "nan") + return NAN; + + if (num == "+inf" + || num == "inf") + return INFINITY; + + if (num == "-inf") + return -INFINITY; + + bool _ok; + const char *num_buff = num.latin1(); + +#ifdef QT_QLOCALE_USES_FCVT + char *endptr; + double d = strtod(num_buff, &endptr); + _ok = TRUE; +#else + const char *endptr; + double d = qstrtod(num_buff, &endptr, &_ok); +#endif + + if (!_ok || *endptr != '\0') { + if (ok != 0) + *ok = FALSE; + return 0.0; + } + else + return d; +} + +TQ_LLONG TQLocalePrivate::stringToLongLong(TQString num, int base, + bool *ok, + GroupSeparatorMode group_sep_mode) const +{ + if (!numberToCLocale(num, group_sep_mode)) { + if (ok != 0) + *ok = FALSE; + return 0; + } + + bool _ok; + const char *endptr; + const char *num_buff = num.latin1(); + TQ_LLONG l = qstrtoll(num_buff, &endptr, base, &_ok); + + if (!_ok || *endptr != '\0') { + if (ok != 0) + *ok = FALSE; + return 0; + } + + if (ok != 0) + *ok = TRUE; + return l; +} + +TQ_ULLONG TQLocalePrivate::stringToUnsLongLong(TQString num, int base, + bool *ok, + GroupSeparatorMode group_sep_mode) const +{ + if (!numberToCLocale(num, group_sep_mode)) { + if (ok != 0) + *ok = FALSE; + return 0; + } + + bool _ok; + const char *endptr; + const char *num_buff = num.latin1(); + TQ_ULLONG l = qstrtoull(num_buff, &endptr, base, &_ok); + + if (!_ok || *endptr != '\0') { + if (ok != 0) + *ok = FALSE; + return 0; + } + + if (ok != 0) + *ok = TRUE; + return l; +} + +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +// static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; +// "$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $"; + +/* + * Convert a string to an TQ_ULLONG integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +static TQ_ULLONG qstrtoull(const char *nptr, const char **endptr, int base, bool *ok) +{ + const char *s = nptr; + TQ_ULLONG acc; + unsigned char c; + TQ_ULLONG qbase, cutoff; + int neg, any, cutlim; + + if (ok != 0) + *ok = TRUE; + + /* + * See strtoq for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + if (ok != 0) + *ok = FALSE; + if (endptr != 0) + *endptr = s - 1; + return 0; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + qbase = (unsigned)base; + cutoff = (TQ_ULLONG)ULLONG_MAX / qbase; + cutlim = (TQ_ULLONG)ULLONG_MAX % qbase; + for (acc = 0, any = 0;; c = *s++) { + if (!isascii(c)) + break; + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= qbase; + acc += c; + } + } + if (any < 0) { + acc = ULLONG_MAX; + if (ok != 0) + *ok = FALSE; + } + else if (neg) + acc = (~acc) + 1; + if (endptr != 0) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + + +// "$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $"; + + +/* + * Convert a string to a TQ_LLONG integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +static TQ_LLONG qstrtoll(const char *nptr, const char **endptr, int base, bool *ok) +{ + const char *s; + TQ_ULLONG acc; + unsigned char c; + TQ_ULLONG qbase, cutoff; + int neg, any, cutlim; + + if (ok != 0) + *ok = TRUE; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for quads is + * [-9223372036854775808..9223372036854775807] and the input base + * is 10, cutoff will be set to 922337203685477580 and cutlim to + * either 7 (neg==0) or 8 (neg==1), meaning that if we have + * accumulated a value > 922337203685477580, or equal but the + * next digit is > 7 (or 8), the number is too big, and we will + * return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + qbase = (unsigned)base; + cutoff = neg ? (TQ_ULLONG)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX + : LLONG_MAX; + cutlim = cutoff % qbase; + cutoff /= qbase; + for (acc = 0, any = 0;; c = *s++) { + if (!isascii(c)) + break; + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= qbase; + acc += c; + } + } + if (any < 0) { + acc = neg ? LLONG_MIN : LLONG_MAX; + if (ok != 0) + *ok = FALSE; + } else if (neg) { + acc = (~acc) + 1; + } + if (endptr != 0) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + +#ifndef QT_QLOCALE_USES_FCVT + +/* From: NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp */ +/* $FreeBSD: src/lib/libc/stdlib/netbsd_strtod.c,v 1.2.2.2 2001/03/02 17:14:15 tegge Exp $ */ + +/* Please send bug reports to + David M. Gay + AT&T Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-2070 + U.S.A. + dmg@research.att.com or research!dmg + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define Sudden_Underflow for IEEE-format machines without gradual + * underflow (i.e., that flush to zero on underflow). + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic. + * #define Unsigned_Shifts if >> does treats its left operand as unsigned. + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision + * integer arithmetic. Whether this speeds things up or slows things + * down depends on the machine and the number being converted. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp $"); +#endif /* LIBC_SCCS and not lint */ + +/* +#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ + defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \ + defined(__powerpc__) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_MACX) || \ + defined(mips) || defined(Q_OS_AIX) || defined(Q_OS_SOLARIS) +# define IEEE_BIG_OR_LITTLE_ENDIAN 1 +#endif +*/ + +// *All* of our architectures have IEEE arithmetic, don't they? +#define IEEE_BIG_OR_LITTLE_ENDIAN 1 + +#ifdef __arm32__ +/* + * Although the CPU is little endian the FP has different + * byte and word endianness. The byte order is still little endian + * but the word order is big endian. + */ +#define IEEE_BIG_OR_LITTLE_ENDIAN +#endif + +#ifdef vax +#define VAX +#endif + +#define Long TQ_INT32 +#define ULong TQ_UINT32 + +#define MALLOC malloc +#define CONST const + +#ifdef BSD_QDTOA_DEBUG +#include +#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} +#endif + +#ifdef Unsigned_Shifts +#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; +#else +#define Sign_Extend(a,b) /*no-op*/ +#endif + +#if (defined(IEEE_BIG_OR_LITTLE_ENDIAN) + defined(VAX) + defined(IBM)) != 1 +#error Exactly one of IEEE_BIG_OR_LITTLE_ENDIAN, VAX, or IBM should be defined. +#endif + +inline ULong getWord0(const NEEDS_VOLATILE double x) +{ + const NEEDS_VOLATILE uchar *ptr = reinterpret_cast(&x); + if (ByteOrder == BigEndian) { + return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3]; + } else { + return (ptr[7]<<24) + (ptr[6]<<16) + (ptr[5]<<8) + ptr[4]; + } +} + +inline void setWord0(NEEDS_VOLATILE double *x, ULong l) +{ + NEEDS_VOLATILE uchar *ptr = reinterpret_cast(x); + if (ByteOrder == BigEndian) { + ptr[0] = (uchar)(l>>24); + ptr[1] = (uchar)(l>>16); + ptr[2] = (uchar)(l>>8); + ptr[3] = (uchar)l; + } else { + ptr[7] = (uchar)(l>>24); + ptr[6] = (uchar)(l>>16); + ptr[5] = (uchar)(l>>8); + ptr[4] = (uchar)l; + } +} + +inline ULong getWord1(const NEEDS_VOLATILE double x) +{ + const NEEDS_VOLATILE uchar *ptr = reinterpret_cast(&x); + if (ByteOrder == BigEndian) { + return (ptr[4]<<24) + (ptr[5]<<16) + (ptr[6]<<8) + ptr[7]; + } else { + return (ptr[3]<<24) + (ptr[2]<<16) + (ptr[1]<<8) + ptr[0]; + } +} +inline void setWord1(NEEDS_VOLATILE double *x, ULong l) +{ + NEEDS_VOLATILE uchar *ptr = reinterpret_cast(x); + if (ByteOrder == BigEndian) { + ptr[4] = (uchar)(l>>24); + ptr[5] = (uchar)(l>>16); + ptr[6] = (uchar)(l>>8); + ptr[7] = (uchar)l; + } else { + ptr[3] = (uchar)(l>>24); + ptr[2] = (uchar)(l>>16); + ptr[1] = (uchar)(l>>8); + ptr[0] = (uchar)l; + } +} + +static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c) +{ + + *a = (((unsigned short)b) << 16) | ((unsigned short)c); + ++a; +} + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#if defined(IEEE_BIG_OR_LITTLE_ENDIAN) +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define IEEE_Arith +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 +#define Infinite(x) (getWord0(x) == 0x7ff00000) /* sufficient test for here */ +#else +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Bias 65 +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Bias 129 +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif +#endif + +#ifndef IEEE_Arith +#define ROUND_BIASED +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) a = rnd_prod(a, b) +#define rounded_quotient(a,b) a = rnd_quot(a, b) +extern double rnd_prod(double, double), rnd_quot(double, double); +#else +#define rounded_product(a,b) a *= b +#define rounded_quotient(a,b) a /= b +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#ifndef Just_16 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#ifndef Pack_32 +#define Pack_32 +#endif +#endif + +#define Kmax 15 + +struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; + + typedef struct Bigint Bigint; + +static Bigint *Balloc(int k) +{ + int x; + Bigint *rv; + + x = 1 << k; + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)); + rv->k = k; + rv->maxwds = x; + rv->sign = rv->wds = 0; + return rv; +} + +static void Bfree(Bigint *v) +{ + free(v); +} + +#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ +y->wds*sizeof(Long) + 2*sizeof(int)) + +/* multiply by m and add a */ +static Bigint *multadd(Bigint *b, int m, int a) +{ + int i, wds; + ULong *x, y; +#ifdef Pack_32 + ULong xi, z; +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + do { +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + a; + z = (xi >> 16) * m + (y >> 16); + a = (int)(z >> 16); + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + a; + a = (int)(y >> 16); + *x++ = y & 0xffff; +#endif + } + while(++i < wds); + if (a) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = a; + b->wds = wds; + } + return b; +} + +static Bigint *s2b(CONST char *s, int nd0, int nd, ULong y9) +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; +#ifdef Pack_32 + b = Balloc(k); + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do b = multadd(b, 10, *s++ - '0'); + while(++i < nd0); + s++; + } + else + s += 10; + for(; i < nd; i++) + b = multadd(b, 10, *s++ - '0'); + return b; +} + +static int hi0bits(ULong x) +{ + int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; +} + +static int lo0bits(ULong *y) +{ + int k; + ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x & 1) + return 32; + } + *y = x; + return k; +} + +static Bigint *i2b(int i) +{ + Bigint *b; + + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; +} + +static Bigint *mult(Bigint *a, Bigint *b) +{ + Bigint *c; + int k, wa, wb, wc; + ULong carry, y, z; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; +#ifdef Pack_32 + ULong z2; +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef Pack_32 + for(; xb < xbe; xb++, xc0++) { + if ((y = *xb & 0xffff) != 0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if ((y = *xb >> 16) != 0) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#else + for(; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while(x < xae); + *xc = carry; + } + } +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; +} + +static Bigint *p5s; + +static Bigint *pow5mult(Bigint *b, int k) +{ + Bigint *b1, *p5, *p51; + int i; + static const int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3) != 0) + b = multadd(b, p05[i-1], 0); + + if (!(k >>= 2)) + return b; + if (!(p5 = p5s)) { + /* first time */ + p5 = p5s = i2b(625); + p5->next = 0; + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) + break; + if (!(p51 = p5->next)) { + p51 = p5->next = mult(p5,p5); + p51->next = 0; + } + p5 = p51; + } + return b; +} + +static Bigint *lshift(Bigint *b, int k) +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + +#ifdef Pack_32 + n = k >> 5; +#else + n = k >> 4; +#endif + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z) != 0) + ++n1; + } +#else + if (k &= 0xf) { + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) + ++n1; + } +#endif + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; +} + +static int cmp(Bigint *a, Bigint *b) +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef BSD_QDTOA_DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; +} + +static Bigint *diff(Bigint *a, Bigint *b) +{ + Bigint *c; + int i, wa, wb; + Long borrow, y; /* We need signed shifts here. */ + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef Pack_32 + Long z; +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*xa++ >> 16) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *xc++ = y & 0xffff; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *xc++ = y & 0xffff; + } +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; +} + +static double ulp(double x) +{ + Long L; + double a; + + L = (getWord0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + setWord0(&a, L); + setWord1(&a, 0); +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + setWord0(&a, 0x80000 >> L); + setWord1(&a, 0); + } + else { + setWord0(&a, 0); + L -= Exp_shift; + setWord1(&a, L >= 31 ? 1U : 1U << (31 - L)); + } + } +#endif + return a; +} + +static double b2d(Bigint *a, int *e) +{ + ULong *xa, *xa0, w, y, z; + int k; + double d; + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef BSD_QDTOA_DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + setWord0(&d, Exp_1 | y >> (Ebits - k)); + w = xa > xa0 ? *--xa : 0; + setWord1(&d, y << ((32-Ebits) + k) | w >> (Ebits - k)); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + setWord0(&d, Exp_1 | y << k | z >> (32 - k)); + y = xa > xa0 ? *--xa : 0; + setWord1(&d, z << k | y >> (32 - k)); + } + else { + setWord0(&d, Exp_1 | y); + setWord1(&d, z); + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + setWord0(&d, Exp_1 | y << k - Ebits | z >> Ebits + 16 - k); + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + setWord1(&d, z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + setWord0(&d, Exp_1 | y << k + 16 | z << k | w >> 16 - k); + y = xa > xa0 ? *--xa : 0; + setWord1(&d, w << k + 16 | y << k); +#endif + ret_d: + return d; +} + +static Bigint *d2b(double d, int *e, int *bits) +{ + Bigint *b; + int de, i, k; + ULong *x, y, z; + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + x = b->x; + + z = getWord0(d) & Frac_mask; + setWord0(&d, getWord0(d) & 0x7fffffff); /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(getWord0(d) >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if ((de = (int)(getWord0(d) >> Exp_shift)) != 0) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if ((y = getWord1(d)) != 0) { + if ((k = lo0bits(&y)) != 0) { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; + i = b->wds = (x[1] = z) ? 2 : 1; + } + else { +#ifdef BSD_QDTOA_DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + x[0] = z; + i = b->wds = 1; + k += 32; + } +#else + if (y = getWord1(d)) { + if (k = lo0bits(&y)) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef BSD_QDTOA_DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while(!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(getWord0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; +} + +static double ratio(Bigint *a, Bigint *b) +{ + double da, db; + int k, ka, kb; + + da = b2d(a, &ka); + db = b2d(b, &kb); +#ifdef Pack_32 + k = ka - kb + 32*(a->wds - b->wds); +#else + k = ka - kb + 16*(a->wds - b->wds); +#endif +#ifdef IBM + if (k > 0) { + setWord0(&da, getWord0(da) + (k >> 2)*Exp_msk1); + if (k &= 3) + da *= 1 << k; + } + else { + k = -k; + setWord0(&db, getWord0(db) + (k >> 2)*Exp_msk1); + if (k &= 3) + db *= 1 << k; + } +#else + if (k > 0) + setWord0(&da, getWord0(da) + k*Exp_msk1); + else { + k = -k; + setWord0(&db, getWord0(db) + k*Exp_msk1); + } +#endif + return da / db; +} + +static CONST double tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif +}; + +#ifdef IEEE_Arith +static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; +#define n_bigtens 5 +#else +#ifdef IBM +static CONST double bigtens[] = { 1e16, 1e32, 1e64 }; +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#define n_bigtens 3 +#else +static CONST double bigtens[] = { 1e16, 1e32 }; +static CONST double tinytens[] = { 1e-16, 1e-32 }; +#define n_bigtens 2 +#endif +#endif + +/* + The pre-release gcc3.3 shipped with SuSE 8.2 has a bug which causes + the comparison 1e-100 == 0.0 to return true. As a workaround, we + compare it to a global variable containing 0.0, which produces + correct assembler output. + + ### consider detecting the broken compilers and using the static + ### double for these, and use a #define for all working compilers +*/ +static double g_double_zero = 0.0; + +static double qstrtod(CONST char *s00, CONST char **se, bool *ok) +{ + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + CONST char *s, *s0, *s1; + double aadj, aadj1, adj, rv, rv0; + Long L; + ULong y, z; + Bigint *bb1, *bd0; + Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */ + + /* + #ifndef KR_headers + CONST char decimal_point = localeconv()->decimal_point[0]; + #else + CONST char decimal_point = '.'; + #endif */ + if (ok != 0) + *ok = TRUE; + + CONST char decimal_point = '.'; + + sign = nz0 = nz = 0; + rv = 0.; + + + for(s = s00; isspace((unsigned char) *s); s++) + ; + + if (*s == '-') { + sign = 1; + s++; + } else if (*s == '+') { + s++; + } + + if (*s == '\0') { + s = s00; + goto ret; + } + + if (*s == '0') { + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; + if (c == decimal_point) { + c = *++s; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + s = s00; + goto ret; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) + s = s00; + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + rv = y; + if (k > 9) + rv = tens[k - 9] * rv + z; + bd0 = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT + && FLT_ROUNDS == 1 +#endif + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else + /* rv = */ rounded_product(rv, tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ + e -= i; + rv *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + setWord0(&rv, getWord0(rv) - P*Exp_msk1); + /* rv = */ rounded_product(rv, tens[e]); + if ((getWord0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + setWord0(&rv, getWord0(rv) + P*Exp_msk1); +#else + /* rv = */ rounded_product(rv, tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { + /* rv = */ rounded_quotient(rv, tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ((i = e1 & 15) != 0) + rv *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: + // errno = ERANGE; + if (ok != 0) + *ok = FALSE; +#ifdef __STDC__ + rv = HUGE_VAL; +#else + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith + setWord0(&rv, Exp_mask); + setWord1(&rv, 0); +#else + setWord0(&rv, Big0); + setWord1(&rv, Big1); +#endif +#endif + if (bd0) + goto retfree; + goto ret; + } + if (e1 >>= 4) { + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + rv *= bigtens[j]; + /* The last multiplication could overflow. */ + setWord0(&rv, getWord0(rv) - P*Exp_msk1); + rv *= bigtens[j]; + if ((z = getWord0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + setWord0(&rv, Big0); + setWord1(&rv, Big1); + } + else + setWord0(&rv, getWord0(rv) + P*Exp_msk1); + } + + } + } + else if (e1 < 0) { + e1 = -e1; + if ((i = e1 & 15) != 0) + rv /= tens[i]; + if (e1 &= ~15) { + e1 >>= 4; + if (e1 >= 1 << n_bigtens) + goto undfl; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + rv *= tinytens[j]; + /* The last multiplication could underflow. */ + rv0 = rv; + rv *= tinytens[j]; + if (rv == g_double_zero) + { + rv = 2.*rv0; + rv *= tinytens[j]; + if (rv == g_double_zero) + { + undfl: + rv = 0.; + // errno = ERANGE; + if (ok != 0) + *ok = FALSE; + if (bd0) + goto retfree; + goto ret; + } + setWord0(&rv, Tiny0); + setWord1(&rv, Tiny1); + /* The refinement below will clean + * this approximation up. + */ + } + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else + i = bbe + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j = bbe + (P-Emin); + else + j = P + 1 - bbbits; +#endif + bb2 += j; + bd2 += j; + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift(bb, bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + delta = diff(bb, bd); + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask) + break; + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((getWord0(rv) & Bndry_mask1) == Bndry_mask1 + && getWord1(rv) == 0xffffffff) { + /*boundary case -- increment exponent*/ + setWord0(&rv, (getWord0(rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ); + setWord1(&rv, 0); + break; + } + } + else if (!(getWord0(rv) & Bndry_mask) && !getWord1(rv)) { + drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow + L = getWord0(rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else + if (L <= Exp_msk1) +#endif + goto undfl; + L -= Exp_msk1; +#else + L = (getWord0(rv) & Exp_mask) - Exp_msk1; +#endif + setWord0(&rv, L | Bndry_mask1); + setWord1(&rv, 0xffffffff); +#ifdef IBM + goto cont; +#else + break; +#endif + } +#ifndef ROUND_BIASED + if (!(getWord1(rv) & LSB)) + break; +#endif + if (dsign) + rv += ulp(rv); +#ifndef ROUND_BIASED + else { + rv -= ulp(rv); +#ifndef Sudden_Underflow + if (rv == g_double_zero) + goto undfl; +#endif + } +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = aadj1 = 1.; + else if (getWord1(rv) || getWord0(rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (getWord1(rv) == Tiny1 && !getWord0(rv)) + goto undfl; +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch(FLT_ROUNDS) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (FLT_ROUNDS == 0) + aadj1 += 0.5; +#endif + } + y = getWord0(rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + rv0 = rv; + setWord0(&rv, getWord0(rv) - P*Exp_msk1); + adj = aadj1 * ulp(rv); + rv += adj; + if ((getWord0(rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (getWord0(rv0) == Big0 && getWord1(rv0) == Big1) + goto ovfl; + setWord0(&rv, Big0); + setWord1(&rv, Big1); + goto cont; + } + else + setWord0(&rv, getWord0(rv) + P*Exp_msk1); + } + else { +#ifdef Sudden_Underflow + if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1) { + rv0 = rv; + setWord0(&rv, getWord0(rv) + P*Exp_msk1); + adj = aadj1 * ulp(rv); + rv += adj; +#ifdef IBM + if ((getWord0(rv) & Exp_mask) < P*Exp_msk1) +#else + if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (getWord0(rv0) == Tiny0 + && getWord1(rv0) == Tiny1) + goto undfl; + setWord0(&rv, Tiny0); + setWord1(&rv, Tiny1); + goto cont; + } + else + setWord0(&rv, getWord0(rv) - P*Exp_msk1); + } + else { + adj = aadj1 * ulp(rv); + rv += adj; + } +#else + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj >= 1.) { + aadj1 = (double)(int)(aadj + 0.5); + if (!dsign) + aadj1 = -aadj1; + } + adj = aadj1 * ulp(rv); + rv += adj; +#endif + } + z = getWord0(rv) & Exp_mask; + if (y == z) { + /* Can we stop now? */ + L = (Long) aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } + cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } + retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + ret: + if (se) + *se = (char *)s; + return sign ? -rv : rv; +} + +static int quorem(Bigint *b, Bigint *S) +{ + int n; + Long borrow, y; + ULong carry, q, ys; + ULong *bx, *bxe, *sx, *sxe; +#ifdef Pack_32 + Long z; + ULong si, zs; +#endif + + n = S->wds; +#ifdef BSD_QDTOA_DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef BSD_QDTOA_DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*bx >> 16) - (zs & 0xffff) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *bx++ = y & 0xffff; +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*bx >> 16) - (zs & 0xffff) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *bx++ = y & 0xffff; +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; +} + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + + +/* This actually sometimes returns a pointer to a string literal + cast to a char*. Do NOT try to modify the return value. */ + +static char *qdtoa ( double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp) +{ + // Some values of the floating-point control word can cause _qdtoa to crash with an underflow. + // We set a safe value here. +#ifdef Q_OS_WIN +#ifndef Q_CC_BOR + unsigned int oldbits = _control87(0, 0); +#ifndef _M_X64 //x64 does not support precition control + _control87(0x9001F, 0xFFFFF); +#else + _control87(0x9001F, _MCW_DN|_MCW_EM|_MCW_RC); +#endif //_M_X64 +#endif +#endif + +#ifdef Q_OS_LINUX + fenv_t envp; + feholdexcept(&envp); +#endif + + char *s = _qdtoa(d, mode, ndigits, decpt, sign, rve, resultp); + +#ifdef Q_OS_WIN +#ifndef Q_CC_BOR + _clear87(); +#ifndef _M_X64 + _control87(oldbits, 0xFFFFF); +#else + _control87(oldbits, _MCW_DN|_MCW_EM|_MCW_RC); +#endif //_M_X64 +#endif +#endif + +#ifdef Q_OS_LINUX + fesetenv(&envp); +#endif + + return s; +} + +static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp) +{ + /* + Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4-9 should give the same return values as 2-3, i.e., + 4 <= mode <= 9 ==> same return as mode + 2 + (mode & 1). These modes are mainly for + debugging; often they run slower but sometimes + faster than modes 2-3. + 4,5,8,9 ==> left-to-right digit generation. + 6-9 ==> don't try fast floating-point estimate + (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim0, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + try_quick; + int ilim = 0, ilim1 = 0, spec_case = 0; /* pacify gcc */ + Long L; +#ifndef Sudden_Underflow + int denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mhi, *S; + Bigint *mlo = NULL; /* pacify gcc */ + double d2; + double ds, eps; + char *s, *s0; + + if (getWord0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + setWord0(&d, getWord0(d) & ~Sign_bit); /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) + defined(VAX) +#ifdef IEEE_Arith + if ((getWord0(d) & Exp_mask) == Exp_mask) +#else + if (getWord0(d) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; + s = +#ifdef IEEE_Arith + !getWord1(d) && !(getWord0(d) & 0xfffff) ? (char*)"Infinity" : +#endif + (char*)"NaN"; + if (rve) + *rve = +#ifdef IEEE_Arith + s[3] ? s + 8 : +#endif + s + 3; + return s; + } +#endif +#ifdef IBM + d += 0; /* normalize */ +#endif + if (d == g_double_zero) + { + *decpt = 1; + s = (char*) "0"; + if (rve) + *rve = s + 1; + return s; + } + + b = d2b(d, &be, &bbits); +#ifdef Sudden_Underflow + i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if ((i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { +#endif + d2 = d; + setWord0(&d2, getWord0(d2) & Frac_mask1); + setWord0(&d2, getWord0(d2) | Exp_11); +#ifdef IBM + if (j = 11 - hi0bits(getWord0(d2) & Frac_mask)) + d2 /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? getWord0(d) << (64 - i) | getWord1(d) >> (i - 32) + : getWord1(d) << (32 - i); + d2 = x; + setWord0(&d2, getWord0(d2) - 31*Exp_msk1); /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (d < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + try_quick = 1; + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + *resultp = (char *) malloc(i + 1); + s = s0 = *resultp; + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + d2 = d; + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + d /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + d /= ds; + } + else if ((j1 = -k) != 0) { + d *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + d *= bigtens[i]; + } + } + if (k_check && d < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + d *= 10.; + ieps++; + } + eps = ieps*d + 7.; + setWord0(&eps, getWord0(eps) - (P-1)*Exp_msk1); + if (ilim == 0) { + S = mhi = 0; + d -= 5.; + if (d > eps) + goto one_digit; + if (d < -eps) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + eps = 0.5/tens[ilim-1] - eps; + for(i = 0;;) { + L = (Long)d; + d -= L; + *s++ = '0' + (int)L; + if (d < eps) + goto ret1; + if (1. - d < eps) + goto bump_up; + if (++i >= ilim) + break; + eps *= 10.; + d *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + eps *= tens[ilim-1]; + for(i = 1;; i++, d *= 10.) { + L = (Long)d; + d -= L; + *s++ = '0' + (int)L; + if (i == ilim) { + if (d > 0.5 + eps) + goto bump_up; + else if (d < 0.5 - eps) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + d = d2; + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || d <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++) { + L = (Long)(d / ds); + d -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (d < 0) { + L--; + d += ds; + } +#endif + *s++ = '0' + (int)L; + if (i == ilim) { + d += d; + if (d > ds || (d == ds && L & 1)) { + bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + if ((d *= 10.) == g_double_zero) + break; + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + if (mode < 2) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + } + else { + j = ilim - 1; + if (m5 >= j) + m5 -= j; + else { + s5 += j -= m5; + b5 += j; + m5 = 0; + } + if ((i = ilim) < 0) { + m2 -= i; + i = 0; + } + } + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if ((j = b5 - m5) != 0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + if (mode < 2) { + if (!getWord1(d) && !(getWord0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && getWord0(d) & Exp_mask +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + else + spec_case = 0; + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0) + i = 32 - i; +#else + if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && mode > 2) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && !mode && !(getWord1(d) & 1)) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || (j == 0 && !mode +#ifndef ROUND_BIASED + && !(getWord1(d) & 1) +#endif + )) { + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || (j1 == 0 && dig & 1)) + && dig++ == '9') + goto round_9_up; + } + *s++ = dig; + goto ret; + } + if (j1 > 0) { + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || (j == 0 && dig & 1)) { + roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + while(*--s == '0'); + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: + Bfree(b); + if (s == s0) { /* don't return empty string */ + *s++ = '0'; + k = 0; + } + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; +} + +#endif // QT_QLOCALE_USES_FCVT diff --git a/src/tools/tqlocale.h b/src/tools/tqlocale.h new file mode 100644 index 000000000..d3a578d1c --- /dev/null +++ b/src/tools/tqlocale.h @@ -0,0 +1,494 @@ +/**************************************************************************** +** +** Declaration of the TQLocale class +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the tools module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TQLOCALE_H +#define TQLOCALE_H + +#include "tqstring.h" + +struct TQLocalePrivate; + +class TQ_EXPORT TQLocale +{ + friend class TQString; + +public: + enum Language { + C = 1, + Abkhazian = 2, + Afan = 3, + Afar = 4, + Afrikaans = 5, + Albanian = 6, + Amharic = 7, + Arabic = 8, + Armenian = 9, + Assamese = 10, + Aymara = 11, + Azerbaijani = 12, + Bashkir = 13, + Basque = 14, + Bengali = 15, + Bhutani = 16, + Bihari = 17, + Bislama = 18, + Breton = 19, + Bulgarian = 20, + Burmese = 21, + Byelorussian = 22, + Cambodian = 23, + Catalan = 24, + Chinese = 25, + Corsican = 26, + Croatian = 27, + Czech = 28, + Danish = 29, + Dutch = 30, + English = 31, + Esperanto = 32, + Estonian = 33, + Faroese = 34, + FijiLanguage = 35, + Finnish = 36, + French = 37, + Frisian = 38, + Gaelic = 39, + Galician = 40, + Georgian = 41, + German = 42, + Greek = 43, + Greenlandic = 44, + Guarani = 45, + Gujarati = 46, + Hausa = 47, + Hebrew = 48, + Hindi = 49, + Hungarian = 50, + Icelandic = 51, + Indonesian = 52, + Interlingua = 53, + Interlingue = 54, + Inuktitut = 55, + Inupiak = 56, + Irish = 57, + Italian = 58, + Japanese = 59, + Javanese = 60, + Kannada = 61, + Kashmiri = 62, + Kazakh = 63, + Kinyarwanda = 64, + Kirghiz = 65, + Korean = 66, + Kurdish = 67, + Kurundi = 68, + Laothian = 69, + Latin = 70, + Latvian = 71, + Lingala = 72, + Lithuanian = 73, + Macedonian = 74, + Malagasy = 75, + Malay = 76, + Malayalam = 77, + Maltese = 78, + Maori = 79, + Marathi = 80, + Moldavian = 81, + Mongolian = 82, + NauruLanguage = 83, + Nepali = 84, + Norwegian = 85, + Occitan = 86, + Oriya = 87, + Pashto = 88, + Persian = 89, + Polish = 90, + Portuguese = 91, + Punjabi = 92, + Quechua = 93, + RhaetoRomance = 94, + Romanian = 95, + Russian = 96, + Samoan = 97, + Sangho = 98, + Sanskrit = 99, + Serbian = 100, + SerboCroatian = 101, + Sesotho = 102, + Setswana = 103, + Shona = 104, + Sindhi = 105, + Singhalese = 106, + Siswati = 107, + Slovak = 108, + Slovenian = 109, + Somali = 110, + Spanish = 111, + Sundanese = 112, + Swahili = 113, + Swedish = 114, + Tagalog = 115, + Tajik = 116, + Tamil = 117, + Tatar = 118, + Telugu = 119, + Thai = 120, + Tibetan = 121, + Tigrinya = 122, + TongaLanguage = 123, + Tsonga = 124, + Turkish = 125, + Turkmen = 126, + Twi = 127, + Uigur = 128, + Ukrainian = 129, + Urdu = 130, + Uzbek = 131, + Vietnamese = 132, + Volapuk = 133, + Welsh = 134, + Wolof = 135, + Xhosa = 136, + Yiddish = 137, + Yoruba = 138, + Zhuang = 139, + Zulu = 140, + LastLanguage = Zulu + }; + + enum Country { + AnyCountry = 0, + Afghanistan = 1, + Albania = 2, + Algeria = 3, + AmericanSamoa = 4, + Andorra = 5, + Angola = 6, + Anguilla = 7, + Antarctica = 8, + AntiguaAndBarbuda = 9, + Argentina = 10, + Armenia = 11, + Aruba = 12, + Australia = 13, + Austria = 14, + Azerbaijan = 15, + Bahamas = 16, + Bahrain = 17, + Bangladesh = 18, + Barbados = 19, + Belarus = 20, + Belgium = 21, + Belize = 22, + Benin = 23, + Bermuda = 24, + Bhutan = 25, + Bolivia = 26, + BosniaAndHerzegowina = 27, + Botswana = 28, + BouvetIsland = 29, + Brazil = 30, + BritishIndianOceanTerritory = 31, + BruneiDarussalam = 32, + Bulgaria = 33, + BurkinaFaso = 34, + Burundi = 35, + Cambodia = 36, + Cameroon = 37, + Canada = 38, + CapeVerde = 39, + CaymanIslands = 40, + CentralAfricanRepublic = 41, + Chad = 42, + Chile = 43, + China = 44, + ChristmasIsland = 45, + CocosIslands = 46, + Colombia = 47, + Comoros = 48, + DemocraticRepublicOfCongo = 49, + PeoplesRepublicOfCongo = 50, + CookIslands = 51, + CostaRica = 52, + IvoryCoast = 53, + Croatia = 54, + Cuba = 55, + Cyprus = 56, + CzechRepublic = 57, + Denmark = 58, + Djibouti = 59, + Dominica = 60, + DominicanRepublic = 61, + EastTimor = 62, + Ecuador = 63, + Egypt = 64, + ElSalvador = 65, + EquatorialGuinea = 66, + Eritrea = 67, + Estonia = 68, + Ethiopia = 69, + FalklandIslands = 70, + FaroeIslands = 71, + FijiCountry = 72, + Finland = 73, + France = 74, + MetropolitanFrance = 75, + FrenchGuiana = 76, + FrenchPolynesia = 77, + FrenchSouthernTerritories = 78, + Gabon = 79, + Gambia = 80, + Georgia = 81, + Germany = 82, + Ghana = 83, + Gibraltar = 84, + Greece = 85, + Greenland = 86, + Grenada = 87, + Guadeloupe = 88, + Guam = 89, + Guatemala = 90, + Guinea = 91, + GuineaBissau = 92, + Guyana = 93, + Haiti = 94, + HeardAndMcDonaldIslands = 95, + Honduras = 96, + HongKong = 97, + Hungary = 98, + Iceland = 99, + India = 100, + Indonesia = 101, + Iran = 102, + Iraq = 103, + Ireland = 104, + Israel = 105, + Italy = 106, + Jamaica = 107, + Japan = 108, + Jordan = 109, + Kazakhstan = 110, + Kenya = 111, + Kiribati = 112, + DemocraticRepublicOfKorea = 113, + RepublicOfKorea = 114, + Kuwait = 115, + Kyrgyzstan = 116, + Lao = 117, + Latvia = 118, + Lebanon = 119, + Lesotho = 120, + Liberia = 121, + LibyanArabJamahiriya = 122, + Liechtenstein = 123, + Lithuania = 124, + Luxembourg = 125, + Macau = 126, + Macedonia = 127, + Madagascar = 128, + Malawi = 129, + Malaysia = 130, + Maldives = 131, + Mali = 132, + Malta = 133, + MarshallIslands = 134, + Martinique = 135, + Mauritania = 136, + Mauritius = 137, + Mayotte = 138, + Mexico = 139, + Micronesia = 140, + Moldova = 141, + Monaco = 142, + Mongolia = 143, + Montserrat = 144, + Morocco = 145, + Mozambique = 146, + Myanmar = 147, + Namibia = 148, + NauruCountry = 149, + Nepal = 150, + Netherlands = 151, + NetherlandsAntilles = 152, + NewCaledonia = 153, + NewZealand = 154, + Nicaragua = 155, + Niger = 156, + Nigeria = 157, + Niue = 158, + NorfolkIsland = 159, + NorthernMarianaIslands = 160, + Norway = 161, + Oman = 162, + Pakistan = 163, + Palau = 164, + PalestinianTerritory = 165, + Panama = 166, + PapuaNewGuinea = 167, + Paraguay = 168, + Peru = 169, + Philippines = 170, + Pitcairn = 171, + Poland = 172, + Portugal = 173, + PuertoRico = 174, + Qatar = 175, + Reunion = 176, + Romania = 177, + RussianFederation = 178, + Rwanda = 179, + SaintKittsAndNevis = 180, + StLucia = 181, + StVincentAndTheGrenadines = 182, + Samoa = 183, + SanMarino = 184, + SaoTomeAndPrincipe = 185, + SaudiArabia = 186, + Senegal = 187, + Seychelles = 188, + SierraLeone = 189, + Singapore = 190, + Slovakia = 191, + Slovenia = 192, + SolomonIslands = 193, + Somalia = 194, + SouthAfrica = 195, + SouthGeorgiaAndTheSouthSandwichIslands = 196, + Spain = 197, + SriLanka = 198, + StHelena = 199, + StPierreAndMiquelon = 200, + Sudan = 201, + Suriname = 202, + SvalbardAndJanMayenIslands = 203, + Swaziland = 204, + Sweden = 205, + Switzerland = 206, + SyrianArabRepublic = 207, + Taiwan = 208, + Tajikistan = 209, + Tanzania = 210, + Thailand = 211, + Togo = 212, + Tokelau = 213, + TongaCountry = 214, + TrinidadAndTobago = 215, + Tunisia = 216, + Turkey = 217, + Turkmenistan = 218, + TurksAndCaicosIslands = 219, + Tuvalu = 220, + Uganda = 221, + Ukraine = 222, + UnitedArabEmirates = 223, + UnitedKingdom = 224, + UnitedStates = 225, + UnitedStatesMinorOutlyingIslands = 226, + Uruguay = 227, + Uzbekistan = 228, + Vanuatu = 229, + VaticanCityState = 230, + Venezuela = 231, + VietNam = 232, + BritishVirginIslands = 233, + USVirginIslands = 234, + WallisAndFutunaIslands = 235, + WesternSahara = 236, + Yemen = 237, + Yugoslavia = 238, + Zambia = 239, + Zimbabwe = 240, + LastCountry = Zimbabwe + }; + + TQLocale(); + TQLocale(const TQString &name); + TQLocale(Language language, Country country = AnyCountry); + TQLocale(const TQLocale &other); + + TQLocale &operator=(const TQLocale &other); + + Language language() const; + Country country() const; + TQString name() const; + + short toShort(const TQString &s, bool *ok = 0) const; + ushort toUShort(const TQString &s, bool *ok = 0) const; + int toInt(const TQString &s, bool *ok = 0) const; + uint toUInt(const TQString &s, bool *ok = 0) const; + TQ_LONG toLong(const TQString &s, bool *ok = 0) const; + TQ_ULONG toULong(const TQString &s, bool *ok = 0) const; + TQ_LLONG toLongLong(const TQString &s, bool *ok = 0) const; + TQ_ULLONG toULongLong(const TQString &s, bool *ok = 0) const; + float toFloat(const TQString &s, bool *ok = 0) const; + double toDouble(const TQString &s, bool *ok = 0) const; + + TQString toString(short i) const + { return toString((TQ_LLONG)i); } + TQString toString(ushort i) const + { return toString((TQ_ULLONG)i); } + TQString toString(int i) const + { return toString((TQ_LLONG)i); } + TQString toString(uint i) const + { return toString((TQ_ULLONG)i); } +#if !defined(Q_OS_WIN64) + TQString toString(TQ_LONG i) const + { return toString((TQ_LLONG)i); } + TQString toString(TQ_ULONG i) const + { return toString((TQ_ULLONG)i); } +#endif + TQString toString(TQ_LLONG i) const; + TQString toString(TQ_ULLONG i) const; + TQString toString(float i, char f = 'g', int prec = 6) const + { return toString((double) i, f, prec); } + TQString toString(double i, char f = 'g', int prec = 6) const; + + static TQString languageToString(Language language); + static TQString countryToString(Country country); + static void setDefault(const TQLocale &locale); + + static TQLocale c() { return TQLocale(C); } + static TQLocale system(); + +private: + const TQLocalePrivate *d; + static const TQLocalePrivate *default_d; +}; + +#endif diff --git a/src/tools/tqlocale_p.h b/src/tools/tqlocale_p.h new file mode 100644 index 000000000..8d562d22c --- /dev/null +++ b/src/tools/tqlocale_p.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Declaration of the TQLocalePrivate class +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TQLOCALE_P_H +#define TQLOCALE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the TQt API. It exists for the convenience +// of internal files. This header file may change from version to version +// without notice, or even be removed. +// +// We mean it. +// +// + +#include + +struct TQLocalePrivate +{ +public: + const TQChar &decimal() const { return (TQChar&)m_decimal; } + const TQChar &group() const { return (TQChar&)m_group; } + const TQChar &list() const { return (TQChar&)m_list; } + const TQChar &percent() const { return (TQChar&)m_percent; } + const TQChar &zero() const { return (TQChar&)m_zero; } + TQChar plus() const { return TQChar('+'); } + const TQChar &minus() const { return (TQChar&)m_minus; } + const TQChar &exponential() const { return (TQChar&)m_exponential; } + TQString infinity() const; + TQString nan() const; + + TQ_UINT32 languageId() const { return m_language_id; } + TQ_UINT32 countryId() const { return m_country_id; } + + bool isDigit(TQChar d) const; + + enum GroupSeparatorMode { + FailOnGroupSeparators, + ParseGroupSeparators + }; + + enum DoubleForm { + DFExponent = 0, // %e or %E + DFDecimal, // %f or %F + DFSignificantDigits, // %g or %G + _DFMax = DFSignificantDigits + }; + + enum Flags { + NoFlags = 0, + + // These correspond to the options in a printf format string + Alternate = 0x01, + ZeroPadded = 0x02, + LeftAdjusted = 0x04, + BlankBeforePositive = 0x08, + AlwaysShowSign = 0x10, + ThousandsGroup = 0x20, + CapitalEorX = 0x40 // %x, %e, %f, %g vs. %X, %E, %F, %G + }; + + TQString doubleToString(double d, + int precision = -1, + DoubleForm form = DFSignificantDigits, + int width = -1, + unsigned flags = NoFlags) const; + TQString longLongToString(TQ_LLONG l, int precision = -1, + int base = 10, + int width = -1, + unsigned flags = NoFlags) const; + TQString unsLongLongToString(TQ_ULLONG l, int precision = -1, + int base = 10, + int width = -1, + unsigned flags = NoFlags) const; + double stringToDouble(TQString num, bool *ok, GroupSeparatorMode group_sep_mode) const; + TQ_LLONG stringToLongLong(TQString num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const; + TQ_ULLONG stringToUnsLongLong(TQString num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const; + bool removeGroupSeparators(TQString &num_str) const; + bool numberToCLocale(TQString &locale_num, GroupSeparatorMode group_sep_mode) const; + + TQ_UINT32 m_language_id, m_country_id; + + TQ_UINT16 m_decimal, m_group, m_list, m_percent, + m_zero, m_minus, m_exponential; + + static const TQString m_infinity; + static const TQString m_nan; + static const TQChar m_plus; + + static const char *systemLocaleName(); +}; + +#endif diff --git a/src/tools/tqstring.cpp b/src/tools/tqstring.cpp index 58a377cd7..546069d48 100644 --- a/src/tools/tqstring.cpp +++ b/src/tools/tqstring.cpp @@ -56,8 +56,8 @@ #ifndef TQT_NO_TEXTCODEC #include "tqtextcodec.h" #endif -#include "ntqlocale.h" -#include "qlocale_p.h" +#include "tqlocale.h" +#include "tqlocale_p.h" #include "qunicodetables_p.h" #include diff --git a/src/widgets/ntqlabel.h b/src/widgets/ntqlabel.h deleted file mode 100644 index f8d728807..000000000 --- a/src/widgets/ntqlabel.h +++ /dev/null @@ -1,174 +0,0 @@ -/********************************************************************** -** -** Definition of TQLabel widget class -** -** Created : 941215 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the widgets module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#ifndef TQLABEL_H -#define TQLABEL_H - -#ifndef QT_H -#include "ntqframe.h" -#endif // QT_H - -#ifndef TQT_NO_LABEL - -class TQSimpleRichText; -class TQLabelPrivate; - -class TQ_EXPORT TQLabel : public TQFrame -{ - TQ_OBJECT - TQ_PROPERTY( TQString text READ text WRITE setText ) - TQ_PROPERTY( TextFormat textFormat READ textFormat WRITE setTextFormat ) - TQ_PROPERTY( TQPixmap pixmap READ pixmap WRITE setPixmap ) - TQ_PROPERTY( bool scaledContents READ hasScaledContents WRITE setScaledContents ) - TQ_PROPERTY( Alignment alignment READ alignment WRITE setAlignment ) - TQ_PROPERTY( int indent READ indent WRITE setIndent ) - TQ_OVERRIDE( BackgroundMode backgroundMode DESIGNABLE true) - -public: - TQLabel( TQWidget *parent, const char* name=0, WFlags f=0 ); - TQLabel( const TQString &text, TQWidget *parent, const char* name=0, - WFlags f=0 ); - TQLabel( TQWidget *buddy, const TQString &, - TQWidget *parent, const char* name=0, WFlags f=0 ); - ~TQLabel(); - - TQString text() const { return ltext; } - TQPixmap *pixmap() const { return lpixmap; } -#ifndef TQT_NO_PICTURE - TQPicture *picture() const { return lpicture; } -#endif -#ifndef TQT_NO_MOVIE - TQMovie *movie() const; -#endif - - TextFormat textFormat() const; - void setTextFormat( TextFormat ); - - int alignment() const { return align; } - virtual void setAlignment( int ); - int indent() const { return extraMargin; } - void setIndent( int ); - - bool autoResize() const { return autoresize; } - virtual void setAutoResize( bool ); -#ifndef TQT_NO_IMAGE_SMOOTHSCALE - bool hasScaledContents() const; - void setScaledContents( bool ); -#endif - TQSize sizeHint() const; - TQSize minimumSizeHint() const; -#ifndef TQT_NO_ACCEL - virtual void setBuddy( TQWidget * ); - TQWidget *buddy() const; -#endif - int heightForWidth(int) const; - - void setFont( const TQFont &f ); - -public slots: - virtual void setText( const TQString &); - virtual void setPixmap( const TQPixmap & ); -#ifndef TQT_NO_PICTURE - virtual void setPicture( const TQPicture & ); -#endif -#ifndef TQT_NO_MOVIE - virtual void setMovie( const TQMovie & ); -#endif - virtual void setNum( int ); - virtual void setNum( double ); - void clear(); - -protected: - void drawContents( TQPainter * ); - void fontChange( const TQFont & ); - void resizeEvent( TQResizeEvent* ); - -private slots: -#ifndef TQT_NO_ACCEL - void acceleratorSlot(); - void buddyDied(); -#endif -#ifndef TQT_NO_MOVIE - void movieUpdated(const TQRect&); - void movieResized(const TQSize&); -#endif - -private: - void init(); - void clearContents(); - void updateLabel( TQSize oldSizeHint ); - TQSize sizeForWidth( int w ) const; - TQString ltext; - TQPixmap *lpixmap; -#ifndef TQT_NO_PICTURE - TQPicture *lpicture; -#endif -#ifndef TQT_NO_MOVIE - TQMovie * lmovie; -#endif -#ifndef TQT_NO_ACCEL - TQWidget * lbuddy; -#endif - ushort align; - short extraMargin; - uint autoresize:1; - uint scaledcontents :1; - TextFormat textformat; -#ifndef TQT_NO_RICHTEXT - TQSimpleRichText* doc; -#endif -#ifndef TQT_NO_ACCEL - TQAccel * accel; -#endif - TQLabelPrivate* d; - - friend class TQTipLabel; - -private: // Disabled copy constructor and operator= -#if defined(TQ_DISABLE_COPY) - TQLabel( const TQLabel & ); - TQLabel &operator=( const TQLabel & ); -#endif -}; - - -#endif // TQT_NO_LABEL - -#endif // TQLABEL_H diff --git a/src/widgets/ntqsyntaxhighlighter.h b/src/widgets/ntqsyntaxhighlighter.h deleted file mode 100644 index 81556553e..000000000 --- a/src/widgets/ntqsyntaxhighlighter.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Definition of the TQSyntaxHighlighter class -** -** Created : 022407 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the widgets module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#ifndef TQSYNTAXHIGHLIGHTER_H -#define TQSYNTAXHIGHLIGHTER_H - -#ifndef QT_H -#include "tqfont.h" -#include "tqcolor.h" -#include "tqstring.h" -#endif // QT_H - -class TQTextEdit; -class TQSyntaxHighlighterInternal; -class TQSyntaxHighlighterPrivate; -class TQTextParagraph; - -class TQ_EXPORT TQSyntaxHighlighter : public TQt -{ - friend class TQSyntaxHighlighterInternal; - -public: - TQSyntaxHighlighter( TQTextEdit *textEdit ); - virtual ~TQSyntaxHighlighter(); - - virtual int highlightParagraph( const TQString &text, int endStateOfLastPara ) = 0; - - void setFormat( int start, int count, const TQFont &font, const TQColor &color ); - void setFormat( int start, int count, const TQColor &color ); - void setFormat( int start, int count, const TQFont &font ); - TQTextEdit *textEdit() const { return edit; } - - void rehighlight(); - - int currentParagraph() const; - -private: - TQTextParagraph *para; - TQTextEdit *edit; - TQSyntaxHighlighterPrivate *d; - -}; - -#endif diff --git a/src/widgets/ntqwhatsthis.h b/src/widgets/ntqwhatsthis.h deleted file mode 100644 index 66b4b3c90..000000000 --- a/src/widgets/ntqwhatsthis.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Definition of TQWhatsThis class -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the widgets module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#ifndef TQWHATSTHIS_H -#define TQWHATSTHIS_H - -#ifndef QT_H -#include "tqobject.h" -#endif // QT_H - -#ifndef TQT_NO_WHATSTHIS - -#include "ntqcursor.h" - -class TQToolButton; -class TQPopupMenu; -class TQStyleSheet; - -class TQ_EXPORT TQWhatsThis: public TQt -{ -public: - TQWhatsThis( TQWidget *); - virtual ~TQWhatsThis(); - - virtual TQString text( const TQPoint & ); - virtual bool clicked( const TQString& href ); - - // the common static functions - static void setFont( const TQFont &font ); - - static void add( TQWidget *, const TQString &); - static void remove( TQWidget * ); - static TQString textFor( TQWidget *, const TQPoint & pos = TQPoint(), bool includeParents = FALSE ); - - static TQToolButton * whatsThisButton( TQWidget * parent ); - - static void enterWhatsThisMode(); - static bool inWhatsThisMode(); - static void leaveWhatsThisMode( const TQString& = TQString::null, const TQPoint& pos = TQCursor::pos(), TQWidget* w = 0 ); - - static void display( const TQString& text, const TQPoint& pos = TQCursor::pos(), TQWidget* w = 0 ); -}; - -#endif // TQT_NO_WHATSTHIS - -#endif // TQWHATSTHIS_H diff --git a/src/widgets/qlabel.cpp b/src/widgets/qlabel.cpp deleted file mode 100644 index 7f2c5cbae..000000000 --- a/src/widgets/qlabel.cpp +++ /dev/null @@ -1,1191 +0,0 @@ -/********************************************************************** -** -** Implementation of TQLabel widget class -** -** Created : 941215 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the widgets module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#include "ntqlabel.h" -#ifndef TQT_NO_LABEL -#include "tqpainter.h" -#include "ntqdrawutil.h" -#include "ntqaccel.h" -#include "tqmovie.h" -#include "tqimage.h" -#include "tqbitmap.h" -#include "tqpicture.h" -#include "ntqapplication.h" -#include "ntqsimplerichtext.h" -#include "tqstylesheet.h" -#include "tqstyle.h" - -class TQLabelPrivate -{ -public: - TQLabelPrivate() - :img(0), pix(0), valid_hints( -1 ) - {} - TQImage* img; // for scaled contents - TQPixmap* pix; // for scaled contents - TQSize sh; - TQSize msh; - int valid_hints; // stores the frameWidth() for the stored size hint, -1 otherwise -}; - - -/*! - \class TQLabel ntqlabel.h - \brief The TQLabel widget provides a text or image display. - - \ingroup basic - \ingroup text - \mainclass - - TQLabel is used for displaying text or an image. No user - interaction functionality is provided. The visual appearance of - the label can be configured in various ways, and it can be used - for specifying a focus accelerator key for another widget. - - A TQLabel can contain any of the following content types: - \table - \header \i Content \i Setting - \row \i Plain text - \i Pass a TQString to setText(). - \row \i Rich text - \i Pass a TQString that contains rich text to setText(). - \row \i A pixmap - \i Pass a TQPixmap to setPixmap(). - \row \i A movie - \i Pass a TQMovie to setMovie(). - \row \i A number - \i Pass an \e int or a \e double to setNum(), which converts - the number to plain text. - \row \i Nothing - \i The same as an empty plain text. This is the default. Set - by clear(). - \endtable - - When the content is changed using any of these functions, any - previous content is cleared. - - The look of a TQLabel can be tuned in several ways. All the - settings of TQFrame are available for specifying a widget frame. - The positioning of the content within the TQLabel widget area can - be tuned with setAlignment() and setIndent(). For example, this - code sets up a sunken panel with a two-line text in the bottom - right corner (both lines being flush with the right side of the - label): - \code - TQLabel *label = new TQLabel( this ); - label->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); - label->setText( "first line\nsecond line" ); - label->setAlignment( AlignBottom | AlignRight ); - \endcode - - A TQLabel is often used as a label for an interactive widget. For - this use TQLabel provides a useful mechanism for adding an - accelerator key (see TQAccel) that will set the keyboard focus to - the other widget (called the TQLabel's "buddy"). For example: - \code - TQLineEdit* phoneEdit = new TQLineEdit( this, "phoneEdit" ); - TQLabel* phoneLabel = new TQLabel( phoneEdit, "&Phone:", this, "phoneLabel" ); - \endcode - - In this example, keyboard focus is transferred to the label's - buddy (the TQLineEdit) when the user presses Alt+P. You can - also use the setBuddy() function to accomplish the same thing. - - - - \sa TQLineEdit, TQTextEdit, TQPixmap, TQMovie, - \link guibooks.html#fowler GUI Design Handbook: Label\endlink -*/ - -/*! - \fn TQPicture * TQLabel::picture() const - - Returns the label's picture or 0 if the label doesn't have a - picture. -*/ - - -/*! - Constructs an empty label. - - The \a parent, \a name and widget flag \a f, arguments are passed - to the TQFrame constructor. - - \sa setAlignment(), setFrameStyle(), setIndent() -*/ - -TQLabel::TQLabel( TQWidget *parent, const char *name, WFlags f ) - : TQFrame( parent, name, f | WMouseNoMask ) -{ - init(); -} - - -/*! - Constructs a label that displays the text, \a text. - - The \a parent, \a name and widget flag \a f, arguments are passed - to the TQFrame constructor. - - \sa setText(), setAlignment(), setFrameStyle(), setIndent() -*/ - -TQLabel::TQLabel( const TQString &text, TQWidget *parent, const char *name, - WFlags f ) - : TQFrame( parent, name, f | WMouseNoMask ) -{ - init(); - setText( text ); -} - - -/*! - Constructs a label that displays the text \a text. The label has a - buddy widget, \a buddy. - - If the \a text contains an underlined letter (a letter preceded by - an ampersand, \&), and the text is in plain text format, when the - user presses Alt+ the underlined letter, focus is passed to the - buddy widget. - - The \a parent, \a name and widget flag, \a f, arguments are passed - to the TQFrame constructor. - - \sa setText(), setBuddy(), setAlignment(), setFrameStyle(), - setIndent() -*/ -TQLabel::TQLabel( TQWidget *buddy, const TQString &text, - TQWidget *parent, const char *name, WFlags f ) - : TQFrame( parent, name, f | WMouseNoMask ) -{ - init(); -#ifndef TQT_NO_ACCEL - setBuddy( buddy ); -#endif - setText( text ); -} - -/*! - Destroys the label. -*/ - -TQLabel::~TQLabel() -{ - clearContents(); - delete d; -} - - -void TQLabel::init() -{ - lpixmap = 0; -#ifndef TQT_NO_MOVIE - lmovie = 0; -#endif -#ifndef TQT_NO_ACCEL - lbuddy = 0; - accel = 0; -#endif - lpixmap = 0; -#ifndef TQT_NO_PICTURE - lpicture = 0; -#endif - align = AlignAuto | AlignVCenter | ExpandTabs; - extraMargin = -1; - autoresize = FALSE; - scaledcontents = FALSE; - textformat = TQt::AutoText; -#ifndef TQT_NO_RICHTEXT - doc = 0; -#endif - - setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) ); - d = new TQLabelPrivate; -} - - -/*! - \property TQLabel::text - \brief the label's text - - If no text has been set this will return an empty string. Setting - the text clears any previous content, unless they are the same. - - The text will be interpreted either as a plain text or as a rich - text, depending on the text format setting; see setTextFormat(). - The default setting is \c AutoText, i.e. TQLabel will try to - auto-detect the format of the text set. - - If the text is interpreted as a plain text and a buddy has been - set, the buddy accelerator key is updated from the new text. - - The label resizes itself if auto-resizing is enabled. - - Note that Qlabel is well-suited to display small rich text - documents, i.e. those small documents that get their document - specific settings (font, text color, link color) from the label's - palette and font properties. For large documents, use TQTextEdit - in read-only mode instead. TQTextEdit will flicker less on resize - and can also provide a scrollbar when necessary. - - \sa text, setTextFormat(), setBuddy(), alignment -*/ - -void TQLabel::setText( const TQString &text ) -{ - if ( ltext == text ) - return; - TQSize osh = sizeHint(); -#ifndef TQT_NO_RICHTEXT - bool hadRichtext = doc != 0; -#endif - clearContents(); - ltext = text; -#ifndef TQT_NO_RICHTEXT - bool useRichText = (textformat == RichText || - ( ( textformat == AutoText ) && TQStyleSheet::mightBeRichText(ltext) ) ); -#else - bool useRichText = TRUE; -#endif -#ifndef TQT_NO_ACCEL - // ### Setting accelerators for rich text labels will not work. - // Eg. >Hello will return ALT+G which is clearly - // not intended. - if ( !useRichText ) { - int p = TQAccel::shortcutKey( ltext ); - if ( p ) { - if ( !accel ) - accel = new TQAccel( this, "accel label accel" ); - accel->connectItem( accel->insertItem( p ), - this, TQ_SLOT(acceleratorSlot()) ); - } - } -#endif -#ifndef TQT_NO_RICHTEXT - if ( useRichText ) { - if ( !hadRichtext ) - align |= WordBreak; - TQString t = ltext; - if ( align & AlignRight ) - t.prepend( "
"); - else if ( align & AlignHCenter ) - t.prepend( "
"); - if ( (align & WordBreak) == 0 ) - t.prepend( "" ); - doc = new TQSimpleRichText( t, font() ); - } -#endif - - updateLabel( osh ); -} - - -/*! - Clears any label contents. Equivalent to setText( "" ). -*/ - -void TQLabel::clear() -{ - setText( TQString::fromLatin1("") ); -} - -/*! - \property TQLabel::pixmap - \brief the label's pixmap - - If no pixmap has been set this will return an invalid pixmap. - - Setting the pixmap clears any previous content, and resizes the - label if \l TQLabel::autoResize() is TRUE. The buddy accelerator, - if any, is disabled. -*/ -void TQLabel::setPixmap( const TQPixmap &pixmap ) -{ - TQSize osh = sizeHint(); - - if ( !lpixmap || lpixmap->serialNumber() != pixmap.serialNumber() ) { - clearContents(); - lpixmap = new TQPixmap( pixmap ); - } - - if ( lpixmap->depth() == 1 && !lpixmap->mask() ) - lpixmap->setMask( *((TQBitmap *)lpixmap) ); - - updateLabel( osh ); -} - -#ifndef TQT_NO_PICTURE -/*! - Sets the label contents to \a picture. Any previous content is - cleared. - - The buddy accelerator, if any, is disabled. - - \sa picture(), setBuddy() -*/ - -void TQLabel::setPicture( const TQPicture &picture ) -{ - TQSize osh = sizeHint(); - clearContents(); - lpicture = new TQPicture( picture ); - - updateLabel( osh ); -} -#endif // TQT_NO_PICTURE - -/*! - Sets the label contents to plain text containing the textual - representation of integer \a num. Any previous content is cleared. - Does nothing if the integer's string representation is the same as - the current contents of the label. - - The buddy accelerator, if any, is disabled. - - The label resizes itself if auto-resizing is enabled. - - \sa setText(), TQString::setNum(), setBuddy() -*/ - -void TQLabel::setNum( int num ) -{ - TQString str; - str.setNum( num ); - setText( str ); -} - -/*! - \overload - - Sets the label contents to plain text containing the textual - representation of double \a num. Any previous content is cleared. - Does nothing if the double's string representation is the same as - the current contents of the label. - - The buddy accelerator, if any, is disabled. - - The label resizes itself if auto-resizing is enabled. - - \sa setText(), TQString::setNum(), setBuddy() -*/ - -void TQLabel::setNum( double num ) -{ - TQString str; - str.setNum( num ); - setText( str ); -} - -/*! - \property TQLabel::alignment - \brief the alignment of the label's contents - - The alignment is a bitwise OR of \c TQt::AlignmentFlags and \c - TQt::TextFlags values. The \c ExpandTabs, \c SingleLine and \c - ShowPrefix flags apply only if the label contains plain text; - otherwise they are ignored. The \c DontClip flag is always - ignored. \c WordBreak applies to both rich text and plain text - labels. The \c BreakAnywhere flag is not supported in TQLabel. - - If the label has a buddy, the \c ShowPrefix flag is forced to - TRUE. - - The default alignment is \c{AlignAuto | AlignVCenter | ExpandTabs} - if the label doesn't have a buddy and \c{AlignAuto | AlignVCenter - | ExpandTabs | ShowPrefix} if the label has a buddy. If the label - contains rich text, additionally \c WordBreak is turned on. - - \sa TQt::AlignmentFlags, alignment, setBuddy(), text -*/ - -void TQLabel::setAlignment( int alignment ) -{ - if ( alignment == align ) - return; - TQSize osh = sizeHint(); -#ifndef TQT_NO_ACCEL - if ( lbuddy ) - align = alignment | ShowPrefix; - else -#endif - align = alignment; - -#ifndef TQT_NO_RICHTEXT - TQString t = ltext; - if ( !t.isNull() ) { - ltext = TQString::null; - setText( t ); - } -#endif - - updateLabel( osh ); -} - - -/*! - \property TQLabel::indent - \brief the label's text indent in pixels - - If a label displays text, the indent applies to the left edge if - alignment() is \c AlignLeft, to the right edge if alignment() is - \c AlignRight, to the top edge if alignment() is \c AlignTop, and - to to the bottom edge if alignment() is \c AlignBottom. - - If indent is negative, or if no indent has been set, the label - computes the effective indent as follows: If frameWidth() is 0, - the effective indent becomes 0. If frameWidth() is greater than 0, - the effective indent becomes half the width of the "x" character - of the widget's current font(). - - \sa alignment, frameWidth(), font() -*/ - -void TQLabel::setIndent( int indent ) -{ - extraMargin = indent; - updateLabel( TQSize( -1, -1 ) ); -} - - -/*! - \fn bool TQLabel::autoResize() const - - \obsolete - - Returns TRUE if auto-resizing is enabled, or FALSE if auto-resizing - is disabled. - - Auto-resizing is disabled by default. - - \sa setAutoResize() -*/ - -/*! \obsolete - Enables auto-resizing if \a enable is TRUE, or disables it if \a - enable is FALSE. - - When auto-resizing is enabled the label will resize itself to fit - the contents whenever the contents change. The top-left corner is - not moved. This is useful for TQLabel widgets that are not managed by - a TQLayout (e.g., top-level widgets). - - Auto-resizing is disabled by default. - - \sa autoResize(), adjustSize(), sizeHint() -*/ - -void TQLabel::setAutoResize( bool enable ) -{ - if ( (bool)autoresize != enable ) { - autoresize = enable; - if ( autoresize ) - adjustSize(); // calls resize which repaints - } -} - - - -/*! - Returns the size that will be used if the width of the label is \a - w. If \a w is -1, the sizeHint() is returned. -*/ - -TQSize TQLabel::sizeForWidth( int w ) const -{ - TQRect br; - TQPixmap *pix = pixmap(); -#ifndef TQT_NO_PICTURE - TQPicture *pic = picture(); -#else - const int pic = 0; -#endif -#ifndef TQT_NO_MOVIE - TQMovie *mov = movie(); -#else - const int mov = 0; -#endif - int hextra = 2 * frameWidth(); - int vextra = hextra; - TQFontMetrics fm( fontMetrics() ); - int xw = fm.width( 'x' ); - if ( !mov && !pix && !pic ) { - int m = indent(); - if ( m < 0 && hextra ) // no indent, but we do have a frame - m = xw / 2 - margin(); - if ( m >= 0 ) { - int horizAlign = TQApplication::horizontalAlignment( align ); - if ( (horizAlign & AlignLeft) || (horizAlign & AlignRight ) ) - hextra += m; - if ( (align & AlignTop) || (align & AlignBottom ) ) - vextra += m; - } - } - - if ( pix ) - br = pix->rect(); -#ifndef TQT_NO_PICTURE - else if ( pic ) - br = pic->boundingRect(); -#endif -#ifndef TQT_NO_MOVIE - else if ( mov ) - br = mov->framePixmap().rect(); -#endif -#ifndef TQT_NO_RICHTEXT - else if ( doc ) { - int oldW = doc->width(); - if ( align & WordBreak ) { - if ( w < 0 ) - doc->adjustSize(); - else - doc->setWidth( w-hextra ); - } - br = TQRect( 0, 0, doc->widthUsed(), doc->height() ); - doc->setWidth( oldW ); - } -#endif - else { - bool tryWidth = (w < 0) && (align & WordBreak); - if ( tryWidth ) - w = xw * 80; - else if ( w < 0 ) - w = 2000; - w -= hextra; - br = fm.boundingRect( 0, 0, w ,2000, alignment(), text() ); - if ( tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2 ) - br = fm.boundingRect( 0, 0, w/2, 2000, alignment(), text() ); - if ( tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4 ) - br = fm.boundingRect( 0, 0, w/4, 2000, alignment(), text() ); - } - int wid = br.width() + hextra; - int hei = br.height() + vextra; - - return TQSize( wid, hei ); -} - - -/*! - \reimp -*/ - -int TQLabel::heightForWidth( int w ) const -{ - if ( -#ifndef TQT_NO_RICHTEXT - doc || -#endif - (align & WordBreak) ) - return sizeForWidth( w ).height(); - return TQWidget::heightForWidth( w ); -} - - - -/*!\reimp -*/ -TQSize TQLabel::sizeHint() const -{ - if ( d->valid_hints != frameWidth() ) - (void) TQLabel::minimumSizeHint(); - return d->sh; -} - -/*! - \reimp -*/ - -TQSize TQLabel::minimumSizeHint() const -{ - if ( d->valid_hints == frameWidth() ) - return d->msh; - - constPolish(); - d->valid_hints = frameWidth(); - d->sh = sizeForWidth( -1 ); - TQSize sz( -1, -1 ); - - if ( -#ifndef TQT_NO_RICHTEXT - !doc && -#endif - (align & WordBreak) == 0 ) { - sz = d->sh; - } else { - // think about caching these for performance - sz.rwidth() = sizeForWidth( 0 ).width(); - sz.rheight() = sizeForWidth(TQWIDGETSIZE_MAX).height(); - if ( d->sh.height() < sz.height() ) - sz.rheight() = d->sh.height(); - } - if ( sizePolicy().horData() == TQSizePolicy::Ignored ) - sz.rwidth() = -1; - if ( sizePolicy().verData() == TQSizePolicy::Ignored ) - sz.rheight() = -1; - d->msh = sz; - return sz; -} - -/*! - \reimp -*/ -void TQLabel::resizeEvent( TQResizeEvent* e ) -{ - TQFrame::resizeEvent( e ); - -#ifdef TQT_NO_RICHTEXT - static const bool doc = FALSE; -#endif - - // optimize for standard labels - if ( frameShape() == NoFrame && (align & WordBreak) == 0 && !doc && - ( e->oldSize().width() >= e->size().width() && (align & AlignLeft ) == AlignLeft ) - && ( e->oldSize().height() >= e->size().height() && (align & AlignTop ) == AlignTop ) ) { - setWFlags( WResizeNoErase ); - return; - } - - clearWFlags( WResizeNoErase ); - TQRect cr = contentsRect(); - if ( !lpixmap || !cr.isValid() || - // masked pixmaps can only reduce flicker when being top/left - // aligned and when we do not perform scaled contents - ( lpixmap->hasAlpha() && ( scaledcontents || ( ( align & (AlignLeft|AlignTop) ) != (AlignLeft|AlignTop) ) ) ) ) - return; - - setWFlags( WResizeNoErase ); - - if ( !scaledcontents ) { - // don't we all love TQFrame? Reduce pixmap flicker - TQRegion reg = TQRect( TQPoint(0, 0), e->size() ); - reg = reg.subtract( cr ); - int x = cr.x(); - int y = cr.y(); - int w = lpixmap->width(); - int h = lpixmap->height(); - if ( (align & TQt::AlignVCenter) == TQt::AlignVCenter ) - y += cr.height()/2 - h/2; - else if ( (align & TQt::AlignBottom) == TQt::AlignBottom) - y += cr.height() - h; - if ( (align & TQt::AlignRight) == TQt::AlignRight ) - x += cr.width() - w; - else if ( (align & TQt::AlignHCenter) == TQt::AlignHCenter ) - x += cr.width()/2 - w/2; - if ( x > cr.x() ) - reg = reg.unite( TQRect( cr.x(), cr.y(), x - cr.x(), cr.height() ) ); - if ( y > cr.y() ) - reg = reg.unite( TQRect( cr.x(), cr.y(), cr.width(), y - cr.y() ) ); - - if ( x + w < cr.right() ) - reg = reg.unite( TQRect( x + w, cr.y(), cr.right() - x - w, cr.height() ) ); - if ( y + h < cr.bottom() ) - reg = reg.unite( TQRect( cr.x(), y + h, cr.width(), cr.bottom() - y - h ) ); - - erase( reg ); - } -} - - -/*! - Draws the label contents using the painter \a p. -*/ - -void TQLabel::drawContents( TQPainter *p ) -{ - TQRect cr = contentsRect(); - - TQPixmap *pix = pixmap(); -#ifndef TQT_NO_PICTURE - TQPicture *pic = picture(); -#else - const int pic = 0; -#endif -#ifndef TQT_NO_MOVIE - TQMovie *mov = movie(); -#else - const int mov = 0; -#endif - - if ( !mov && !pix && !pic ) { - int m = indent(); - if ( m < 0 && frameWidth() ) // no indent, but we do have a frame - m = fontMetrics().width('x') / 2 - margin(); - if ( m > 0 ) { - int hAlign = TQApplication::horizontalAlignment( align ); - if ( hAlign & AlignLeft ) - cr.setLeft( cr.left() + m ); - if ( hAlign & AlignRight ) - cr.setRight( cr.right() - m ); - if ( align & AlignTop ) - cr.setTop( cr.top() + m ); - if ( align & AlignBottom ) - cr.setBottom( cr.bottom() - m ); - } - } - -#ifndef TQT_NO_MOVIE - if ( mov ) { - // ### should add movie to qDrawItem - TQRect r = style().itemRect( p, cr, align, isEnabled(), &(mov->framePixmap()), - TQString::null ); - // ### could resize movie frame at this point - p->drawPixmap(r.x(), r.y(), mov->framePixmap() ); - } - else -#endif -#ifndef TQT_NO_RICHTEXT - if ( doc ) { - doc->setWidth(p, cr.width() ); - int rh = doc->height(); - int yo = 0; - if ( align & AlignVCenter ) - yo = (cr.height()-rh)/2; - else if ( align & AlignBottom ) - yo = cr.height()-rh; - if (! isEnabled() && - style().styleHint(TQStyle::SH_EtchDisabledText, this)) { - TQColorGroup cg = colorGroup(); - cg.setColor( TQColorGroup::Text, cg.light() ); - doc->draw(p, cr.x()+1, cr.y()+yo+1, cr, cg, 0); - } - - // TQSimpleRichText always draws with TQColorGroup::Text as with - // background mode PaletteBase. TQLabel typically has - // background mode PaletteBackground, so we create a temporary - // color group with the text color adjusted. - TQColorGroup cg = colorGroup(); - if ( backgroundMode() != PaletteBase && isEnabled() ) - cg.setColor( TQColorGroup::Text, paletteForegroundColor() ); - - doc->draw(p, cr.x(), cr.y()+yo, cr, cg, 0); - } else -#endif -#ifndef TQT_NO_PICTURE - if ( pic ) { - TQRect br = pic->boundingRect(); - int rw = br.width(); - int rh = br.height(); - if ( scaledcontents ) { - p->save(); - p->translate( cr.x(), cr.y() ); -#ifndef TQT_NO_TRANSFORMATIONS - p->scale( (double)cr.width()/rw, (double)cr.height()/rh ); -#endif - p->drawPicture( -br.x(), -br.y(), *pic ); - p->restore(); - } else { - int xo = 0; - int yo = 0; - if ( align & AlignVCenter ) - yo = (cr.height()-rh)/2; - else if ( align & AlignBottom ) - yo = cr.height()-rh; - if ( align & AlignRight ) - xo = cr.width()-rw; - else if ( align & AlignHCenter ) - xo = (cr.width()-rw)/2; - p->drawPicture( cr.x()+xo-br.x(), cr.y()+yo-br.y(), *pic ); - } - } else -#endif - { -#ifndef TQT_NO_IMAGE_SMOOTHSCALE - if ( scaledcontents && pix ) { - if ( !d->img ) - d->img = new TQImage( lpixmap->convertToImage() ); - - if ( !d->pix ) - d->pix = new TQPixmap; - if ( d->pix->size() != cr.size() ) - d->pix->convertFromImage( d->img->smoothScale( cr.width(), cr.height() ) ); - pix = d->pix; - } -#endif - int alignment = align; - if ((align & ShowPrefix) && ((!style().styleHint(TQStyle::SH_UnderlineAccelerator, this)) || ((style().styleHint(TQStyle::SH_HideUnderlineAcceleratorWhenAltUp, this)) && (!style().acceleratorsShown())))) { - alignment |= NoAccel; - } - // ordinary text or pixmap label - style().drawItem( p, cr, alignment, colorGroup(), isEnabled(), - pix, ltext ); - } -} - - -/*! - Updates the label, but not the frame. -*/ - -void TQLabel::updateLabel( TQSize oldSizeHint ) -{ - d->valid_hints = -1; - TQSizePolicy policy = sizePolicy(); - bool wordBreak = align & WordBreak; - policy.setHeightForWidth( wordBreak ); - if ( policy != sizePolicy() ) - setSizePolicy( policy ); - if ( sizeHint() != oldSizeHint ) - updateGeometry(); - if ( autoresize ) { - adjustSize(); - update( contentsRect() ); - } else { - update( contentsRect() ); - } -} - - -/*! - \internal - - Internal slot, used to set focus for accelerator labels. -*/ -#ifndef TQT_NO_ACCEL -void TQLabel::acceleratorSlot() -{ - if ( !lbuddy ) - return; - TQWidget * w = lbuddy; - while ( w->focusProxy() ) - w = w->focusProxy(); - if ( !w->hasFocus() && - w->isEnabled() && - w->isVisible() && - w->focusPolicy() != NoFocus ) { - TQFocusEvent::setReason( TQFocusEvent::Shortcut ); - w->setFocus(); - TQFocusEvent::resetReason(); - } -} -#endif - -/*! - \internal - - Internal slot, used to clean up if the buddy widget dies. -*/ -#ifndef TQT_NO_ACCEL -void TQLabel::buddyDied() // I can't remember if I cried. -{ - lbuddy = 0; -} - -/*! - Sets this label's buddy to \a buddy. - - When the user presses the accelerator key indicated by this label, - the keyboard focus is transferred to the label's buddy widget. - - The buddy mechanism is only available for TQLabels that contain - plain text in which one letter is prefixed with an ampersand, \&. - This letter is set as the accelerator key. The letter is displayed - underlined, and the '\&' is not displayed (i.e. the \c ShowPrefix - alignment flag is turned on; see setAlignment()). - - In a dialog, you might create two data entry widgets and a label - for each, and set up the geometry layout so each label is just to - the left of its data entry widget (its "buddy"), for example: - \code - TQLineEdit *nameEd = new TQLineEdit( this ); - TQLabel *nameLb = new TQLabel( "&Name:", this ); - nameLb->setBuddy( nameEd ); - TQLineEdit *phoneEd = new TQLineEdit( this ); - TQLabel *phoneLb = new TQLabel( "&Phone:", this ); - phoneLb->setBuddy( phoneEd ); - // ( layout setup not shown ) - \endcode - - With the code above, the focus jumps to the Name field when the - user presses Alt+N, and to the Phone field when the user presses - Alt+P. - - To unset a previously set buddy, call this function with \a buddy - set to 0. - - \sa buddy(), setText(), TQAccel, setAlignment() -*/ - -void TQLabel::setBuddy( TQWidget *buddy ) -{ - if ( buddy ) - setAlignment( alignment() | ShowPrefix ); - else - setAlignment( alignment() & ~ShowPrefix ); - - if ( lbuddy ) - disconnect( lbuddy, TQ_SIGNAL(destroyed()), this, TQ_SLOT(buddyDied()) ); - - lbuddy = buddy; - - if ( !lbuddy ) - return; -#ifndef TQT_NO_RICHTEXT - if ( !( textformat == RichText || (textformat == AutoText && - TQStyleSheet::mightBeRichText(ltext) ) ) ) -#endif - { - int p = TQAccel::shortcutKey( ltext ); - if ( p ) { - if ( !accel ) - accel = new TQAccel( this, "accel label accel" ); - accel->connectItem( accel->insertItem( p ), - this, TQ_SLOT(acceleratorSlot()) ); - } - } - - connect( lbuddy, TQ_SIGNAL(destroyed()), this, TQ_SLOT(buddyDied()) ); -} - - -/*! - Returns this label's buddy, or 0 if no buddy is currently set. - - \sa setBuddy() -*/ - -TQWidget * TQLabel::buddy() const -{ - return lbuddy; -} -#endif //TQT_NO_ACCEL - - -#ifndef TQT_NO_MOVIE -void TQLabel::movieUpdated(const TQRect& rect) -{ - TQMovie *mov = movie(); - if ( mov && !mov->isNull() ) { - TQRect r = contentsRect(); - r = style().itemRect( 0, r, align, isEnabled(), &(mov->framePixmap()), - TQString::null ); - r.moveBy(rect.x(), rect.y()); - r.setWidth(TQMIN(r.width(), rect.width())); - r.setHeight(TQMIN(r.height(), rect.height())); - repaint( r, mov->framePixmap().mask() != 0 ); - } -} - -void TQLabel::movieResized( const TQSize& size ) -{ - d->valid_hints = -1; - if ( autoresize ) - adjustSize(); - movieUpdated( TQRect( TQPoint(0,0), size ) ); - updateGeometry(); -} - -/*! - Sets the label contents to \a movie. Any previous content is - cleared. - - The buddy accelerator, if any, is disabled. - - The label resizes itself if auto-resizing is enabled. - - \sa movie(), setBuddy() -*/ - -void TQLabel::setMovie( const TQMovie& movie ) -{ - TQSize osh = sizeHint(); - clearContents(); - - lmovie = new TQMovie( movie ); - lmovie->connectResize(this, TQ_SLOT(movieResized(const TQSize&))); - lmovie->connectUpdate(this, TQ_SLOT(movieUpdated(const TQRect&))); - - if ( !lmovie->running() ) // Assume that if the movie is running, - updateLabel( osh ); // resize/update signals will come soon enough -} - -#endif // TQT_NO_MOVIE - -/*! - \internal - - Clears any contents, without updating/repainting the label. -*/ - -void TQLabel::clearContents() -{ -#ifndef TQT_NO_RICHTEXT - delete doc; - doc = 0; -#endif - - delete lpixmap; - lpixmap = 0; -#ifndef TQT_NO_PICTURE - delete lpicture; - lpicture = 0; -#endif - delete d->img; - d->img = 0; - delete d->pix; - d->pix = 0; - - ltext = TQString::null; -#ifndef TQT_NO_ACCEL - if ( accel ) - accel->clear(); -#endif -#ifndef TQT_NO_MOVIE - if ( lmovie ) { - lmovie->disconnectResize(this, TQ_SLOT(movieResized(const TQSize&))); - lmovie->disconnectUpdate(this, TQ_SLOT(movieUpdated(const TQRect&))); - delete lmovie; - lmovie = 0; - } -#endif -} - - -#ifndef TQT_NO_MOVIE - -/*! - Returns a pointer to the label's movie, or 0 if no movie has been - set. - - \sa setMovie() -*/ - -TQMovie* TQLabel::movie() const -{ - return lmovie; -} - -#endif // TQT_NO_MOVIE - -/*! - \property TQLabel::backgroundMode - \brief the label's background mode - - Get this property with backgroundMode(). - - \sa TQWidget::setBackgroundMode() -*/ - -/*! - \property TQLabel::textFormat - \brief the label's text format - - See the \c TQt::TextFormat enum for an explanation of the possible - options. - - The default format is \c AutoText. - - \sa text -*/ - -TQt::TextFormat TQLabel::textFormat() const -{ - return textformat; -} - -void TQLabel::setTextFormat( TQt::TextFormat format ) -{ - if ( format != textformat ) { - textformat = format; - TQString t = ltext; - if ( !t.isNull() ) { - ltext = TQString::null; - setText( t ); - } - } -} - -/*! - \reimp -*/ - -void TQLabel::fontChange( const TQFont & ) -{ - if ( !ltext.isEmpty() ) { -#ifndef TQT_NO_RICHTEXT - if ( doc ) - doc->setDefaultFont( font() ); -#endif - updateLabel( TQSize( -1, -1 ) ); - } -} - -#ifndef TQT_NO_IMAGE_SMOOTHSCALE -/*! - \property TQLabel::scaledContents - \brief whether the label will scale its contents to fill all - available space. - - When enabled and the label shows a pixmap, it will scale the - pixmap to fill the available space. - - This property's default is FALSE. - - \sa setScaledContents() -*/ -bool TQLabel::hasScaledContents() const -{ - return scaledcontents; -} - -void TQLabel::setScaledContents( bool enable ) -{ - if ( (bool)scaledcontents == enable ) - return; - scaledcontents = enable; - if ( !enable ) { - delete d->img; - d->img = 0; - delete d->pix; - d->pix = 0; - } - update( contentsRect() ); -} - -#endif // TQT_NO_IMAGE_SMOOTHSCALE - -/*! - Sets the font used on the TQLabel to font \a f. -*/ - -void TQLabel::setFont( const TQFont &f ) -{ - TQFrame::setFont( f ); -} - -#endif // TQT_NO_LABEL diff --git a/src/widgets/qlineedit.cpp b/src/widgets/qlineedit.cpp index 75570cc09..d37c43539 100644 --- a/src/widgets/qlineedit.cpp +++ b/src/widgets/qlineedit.cpp @@ -59,7 +59,7 @@ #include "tqstringlist.h" #include "ntqguardedptr.h" #include "tqstyle.h" -#include "ntqwhatsthis.h" +#include "tqwhatsthis.h" #include "../kernel/qinternal_p.h" #include "private/tqtextlayout_p.h" #include "tqvaluevector.h" diff --git a/src/widgets/qsyntaxhighlighter.cpp b/src/widgets/qsyntaxhighlighter.cpp deleted file mode 100644 index d9fececf1..000000000 --- a/src/widgets/qsyntaxhighlighter.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/**************************************************************************** -** -** Implementation of the TQSyntaxHighlighter class -** -** Created : 990101 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the widgets module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#include "ntqsyntaxhighlighter.h" -#include "private/qsyntaxhighlighter_p.h" - -#ifndef TQT_NO_SYNTAXHIGHLIGHTER -#include "../kernel/qrichtext_p.h" -#include "tqtextedit.h" -#include "tqtimer.h" - -/*! - \class TQSyntaxHighlighter ntqsyntaxhighlighter.h - \brief The TQSyntaxHighlighter class is a base class for - implementing TQTextEdit syntax highlighters. - - \ingroup basic - \ingroup text - - A syntax highligher automatically highlights parts of the text in - a TQTextEdit. Syntax highlighters are often used when the user is - entering text in a specific format (for example, source code) and - help the user to read the text and identify syntax errors. - - To provide your own syntax highlighting for TQTextEdit, you must - subclass TQSyntaxHighlighter and reimplement highlightParagraph(). - - When you create an instance of your TQSyntaxHighlighter subclass, - pass it the TQTextEdit that you want the syntax highlighting to be - applied to. After this your highlightParagraph() function will be - called automatically whenever necessary. Use your - highlightParagraph() function to apply formatting (e.g. setting - the font and color) to the text that is passed to it. -*/ - -/*! - Constructs the TQSyntaxHighlighter and installs it on \a textEdit. - - It is the caller's responsibility to delete the - TQSyntaxHighlighter when it is no longer needed. -*/ - -TQSyntaxHighlighter::TQSyntaxHighlighter( TQTextEdit *textEdit ) - : para( 0 ), edit( textEdit ), d( new TQSyntaxHighlighterPrivate ) -{ - textEdit->document()->setPreProcessor( new TQSyntaxHighlighterInternal( this ) ); - textEdit->document()->invalidate(); - TQTimer::singleShot( 0, textEdit->viewport(), TQ_SLOT( update() ) ); -} - -/*! - Destructor. Uninstalls this syntax highlighter from the textEdit() -*/ - -TQSyntaxHighlighter::~TQSyntaxHighlighter() -{ - delete d; - textEdit()->document()->setPreProcessor( 0 ); -} - -/*! - \fn int TQSyntaxHighlighter::highlightParagraph( const TQString &text, int endStateOfLastPara ) - - This function is called when necessary by the rich text engine, - i.e. on paragraphs which have changed. - - In your reimplementation you should parse the paragraph's \a text - and call setFormat() as often as necessary to apply any font and - color changes that you require. Your function must return a value - which indicates the paragraph's end state: see below. - - Some syntaxes can have constructs that span paragraphs. For - example, a C++ syntax highlighter should be able to cope with - \c{/}\c{*...*}\c{/} comments that span paragraphs. To deal - with these cases it is necessary to know the end state of the - previous paragraph (e.g. "in comment"). - - If your syntax does not have paragraph spanning constructs, simply - ignore the \a endStateOfLastPara parameter and always return 0. - - Whenever highlightParagraph() is called it is passed a value for - \a endStateOfLastPara. For the very first paragraph this value is - always -2. For any other paragraph the value is the value returned - by the most recent highlightParagraph() call that applied to the - preceding paragraph. - - The value you return is up to you. We recommend only returning 0 - (to signify that this paragraph's syntax highlighting does not - affect the following paragraph), or a positive integer (to signify - that this paragraph has ended in the middle of a paragraph - spanning construct). - - To find out which paragraph is highlighted, call - currentParagraph(). - - For example, if you're writing a simple C++ syntax highlighter, - you might designate 1 to signify "in comment". For a paragraph - that ended in the middle of a comment you'd return 1, and for - other paragraphs you'd return 0. In your parsing code if \a - endStateOfLastPara was 1, you would highlight the text as a C++ - comment until you reached the closing \c{*}\c{/}. -*/ - -/*! - This function is applied to the syntax highlighter's current - paragraph (the text of which is passed to the highlightParagraph() - function). - - The specified \a font and \a color are applied to the text from - position \a start for \a count characters. (If \a count is 0, - nothing is done.) -*/ - -void TQSyntaxHighlighter::setFormat( int start, int count, const TQFont &font, const TQColor &color ) -{ - if ( !para || count <= 0 ) - return; - TQTextFormat *f = 0; - f = para->document()->formatCollection()->format( font, color ); - para->setFormat( start, count, f ); - f->removeRef(); -} - -/*! \overload */ - -void TQSyntaxHighlighter::setFormat( int start, int count, const TQColor &color ) -{ - if ( !para || count <= 0 ) - return; - TQTextFormat *f = 0; - TQFont fnt = textEdit()->TQWidget::font(); - f = para->document()->formatCollection()->format( fnt, color ); - para->setFormat( start, count, f ); - f->removeRef(); -} - -/*! \overload */ - -void TQSyntaxHighlighter::setFormat( int start, int count, const TQFont &font ) -{ - if ( !para || count <= 0 ) - return; - TQTextFormat *f = 0; - TQColor c = textEdit()->viewport()->paletteForegroundColor(); - f = para->document()->formatCollection()->format( font, c ); - para->setFormat( start, count, f ); - f->removeRef(); -} - -/*! - \fn TQTextEdit *TQSyntaxHighlighter::textEdit() const - - Returns the TQTextEdit on which this syntax highlighter is - installed -*/ - -/*! Redoes the highlighting of the whole document. -*/ - -void TQSyntaxHighlighter::rehighlight() -{ - TQTextParagraph *s = edit->document()->firstParagraph(); - while ( s ) { - s->invalidate( 0 ); - s->state = -1; - s->needPreProcess = TRUE; - s = s->next(); - } - edit->repaintContents( FALSE ); -} - -/*! - Returns the id of the paragraph which is highlighted, or -1 of no - paragraph is currently highlighted. - - Usually this function is called from within highlightParagraph(). -*/ - -int TQSyntaxHighlighter::currentParagraph() const -{ - return d->currentParagraph; -} - -#endif diff --git a/src/widgets/qsyntaxhighlighter_p.h b/src/widgets/qsyntaxhighlighter_p.h deleted file mode 100644 index 156cc9321..000000000 --- a/src/widgets/qsyntaxhighlighter_p.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Definition of the internal TQSyntaxHighlighterInternal class -** -** Created : 031111 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the widgets module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#ifndef TQSYNTAXHIGHLIGHTER_P_H -#define TQSYNTAXHIGHLIGHTER_P_H - -#ifndef TQT_NO_SYNTAXHIGHLIGHTER -#include "ntqsyntaxhighlighter.h" -#include "private/qrichtext_p.h" - -class TQSyntaxHighlighterPrivate -{ -public: - TQSyntaxHighlighterPrivate() : - currentParagraph( -1 ) - {} - - int currentParagraph; -}; - -class TQSyntaxHighlighterInternal : public TQTextPreProcessor -{ -public: - TQSyntaxHighlighterInternal( TQSyntaxHighlighter *h ) : highlighter( h ) {} - void process( TQTextDocument *doc, TQTextParagraph *p, int, bool invalidate ) { - if ( p->prev() && p->prev()->endState() == -1 ) - process( doc, p->prev(), 0, FALSE ); - - highlighter->para = p; - TQString text = p->string()->toString(); - int endState = p->prev() ? p->prev()->endState() : -2; - int oldEndState = p->endState(); - highlighter->d->currentParagraph = p->paragId(); - p->setEndState( highlighter->highlightParagraph( text, endState ) ); - highlighter->d->currentParagraph = -1; - highlighter->para = 0; - - p->setFirstPreProcess( FALSE ); - TQTextParagraph *op = p; - p = p->next(); - if ( (!!oldEndState || !!op->endState()) && oldEndState != op->endState() && - invalidate && p && !p->firstPreProcess() && p->endState() != -1 ) { - while ( p ) { - if ( p->endState() == -1 ) - return; - p->setEndState( -1 ); - p = p->next(); - } - } - } - TQTextFormat *format( int ) { return 0; } - -private: - TQSyntaxHighlighter *highlighter; - - friend class TQTextEdit; -}; - -#endif // TQT_NO_SYNTAXHIGHLIGHTER -#endif // TQSYNTAXHIGHLIGHTER_P_H diff --git a/src/widgets/qt_widgets.pri b/src/widgets/qt_widgets.pri index 38ef25ca9..876cc428c 100644 --- a/src/widgets/qt_widgets.pri +++ b/src/widgets/qt_widgets.pri @@ -21,7 +21,7 @@ widgets { $$WIDGETS_H/ntqhgroupbox.h \ $$WIDGETS_H/ntqhbox.h \ $$WIDGETS_H/tqiconview.h \ - $$WIDGETS_H/ntqlabel.h \ + $$WIDGETS_H/tqlabel.h \ $$WIDGETS_H/ntqlcdnumber.h \ $$WIDGETS_H/ntqlineedit.h \ $$WIDGETS_H/ntqlistbox.h \ @@ -43,8 +43,8 @@ widgets { $$WIDGETS_H/ntqsplitter.h \ $$WIDGETS_H/tqstatusbar.h \ $$WIDGETS_H/ntqtabbar.h \ - $$WIDGETS_H/ntqsyntaxhighlighter.h \ - $$WIDGETS_P/qsyntaxhighlighter_p.h \ + $$WIDGETS_H/tqsyntaxhighlighter.h \ + $$WIDGETS_P/tqsyntaxhighlighter_p.h \ $$WIDGETS_H/ntqtabwidget.h \ $$WIDGETS_P/qtitlebar_p.h \ $$WIDGETS_H/tqtoolbar.h \ @@ -55,7 +55,7 @@ widgets { $$WIDGETS_H/ntqvbox.h \ $$WIDGETS_H/ntqvbuttongroup.h \ $$WIDGETS_H/ntqvgroupbox.h \ - $$WIDGETS_H/ntqwhatsthis.h \ + $$WIDGETS_H/tqwhatsthis.h \ $$WIDGETS_H/tqwidgetstack.h \ $$WIDGETS_H/tqaction.h \ $$WIDGETS_H/tqdatetimeedit.h \ @@ -83,7 +83,7 @@ widgets { $$WIDGETS_CPP/qhgroupbox.cpp \ $$WIDGETS_CPP/qhbox.cpp \ $$WIDGETS_CPP/tqiconview.cpp \ - $$WIDGETS_CPP/qlabel.cpp \ + $$WIDGETS_CPP/tqlabel.cpp \ $$WIDGETS_CPP/qlcdnumber.cpp \ $$WIDGETS_CPP/qlineedit.cpp \ $$WIDGETS_CPP/qlistbox.cpp \ @@ -105,7 +105,7 @@ widgets { $$WIDGETS_CPP/qspinwidget.cpp \ $$WIDGETS_CPP/qsplitter.cpp \ $$WIDGETS_CPP/tqstatusbar.cpp \ - $$WIDGETS_CPP/qsyntaxhighlighter.cpp \ + $$WIDGETS_CPP/tqsyntaxhighlighter.cpp \ $$WIDGETS_CPP/qtabbar.cpp \ $$WIDGETS_CPP/qtabwidget.cpp \ $$WIDGETS_CPP/qtitlebar.cpp \ @@ -117,7 +117,7 @@ widgets { $$WIDGETS_CPP/qvbox.cpp \ $$WIDGETS_CPP/qvbuttongroup.cpp \ $$WIDGETS_CPP/qvgroupbox.cpp \ - $$WIDGETS_CPP/qwhatsthis.cpp \ + $$WIDGETS_CPP/tqwhatsthis.cpp \ $$WIDGETS_CPP/tqwidgetstack.cpp \ $$WIDGETS_CPP/tqaction.cpp \ $$WIDGETS_CPP/tqdatetimeedit.cpp \ @@ -133,9 +133,9 @@ wince-* { SOURCES += $$WIDGETS_CPP/ce/qcemainwindow.cpp HEADERS += $$WIDGETS_H/ce/qcemainwindow.h - SOURCES -= $$WIDGETS_CPP/qsyntaxhighlighter.cpp \ + SOURCES -= $$WIDGETS_CPP/tqsyntaxhighlighter.cpp \ $$WIDGETS_CPP/qsplashscreen.cpp - HEADERS -= $$WIDGETS_H/ntqsyntaxhighlighter.h \ + HEADERS -= $$WIDGETS_H/tqsyntaxhighlighter.h \ $$WIDGETS_H/ntqsplashscreen.h } diff --git a/src/widgets/qtitlebar_p.h b/src/widgets/qtitlebar_p.h index b933658dd..ae9fd6b15 100644 --- a/src/widgets/qtitlebar_p.h +++ b/src/widgets/qtitlebar_p.h @@ -57,7 +57,7 @@ #ifndef QT_H #include "ntqbutton.h" -#include "ntqlabel.h" +#include "tqlabel.h" #endif // QT_H #if !defined(TQT_NO_TITLEBAR) diff --git a/src/widgets/qwhatsthis.cpp b/src/widgets/qwhatsthis.cpp deleted file mode 100644 index 65df04e7b..000000000 --- a/src/widgets/qwhatsthis.cpp +++ /dev/null @@ -1,1001 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQWhatsThis class -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the widgets module of the TQt GUI Toolkit. -** -** This file may be used under the terms of the GNU General -** Public License versions 2.0 or 3.0 as published by the Free -** Software Foundation and appearing in the files LICENSE.GPL2 -** and LICENSE.GPL3 included in the packaging of this file. -** Alternatively you may (at your option) use any later version -** of the GNU General Public License if such license has been -** publicly approved by Trolltech ASA (or its successors, if any) -** and the KDE Free TQt Foundation. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** This file may be used under the terms of the Q Public License as -** defined by Trolltech ASA and appearing in the file LICENSE.TQPL -** included in the packaging of this file. Licensees holding valid TQt -** Commercial licenses may use this file in accordance with the TQt -** Commercial License Agreement provided with the Software. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted -** herein. -** -**********************************************************************/ - -#include "ntqwhatsthis.h" -#ifndef TQT_NO_WHATSTHIS -#include "ntqapplication.h" -#include "tqpaintdevicemetrics.h" -#include "tqpixmap.h" -#include "tqpainter.h" -#include "tqtimer.h" -#include "tqptrdict.h" -#include "tqtoolbutton.h" -#include "ntqshared.h" -#include "ntqcursor.h" -#include "tqbitmap.h" -#include "tqtooltip.h" -#include "ntqsimplerichtext.h" -#include "tqstylesheet.h" -#if defined(QT_ACCESSIBILITY_SUPPORT) -#include "ntqaccessible.h" -#endif -#if defined(TQ_WS_WIN) -#include "qt_windows.h" -#ifndef SPI_GETDROPSHADOW -#define SPI_GETDROPSHADOW 0x1024 -#endif -#endif - -/*! - \class TQWhatsThis ntqwhatsthis.h - \brief The TQWhatsThis class provides a simple description of any - widget, i.e. answering the question "What's this?". - - \ingroup helpsystem - \mainclass - - "What's this?" help is part of an application's online help system - that provides users with information about functionality, usage, - background etc., in various levels of detail from short tool tips - to full text browsing help windows. - - TQWhatsThis provides a single window with an explanatory text that - pops up when the user asks "What's this?". The default way to do - this is to focus the relevant widget and press Shift+F1. The help - text appears immediately; it goes away as soon as the user does - something else. - - (Note that if there is an accelerator for Shift+F1, this mechanism - will not work.) - - To add "What's this?" text to a widget you simply call - TQWhatsThis::add() for the widget. For example, to assign text to a - menu item, call TQMenuData::setWhatsThis(); for a global - accelerator key, call TQAccel::setWhatsThis() and If you're using - actions, use TQAction::setWhatsThis(). - - The text can be either rich text or plain text. If you specify a - rich text formatted string, it will be rendered using the default - stylesheet. This makes it possible to embed images. See - TQStyleSheet::defaultSheet() for details. - - \quotefile action/application.cpp - \skipto fileOpenText - \printuntil setWhatsThis - - An alternative way to enter "What's this?" mode is to use the - ready-made tool bar tool button from - TQWhatsThis::whatsThisButton(). By invoking this context help - button (in the picture below the first one from the right) the - user switches into "What's this?" mode. If they now click on a - widget the appropriate help text is shown. The mode is left when - help is given or when the user presses Esc. - - \img whatsthis.png - - If you are using TQMainWindow you can also use the - TQMainWindow::whatsThis() slot to invoke the mode from a menu item. - - For more control you can create a dedicated TQWhatsThis object for - a special widget. By subclassing and reimplementing - TQWhatsThis::text() it is possible to have different help texts, - depending on the position of the mouse click. By reimplementing - TQWhatsThis::clicked() it is possible to have hyperlinks inside the - help texts. - - If you wish to control the "What's this?" behavior of a widget - manually see TQWidget::customWhatsThis(). - - The What's This object can be removed using TQWhatsThis::remove(), - although this is rarely necessary because it is automatically - removed when the widget is destroyed. - - \sa TQToolTip -*/ - -// a special button -class TQWhatsThisButton: public TQToolButton -{ - TQ_OBJECT - -public: - TQWhatsThisButton( TQWidget * parent, const char * name ); - ~TQWhatsThisButton(); - -public slots: - void mouseReleased(); - -}; - - -class TQWhatsThat : public TQWidget -{ - TQ_OBJECT -public: - TQWhatsThat( TQWidget* w, const TQString& txt, TQWidget* parent, const char* name ); - ~TQWhatsThat() ; - -public slots: - void hide(); - inline void widgetDestroyed() { widget = 0; } - -protected: - void mousePressEvent( TQMouseEvent* ); - void mouseReleaseEvent( TQMouseEvent* ); - void mouseMoveEvent( TQMouseEvent* ); - void keyPressEvent( TQKeyEvent* ); - void paintEvent( TQPaintEvent* ); - -private: - TQString text; -#ifndef TQT_NO_RICHTEXT - TQSimpleRichText* doc; -#endif - TQString anchor; - bool pressed; - TQWidget* widget; -}; - - -class TQWhatsThisPrivate: public TQObject -{ - TQ_OBJECT -public: - - // an item for storing texts - struct WhatsThisItem: public TQShared - { - WhatsThisItem(): TQShared() { whatsthis = 0; } - ~WhatsThisItem(); - TQString s; - TQWhatsThis* whatsthis; - }; - - // the (these days pretty small) state machine - enum State { Inactive, Waiting }; - - TQWhatsThisPrivate(); - ~TQWhatsThisPrivate(); - - bool eventFilter( TQObject *, TQEvent * ); - - WhatsThisItem* newItem( TQWidget * widget ); - void add( TQWidget * widget, TQWhatsThis* special ); - void add( TQWidget * widget, const TQString& text ); - - // say it. - void say( TQWidget *, const TQString&, const TQPoint& ); - - // setup and teardown - static void setUpWhatsThis(); - - void enterWhatsThisMode(); - void leaveWhatsThisMode(); - - // variables - TQWhatsThat * whatsThat; - TQPtrDict * dict; - TQPtrDict * tlw; - TQPtrDict * buttons; - State state; - -private slots: - void cleanupWidget() - { - const TQObject* o = sender(); - if ( o->isWidgetType() ) // sanity - TQWhatsThis::remove((TQWidget*)o); - } - -}; - -// static, but static the less-typing way -static TQWhatsThisPrivate * wt = 0; - -// shadowWidth not const, for XP drop-shadow-fu turns it to 0 -static int shadowWidth = 6; // also used as '5' and '6' and even '8' below -const int vMargin = 8; -const int hMargin = 12; - -// Lets TQPopupMenu destroy the TQWhatsThat. -void qWhatsThisBDH() -{ - if ( wt && wt->whatsThat ) - wt->whatsThat->hide(); -} - - -TQWhatsThat::TQWhatsThat( TQWidget* w, const TQString& txt, TQWidget* parent, const char* name ) - : TQWidget( parent, name, WType_Popup ), text( txt ), pressed( FALSE ), widget( w ) -{ - - setBackgroundMode( NoBackground ); - setPalette( TQToolTip::palette() ); - setMouseTracking( TRUE ); -#ifndef TQT_NO_CURSOR - setCursor( arrowCursor ); -#endif - - if ( widget ) - connect( widget, TQ_SIGNAL( destroyed() ), this, TQ_SLOT( widgetDestroyed() ) ); - - - TQRect r; -#ifndef TQT_NO_RICHTEXT - doc = 0; - if ( TQStyleSheet::mightBeRichText( text ) ) { - TQFont f = TQApplication::font( this ); - doc = new TQSimpleRichText( text, f ); - doc->adjustSize(); - r.setRect( 0, 0, doc->width(), doc->height() ); - } - else -#endif - { - int sw = TQApplication::desktop()->width() / 3; - if ( sw < 200 ) - sw = 200; - else if ( sw > 300 ) - sw = 300; - - r = fontMetrics().boundingRect( 0, 0, sw, 1000, - AlignAuto + AlignTop + WordBreak + ExpandTabs, - text ); - } -#if defined(TQ_WS_WIN) - if ( (qWinVersion()&WV_NT_based) > WV_2000 ) { - BOOL shadow; - SystemParametersInfo( SPI_GETDROPSHADOW, 0, &shadow, 0 ); - shadowWidth = shadow ? 0 : 6; - } -#endif - resize( r.width() + 2*hMargin + shadowWidth, r.height() + 2*vMargin + shadowWidth ); -} - -TQWhatsThat::~TQWhatsThat() -{ - if ( wt && wt->whatsThat == this ) - wt->whatsThat = 0; -#ifndef TQT_NO_RICHTEXT - if ( doc ) - delete doc; -#endif -} - -void TQWhatsThat::hide() -{ - TQWidget::hide(); -#if defined(QT_ACCESSIBILITY_SUPPORT) - TQAccessible::updateAccessibility( this, 0, TQAccessible::ContextHelpEnd ); -#endif -} - -void TQWhatsThat::mousePressEvent( TQMouseEvent* e ) -{ - pressed = TRUE; - if ( e->button() == LeftButton && rect().contains( e->pos() ) ) { -#ifndef TQT_NO_RICHTEXT - if ( doc ) - anchor = doc->anchorAt( e->pos() - TQPoint( hMargin, vMargin) ); -#endif - return; - } - hide(); -} - -void TQWhatsThat::mouseReleaseEvent( TQMouseEvent* e ) -{ - if ( !pressed ) - return; -#ifndef TQT_NO_RICHTEXT - if ( e->button() == LeftButton && doc && rect().contains( e->pos() ) ) { - TQString a = doc->anchorAt( e->pos() - TQPoint( hMargin, vMargin ) ); - TQString href; - if ( anchor == a ) - href = a; - anchor = TQString::null; - if ( widget && wt && wt->dict ) { - TQWhatsThisPrivate::WhatsThisItem * i = wt->dict->find( widget ); - if ( i && i->whatsthis && !i->whatsthis->clicked( href ) ) - return; - } - } -#endif - hide(); -} - -void TQWhatsThat::mouseMoveEvent( TQMouseEvent* e) -{ -#ifndef TQT_NO_RICHTEXT -#ifndef TQT_NO_CURSOR - if ( !doc ) - return; - TQString a = doc->anchorAt( e->pos() - TQPoint( hMargin, vMargin ) ); - if ( !a.isEmpty() ) - setCursor( pointingHandCursor ); - else - setCursor( arrowCursor ); -#endif -#endif -} - - -void TQWhatsThat::keyPressEvent( TQKeyEvent* ) -{ - hide(); -} - - - -void TQWhatsThat::paintEvent( TQPaintEvent* ) -{ - bool drawShadow = TRUE; -#if defined(TQ_WS_WIN) - if ( (qWinVersion()&WV_NT_based) > WV_2000 ) { - BOOL shadow; - SystemParametersInfo( SPI_GETDROPSHADOW, 0, &shadow, 0 ); - drawShadow = !shadow; - } -#elif defined(TQ_WS_MACX) - drawShadow = FALSE; //never draw it on OS X we get it for free -#endif - - TQRect r = rect(); - if ( drawShadow ) - r.addCoords( 0, 0, -shadowWidth, -shadowWidth ); - TQPainter p( this); - p.setPen( colorGroup().foreground() ); - p.drawRect( r ); - p.setPen( colorGroup().mid() ); - p.setBrush( colorGroup().brush( TQColorGroup::Background ) ); - int w = r.width(); - int h = r.height(); - p.drawRect( 1, 1, w-2, h-2 ); - if ( drawShadow ) { - p.setPen( colorGroup().shadow() ); - p.drawPoint( w + 5, 6 ); - p.drawLine( w + 3, 6, w + 5, 8 ); - p.drawLine( w + 1, 6, w + 5, 10 ); - int i; - for( i=7; i < h; i += 2 ) - p.drawLine( w, i, w + 5, i + 5 ); - for( i = w - i + h; i > 6; i -= 2 ) - p.drawLine( i, h, i + 5, h + 5 ); - for( ; i > 0 ; i -= 2 ) - p.drawLine( 6, h + 6 - i, i + 5, h + 5 ); - } - p.setPen( colorGroup().foreground() ); - r.addCoords( hMargin, vMargin, -hMargin, -vMargin ); - -#ifndef TQT_NO_RICHTEXT - if ( doc ) { - doc->draw( &p, r.x(), r.y(), r, colorGroup(), 0 ); - } - else -#endif - { - p.drawText( r, AlignAuto + AlignTop + WordBreak + ExpandTabs, text ); - } -} - -// the item -TQWhatsThisPrivate::WhatsThisItem::~WhatsThisItem() -{ - if ( count ) - tqFatal( "TQWhatsThis: Internal error (%d)", count ); - delete whatsthis; -} - - -static const char * const button_image[] = { -"16 16 3 1", -" c None", -"o c #000000", -"a c #000080", -"o aaaaa ", -"oo aaa aaa ", -"ooo aaa aaa", -"oooo aa aa", -"ooooo aa aa", -"oooooo a aaa", -"ooooooo aaa ", -"oooooooo aaa ", -"ooooooooo aaa ", -"ooooo aaa ", -"oo ooo ", -"o ooo aaa ", -" ooo aaa ", -" ooo ", -" ooo ", -" ooo "}; - -// the button class -TQWhatsThisButton::TQWhatsThisButton( TQWidget * parent, const char * name ) - : TQToolButton( parent, name ) -{ - TQPixmap p( (const char**)button_image ); - setPixmap( p ); - setToggleButton( TRUE ); - setAutoRaise( TRUE ); - setFocusPolicy( NoFocus ); - setTextLabel( tr( "What's this?" ) ); - wt->buttons->insert( (void *)this, this ); - connect( this, TQ_SIGNAL( released() ), - this, TQ_SLOT( mouseReleased() ) ); -} - - -TQWhatsThisButton::~TQWhatsThisButton() -{ - if ( wt && wt->buttons ) - wt->buttons->take( (void *)this ); -} - - -void TQWhatsThisButton::mouseReleased() -{ - if ( wt->state == TQWhatsThisPrivate::Inactive && isOn() ) { - TQWhatsThisPrivate::setUpWhatsThis(); -#ifndef TQT_NO_CURSOR - TQApplication::setOverrideCursor( whatsThisCursor, FALSE ); -#endif - wt->state = TQWhatsThisPrivate::Waiting; - tqApp->installEventFilter( wt ); - } -} - -static void qWhatsThisPrivateCleanup() -{ - if( wt ) { - delete wt; - wt = 0; - } -} - -// the what's this manager class -TQWhatsThisPrivate::TQWhatsThisPrivate() - : TQObject( 0, "global what's this object" ) -{ - whatsThat = 0; - dict = new TQPtrDict; - tlw = new TQPtrDict; - wt = this; - buttons = new TQPtrDict; - state = Inactive; -} - -TQWhatsThisPrivate::~TQWhatsThisPrivate() -{ -#ifndef TQT_NO_CURSOR - if ( state == Waiting && tqApp ) - TQApplication::restoreOverrideCursor(); -#endif - // the two straight-and-simple dicts - delete tlw; - delete buttons; - - // then delete the complex one. - TQPtrDictIterator it( *dict ); - WhatsThisItem * i; - TQWidget * w; - while( (i=it.current()) != 0 ) { - w = (TQWidget *)it.currentKey(); - ++it; - dict->take( w ); - if ( i->deref() ) - delete i; - } - delete dict; - if ( whatsThat && !whatsThat->parentWidget() ) { - delete whatsThat; - } - // and finally lose wt - wt = 0; -} - -bool TQWhatsThisPrivate::eventFilter( TQObject * o, TQEvent * e ) -{ - switch( state ) { - case Waiting: - if ( e->type() == TQEvent::MouseButtonPress && o->isWidgetType() ) { - TQWidget * w = (TQWidget *) o; - if ( ( (TQMouseEvent*)e)->button() == RightButton ) - return FALSE; // ignore RMB - if ( w->customWhatsThis() ) - return FALSE; - TQWhatsThisPrivate::WhatsThisItem * i = 0; - TQMouseEvent* me = (TQMouseEvent*) e; - TQPoint p = me->pos(); - while( w && !i ) { - i = dict->find( w ); - if ( !i ) { - p += w->pos(); - w = w->parentWidget( TRUE ); - } - } - leaveWhatsThisMode(); - if (!i ) { -#if defined(QT_ACCESSIBILITY_SUPPORT) - TQAccessible::updateAccessibility( this, 0, TQAccessible::ContextHelpEnd ); -#endif - return TRUE; - } - if ( i->whatsthis ) - say( w, i->whatsthis->text( p ), me->globalPos() ); - else - say( w, i->s, me->globalPos() ); - return TRUE; - } else if ( e->type() == TQEvent::MouseButtonRelease ) { - if ( ( (TQMouseEvent*)e)->button() == RightButton ) - return FALSE; // ignore RMB - return !o->isWidgetType() || !((TQWidget*)o)->customWhatsThis(); - } else if ( e->type() == TQEvent::MouseMove ) { - return !o->isWidgetType() || !((TQWidget*)o)->customWhatsThis(); - } else if ( e->type() == TQEvent::KeyPress ) { - TQKeyEvent* kev = (TQKeyEvent*)e; - - if ( kev->key() == TQt::Key_Escape ) { - leaveWhatsThisMode(); - return TRUE; - } else if ( o->isWidgetType() && ((TQWidget*)o)->customWhatsThis() ) { - return FALSE; - } else if ( kev->key() == Key_Menu || - ( kev->key() == Key_F10 && - kev->state() == ShiftButton ) ) { - // we don't react to these keys, they are used for context menus - return FALSE; - } else if ( kev->state() == kev->stateAfter() && - kev->key() != Key_Meta ) { // not a modifier key - leaveWhatsThisMode(); - } - } else if ( e->type() == TQEvent::MouseButtonDblClick ) { - return TRUE; - } - break; - case Inactive: - if ( e->type() == TQEvent::Accel && - ((TQKeyEvent *)e)->key() == Key_F1 && - o->isWidgetType() && - ((TQKeyEvent *)e)->state() == ShiftButton ) { - TQWidget * w = ((TQWidget *)o)->focusWidget(); - if ( !w ) - break; - TQString s = TQWhatsThis::textFor( w, TQPoint(0,0), TRUE ); - if ( !s.isNull() ) { - say ( w, s, w->mapToGlobal( w->rect().center() ) ); - ((TQKeyEvent *)e)->accept(); - return TRUE; - } - } - break; - } - return FALSE; -} - - - -void TQWhatsThisPrivate::setUpWhatsThis() -{ - if ( !wt ) { - wt = new TQWhatsThisPrivate(); - - // It is necessary to use a post routine, because - // the destructor deletes pixmaps and other stuff that - // needs a working X connection under X11. - tqAddPostRoutine( qWhatsThisPrivateCleanup ); - } -} - - -void TQWhatsThisPrivate::enterWhatsThisMode() -{ -#if defined(QT_ACCESSIBILITY_SUPPORT) - TQAccessible::updateAccessibility( this, 0, TQAccessible::ContextHelpStart ); -#endif -} - - -void TQWhatsThisPrivate::leaveWhatsThisMode() -{ - if ( state == Waiting ) { - TQPtrDictIterator it( *(wt->buttons) ); - TQWhatsThisButton * b; - while( (b=it.current()) != 0 ) { - ++it; - b->setOn( FALSE ); - } -#ifndef TQT_NO_CURSOR - TQApplication::restoreOverrideCursor(); -#endif - state = Inactive; - tqApp->removeEventFilter( this ); - } -} - - - -void TQWhatsThisPrivate::say( TQWidget * widget, const TQString &text, const TQPoint& ppos) -{ - if ( text.isEmpty() ) - return; - // make a fresh widget, and set it up - delete whatsThat; - whatsThat = new TQWhatsThat( - widget, text, -#if defined(TQ_WS_X11) - TQApplication::desktop()->screen( widget ? - widget->x11Screen() : - TQCursor::x11Screen() ), -#else - 0, -#endif - "automatic what's this? widget" ); - - - // okay, now to find a suitable location - - int scr = ( widget ? - TQApplication::desktop()->screenNumber( widget ) : -#if defined(TQ_WS_X11) - TQCursor::x11Screen() -#else - TQApplication::desktop()->screenNumber( ppos ) -#endif // TQ_WS_X11 - ); - TQRect screen = TQApplication::desktop()->screenGeometry( scr ); - - int x; - int w = whatsThat->width(); - int h = whatsThat->height(); - int sx = screen.x(); - int sy = screen.y(); - - // first try locating the widget immediately above/below, - // with nice alignment if possible. - TQPoint pos; - if ( widget ) - pos = widget->mapToGlobal( TQPoint( 0,0 ) ); - - if ( widget && w > widget->width() + 16 ) - x = pos.x() + widget->width()/2 - w/2; - else - x = ppos.x() - w/2; - - // squeeze it in if that would result in part of what's this - // being only partially visible - if ( x + w + shadowWidth > sx+screen.width() ) - x = (widget? (TQMIN(screen.width(), - pos.x() + widget->width()) - ) : screen.width() ) - - w; - - if ( x < sx ) - x = sx; - - int y; - if ( widget && h > widget->height() + 16 ) { - y = pos.y() + widget->height() + 2; // below, two pixels spacing - // what's this is above or below, wherever there's most space - if ( y + h + 10 > sy+screen.height() ) - y = pos.y() + 2 - shadowWidth - h; // above, overlap - } - y = ppos.y() + 2; - - // squeeze it in if that would result in part of what's this - // being only partially visible - if ( y + h + shadowWidth > sy+screen.height() ) - y = ( widget ? (TQMIN(screen.height(), - pos.y() + widget->height()) - ) : screen.height() ) - - h; - if ( y < sy ) - y = sy; - - whatsThat->move( x, y ); - whatsThat->show(); -} - -TQWhatsThisPrivate::WhatsThisItem* TQWhatsThisPrivate::newItem( TQWidget * widget ) -{ - WhatsThisItem * i = dict->find( (void *)widget ); - if ( i ) - TQWhatsThis::remove( widget ); - i = new WhatsThisItem; - dict->insert( (void *)widget, i ); - TQWidget * t = widget->topLevelWidget(); - if ( !tlw->find( (void *)t ) ) { - tlw->insert( (void *)t, t ); - t->installEventFilter( this ); - } - connect( widget, TQ_SIGNAL(destroyed()), this, TQ_SLOT(cleanupWidget()) ); - return i; -} - -void TQWhatsThisPrivate::add( TQWidget * widget, TQWhatsThis* special ) -{ - newItem( widget )->whatsthis = special; -} - -void TQWhatsThisPrivate::add( TQWidget * widget, const TQString &text ) -{ - newItem( widget )->s = text; -} - - -// and finally the What's This class itself - -/*! - Adds \a text as "What's this" help for \a widget. If the text is - rich text formatted (i.e. it contains markup) it will be rendered - with the default stylesheet TQStyleSheet::defaultSheet(). - - The text is destroyed if the widget is later destroyed, so it need - not be explicitly removed. - - \sa remove() -*/ -void TQWhatsThis::add( TQWidget * widget, const TQString &text ) -{ - if ( text.isEmpty() ) - return; // pointless - TQWhatsThisPrivate::setUpWhatsThis(); - wt->add(widget,text); -} - - -/*! - Removes the "What's this?" help associated with the \a widget. - This happens automatically if the widget is destroyed. - - \sa add() -*/ -void TQWhatsThis::remove( TQWidget * widget ) -{ - TQWhatsThisPrivate::setUpWhatsThis(); - TQWhatsThisPrivate::WhatsThisItem * i = wt->dict->find( (void *)widget ); - if ( !i ) - return; - - wt->dict->take( (void *)widget ); - - i->deref(); - if ( !i->count ) - delete i; -} - - -/*! - Returns the what's this text for widget \a w or TQString::null if - there is no "What's this?" help for the widget. \a pos contains - the mouse position; this is useful, for example, if you've - subclassed to make the text that is displayed position dependent. - - If \a includeParents is TRUE, parent widgets are taken into - consideration as well when looking for what's this help text. - - \sa add() -*/ -TQString TQWhatsThis::textFor( TQWidget * w, const TQPoint& pos, bool includeParents ) -{ - TQWhatsThisPrivate::setUpWhatsThis(); - TQWhatsThisPrivate::WhatsThisItem * i = 0; - TQPoint p = pos; - while( w && !i ) { - i = wt->dict->find( w ); - if ( !includeParents ) - break; - if ( !i ) { - p += w->pos(); - w = w->parentWidget( TRUE ); - } - } - if (!i) - return TQString::null; - if ( i->whatsthis ) - return i->whatsthis->text( p ); - return i->s; -} - - -/*! - Creates a TQToolButton preconfigured to enter "What's this?" mode - when clicked. You will often use this with a tool bar as \a - parent: - \code - (void) TQWhatsThis::whatsThisButton( my_help_tool_bar ); - \endcode -*/ -TQToolButton * TQWhatsThis::whatsThisButton( TQWidget * parent ) -{ - TQWhatsThisPrivate::setUpWhatsThis(); - return new TQWhatsThisButton( parent, - "automatic what's this? button" ); -} - -/*! - Constructs a dynamic "What's this?" object for \a widget. The - object is deleted when the \a widget is destroyed. - - When the widget is queried by the user the text() function of this - TQWhatsThis will be called to provide the appropriate text, rather - than using the text assigned by add(). -*/ -TQWhatsThis::TQWhatsThis( TQWidget * widget) -{ - TQWhatsThisPrivate::setUpWhatsThis(); - wt->add(widget,this); -} - - -/*! - Destroys the object and frees any allocated resources. -*/ -TQWhatsThis::~TQWhatsThis() -{ -} - - -/*! - This virtual function returns the text for position \e p in the - widget that this "What's this?" object documents. If there is no - "What's this?" text for the position, TQString::null is returned. - - The default implementation returns TQString::null. -*/ -TQString TQWhatsThis::text( const TQPoint & ) -{ - return TQString::null; -} - -/*! - \fn bool TQWhatsThis::clicked( const TQString& href ) - - This virtual function is called when the user clicks inside the - "What's this?" window. \a href is the link the user clicked on, or - TQString::null if there was no link. - - If the function returns TRUE (the default), the "What's this?" - window is closed, otherwise it remains visible. - - The default implementation ignores \a href and returns TRUE. -*/ -bool TQWhatsThis::clicked( const TQString& ) -{ - return TRUE; -} - - -/*! - Enters "What's this?" mode and returns immediately. - - TQt will install a special cursor and take over mouse input until - the user clicks somewhere. It then shows any help available and - ends "What's this?" mode. Finally, TQt removes the special cursor - and help window and then restores ordinary event processing, at - which point the left mouse button is no longer pressed. - - The user can also use the Esc key to leave "What's this?" mode. - - \sa inWhatsThisMode(), leaveWhatsThisMode() -*/ - -void TQWhatsThis::enterWhatsThisMode() -{ - TQWhatsThisPrivate::setUpWhatsThis(); - if ( wt->state == TQWhatsThisPrivate::Inactive ) { - wt->enterWhatsThisMode(); -#ifndef TQT_NO_CURSOR - TQApplication::setOverrideCursor( whatsThisCursor, FALSE ); -#endif - wt->state = TQWhatsThisPrivate::Waiting; - tqApp->installEventFilter( wt ); - } -} - - -/*! - Returns TRUE if the application is in "What's this?" mode; - otherwise returns FALSE. - - \sa enterWhatsThisMode(), leaveWhatsThisMode() -*/ -bool TQWhatsThis::inWhatsThisMode() -{ - if (!wt) - return FALSE; - return wt->state == TQWhatsThisPrivate::Waiting; -} - - -/*! - Leaves "What's this?" question mode. - - This function is used internally by widgets that support - TQWidget::customWhatsThis(); applications do not usually call it. - An example of such a widget is TQPopupMenu: menus still work - normally in "What's this?" mode but also provide help texts for - individual menu items. - - If \a text is not TQString::null, a "What's this?" help window is - displayed at the global screen position \a pos. If widget \a w is - not 0 and has its own dedicated TQWhatsThis object, this object - will receive clicked() messages when the user clicks on hyperlinks - inside the help text. - - \sa inWhatsThisMode(), enterWhatsThisMode(), TQWhatsThis::clicked() -*/ -void TQWhatsThis::leaveWhatsThisMode( const TQString& text, const TQPoint& pos, TQWidget* w ) -{ - if ( !inWhatsThisMode() ) - return; - - wt->leaveWhatsThisMode(); - if ( !text.isNull() ) - wt->say( w, text, pos ); -} - -/*! - Display \a text in a help window at the global screen position \a - pos. - - If widget \a w is not 0 and has its own dedicated TQWhatsThis - object, this object will receive clicked() messages when the user - clicks on hyperlinks inside the help text. - - \sa TQWhatsThis::clicked() -*/ -void TQWhatsThis::display( const TQString& text, const TQPoint& pos, TQWidget* w ) -{ - if ( inWhatsThisMode() ) { - leaveWhatsThisMode( text, pos, w ); - return; - } - TQWhatsThisPrivate::setUpWhatsThis(); - wt->say( w, text, pos ); -} - -/*! - Sets the font for all "What's this?" helps to \a font. -*/ -void TQWhatsThis::setFont( const TQFont &font ) -{ - TQApplication::setFont( font, TRUE, "TQWhatsThat" ); -} - -#include "qwhatsthis.moc" -#endif diff --git a/src/widgets/tqaction.cpp b/src/widgets/tqaction.cpp index 6bf1a50f8..31d308420 100644 --- a/src/widgets/tqaction.cpp +++ b/src/widgets/tqaction.cpp @@ -47,7 +47,7 @@ #include "tqtoolbutton.h" #include "ntqcombobox.h" #include "tqtooltip.h" -#include "ntqwhatsthis.h" +#include "tqwhatsthis.h" #include "tqstatusbar.h" #include "tqobjectlist.h" diff --git a/src/widgets/tqlabel.cpp b/src/widgets/tqlabel.cpp new file mode 100644 index 000000000..7f9d858bb --- /dev/null +++ b/src/widgets/tqlabel.cpp @@ -0,0 +1,1191 @@ +/********************************************************************** +** +** Implementation of TQLabel widget class +** +** Created : 941215 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "tqlabel.h" +#ifndef TQT_NO_LABEL +#include "tqpainter.h" +#include "ntqdrawutil.h" +#include "ntqaccel.h" +#include "tqmovie.h" +#include "tqimage.h" +#include "tqbitmap.h" +#include "tqpicture.h" +#include "ntqapplication.h" +#include "tqsimplerichtext.h" +#include "tqstylesheet.h" +#include "tqstyle.h" + +class TQLabelPrivate +{ +public: + TQLabelPrivate() + :img(0), pix(0), valid_hints( -1 ) + {} + TQImage* img; // for scaled contents + TQPixmap* pix; // for scaled contents + TQSize sh; + TQSize msh; + int valid_hints; // stores the frameWidth() for the stored size hint, -1 otherwise +}; + + +/*! + \class TQLabel tqlabel.h + \brief The TQLabel widget provides a text or image display. + + \ingroup basic + \ingroup text + \mainclass + + TQLabel is used for displaying text or an image. No user + interaction functionality is provided. The visual appearance of + the label can be configured in various ways, and it can be used + for specifying a focus accelerator key for another widget. + + A TQLabel can contain any of the following content types: + \table + \header \i Content \i Setting + \row \i Plain text + \i Pass a TQString to setText(). + \row \i Rich text + \i Pass a TQString that contains rich text to setText(). + \row \i A pixmap + \i Pass a TQPixmap to setPixmap(). + \row \i A movie + \i Pass a TQMovie to setMovie(). + \row \i A number + \i Pass an \e int or a \e double to setNum(), which converts + the number to plain text. + \row \i Nothing + \i The same as an empty plain text. This is the default. Set + by clear(). + \endtable + + When the content is changed using any of these functions, any + previous content is cleared. + + The look of a TQLabel can be tuned in several ways. All the + settings of TQFrame are available for specifying a widget frame. + The positioning of the content within the TQLabel widget area can + be tuned with setAlignment() and setIndent(). For example, this + code sets up a sunken panel with a two-line text in the bottom + right corner (both lines being flush with the right side of the + label): + \code + TQLabel *label = new TQLabel( this ); + label->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); + label->setText( "first line\nsecond line" ); + label->setAlignment( AlignBottom | AlignRight ); + \endcode + + A TQLabel is often used as a label for an interactive widget. For + this use TQLabel provides a useful mechanism for adding an + accelerator key (see TQAccel) that will set the keyboard focus to + the other widget (called the TQLabel's "buddy"). For example: + \code + TQLineEdit* phoneEdit = new TQLineEdit( this, "phoneEdit" ); + TQLabel* phoneLabel = new TQLabel( phoneEdit, "&Phone:", this, "phoneLabel" ); + \endcode + + In this example, keyboard focus is transferred to the label's + buddy (the TQLineEdit) when the user presses Alt+P. You can + also use the setBuddy() function to accomplish the same thing. + + + + \sa TQLineEdit, TQTextEdit, TQPixmap, TQMovie, + \link guibooks.html#fowler GUI Design Handbook: Label\endlink +*/ + +/*! + \fn TQPicture * TQLabel::picture() const + + Returns the label's picture or 0 if the label doesn't have a + picture. +*/ + + +/*! + Constructs an empty label. + + The \a parent, \a name and widget flag \a f, arguments are passed + to the TQFrame constructor. + + \sa setAlignment(), setFrameStyle(), setIndent() +*/ + +TQLabel::TQLabel( TQWidget *parent, const char *name, WFlags f ) + : TQFrame( parent, name, f | WMouseNoMask ) +{ + init(); +} + + +/*! + Constructs a label that displays the text, \a text. + + The \a parent, \a name and widget flag \a f, arguments are passed + to the TQFrame constructor. + + \sa setText(), setAlignment(), setFrameStyle(), setIndent() +*/ + +TQLabel::TQLabel( const TQString &text, TQWidget *parent, const char *name, + WFlags f ) + : TQFrame( parent, name, f | WMouseNoMask ) +{ + init(); + setText( text ); +} + + +/*! + Constructs a label that displays the text \a text. The label has a + buddy widget, \a buddy. + + If the \a text contains an underlined letter (a letter preceded by + an ampersand, \&), and the text is in plain text format, when the + user presses Alt+ the underlined letter, focus is passed to the + buddy widget. + + The \a parent, \a name and widget flag, \a f, arguments are passed + to the TQFrame constructor. + + \sa setText(), setBuddy(), setAlignment(), setFrameStyle(), + setIndent() +*/ +TQLabel::TQLabel( TQWidget *buddy, const TQString &text, + TQWidget *parent, const char *name, WFlags f ) + : TQFrame( parent, name, f | WMouseNoMask ) +{ + init(); +#ifndef TQT_NO_ACCEL + setBuddy( buddy ); +#endif + setText( text ); +} + +/*! + Destroys the label. +*/ + +TQLabel::~TQLabel() +{ + clearContents(); + delete d; +} + + +void TQLabel::init() +{ + lpixmap = 0; +#ifndef TQT_NO_MOVIE + lmovie = 0; +#endif +#ifndef TQT_NO_ACCEL + lbuddy = 0; + accel = 0; +#endif + lpixmap = 0; +#ifndef TQT_NO_PICTURE + lpicture = 0; +#endif + align = AlignAuto | AlignVCenter | ExpandTabs; + extraMargin = -1; + autoresize = FALSE; + scaledcontents = FALSE; + textformat = TQt::AutoText; +#ifndef TQT_NO_RICHTEXT + doc = 0; +#endif + + setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) ); + d = new TQLabelPrivate; +} + + +/*! + \property TQLabel::text + \brief the label's text + + If no text has been set this will return an empty string. Setting + the text clears any previous content, unless they are the same. + + The text will be interpreted either as a plain text or as a rich + text, depending on the text format setting; see setTextFormat(). + The default setting is \c AutoText, i.e. TQLabel will try to + auto-detect the format of the text set. + + If the text is interpreted as a plain text and a buddy has been + set, the buddy accelerator key is updated from the new text. + + The label resizes itself if auto-resizing is enabled. + + Note that TQLabel is well-suited to display small rich text + documents, i.e. those small documents that get their document + specific settings (font, text color, link color) from the label's + palette and font properties. For large documents, use TQTextEdit + in read-only mode instead. TQTextEdit will flicker less on resize + and can also provide a scrollbar when necessary. + + \sa text, setTextFormat(), setBuddy(), alignment +*/ + +void TQLabel::setText( const TQString &text ) +{ + if ( ltext == text ) + return; + TQSize osh = sizeHint(); +#ifndef TQT_NO_RICHTEXT + bool hadRichtext = doc != 0; +#endif + clearContents(); + ltext = text; +#ifndef TQT_NO_RICHTEXT + bool useRichText = (textformat == RichText || + ( ( textformat == AutoText ) && TQStyleSheet::mightBeRichText(ltext) ) ); +#else + bool useRichText = TRUE; +#endif +#ifndef TQT_NO_ACCEL + // ### Setting accelerators for rich text labels will not work. + // Eg. >Hello will return ALT+G which is clearly + // not intended. + if ( !useRichText ) { + int p = TQAccel::shortcutKey( ltext ); + if ( p ) { + if ( !accel ) + accel = new TQAccel( this, "accel label accel" ); + accel->connectItem( accel->insertItem( p ), + this, TQ_SLOT(acceleratorSlot()) ); + } + } +#endif +#ifndef TQT_NO_RICHTEXT + if ( useRichText ) { + if ( !hadRichtext ) + align |= WordBreak; + TQString t = ltext; + if ( align & AlignRight ) + t.prepend( "
"); + else if ( align & AlignHCenter ) + t.prepend( "
"); + if ( (align & WordBreak) == 0 ) + t.prepend( "" ); + doc = new TQSimpleRichText( t, font() ); + } +#endif + + updateLabel( osh ); +} + + +/*! + Clears any label contents. Equivalent to setText( "" ). +*/ + +void TQLabel::clear() +{ + setText( TQString::fromLatin1("") ); +} + +/*! + \property TQLabel::pixmap + \brief the label's pixmap + + If no pixmap has been set this will return an invalid pixmap. + + Setting the pixmap clears any previous content, and resizes the + label if \l TQLabel::autoResize() is TRUE. The buddy accelerator, + if any, is disabled. +*/ +void TQLabel::setPixmap( const TQPixmap &pixmap ) +{ + TQSize osh = sizeHint(); + + if ( !lpixmap || lpixmap->serialNumber() != pixmap.serialNumber() ) { + clearContents(); + lpixmap = new TQPixmap( pixmap ); + } + + if ( lpixmap->depth() == 1 && !lpixmap->mask() ) + lpixmap->setMask( *((TQBitmap *)lpixmap) ); + + updateLabel( osh ); +} + +#ifndef TQT_NO_PICTURE +/*! + Sets the label contents to \a picture. Any previous content is + cleared. + + The buddy accelerator, if any, is disabled. + + \sa picture(), setBuddy() +*/ + +void TQLabel::setPicture( const TQPicture &picture ) +{ + TQSize osh = sizeHint(); + clearContents(); + lpicture = new TQPicture( picture ); + + updateLabel( osh ); +} +#endif // TQT_NO_PICTURE + +/*! + Sets the label contents to plain text containing the textual + representation of integer \a num. Any previous content is cleared. + Does nothing if the integer's string representation is the same as + the current contents of the label. + + The buddy accelerator, if any, is disabled. + + The label resizes itself if auto-resizing is enabled. + + \sa setText(), TQString::setNum(), setBuddy() +*/ + +void TQLabel::setNum( int num ) +{ + TQString str; + str.setNum( num ); + setText( str ); +} + +/*! + \overload + + Sets the label contents to plain text containing the textual + representation of double \a num. Any previous content is cleared. + Does nothing if the double's string representation is the same as + the current contents of the label. + + The buddy accelerator, if any, is disabled. + + The label resizes itself if auto-resizing is enabled. + + \sa setText(), TQString::setNum(), setBuddy() +*/ + +void TQLabel::setNum( double num ) +{ + TQString str; + str.setNum( num ); + setText( str ); +} + +/*! + \property TQLabel::alignment + \brief the alignment of the label's contents + + The alignment is a bitwise OR of \c TQt::AlignmentFlags and \c + TQt::TextFlags values. The \c ExpandTabs, \c SingleLine and \c + ShowPrefix flags apply only if the label contains plain text; + otherwise they are ignored. The \c DontClip flag is always + ignored. \c WordBreak applies to both rich text and plain text + labels. The \c BreakAnywhere flag is not supported in TQLabel. + + If the label has a buddy, the \c ShowPrefix flag is forced to + TRUE. + + The default alignment is \c{AlignAuto | AlignVCenter | ExpandTabs} + if the label doesn't have a buddy and \c{AlignAuto | AlignVCenter + | ExpandTabs | ShowPrefix} if the label has a buddy. If the label + contains rich text, additionally \c WordBreak is turned on. + + \sa TQt::AlignmentFlags, alignment, setBuddy(), text +*/ + +void TQLabel::setAlignment( int alignment ) +{ + if ( alignment == align ) + return; + TQSize osh = sizeHint(); +#ifndef TQT_NO_ACCEL + if ( lbuddy ) + align = alignment | ShowPrefix; + else +#endif + align = alignment; + +#ifndef TQT_NO_RICHTEXT + TQString t = ltext; + if ( !t.isNull() ) { + ltext = TQString::null; + setText( t ); + } +#endif + + updateLabel( osh ); +} + + +/*! + \property TQLabel::indent + \brief the label's text indent in pixels + + If a label displays text, the indent applies to the left edge if + alignment() is \c AlignLeft, to the right edge if alignment() is + \c AlignRight, to the top edge if alignment() is \c AlignTop, and + to to the bottom edge if alignment() is \c AlignBottom. + + If indent is negative, or if no indent has been set, the label + computes the effective indent as follows: If frameWidth() is 0, + the effective indent becomes 0. If frameWidth() is greater than 0, + the effective indent becomes half the width of the "x" character + of the widget's current font(). + + \sa alignment, frameWidth(), font() +*/ + +void TQLabel::setIndent( int indent ) +{ + extraMargin = indent; + updateLabel( TQSize( -1, -1 ) ); +} + + +/*! + \fn bool TQLabel::autoResize() const + + \obsolete + + Returns TRUE if auto-resizing is enabled, or FALSE if auto-resizing + is disabled. + + Auto-resizing is disabled by default. + + \sa setAutoResize() +*/ + +/*! \obsolete + Enables auto-resizing if \a enable is TRUE, or disables it if \a + enable is FALSE. + + When auto-resizing is enabled the label will resize itself to fit + the contents whenever the contents change. The top-left corner is + not moved. This is useful for TQLabel widgets that are not managed by + a TQLayout (e.g., top-level widgets). + + Auto-resizing is disabled by default. + + \sa autoResize(), adjustSize(), sizeHint() +*/ + +void TQLabel::setAutoResize( bool enable ) +{ + if ( (bool)autoresize != enable ) { + autoresize = enable; + if ( autoresize ) + adjustSize(); // calls resize which repaints + } +} + + + +/*! + Returns the size that will be used if the width of the label is \a + w. If \a w is -1, the sizeHint() is returned. +*/ + +TQSize TQLabel::sizeForWidth( int w ) const +{ + TQRect br; + TQPixmap *pix = pixmap(); +#ifndef TQT_NO_PICTURE + TQPicture *pic = picture(); +#else + const int pic = 0; +#endif +#ifndef TQT_NO_MOVIE + TQMovie *mov = movie(); +#else + const int mov = 0; +#endif + int hextra = 2 * frameWidth(); + int vextra = hextra; + TQFontMetrics fm( fontMetrics() ); + int xw = fm.width( 'x' ); + if ( !mov && !pix && !pic ) { + int m = indent(); + if ( m < 0 && hextra ) // no indent, but we do have a frame + m = xw / 2 - margin(); + if ( m >= 0 ) { + int horizAlign = TQApplication::horizontalAlignment( align ); + if ( (horizAlign & AlignLeft) || (horizAlign & AlignRight ) ) + hextra += m; + if ( (align & AlignTop) || (align & AlignBottom ) ) + vextra += m; + } + } + + if ( pix ) + br = pix->rect(); +#ifndef TQT_NO_PICTURE + else if ( pic ) + br = pic->boundingRect(); +#endif +#ifndef TQT_NO_MOVIE + else if ( mov ) + br = mov->framePixmap().rect(); +#endif +#ifndef TQT_NO_RICHTEXT + else if ( doc ) { + int oldW = doc->width(); + if ( align & WordBreak ) { + if ( w < 0 ) + doc->adjustSize(); + else + doc->setWidth( w-hextra ); + } + br = TQRect( 0, 0, doc->widthUsed(), doc->height() ); + doc->setWidth( oldW ); + } +#endif + else { + bool tryWidth = (w < 0) && (align & WordBreak); + if ( tryWidth ) + w = xw * 80; + else if ( w < 0 ) + w = 2000; + w -= hextra; + br = fm.boundingRect( 0, 0, w ,2000, alignment(), text() ); + if ( tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2 ) + br = fm.boundingRect( 0, 0, w/2, 2000, alignment(), text() ); + if ( tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4 ) + br = fm.boundingRect( 0, 0, w/4, 2000, alignment(), text() ); + } + int wid = br.width() + hextra; + int hei = br.height() + vextra; + + return TQSize( wid, hei ); +} + + +/*! + \reimp +*/ + +int TQLabel::heightForWidth( int w ) const +{ + if ( +#ifndef TQT_NO_RICHTEXT + doc || +#endif + (align & WordBreak) ) + return sizeForWidth( w ).height(); + return TQWidget::heightForWidth( w ); +} + + + +/*!\reimp +*/ +TQSize TQLabel::sizeHint() const +{ + if ( d->valid_hints != frameWidth() ) + (void) TQLabel::minimumSizeHint(); + return d->sh; +} + +/*! + \reimp +*/ + +TQSize TQLabel::minimumSizeHint() const +{ + if ( d->valid_hints == frameWidth() ) + return d->msh; + + constPolish(); + d->valid_hints = frameWidth(); + d->sh = sizeForWidth( -1 ); + TQSize sz( -1, -1 ); + + if ( +#ifndef TQT_NO_RICHTEXT + !doc && +#endif + (align & WordBreak) == 0 ) { + sz = d->sh; + } else { + // think about caching these for performance + sz.rwidth() = sizeForWidth( 0 ).width(); + sz.rheight() = sizeForWidth(TQWIDGETSIZE_MAX).height(); + if ( d->sh.height() < sz.height() ) + sz.rheight() = d->sh.height(); + } + if ( sizePolicy().horData() == TQSizePolicy::Ignored ) + sz.rwidth() = -1; + if ( sizePolicy().verData() == TQSizePolicy::Ignored ) + sz.rheight() = -1; + d->msh = sz; + return sz; +} + +/*! + \reimp +*/ +void TQLabel::resizeEvent( TQResizeEvent* e ) +{ + TQFrame::resizeEvent( e ); + +#ifdef TQT_NO_RICHTEXT + static const bool doc = FALSE; +#endif + + // optimize for standard labels + if ( frameShape() == NoFrame && (align & WordBreak) == 0 && !doc && + ( e->oldSize().width() >= e->size().width() && (align & AlignLeft ) == AlignLeft ) + && ( e->oldSize().height() >= e->size().height() && (align & AlignTop ) == AlignTop ) ) { + setWFlags( WResizeNoErase ); + return; + } + + clearWFlags( WResizeNoErase ); + TQRect cr = contentsRect(); + if ( !lpixmap || !cr.isValid() || + // masked pixmaps can only reduce flicker when being top/left + // aligned and when we do not perform scaled contents + ( lpixmap->hasAlpha() && ( scaledcontents || ( ( align & (AlignLeft|AlignTop) ) != (AlignLeft|AlignTop) ) ) ) ) + return; + + setWFlags( WResizeNoErase ); + + if ( !scaledcontents ) { + // don't we all love TQFrame? Reduce pixmap flicker + TQRegion reg = TQRect( TQPoint(0, 0), e->size() ); + reg = reg.subtract( cr ); + int x = cr.x(); + int y = cr.y(); + int w = lpixmap->width(); + int h = lpixmap->height(); + if ( (align & TQt::AlignVCenter) == TQt::AlignVCenter ) + y += cr.height()/2 - h/2; + else if ( (align & TQt::AlignBottom) == TQt::AlignBottom) + y += cr.height() - h; + if ( (align & TQt::AlignRight) == TQt::AlignRight ) + x += cr.width() - w; + else if ( (align & TQt::AlignHCenter) == TQt::AlignHCenter ) + x += cr.width()/2 - w/2; + if ( x > cr.x() ) + reg = reg.unite( TQRect( cr.x(), cr.y(), x - cr.x(), cr.height() ) ); + if ( y > cr.y() ) + reg = reg.unite( TQRect( cr.x(), cr.y(), cr.width(), y - cr.y() ) ); + + if ( x + w < cr.right() ) + reg = reg.unite( TQRect( x + w, cr.y(), cr.right() - x - w, cr.height() ) ); + if ( y + h < cr.bottom() ) + reg = reg.unite( TQRect( cr.x(), y + h, cr.width(), cr.bottom() - y - h ) ); + + erase( reg ); + } +} + + +/*! + Draws the label contents using the painter \a p. +*/ + +void TQLabel::drawContents( TQPainter *p ) +{ + TQRect cr = contentsRect(); + + TQPixmap *pix = pixmap(); +#ifndef TQT_NO_PICTURE + TQPicture *pic = picture(); +#else + const int pic = 0; +#endif +#ifndef TQT_NO_MOVIE + TQMovie *mov = movie(); +#else + const int mov = 0; +#endif + + if ( !mov && !pix && !pic ) { + int m = indent(); + if ( m < 0 && frameWidth() ) // no indent, but we do have a frame + m = fontMetrics().width('x') / 2 - margin(); + if ( m > 0 ) { + int hAlign = TQApplication::horizontalAlignment( align ); + if ( hAlign & AlignLeft ) + cr.setLeft( cr.left() + m ); + if ( hAlign & AlignRight ) + cr.setRight( cr.right() - m ); + if ( align & AlignTop ) + cr.setTop( cr.top() + m ); + if ( align & AlignBottom ) + cr.setBottom( cr.bottom() - m ); + } + } + +#ifndef TQT_NO_MOVIE + if ( mov ) { + // ### should add movie to qDrawItem + TQRect r = style().itemRect( p, cr, align, isEnabled(), &(mov->framePixmap()), + TQString::null ); + // ### could resize movie frame at this point + p->drawPixmap(r.x(), r.y(), mov->framePixmap() ); + } + else +#endif +#ifndef TQT_NO_RICHTEXT + if ( doc ) { + doc->setWidth(p, cr.width() ); + int rh = doc->height(); + int yo = 0; + if ( align & AlignVCenter ) + yo = (cr.height()-rh)/2; + else if ( align & AlignBottom ) + yo = cr.height()-rh; + if (! isEnabled() && + style().styleHint(TQStyle::SH_EtchDisabledText, this)) { + TQColorGroup cg = colorGroup(); + cg.setColor( TQColorGroup::Text, cg.light() ); + doc->draw(p, cr.x()+1, cr.y()+yo+1, cr, cg, 0); + } + + // TQSimpleRichText always draws with TQColorGroup::Text as with + // background mode PaletteBase. TQLabel typically has + // background mode PaletteBackground, so we create a temporary + // color group with the text color adjusted. + TQColorGroup cg = colorGroup(); + if ( backgroundMode() != PaletteBase && isEnabled() ) + cg.setColor( TQColorGroup::Text, paletteForegroundColor() ); + + doc->draw(p, cr.x(), cr.y()+yo, cr, cg, 0); + } else +#endif +#ifndef TQT_NO_PICTURE + if ( pic ) { + TQRect br = pic->boundingRect(); + int rw = br.width(); + int rh = br.height(); + if ( scaledcontents ) { + p->save(); + p->translate( cr.x(), cr.y() ); +#ifndef TQT_NO_TRANSFORMATIONS + p->scale( (double)cr.width()/rw, (double)cr.height()/rh ); +#endif + p->drawPicture( -br.x(), -br.y(), *pic ); + p->restore(); + } else { + int xo = 0; + int yo = 0; + if ( align & AlignVCenter ) + yo = (cr.height()-rh)/2; + else if ( align & AlignBottom ) + yo = cr.height()-rh; + if ( align & AlignRight ) + xo = cr.width()-rw; + else if ( align & AlignHCenter ) + xo = (cr.width()-rw)/2; + p->drawPicture( cr.x()+xo-br.x(), cr.y()+yo-br.y(), *pic ); + } + } else +#endif + { +#ifndef TQT_NO_IMAGE_SMOOTHSCALE + if ( scaledcontents && pix ) { + if ( !d->img ) + d->img = new TQImage( lpixmap->convertToImage() ); + + if ( !d->pix ) + d->pix = new TQPixmap; + if ( d->pix->size() != cr.size() ) + d->pix->convertFromImage( d->img->smoothScale( cr.width(), cr.height() ) ); + pix = d->pix; + } +#endif + int alignment = align; + if ((align & ShowPrefix) && ((!style().styleHint(TQStyle::SH_UnderlineAccelerator, this)) || ((style().styleHint(TQStyle::SH_HideUnderlineAcceleratorWhenAltUp, this)) && (!style().acceleratorsShown())))) { + alignment |= NoAccel; + } + // ordinary text or pixmap label + style().drawItem( p, cr, alignment, colorGroup(), isEnabled(), + pix, ltext ); + } +} + + +/*! + Updates the label, but not the frame. +*/ + +void TQLabel::updateLabel( TQSize oldSizeHint ) +{ + d->valid_hints = -1; + TQSizePolicy policy = sizePolicy(); + bool wordBreak = align & WordBreak; + policy.setHeightForWidth( wordBreak ); + if ( policy != sizePolicy() ) + setSizePolicy( policy ); + if ( sizeHint() != oldSizeHint ) + updateGeometry(); + if ( autoresize ) { + adjustSize(); + update( contentsRect() ); + } else { + update( contentsRect() ); + } +} + + +/*! + \internal + + Internal slot, used to set focus for accelerator labels. +*/ +#ifndef TQT_NO_ACCEL +void TQLabel::acceleratorSlot() +{ + if ( !lbuddy ) + return; + TQWidget * w = lbuddy; + while ( w->focusProxy() ) + w = w->focusProxy(); + if ( !w->hasFocus() && + w->isEnabled() && + w->isVisible() && + w->focusPolicy() != NoFocus ) { + TQFocusEvent::setReason( TQFocusEvent::Shortcut ); + w->setFocus(); + TQFocusEvent::resetReason(); + } +} +#endif + +/*! + \internal + + Internal slot, used to clean up if the buddy widget dies. +*/ +#ifndef TQT_NO_ACCEL +void TQLabel::buddyDied() // I can't remember if I cried. +{ + lbuddy = 0; +} + +/*! + Sets this label's buddy to \a buddy. + + When the user presses the accelerator key indicated by this label, + the keyboard focus is transferred to the label's buddy widget. + + The buddy mechanism is only available for TQLabels that contain + plain text in which one letter is prefixed with an ampersand, \&. + This letter is set as the accelerator key. The letter is displayed + underlined, and the '\&' is not displayed (i.e. the \c ShowPrefix + alignment flag is turned on; see setAlignment()). + + In a dialog, you might create two data entry widgets and a label + for each, and set up the geometry layout so each label is just to + the left of its data entry widget (its "buddy"), for example: + \code + TQLineEdit *nameEd = new TQLineEdit( this ); + TQLabel *nameLb = new TQLabel( "&Name:", this ); + nameLb->setBuddy( nameEd ); + TQLineEdit *phoneEd = new TQLineEdit( this ); + TQLabel *phoneLb = new TQLabel( "&Phone:", this ); + phoneLb->setBuddy( phoneEd ); + // ( layout setup not shown ) + \endcode + + With the code above, the focus jumps to the Name field when the + user presses Alt+N, and to the Phone field when the user presses + Alt+P. + + To unset a previously set buddy, call this function with \a buddy + set to 0. + + \sa buddy(), setText(), TQAccel, setAlignment() +*/ + +void TQLabel::setBuddy( TQWidget *buddy ) +{ + if ( buddy ) + setAlignment( alignment() | ShowPrefix ); + else + setAlignment( alignment() & ~ShowPrefix ); + + if ( lbuddy ) + disconnect( lbuddy, TQ_SIGNAL(destroyed()), this, TQ_SLOT(buddyDied()) ); + + lbuddy = buddy; + + if ( !lbuddy ) + return; +#ifndef TQT_NO_RICHTEXT + if ( !( textformat == RichText || (textformat == AutoText && + TQStyleSheet::mightBeRichText(ltext) ) ) ) +#endif + { + int p = TQAccel::shortcutKey( ltext ); + if ( p ) { + if ( !accel ) + accel = new TQAccel( this, "accel label accel" ); + accel->connectItem( accel->insertItem( p ), + this, TQ_SLOT(acceleratorSlot()) ); + } + } + + connect( lbuddy, TQ_SIGNAL(destroyed()), this, TQ_SLOT(buddyDied()) ); +} + + +/*! + Returns this label's buddy, or 0 if no buddy is currently set. + + \sa setBuddy() +*/ + +TQWidget * TQLabel::buddy() const +{ + return lbuddy; +} +#endif //TQT_NO_ACCEL + + +#ifndef TQT_NO_MOVIE +void TQLabel::movieUpdated(const TQRect& rect) +{ + TQMovie *mov = movie(); + if ( mov && !mov->isNull() ) { + TQRect r = contentsRect(); + r = style().itemRect( 0, r, align, isEnabled(), &(mov->framePixmap()), + TQString::null ); + r.moveBy(rect.x(), rect.y()); + r.setWidth(TQMIN(r.width(), rect.width())); + r.setHeight(TQMIN(r.height(), rect.height())); + repaint( r, mov->framePixmap().mask() != 0 ); + } +} + +void TQLabel::movieResized( const TQSize& size ) +{ + d->valid_hints = -1; + if ( autoresize ) + adjustSize(); + movieUpdated( TQRect( TQPoint(0,0), size ) ); + updateGeometry(); +} + +/*! + Sets the label contents to \a movie. Any previous content is + cleared. + + The buddy accelerator, if any, is disabled. + + The label resizes itself if auto-resizing is enabled. + + \sa movie(), setBuddy() +*/ + +void TQLabel::setMovie( const TQMovie& movie ) +{ + TQSize osh = sizeHint(); + clearContents(); + + lmovie = new TQMovie( movie ); + lmovie->connectResize(this, TQ_SLOT(movieResized(const TQSize&))); + lmovie->connectUpdate(this, TQ_SLOT(movieUpdated(const TQRect&))); + + if ( !lmovie->running() ) // Assume that if the movie is running, + updateLabel( osh ); // resize/update signals will come soon enough +} + +#endif // TQT_NO_MOVIE + +/*! + \internal + + Clears any contents, without updating/repainting the label. +*/ + +void TQLabel::clearContents() +{ +#ifndef TQT_NO_RICHTEXT + delete doc; + doc = 0; +#endif + + delete lpixmap; + lpixmap = 0; +#ifndef TQT_NO_PICTURE + delete lpicture; + lpicture = 0; +#endif + delete d->img; + d->img = 0; + delete d->pix; + d->pix = 0; + + ltext = TQString::null; +#ifndef TQT_NO_ACCEL + if ( accel ) + accel->clear(); +#endif +#ifndef TQT_NO_MOVIE + if ( lmovie ) { + lmovie->disconnectResize(this, TQ_SLOT(movieResized(const TQSize&))); + lmovie->disconnectUpdate(this, TQ_SLOT(movieUpdated(const TQRect&))); + delete lmovie; + lmovie = 0; + } +#endif +} + + +#ifndef TQT_NO_MOVIE + +/*! + Returns a pointer to the label's movie, or 0 if no movie has been + set. + + \sa setMovie() +*/ + +TQMovie* TQLabel::movie() const +{ + return lmovie; +} + +#endif // TQT_NO_MOVIE + +/*! + \property TQLabel::backgroundMode + \brief the label's background mode + + Get this property with backgroundMode(). + + \sa TQWidget::setBackgroundMode() +*/ + +/*! + \property TQLabel::textFormat + \brief the label's text format + + See the \c TQt::TextFormat enum for an explanation of the possible + options. + + The default format is \c AutoText. + + \sa text +*/ + +TQt::TextFormat TQLabel::textFormat() const +{ + return textformat; +} + +void TQLabel::setTextFormat( TQt::TextFormat format ) +{ + if ( format != textformat ) { + textformat = format; + TQString t = ltext; + if ( !t.isNull() ) { + ltext = TQString::null; + setText( t ); + } + } +} + +/*! + \reimp +*/ + +void TQLabel::fontChange( const TQFont & ) +{ + if ( !ltext.isEmpty() ) { +#ifndef TQT_NO_RICHTEXT + if ( doc ) + doc->setDefaultFont( font() ); +#endif + updateLabel( TQSize( -1, -1 ) ); + } +} + +#ifndef TQT_NO_IMAGE_SMOOTHSCALE +/*! + \property TQLabel::scaledContents + \brief whether the label will scale its contents to fill all + available space. + + When enabled and the label shows a pixmap, it will scale the + pixmap to fill the available space. + + This property's default is FALSE. + + \sa setScaledContents() +*/ +bool TQLabel::hasScaledContents() const +{ + return scaledcontents; +} + +void TQLabel::setScaledContents( bool enable ) +{ + if ( (bool)scaledcontents == enable ) + return; + scaledcontents = enable; + if ( !enable ) { + delete d->img; + d->img = 0; + delete d->pix; + d->pix = 0; + } + update( contentsRect() ); +} + +#endif // TQT_NO_IMAGE_SMOOTHSCALE + +/*! + Sets the font used on the TQLabel to font \a f. +*/ + +void TQLabel::setFont( const TQFont &f ) +{ + TQFrame::setFont( f ); +} + +#endif // TQT_NO_LABEL diff --git a/src/widgets/tqlabel.h b/src/widgets/tqlabel.h new file mode 100644 index 000000000..f8d728807 --- /dev/null +++ b/src/widgets/tqlabel.h @@ -0,0 +1,174 @@ +/********************************************************************** +** +** Definition of TQLabel widget class +** +** Created : 941215 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TQLABEL_H +#define TQLABEL_H + +#ifndef QT_H +#include "ntqframe.h" +#endif // QT_H + +#ifndef TQT_NO_LABEL + +class TQSimpleRichText; +class TQLabelPrivate; + +class TQ_EXPORT TQLabel : public TQFrame +{ + TQ_OBJECT + TQ_PROPERTY( TQString text READ text WRITE setText ) + TQ_PROPERTY( TextFormat textFormat READ textFormat WRITE setTextFormat ) + TQ_PROPERTY( TQPixmap pixmap READ pixmap WRITE setPixmap ) + TQ_PROPERTY( bool scaledContents READ hasScaledContents WRITE setScaledContents ) + TQ_PROPERTY( Alignment alignment READ alignment WRITE setAlignment ) + TQ_PROPERTY( int indent READ indent WRITE setIndent ) + TQ_OVERRIDE( BackgroundMode backgroundMode DESIGNABLE true) + +public: + TQLabel( TQWidget *parent, const char* name=0, WFlags f=0 ); + TQLabel( const TQString &text, TQWidget *parent, const char* name=0, + WFlags f=0 ); + TQLabel( TQWidget *buddy, const TQString &, + TQWidget *parent, const char* name=0, WFlags f=0 ); + ~TQLabel(); + + TQString text() const { return ltext; } + TQPixmap *pixmap() const { return lpixmap; } +#ifndef TQT_NO_PICTURE + TQPicture *picture() const { return lpicture; } +#endif +#ifndef TQT_NO_MOVIE + TQMovie *movie() const; +#endif + + TextFormat textFormat() const; + void setTextFormat( TextFormat ); + + int alignment() const { return align; } + virtual void setAlignment( int ); + int indent() const { return extraMargin; } + void setIndent( int ); + + bool autoResize() const { return autoresize; } + virtual void setAutoResize( bool ); +#ifndef TQT_NO_IMAGE_SMOOTHSCALE + bool hasScaledContents() const; + void setScaledContents( bool ); +#endif + TQSize sizeHint() const; + TQSize minimumSizeHint() const; +#ifndef TQT_NO_ACCEL + virtual void setBuddy( TQWidget * ); + TQWidget *buddy() const; +#endif + int heightForWidth(int) const; + + void setFont( const TQFont &f ); + +public slots: + virtual void setText( const TQString &); + virtual void setPixmap( const TQPixmap & ); +#ifndef TQT_NO_PICTURE + virtual void setPicture( const TQPicture & ); +#endif +#ifndef TQT_NO_MOVIE + virtual void setMovie( const TQMovie & ); +#endif + virtual void setNum( int ); + virtual void setNum( double ); + void clear(); + +protected: + void drawContents( TQPainter * ); + void fontChange( const TQFont & ); + void resizeEvent( TQResizeEvent* ); + +private slots: +#ifndef TQT_NO_ACCEL + void acceleratorSlot(); + void buddyDied(); +#endif +#ifndef TQT_NO_MOVIE + void movieUpdated(const TQRect&); + void movieResized(const TQSize&); +#endif + +private: + void init(); + void clearContents(); + void updateLabel( TQSize oldSizeHint ); + TQSize sizeForWidth( int w ) const; + TQString ltext; + TQPixmap *lpixmap; +#ifndef TQT_NO_PICTURE + TQPicture *lpicture; +#endif +#ifndef TQT_NO_MOVIE + TQMovie * lmovie; +#endif +#ifndef TQT_NO_ACCEL + TQWidget * lbuddy; +#endif + ushort align; + short extraMargin; + uint autoresize:1; + uint scaledcontents :1; + TextFormat textformat; +#ifndef TQT_NO_RICHTEXT + TQSimpleRichText* doc; +#endif +#ifndef TQT_NO_ACCEL + TQAccel * accel; +#endif + TQLabelPrivate* d; + + friend class TQTipLabel; + +private: // Disabled copy constructor and operator= +#if defined(TQ_DISABLE_COPY) + TQLabel( const TQLabel & ); + TQLabel &operator=( const TQLabel & ); +#endif +}; + + +#endif // TQT_NO_LABEL + +#endif // TQLABEL_H diff --git a/src/widgets/tqmainwindow.cpp b/src/widgets/tqmainwindow.cpp index 071a330ff..7b66839db 100644 --- a/src/widgets/tqmainwindow.cpp +++ b/src/widgets/tqmainwindow.cpp @@ -57,7 +57,7 @@ #include "ntqscrollview.h" #include "tqtooltip.h" #include "tqdatetime.h" -#include "ntqwhatsthis.h" +#include "tqwhatsthis.h" #include "tqbitmap.h" #include "ntqdockarea.h" #include "tqstringlist.h" diff --git a/src/widgets/tqpopupmenu.cpp b/src/widgets/tqpopupmenu.cpp index 09961bf03..26aa7f9cc 100644 --- a/src/widgets/tqpopupmenu.cpp +++ b/src/widgets/tqpopupmenu.cpp @@ -48,7 +48,7 @@ #include "tqpixmap.h" #include "tqpixmapcache.h" #include "tqtimer.h" -#include "ntqwhatsthis.h" +#include "tqwhatsthis.h" #include "tqobjectlist.h" #include "ntqguardedptr.h" #include "qeffects_p.h" @@ -124,7 +124,7 @@ static void popupSubMenuLater( int msec, TQPopupMenu * receiver ) { static bool preventAnimation = FALSE; #ifndef TQT_NO_WHATSTHIS -extern void qWhatsThisBDH(); +extern void tqWhatsThisBDH(); static TQMenuItem* whatsThisItem = 0; #endif @@ -816,7 +816,7 @@ void TQPopupMenu::hideAllPopups() #ifndef TQT_NO_WHATSTHIS if (whatsThisItem) { - qWhatsThisBDH(); + tqWhatsThisBDH(); whatsThisItem = 0; } #endif @@ -2570,7 +2570,7 @@ void TQPopupMenu::setActiveItem( int i ) hilitSig( mi->id() ); #ifndef TQT_NO_WHATSTHIS if (whatsThisItem && whatsThisItem != mi) { - qWhatsThisBDH(); + tqWhatsThisBDH(); } whatsThisItem = mi; #endif diff --git a/src/widgets/tqsyntaxhighlighter.cpp b/src/widgets/tqsyntaxhighlighter.cpp new file mode 100644 index 000000000..223f7930c --- /dev/null +++ b/src/widgets/tqsyntaxhighlighter.cpp @@ -0,0 +1,221 @@ +/**************************************************************************** +** +** Implementation of the TQSyntaxHighlighter class +** +** Created : 990101 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "tqsyntaxhighlighter.h" +#include "private/tqsyntaxhighlighter_p.h" + +#ifndef TQT_NO_SYNTAXHIGHLIGHTER +#include "../kernel/qrichtext_p.h" +#include "tqtextedit.h" +#include "tqtimer.h" + +/*! + \class TQSyntaxHighlighter tqsyntaxhighlighter.h + \brief The TQSyntaxHighlighter class is a base class for + implementing TQTextEdit syntax highlighters. + + \ingroup basic + \ingroup text + + A syntax highligher automatically highlights parts of the text in + a TQTextEdit. Syntax highlighters are often used when the user is + entering text in a specific format (for example, source code) and + help the user to read the text and identify syntax errors. + + To provide your own syntax highlighting for TQTextEdit, you must + subclass TQSyntaxHighlighter and reimplement highlightParagraph(). + + When you create an instance of your TQSyntaxHighlighter subclass, + pass it the TQTextEdit that you want the syntax highlighting to be + applied to. After this your highlightParagraph() function will be + called automatically whenever necessary. Use your + highlightParagraph() function to apply formatting (e.g. setting + the font and color) to the text that is passed to it. +*/ + +/*! + Constructs the TQSyntaxHighlighter and installs it on \a textEdit. + + It is the caller's responsibility to delete the + TQSyntaxHighlighter when it is no longer needed. +*/ + +TQSyntaxHighlighter::TQSyntaxHighlighter( TQTextEdit *textEdit ) + : para( 0 ), edit( textEdit ), d( new TQSyntaxHighlighterPrivate ) +{ + textEdit->document()->setPreProcessor( new TQSyntaxHighlighterInternal( this ) ); + textEdit->document()->invalidate(); + TQTimer::singleShot( 0, textEdit->viewport(), TQ_SLOT( update() ) ); +} + +/*! + Destructor. Uninstalls this syntax highlighter from the textEdit() +*/ + +TQSyntaxHighlighter::~TQSyntaxHighlighter() +{ + delete d; + textEdit()->document()->setPreProcessor( 0 ); +} + +/*! + \fn int TQSyntaxHighlighter::highlightParagraph( const TQString &text, int endStateOfLastPara ) + + This function is called when necessary by the rich text engine, + i.e. on paragraphs which have changed. + + In your reimplementation you should parse the paragraph's \a text + and call setFormat() as often as necessary to apply any font and + color changes that you require. Your function must return a value + which indicates the paragraph's end state: see below. + + Some syntaxes can have constructs that span paragraphs. For + example, a C++ syntax highlighter should be able to cope with + \c{/}\c{*...*}\c{/} comments that span paragraphs. To deal + with these cases it is necessary to know the end state of the + previous paragraph (e.g. "in comment"). + + If your syntax does not have paragraph spanning constructs, simply + ignore the \a endStateOfLastPara parameter and always return 0. + + Whenever highlightParagraph() is called it is passed a value for + \a endStateOfLastPara. For the very first paragraph this value is + always -2. For any other paragraph the value is the value returned + by the most recent highlightParagraph() call that applied to the + preceding paragraph. + + The value you return is up to you. We recommend only returning 0 + (to signify that this paragraph's syntax highlighting does not + affect the following paragraph), or a positive integer (to signify + that this paragraph has ended in the middle of a paragraph + spanning construct). + + To find out which paragraph is highlighted, call + currentParagraph(). + + For example, if you're writing a simple C++ syntax highlighter, + you might designate 1 to signify "in comment". For a paragraph + that ended in the middle of a comment you'd return 1, and for + other paragraphs you'd return 0. In your parsing code if \a + endStateOfLastPara was 1, you would highlight the text as a C++ + comment until you reached the closing \c{*}\c{/}. +*/ + +/*! + This function is applied to the syntax highlighter's current + paragraph (the text of which is passed to the highlightParagraph() + function). + + The specified \a font and \a color are applied to the text from + position \a start for \a count characters. (If \a count is 0, + nothing is done.) +*/ + +void TQSyntaxHighlighter::setFormat( int start, int count, const TQFont &font, const TQColor &color ) +{ + if ( !para || count <= 0 ) + return; + TQTextFormat *f = 0; + f = para->document()->formatCollection()->format( font, color ); + para->setFormat( start, count, f ); + f->removeRef(); +} + +/*! \overload */ + +void TQSyntaxHighlighter::setFormat( int start, int count, const TQColor &color ) +{ + if ( !para || count <= 0 ) + return; + TQTextFormat *f = 0; + TQFont fnt = textEdit()->TQWidget::font(); + f = para->document()->formatCollection()->format( fnt, color ); + para->setFormat( start, count, f ); + f->removeRef(); +} + +/*! \overload */ + +void TQSyntaxHighlighter::setFormat( int start, int count, const TQFont &font ) +{ + if ( !para || count <= 0 ) + return; + TQTextFormat *f = 0; + TQColor c = textEdit()->viewport()->paletteForegroundColor(); + f = para->document()->formatCollection()->format( font, c ); + para->setFormat( start, count, f ); + f->removeRef(); +} + +/*! + \fn TQTextEdit *TQSyntaxHighlighter::textEdit() const + + Returns the TQTextEdit on which this syntax highlighter is + installed +*/ + +/*! Redoes the highlighting of the whole document. +*/ + +void TQSyntaxHighlighter::rehighlight() +{ + TQTextParagraph *s = edit->document()->firstParagraph(); + while ( s ) { + s->invalidate( 0 ); + s->state = -1; + s->needPreProcess = TRUE; + s = s->next(); + } + edit->repaintContents( FALSE ); +} + +/*! + Returns the id of the paragraph which is highlighted, or -1 of no + paragraph is currently highlighted. + + Usually this function is called from within highlightParagraph(). +*/ + +int TQSyntaxHighlighter::currentParagraph() const +{ + return d->currentParagraph; +} + +#endif diff --git a/src/widgets/tqsyntaxhighlighter.h b/src/widgets/tqsyntaxhighlighter.h new file mode 100644 index 000000000..81556553e --- /dev/null +++ b/src/widgets/tqsyntaxhighlighter.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Definition of the TQSyntaxHighlighter class +** +** Created : 022407 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TQSYNTAXHIGHLIGHTER_H +#define TQSYNTAXHIGHLIGHTER_H + +#ifndef QT_H +#include "tqfont.h" +#include "tqcolor.h" +#include "tqstring.h" +#endif // QT_H + +class TQTextEdit; +class TQSyntaxHighlighterInternal; +class TQSyntaxHighlighterPrivate; +class TQTextParagraph; + +class TQ_EXPORT TQSyntaxHighlighter : public TQt +{ + friend class TQSyntaxHighlighterInternal; + +public: + TQSyntaxHighlighter( TQTextEdit *textEdit ); + virtual ~TQSyntaxHighlighter(); + + virtual int highlightParagraph( const TQString &text, int endStateOfLastPara ) = 0; + + void setFormat( int start, int count, const TQFont &font, const TQColor &color ); + void setFormat( int start, int count, const TQColor &color ); + void setFormat( int start, int count, const TQFont &font ); + TQTextEdit *textEdit() const { return edit; } + + void rehighlight(); + + int currentParagraph() const; + +private: + TQTextParagraph *para; + TQTextEdit *edit; + TQSyntaxHighlighterPrivate *d; + +}; + +#endif diff --git a/src/widgets/tqsyntaxhighlighter_p.h b/src/widgets/tqsyntaxhighlighter_p.h new file mode 100644 index 000000000..c4d7deabf --- /dev/null +++ b/src/widgets/tqsyntaxhighlighter_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Definition of the internal TQSyntaxHighlighterInternal class +** +** Created : 031111 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TQSYNTAXHIGHLIGHTER_P_H +#define TQSYNTAXHIGHLIGHTER_P_H + +#ifndef TQT_NO_SYNTAXHIGHLIGHTER +#include "tqsyntaxhighlighter.h" +#include "private/qrichtext_p.h" + +class TQSyntaxHighlighterPrivate +{ +public: + TQSyntaxHighlighterPrivate() : + currentParagraph( -1 ) + {} + + int currentParagraph; +}; + +class TQSyntaxHighlighterInternal : public TQTextPreProcessor +{ +public: + TQSyntaxHighlighterInternal( TQSyntaxHighlighter *h ) : highlighter( h ) {} + void process( TQTextDocument *doc, TQTextParagraph *p, int, bool invalidate ) { + if ( p->prev() && p->prev()->endState() == -1 ) + process( doc, p->prev(), 0, FALSE ); + + highlighter->para = p; + TQString text = p->string()->toString(); + int endState = p->prev() ? p->prev()->endState() : -2; + int oldEndState = p->endState(); + highlighter->d->currentParagraph = p->paragId(); + p->setEndState( highlighter->highlightParagraph( text, endState ) ); + highlighter->d->currentParagraph = -1; + highlighter->para = 0; + + p->setFirstPreProcess( FALSE ); + TQTextParagraph *op = p; + p = p->next(); + if ( (!!oldEndState || !!op->endState()) && oldEndState != op->endState() && + invalidate && p && !p->firstPreProcess() && p->endState() != -1 ) { + while ( p ) { + if ( p->endState() == -1 ) + return; + p->setEndState( -1 ); + p = p->next(); + } + } + } + TQTextFormat *format( int ) { return 0; } + +private: + TQSyntaxHighlighter *highlighter; + + friend class TQTextEdit; +}; + +#endif // TQT_NO_SYNTAXHIGHLIGHTER +#endif // TQSYNTAXHIGHLIGHTER_P_H diff --git a/src/widgets/tqtextbrowser.cpp b/src/widgets/tqtextbrowser.cpp index fd4bced0a..1409a20ff 100644 --- a/src/widgets/tqtextbrowser.cpp +++ b/src/widgets/tqtextbrowser.cpp @@ -54,7 +54,7 @@ #include "tqbitmap.h" #include "tqtimer.h" #include "tqimage.h" -#include "ntqsimplerichtext.h" +#include "tqsimplerichtext.h" #include "tqdragobject.h" #include "tqurl.h" #include "ntqcursor.h" diff --git a/src/widgets/tqtextedit.cpp b/src/widgets/tqtextedit.cpp index a0887cb5d..9ef0752a7 100644 --- a/src/widgets/tqtextedit.cpp +++ b/src/widgets/tqtextedit.cpp @@ -75,7 +75,7 @@ #include "ntqmetaobject.h" #include "tqtextbrowser.h" #include -#include "private/qsyntaxhighlighter_p.h" +#include "private/tqsyntaxhighlighter_p.h" #include #ifndef TQT_NO_ACCEL diff --git a/src/widgets/tqtooltip.cpp b/src/widgets/tqtooltip.cpp index 6a048f5e1..7a9166452 100644 --- a/src/widgets/tqtooltip.cpp +++ b/src/widgets/tqtooltip.cpp @@ -38,7 +38,7 @@ #include "tqtooltip.h" #ifndef TQT_NO_TOOLTIP -#include "ntqlabel.h" +#include "tqlabel.h" #include "tqptrdict.h" #include "ntqapplication.h" #include "ntqguardedptr.h" diff --git a/src/widgets/tqwhatsthis.cpp b/src/widgets/tqwhatsthis.cpp new file mode 100644 index 000000000..1328c49ea --- /dev/null +++ b/src/widgets/tqwhatsthis.cpp @@ -0,0 +1,1001 @@ +/**************************************************************************** +** +** Implementation of TQWhatsThis class +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "tqwhatsthis.h" +#ifndef TQT_NO_WHATSTHIS +#include "ntqapplication.h" +#include "tqpaintdevicemetrics.h" +#include "tqpixmap.h" +#include "tqpainter.h" +#include "tqtimer.h" +#include "tqptrdict.h" +#include "tqtoolbutton.h" +#include "ntqshared.h" +#include "ntqcursor.h" +#include "tqbitmap.h" +#include "tqtooltip.h" +#include "tqsimplerichtext.h" +#include "tqstylesheet.h" +#if defined(QT_ACCESSIBILITY_SUPPORT) +#include "ntqaccessible.h" +#endif +#if defined(TQ_WS_WIN) +#include "qt_windows.h" +#ifndef SPI_GETDROPSHADOW +#define SPI_GETDROPSHADOW 0x1024 +#endif +#endif + +/*! + \class TQWhatsThis tqwhatsthis.h + \brief The TQWhatsThis class provides a simple description of any + widget, i.e. answering the question "What's this?". + + \ingroup helpsystem + \mainclass + + "What's this?" help is part of an application's online help system + that provides users with information about functionality, usage, + background etc., in various levels of detail from short tool tips + to full text browsing help windows. + + TQWhatsThis provides a single window with an explanatory text that + pops up when the user asks "What's this?". The default way to do + this is to focus the relevant widget and press Shift+F1. The help + text appears immediately; it goes away as soon as the user does + something else. + + (Note that if there is an accelerator for Shift+F1, this mechanism + will not work.) + + To add "What's this?" text to a widget you simply call + TQWhatsThis::add() for the widget. For example, to assign text to a + menu item, call TQMenuData::setWhatsThis(); for a global + accelerator key, call TQAccel::setWhatsThis() and If you're using + actions, use TQAction::setWhatsThis(). + + The text can be either rich text or plain text. If you specify a + rich text formatted string, it will be rendered using the default + stylesheet. This makes it possible to embed images. See + TQStyleSheet::defaultSheet() for details. + + \quotefile action/application.cpp + \skipto fileOpenText + \printuntil setWhatsThis + + An alternative way to enter "What's this?" mode is to use the + ready-made tool bar tool button from + TQWhatsThis::whatsThisButton(). By invoking this context help + button (in the picture below the first one from the right) the + user switches into "What's this?" mode. If they now click on a + widget the appropriate help text is shown. The mode is left when + help is given or when the user presses Esc. + + \img whatsthis.png + + If you are using TQMainWindow you can also use the + TQMainWindow::whatsThis() slot to invoke the mode from a menu item. + + For more control you can create a dedicated TQWhatsThis object for + a special widget. By subclassing and reimplementing + TQWhatsThis::text() it is possible to have different help texts, + depending on the position of the mouse click. By reimplementing + TQWhatsThis::clicked() it is possible to have hyperlinks inside the + help texts. + + If you wish to control the "What's this?" behavior of a widget + manually see TQWidget::customWhatsThis(). + + The What's This object can be removed using TQWhatsThis::remove(), + although this is rarely necessary because it is automatically + removed when the widget is destroyed. + + \sa TQToolTip +*/ + +// a special button +class TQWhatsThisButton: public TQToolButton +{ + TQ_OBJECT + +public: + TQWhatsThisButton( TQWidget * parent, const char * name ); + ~TQWhatsThisButton(); + +public slots: + void mouseReleased(); + +}; + + +class TQWhatsThat : public TQWidget +{ + TQ_OBJECT +public: + TQWhatsThat( TQWidget* w, const TQString& txt, TQWidget* parent, const char* name ); + ~TQWhatsThat() ; + +public slots: + void hide(); + inline void widgetDestroyed() { widget = 0; } + +protected: + void mousePressEvent( TQMouseEvent* ); + void mouseReleaseEvent( TQMouseEvent* ); + void mouseMoveEvent( TQMouseEvent* ); + void keyPressEvent( TQKeyEvent* ); + void paintEvent( TQPaintEvent* ); + +private: + TQString text; +#ifndef TQT_NO_RICHTEXT + TQSimpleRichText* doc; +#endif + TQString anchor; + bool pressed; + TQWidget* widget; +}; + + +class TQWhatsThisPrivate: public TQObject +{ + TQ_OBJECT +public: + + // an item for storing texts + struct WhatsThisItem: public TQShared + { + WhatsThisItem(): TQShared() { whatsthis = 0; } + ~WhatsThisItem(); + TQString s; + TQWhatsThis* whatsthis; + }; + + // the (these days pretty small) state machine + enum State { Inactive, Waiting }; + + TQWhatsThisPrivate(); + ~TQWhatsThisPrivate(); + + bool eventFilter( TQObject *, TQEvent * ); + + WhatsThisItem* newItem( TQWidget * widget ); + void add( TQWidget * widget, TQWhatsThis* special ); + void add( TQWidget * widget, const TQString& text ); + + // say it. + void say( TQWidget *, const TQString&, const TQPoint& ); + + // setup and teardown + static void setUpWhatsThis(); + + void enterWhatsThisMode(); + void leaveWhatsThisMode(); + + // variables + TQWhatsThat * whatsThat; + TQPtrDict * dict; + TQPtrDict * tlw; + TQPtrDict * buttons; + State state; + +private slots: + void cleanupWidget() + { + const TQObject* o = sender(); + if ( o->isWidgetType() ) // sanity + TQWhatsThis::remove((TQWidget*)o); + } + +}; + +// static, but static the less-typing way +static TQWhatsThisPrivate * wt = 0; + +// shadowWidth not const, for XP drop-shadow-fu turns it to 0 +static int shadowWidth = 6; // also used as '5' and '6' and even '8' below +const int vMargin = 8; +const int hMargin = 12; + +// Lets TQPopupMenu destroy the TQWhatsThat. +void tqWhatsThisBDH() +{ + if ( wt && wt->whatsThat ) + wt->whatsThat->hide(); +} + + +TQWhatsThat::TQWhatsThat( TQWidget* w, const TQString& txt, TQWidget* parent, const char* name ) + : TQWidget( parent, name, WType_Popup ), text( txt ), pressed( FALSE ), widget( w ) +{ + + setBackgroundMode( NoBackground ); + setPalette( TQToolTip::palette() ); + setMouseTracking( TRUE ); +#ifndef TQT_NO_CURSOR + setCursor( arrowCursor ); +#endif + + if ( widget ) + connect( widget, TQ_SIGNAL( destroyed() ), this, TQ_SLOT( widgetDestroyed() ) ); + + + TQRect r; +#ifndef TQT_NO_RICHTEXT + doc = 0; + if ( TQStyleSheet::mightBeRichText( text ) ) { + TQFont f = TQApplication::font( this ); + doc = new TQSimpleRichText( text, f ); + doc->adjustSize(); + r.setRect( 0, 0, doc->width(), doc->height() ); + } + else +#endif + { + int sw = TQApplication::desktop()->width() / 3; + if ( sw < 200 ) + sw = 200; + else if ( sw > 300 ) + sw = 300; + + r = fontMetrics().boundingRect( 0, 0, sw, 1000, + AlignAuto + AlignTop + WordBreak + ExpandTabs, + text ); + } +#if defined(TQ_WS_WIN) + if ( (qWinVersion()&WV_NT_based) > WV_2000 ) { + BOOL shadow; + SystemParametersInfo( SPI_GETDROPSHADOW, 0, &shadow, 0 ); + shadowWidth = shadow ? 0 : 6; + } +#endif + resize( r.width() + 2*hMargin + shadowWidth, r.height() + 2*vMargin + shadowWidth ); +} + +TQWhatsThat::~TQWhatsThat() +{ + if ( wt && wt->whatsThat == this ) + wt->whatsThat = 0; +#ifndef TQT_NO_RICHTEXT + if ( doc ) + delete doc; +#endif +} + +void TQWhatsThat::hide() +{ + TQWidget::hide(); +#if defined(QT_ACCESSIBILITY_SUPPORT) + TQAccessible::updateAccessibility( this, 0, TQAccessible::ContextHelpEnd ); +#endif +} + +void TQWhatsThat::mousePressEvent( TQMouseEvent* e ) +{ + pressed = TRUE; + if ( e->button() == LeftButton && rect().contains( e->pos() ) ) { +#ifndef TQT_NO_RICHTEXT + if ( doc ) + anchor = doc->anchorAt( e->pos() - TQPoint( hMargin, vMargin) ); +#endif + return; + } + hide(); +} + +void TQWhatsThat::mouseReleaseEvent( TQMouseEvent* e ) +{ + if ( !pressed ) + return; +#ifndef TQT_NO_RICHTEXT + if ( e->button() == LeftButton && doc && rect().contains( e->pos() ) ) { + TQString a = doc->anchorAt( e->pos() - TQPoint( hMargin, vMargin ) ); + TQString href; + if ( anchor == a ) + href = a; + anchor = TQString::null; + if ( widget && wt && wt->dict ) { + TQWhatsThisPrivate::WhatsThisItem * i = wt->dict->find( widget ); + if ( i && i->whatsthis && !i->whatsthis->clicked( href ) ) + return; + } + } +#endif + hide(); +} + +void TQWhatsThat::mouseMoveEvent( TQMouseEvent* e) +{ +#ifndef TQT_NO_RICHTEXT +#ifndef TQT_NO_CURSOR + if ( !doc ) + return; + TQString a = doc->anchorAt( e->pos() - TQPoint( hMargin, vMargin ) ); + if ( !a.isEmpty() ) + setCursor( pointingHandCursor ); + else + setCursor( arrowCursor ); +#endif +#endif +} + + +void TQWhatsThat::keyPressEvent( TQKeyEvent* ) +{ + hide(); +} + + + +void TQWhatsThat::paintEvent( TQPaintEvent* ) +{ + bool drawShadow = TRUE; +#if defined(TQ_WS_WIN) + if ( (qWinVersion()&WV_NT_based) > WV_2000 ) { + BOOL shadow; + SystemParametersInfo( SPI_GETDROPSHADOW, 0, &shadow, 0 ); + drawShadow = !shadow; + } +#elif defined(TQ_WS_MACX) + drawShadow = FALSE; //never draw it on OS X we get it for free +#endif + + TQRect r = rect(); + if ( drawShadow ) + r.addCoords( 0, 0, -shadowWidth, -shadowWidth ); + TQPainter p( this); + p.setPen( colorGroup().foreground() ); + p.drawRect( r ); + p.setPen( colorGroup().mid() ); + p.setBrush( colorGroup().brush( TQColorGroup::Background ) ); + int w = r.width(); + int h = r.height(); + p.drawRect( 1, 1, w-2, h-2 ); + if ( drawShadow ) { + p.setPen( colorGroup().shadow() ); + p.drawPoint( w + 5, 6 ); + p.drawLine( w + 3, 6, w + 5, 8 ); + p.drawLine( w + 1, 6, w + 5, 10 ); + int i; + for( i=7; i < h; i += 2 ) + p.drawLine( w, i, w + 5, i + 5 ); + for( i = w - i + h; i > 6; i -= 2 ) + p.drawLine( i, h, i + 5, h + 5 ); + for( ; i > 0 ; i -= 2 ) + p.drawLine( 6, h + 6 - i, i + 5, h + 5 ); + } + p.setPen( colorGroup().foreground() ); + r.addCoords( hMargin, vMargin, -hMargin, -vMargin ); + +#ifndef TQT_NO_RICHTEXT + if ( doc ) { + doc->draw( &p, r.x(), r.y(), r, colorGroup(), 0 ); + } + else +#endif + { + p.drawText( r, AlignAuto + AlignTop + WordBreak + ExpandTabs, text ); + } +} + +// the item +TQWhatsThisPrivate::WhatsThisItem::~WhatsThisItem() +{ + if ( count ) + tqFatal( "TQWhatsThis: Internal error (%d)", count ); + delete whatsthis; +} + + +static const char * const button_image[] = { +"16 16 3 1", +" c None", +"o c #000000", +"a c #000080", +"o aaaaa ", +"oo aaa aaa ", +"ooo aaa aaa", +"oooo aa aa", +"ooooo aa aa", +"oooooo a aaa", +"ooooooo aaa ", +"oooooooo aaa ", +"ooooooooo aaa ", +"ooooo aaa ", +"oo ooo ", +"o ooo aaa ", +" ooo aaa ", +" ooo ", +" ooo ", +" ooo "}; + +// the button class +TQWhatsThisButton::TQWhatsThisButton( TQWidget * parent, const char * name ) + : TQToolButton( parent, name ) +{ + TQPixmap p( (const char**)button_image ); + setPixmap( p ); + setToggleButton( TRUE ); + setAutoRaise( TRUE ); + setFocusPolicy( NoFocus ); + setTextLabel( tr( "What's this?" ) ); + wt->buttons->insert( (void *)this, this ); + connect( this, TQ_SIGNAL( released() ), + this, TQ_SLOT( mouseReleased() ) ); +} + + +TQWhatsThisButton::~TQWhatsThisButton() +{ + if ( wt && wt->buttons ) + wt->buttons->take( (void *)this ); +} + + +void TQWhatsThisButton::mouseReleased() +{ + if ( wt->state == TQWhatsThisPrivate::Inactive && isOn() ) { + TQWhatsThisPrivate::setUpWhatsThis(); +#ifndef TQT_NO_CURSOR + TQApplication::setOverrideCursor( whatsThisCursor, FALSE ); +#endif + wt->state = TQWhatsThisPrivate::Waiting; + tqApp->installEventFilter( wt ); + } +} + +static void tqWhatsThisPrivateCleanup() +{ + if( wt ) { + delete wt; + wt = 0; + } +} + +// the what's this manager class +TQWhatsThisPrivate::TQWhatsThisPrivate() + : TQObject( 0, "global what's this object" ) +{ + whatsThat = 0; + dict = new TQPtrDict; + tlw = new TQPtrDict; + wt = this; + buttons = new TQPtrDict; + state = Inactive; +} + +TQWhatsThisPrivate::~TQWhatsThisPrivate() +{ +#ifndef TQT_NO_CURSOR + if ( state == Waiting && tqApp ) + TQApplication::restoreOverrideCursor(); +#endif + // the two straight-and-simple dicts + delete tlw; + delete buttons; + + // then delete the complex one. + TQPtrDictIterator it( *dict ); + WhatsThisItem * i; + TQWidget * w; + while( (i=it.current()) != 0 ) { + w = (TQWidget *)it.currentKey(); + ++it; + dict->take( w ); + if ( i->deref() ) + delete i; + } + delete dict; + if ( whatsThat && !whatsThat->parentWidget() ) { + delete whatsThat; + } + // and finally lose wt + wt = 0; +} + +bool TQWhatsThisPrivate::eventFilter( TQObject * o, TQEvent * e ) +{ + switch( state ) { + case Waiting: + if ( e->type() == TQEvent::MouseButtonPress && o->isWidgetType() ) { + TQWidget * w = (TQWidget *) o; + if ( ( (TQMouseEvent*)e)->button() == RightButton ) + return FALSE; // ignore RMB + if ( w->customWhatsThis() ) + return FALSE; + TQWhatsThisPrivate::WhatsThisItem * i = 0; + TQMouseEvent* me = (TQMouseEvent*) e; + TQPoint p = me->pos(); + while( w && !i ) { + i = dict->find( w ); + if ( !i ) { + p += w->pos(); + w = w->parentWidget( TRUE ); + } + } + leaveWhatsThisMode(); + if (!i ) { +#if defined(QT_ACCESSIBILITY_SUPPORT) + TQAccessible::updateAccessibility( this, 0, TQAccessible::ContextHelpEnd ); +#endif + return TRUE; + } + if ( i->whatsthis ) + say( w, i->whatsthis->text( p ), me->globalPos() ); + else + say( w, i->s, me->globalPos() ); + return TRUE; + } else if ( e->type() == TQEvent::MouseButtonRelease ) { + if ( ( (TQMouseEvent*)e)->button() == RightButton ) + return FALSE; // ignore RMB + return !o->isWidgetType() || !((TQWidget*)o)->customWhatsThis(); + } else if ( e->type() == TQEvent::MouseMove ) { + return !o->isWidgetType() || !((TQWidget*)o)->customWhatsThis(); + } else if ( e->type() == TQEvent::KeyPress ) { + TQKeyEvent* kev = (TQKeyEvent*)e; + + if ( kev->key() == TQt::Key_Escape ) { + leaveWhatsThisMode(); + return TRUE; + } else if ( o->isWidgetType() && ((TQWidget*)o)->customWhatsThis() ) { + return FALSE; + } else if ( kev->key() == Key_Menu || + ( kev->key() == Key_F10 && + kev->state() == ShiftButton ) ) { + // we don't react to these keys, they are used for context menus + return FALSE; + } else if ( kev->state() == kev->stateAfter() && + kev->key() != Key_Meta ) { // not a modifier key + leaveWhatsThisMode(); + } + } else if ( e->type() == TQEvent::MouseButtonDblClick ) { + return TRUE; + } + break; + case Inactive: + if ( e->type() == TQEvent::Accel && + ((TQKeyEvent *)e)->key() == Key_F1 && + o->isWidgetType() && + ((TQKeyEvent *)e)->state() == ShiftButton ) { + TQWidget * w = ((TQWidget *)o)->focusWidget(); + if ( !w ) + break; + TQString s = TQWhatsThis::textFor( w, TQPoint(0,0), TRUE ); + if ( !s.isNull() ) { + say ( w, s, w->mapToGlobal( w->rect().center() ) ); + ((TQKeyEvent *)e)->accept(); + return TRUE; + } + } + break; + } + return FALSE; +} + + + +void TQWhatsThisPrivate::setUpWhatsThis() +{ + if ( !wt ) { + wt = new TQWhatsThisPrivate(); + + // It is necessary to use a post routine, because + // the destructor deletes pixmaps and other stuff that + // needs a working X connection under X11. + tqAddPostRoutine( tqWhatsThisPrivateCleanup ); + } +} + + +void TQWhatsThisPrivate::enterWhatsThisMode() +{ +#if defined(QT_ACCESSIBILITY_SUPPORT) + TQAccessible::updateAccessibility( this, 0, TQAccessible::ContextHelpStart ); +#endif +} + + +void TQWhatsThisPrivate::leaveWhatsThisMode() +{ + if ( state == Waiting ) { + TQPtrDictIterator it( *(wt->buttons) ); + TQWhatsThisButton * b; + while( (b=it.current()) != 0 ) { + ++it; + b->setOn( FALSE ); + } +#ifndef TQT_NO_CURSOR + TQApplication::restoreOverrideCursor(); +#endif + state = Inactive; + tqApp->removeEventFilter( this ); + } +} + + + +void TQWhatsThisPrivate::say( TQWidget * widget, const TQString &text, const TQPoint& ppos) +{ + if ( text.isEmpty() ) + return; + // make a fresh widget, and set it up + delete whatsThat; + whatsThat = new TQWhatsThat( + widget, text, +#if defined(TQ_WS_X11) + TQApplication::desktop()->screen( widget ? + widget->x11Screen() : + TQCursor::x11Screen() ), +#else + 0, +#endif + "automatic what's this? widget" ); + + + // okay, now to find a suitable location + + int scr = ( widget ? + TQApplication::desktop()->screenNumber( widget ) : +#if defined(TQ_WS_X11) + TQCursor::x11Screen() +#else + TQApplication::desktop()->screenNumber( ppos ) +#endif // TQ_WS_X11 + ); + TQRect screen = TQApplication::desktop()->screenGeometry( scr ); + + int x; + int w = whatsThat->width(); + int h = whatsThat->height(); + int sx = screen.x(); + int sy = screen.y(); + + // first try locating the widget immediately above/below, + // with nice alignment if possible. + TQPoint pos; + if ( widget ) + pos = widget->mapToGlobal( TQPoint( 0,0 ) ); + + if ( widget && w > widget->width() + 16 ) + x = pos.x() + widget->width()/2 - w/2; + else + x = ppos.x() - w/2; + + // squeeze it in if that would result in part of what's this + // being only partially visible + if ( x + w + shadowWidth > sx+screen.width() ) + x = (widget? (TQMIN(screen.width(), + pos.x() + widget->width()) + ) : screen.width() ) + - w; + + if ( x < sx ) + x = sx; + + int y; + if ( widget && h > widget->height() + 16 ) { + y = pos.y() + widget->height() + 2; // below, two pixels spacing + // what's this is above or below, wherever there's most space + if ( y + h + 10 > sy+screen.height() ) + y = pos.y() + 2 - shadowWidth - h; // above, overlap + } + y = ppos.y() + 2; + + // squeeze it in if that would result in part of what's this + // being only partially visible + if ( y + h + shadowWidth > sy+screen.height() ) + y = ( widget ? (TQMIN(screen.height(), + pos.y() + widget->height()) + ) : screen.height() ) + - h; + if ( y < sy ) + y = sy; + + whatsThat->move( x, y ); + whatsThat->show(); +} + +TQWhatsThisPrivate::WhatsThisItem* TQWhatsThisPrivate::newItem( TQWidget * widget ) +{ + WhatsThisItem * i = dict->find( (void *)widget ); + if ( i ) + TQWhatsThis::remove( widget ); + i = new WhatsThisItem; + dict->insert( (void *)widget, i ); + TQWidget * t = widget->topLevelWidget(); + if ( !tlw->find( (void *)t ) ) { + tlw->insert( (void *)t, t ); + t->installEventFilter( this ); + } + connect( widget, TQ_SIGNAL(destroyed()), this, TQ_SLOT(cleanupWidget()) ); + return i; +} + +void TQWhatsThisPrivate::add( TQWidget * widget, TQWhatsThis* special ) +{ + newItem( widget )->whatsthis = special; +} + +void TQWhatsThisPrivate::add( TQWidget * widget, const TQString &text ) +{ + newItem( widget )->s = text; +} + + +// and finally the What's This class itself + +/*! + Adds \a text as "What's this" help for \a widget. If the text is + rich text formatted (i.e. it contains markup) it will be rendered + with the default stylesheet TQStyleSheet::defaultSheet(). + + The text is destroyed if the widget is later destroyed, so it need + not be explicitly removed. + + \sa remove() +*/ +void TQWhatsThis::add( TQWidget * widget, const TQString &text ) +{ + if ( text.isEmpty() ) + return; // pointless + TQWhatsThisPrivate::setUpWhatsThis(); + wt->add(widget,text); +} + + +/*! + Removes the "What's this?" help associated with the \a widget. + This happens automatically if the widget is destroyed. + + \sa add() +*/ +void TQWhatsThis::remove( TQWidget * widget ) +{ + TQWhatsThisPrivate::setUpWhatsThis(); + TQWhatsThisPrivate::WhatsThisItem * i = wt->dict->find( (void *)widget ); + if ( !i ) + return; + + wt->dict->take( (void *)widget ); + + i->deref(); + if ( !i->count ) + delete i; +} + + +/*! + Returns the what's this text for widget \a w or TQString::null if + there is no "What's this?" help for the widget. \a pos contains + the mouse position; this is useful, for example, if you've + subclassed to make the text that is displayed position dependent. + + If \a includeParents is TRUE, parent widgets are taken into + consideration as well when looking for what's this help text. + + \sa add() +*/ +TQString TQWhatsThis::textFor( TQWidget * w, const TQPoint& pos, bool includeParents ) +{ + TQWhatsThisPrivate::setUpWhatsThis(); + TQWhatsThisPrivate::WhatsThisItem * i = 0; + TQPoint p = pos; + while( w && !i ) { + i = wt->dict->find( w ); + if ( !includeParents ) + break; + if ( !i ) { + p += w->pos(); + w = w->parentWidget( TRUE ); + } + } + if (!i) + return TQString::null; + if ( i->whatsthis ) + return i->whatsthis->text( p ); + return i->s; +} + + +/*! + Creates a TQToolButton preconfigured to enter "What's this?" mode + when clicked. You will often use this with a tool bar as \a + parent: + \code + (void) TQWhatsThis::whatsThisButton( my_help_tool_bar ); + \endcode +*/ +TQToolButton * TQWhatsThis::whatsThisButton( TQWidget * parent ) +{ + TQWhatsThisPrivate::setUpWhatsThis(); + return new TQWhatsThisButton( parent, + "automatic what's this? button" ); +} + +/*! + Constructs a dynamic "What's this?" object for \a widget. The + object is deleted when the \a widget is destroyed. + + When the widget is queried by the user the text() function of this + TQWhatsThis will be called to provide the appropriate text, rather + than using the text assigned by add(). +*/ +TQWhatsThis::TQWhatsThis( TQWidget * widget) +{ + TQWhatsThisPrivate::setUpWhatsThis(); + wt->add(widget,this); +} + + +/*! + Destroys the object and frees any allocated resources. +*/ +TQWhatsThis::~TQWhatsThis() +{ +} + + +/*! + This virtual function returns the text for position \e p in the + widget that this "What's this?" object documents. If there is no + "What's this?" text for the position, TQString::null is returned. + + The default implementation returns TQString::null. +*/ +TQString TQWhatsThis::text( const TQPoint & ) +{ + return TQString::null; +} + +/*! + \fn bool TQWhatsThis::clicked( const TQString& href ) + + This virtual function is called when the user clicks inside the + "What's this?" window. \a href is the link the user clicked on, or + TQString::null if there was no link. + + If the function returns TRUE (the default), the "What's this?" + window is closed, otherwise it remains visible. + + The default implementation ignores \a href and returns TRUE. +*/ +bool TQWhatsThis::clicked( const TQString& ) +{ + return TRUE; +} + + +/*! + Enters "What's this?" mode and returns immediately. + + TQt will install a special cursor and take over mouse input until + the user clicks somewhere. It then shows any help available and + ends "What's this?" mode. Finally, TQt removes the special cursor + and help window and then restores ordinary event processing, at + which point the left mouse button is no longer pressed. + + The user can also use the Esc key to leave "What's this?" mode. + + \sa inWhatsThisMode(), leaveWhatsThisMode() +*/ + +void TQWhatsThis::enterWhatsThisMode() +{ + TQWhatsThisPrivate::setUpWhatsThis(); + if ( wt->state == TQWhatsThisPrivate::Inactive ) { + wt->enterWhatsThisMode(); +#ifndef TQT_NO_CURSOR + TQApplication::setOverrideCursor( whatsThisCursor, FALSE ); +#endif + wt->state = TQWhatsThisPrivate::Waiting; + tqApp->installEventFilter( wt ); + } +} + + +/*! + Returns TRUE if the application is in "What's this?" mode; + otherwise returns FALSE. + + \sa enterWhatsThisMode(), leaveWhatsThisMode() +*/ +bool TQWhatsThis::inWhatsThisMode() +{ + if (!wt) + return FALSE; + return wt->state == TQWhatsThisPrivate::Waiting; +} + + +/*! + Leaves "What's this?" question mode. + + This function is used internally by widgets that support + TQWidget::customWhatsThis(); applications do not usually call it. + An example of such a widget is TQPopupMenu: menus still work + normally in "What's this?" mode but also provide help texts for + individual menu items. + + If \a text is not TQString::null, a "What's this?" help window is + displayed at the global screen position \a pos. If widget \a w is + not 0 and has its own dedicated TQWhatsThis object, this object + will receive clicked() messages when the user clicks on hyperlinks + inside the help text. + + \sa inWhatsThisMode(), enterWhatsThisMode(), TQWhatsThis::clicked() +*/ +void TQWhatsThis::leaveWhatsThisMode( const TQString& text, const TQPoint& pos, TQWidget* w ) +{ + if ( !inWhatsThisMode() ) + return; + + wt->leaveWhatsThisMode(); + if ( !text.isNull() ) + wt->say( w, text, pos ); +} + +/*! + Display \a text in a help window at the global screen position \a + pos. + + If widget \a w is not 0 and has its own dedicated TQWhatsThis + object, this object will receive clicked() messages when the user + clicks on hyperlinks inside the help text. + + \sa TQWhatsThis::clicked() +*/ +void TQWhatsThis::display( const TQString& text, const TQPoint& pos, TQWidget* w ) +{ + if ( inWhatsThisMode() ) { + leaveWhatsThisMode( text, pos, w ); + return; + } + TQWhatsThisPrivate::setUpWhatsThis(); + wt->say( w, text, pos ); +} + +/*! + Sets the font for all "What's this?" helps to \a font. +*/ +void TQWhatsThis::setFont( const TQFont &font ) +{ + TQApplication::setFont( font, TRUE, "TQWhatsThat" ); +} + +#include "tqwhatsthis.moc" +#endif diff --git a/src/widgets/tqwhatsthis.h b/src/widgets/tqwhatsthis.h new file mode 100644 index 000000000..66b4b3c90 --- /dev/null +++ b/src/widgets/tqwhatsthis.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Definition of TQWhatsThis class +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TQWHATSTHIS_H +#define TQWHATSTHIS_H + +#ifndef QT_H +#include "tqobject.h" +#endif // QT_H + +#ifndef TQT_NO_WHATSTHIS + +#include "ntqcursor.h" + +class TQToolButton; +class TQPopupMenu; +class TQStyleSheet; + +class TQ_EXPORT TQWhatsThis: public TQt +{ +public: + TQWhatsThis( TQWidget *); + virtual ~TQWhatsThis(); + + virtual TQString text( const TQPoint & ); + virtual bool clicked( const TQString& href ); + + // the common static functions + static void setFont( const TQFont &font ); + + static void add( TQWidget *, const TQString &); + static void remove( TQWidget * ); + static TQString textFor( TQWidget *, const TQPoint & pos = TQPoint(), bool includeParents = FALSE ); + + static TQToolButton * whatsThisButton( TQWidget * parent ); + + static void enterWhatsThisMode(); + static bool inWhatsThisMode(); + static void leaveWhatsThisMode( const TQString& = TQString::null, const TQPoint& pos = TQCursor::pos(), TQWidget* w = 0 ); + + static void display( const TQString& text, const TQPoint& pos = TQCursor::pos(), TQWidget* w = 0 ); +}; + +#endif // TQT_NO_WHATSTHIS + +#endif // TQWHATSTHIS_H diff --git a/src/workspace/tqworkspace.cpp b/src/workspace/tqworkspace.cpp index bf4fe9de0..72319497b 100644 --- a/src/workspace/tqworkspace.cpp +++ b/src/workspace/tqworkspace.cpp @@ -45,7 +45,7 @@ #include "tqobjectlist.h" #include "ntqlayout.h" #include "tqtoolbutton.h" -#include "ntqlabel.h" +#include "tqlabel.h" #include "ntqvbox.h" #include "ntqaccel.h" #include "ntqcursor.h" -- cgit v1.2.3