Beispiel #1
0
    QString doSanitizeKeyword(const QString &keyword) {
        QString allowed = QString(ALLOWED_SYMBOLS);
        int start = 0;
        int length = keyword.length();
        QChar c;
        while (start < length) {
            c = keyword.at(start);
            if (c.isLetterOrNumber() ||
                    allowed.contains(c) ||
                    c.category() == QChar::Symbol_Currency) {
                break;
            } else {
                start++;
            }
        }

        int end = length - 1;
        while (end >= 0) {
            c = keyword.at(end);
            if (c.isLetterOrNumber() ||
                    allowed.contains(c) ||
                    c.category() == QChar::Symbol_Currency) {
                break;
            } else {
                end--;
            }
        }

        QString result;
        if (start <= end) {
            result = keyword.mid(start, end - start + 1).simplified();
        }

        return result;
    }
Beispiel #2
0
Word Filter::nextWord() const
{
    QChar currentChar = skipToLetter( m_currentPosition );

    if ( m_currentPosition >= m_buffer.length() ) {
        return Filter::end();
    }

    bool allUppercase = currentChar.category() & QChar::Letter_Uppercase;
    bool runTogether = false;

    QString foundWord;
    int start = m_currentPosition;
    while ( currentChar.isLetter() ) {
        if ( currentChar.category() & QChar::Letter_Lowercase )
            allUppercase = false;

	/* FIXME: this does not work for Hebrew for example
        //we consider run-together words as mixed-case words
        if ( !allUppercase &&
             currentChar.category() & QChar::Letter_Uppercase )
            runTogether = true;
	*/

        foundWord += currentChar;
        ++m_currentPosition;
        currentChar = m_buffer[ m_currentPosition ];
    }

    if ( shouldBeSkipped( allUppercase, runTogether, foundWord ) )
        return nextWord();

    return Word( foundWord, start );
}
Beispiel #3
0
static bool isIdentifierPart(QChar ch)
{
    // fast path for ascii
    if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
        (ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
        (ch.unicode() >= '0' && ch.unicode() <= '9') ||
        ch == '$' || ch == '_' ||
        ch.unicode() == 0x200c /* ZWNJ */ || ch.unicode() == 0x200d /* ZWJ */)
        return true;

    switch (ch.category()) {
    case QChar::Mark_NonSpacing:
    case QChar::Mark_SpacingCombining:

    case QChar::Number_DecimalDigit:
    case QChar::Number_Letter:

    case QChar::Letter_Uppercase:
    case QChar::Letter_Lowercase:
    case QChar::Letter_Titlecase:
    case QChar::Letter_Modifier:
    case QChar::Letter_Other:

    case QChar::Punctuation_Connector:
        return true;
    default:
        break;
    }
    return false;
}
 void searchTargetFromScreen(QEditor *editor, const QChar &target)
 {
   m_targetPos.clear();
   if (editor == NULL) {
     return;
   }
   m_currentGroup = 0;
   m_targetChar = target;
   QTextDocument *doc = editor->document();
   int cursorPos = editor->textCursor().position();
   QPair<int, int> visibleRange = getFirstAndLastVisiblePosition(editor);
   int  firstPos = visibleRange.first;
   int lastPos = visibleRange.second;
   bool notCaseSensative = target.category() != QChar::Letter_Uppercase;
   for (int offset = 1; cursorPos - offset >= firstPos || cursorPos + offset <= lastPos; offset++) {
     if (cursorPos + offset <= lastPos) {
       QChar c = doc->characterAt(cursorPos + offset);
       if (notCaseSensative) {
         c = c.toLower();
       }
       if (c == target) {
         m_targetPos << (cursorPos + offset);
       }
     }
     if (cursorPos - offset >= firstPos) {
       QChar c = doc->characterAt(cursorPos - offset);
       if (notCaseSensative) {
         c = c.toLower();
       }
       if (c == target) {
         m_targetPos << (cursorPos - offset);
       }
     }
   }
 }
int KNewPasswordWidget::KNewPasswordWidgetPrivate::effectivePasswordLength(const QString &password)
{
    enum Category {
        Digit,
        Upper,
        Vowel,
        Consonant,
        Special
    };

    Category previousCategory = Vowel;
    QString vowels(QStringLiteral("aeiou"));
    int count = 0;

    for (int i = 0; i < password.length(); ++i) {
        QChar currentChar = password.at(i);
        if (!password.leftRef(i).contains(currentChar)) {
            Category currentCategory;
            switch (currentChar.category()) {
            case QChar::Letter_Uppercase:
                currentCategory = Upper;
                break;
            case QChar::Letter_Lowercase:
                if (vowels.contains(currentChar)) {
                    currentCategory = Vowel;
                } else {
                    currentCategory = Consonant;
                }
                break;
            case QChar::Number_DecimalDigit:
                currentCategory = Digit;
                break;
            default:
                currentCategory = Special;
                break;
            }
            switch (currentCategory) {
            case Vowel:
                if (previousCategory != Consonant) {
                    ++count;
                }
                break;
            case Consonant:
                if (previousCategory != Vowel) {
                    ++count;
                }
                break;
            default:
                if (previousCategory != currentCategory) {
                    ++count;
                }
                break;
            }
            previousCategory = currentCategory;
        }
    }
    return count;
}
Beispiel #6
0
static void formatCharacter(QTextStream &str, const QChar &qc, FormattingContext &context)
{
    const ushort unicode = qc.unicode();
    str << "U+" << qSetFieldWidth(4) << qSetPadChar('0') << uppercasedigits << hex << unicode
        << dec << qSetFieldWidth(0) << ' ';

    const EnumLookup *specialChar = enumLookup(unicode, specialCharactersEnumLookup, sizeof(specialCharactersEnumLookup) / sizeof(EnumLookup));
    if (specialChar)
        str << specialChar->description;
    else
        str << "'" << qc << '\'';

    const int category = qc.category();
    if (category != context.category) {
        str << " category="
            << enumName(category, categoryEnumLookup, sizeof(categoryEnumLookup) / sizeof(EnumLookup));
        context.category = category;
    }
#if QT_VERSION >= 0x050100
    const int script = qc.script();
    if (script != context.script) {
        str << " script="
            << enumName(script, scriptEnumLookup, sizeof(scriptEnumLookup) / sizeof(EnumLookup))
            << '(' << script << ')';
        context.script = script;
    }
#endif // Qt 5
    const int direction = qc.direction();
    if (direction != context.direction) {
        str << " direction="
            << enumName(direction, directionEnumLookup, sizeof(directionEnumLookup) / sizeof(EnumLookup));
        context.direction = direction;
    }
#if QT_VERSION >= 0x050000
    const int joiningType = qc.joiningType();
    if (joiningType != context.joiningType) {
        str << " joiningType="
            << enumName(joiningType, joiningTypeEnumLookup, sizeof(joiningTypeEnumLookup) / sizeof(EnumLookup));
        context.joiningType = joiningType;
    }
#endif // Qt 5QWidget
    const int decompositionTag = qc.decompositionTag();
    if (decompositionTag != context.decompositionTag) {
        str << " decomposition="
            << enumName(decompositionTag, decompositionEnumLookup, sizeof(decompositionEnumLookup) / sizeof(EnumLookup));
        context.decompositionTag = decompositionTag;
    }
    const int unicodeVersion = qc.unicodeVersion();
    if (unicodeVersion != context.unicodeVersion) {
        str << " version="
        << enumName(unicodeVersion, unicodeVersionEnumLookup, sizeof(unicodeVersionEnumLookup) / sizeof(EnumLookup));
        context.unicodeVersion = unicodeVersion;
    }
}
Beispiel #7
0
QString Private::Converter::toPortablePath(const QString &path) const
{
    if (path.isEmpty() || m_baseDir.path().isEmpty())
        return path;

#ifdef Q_OS_WIN
    if (QDir::isAbsolutePath(path)) {
        QChar driveLeter = path[0].toUpper();
        QChar baseDriveLetter = m_baseDir.path()[0].toUpper();
        bool onSameDrive = (driveLeter.category() == QChar::Letter_Uppercase) && (driveLeter == baseDriveLetter);
        if (!onSameDrive)
            return path;
    }
#endif
    return m_baseDir.relativeFilePath(path);
}
Beispiel #8
0
    bool isValidKeyword(const QString &keyword) {
        bool isValid = false;
        int length = keyword.length();

        if (2 <= length && length < 30) {
            isValid = true;
        }

        if (length == 1) {
            QChar symbol = keyword.at(0);
            if (symbol.isLetterOrNumber() ||
                    QString(ALLOWED_SYMBOLS).contains(symbol) ||
                    symbol.category() == QChar::Symbol_Currency) {
                isValid = true;
            }
        }

        return isValid;
    }
Beispiel #9
0
static inline bool isIdentifierStart(QChar ch)
{
    // fast path for ascii
    if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
        (ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
        ch == '$' || ch == '_')
        return true;

    switch (ch.category()) {
    case QChar::Number_Letter:
    case QChar::Letter_Uppercase:
    case QChar::Letter_Lowercase:
    case QChar::Letter_Titlecase:
    case QChar::Letter_Modifier:
    case QChar::Letter_Other:
        return true;
    default:
        break;
    }
    return false;
}
Beispiel #10
0
Token* Tokenizer::getToken()
{
	int startRow = row;
	int startCol = col;

	QChar c = getChar();  // get and store the next character from the string

	// catch the end of the input string
	if (atEnd)
		return new Token(Token::EndOfInput, "END", row, col, row, col);

	int cType = translator->look2type(c);  // since we need to know it often we store it

	// catch spaces
	if (isSpace(c)) {
		QString look;
		do {
			look += (isTab(c) ? "  " : " ");
			c = getChar();
		} while (isSpace(c) && !atEnd);
		ungetChar();
		return new Token(Token::WhiteSpace, look, startRow, startCol, row, col);
	}

	// catch EndOfLine's
	if (isBreak(c)) {
		return new Token(Token::EndOfLine, "\\n", startRow, startCol, startRow+1, 1);
	}

	// catch comments
	if (cType == Token::Comment) {
		QString look;
		do {
			look += c;
			c = getChar();
		} while (!isBreak(c) && !atEnd);
		ungetChar();
		return new Token(Token::Comment, look, startRow, startCol, row, col);
	}

	// catch strings
	if (cType == Token::StringDelimiter) {
		QString look = QString(c);
		do {
			c = getChar();
			look += c;
		} while (!(translator->look2type(c) == Token::StringDelimiter && look.right(2) != "\\\"") &&
		         !isBreak(c) && !atEnd);
		return new Token(Token::String, look, startRow, startCol, row, col);
	}

	// catch variables
	if (cType == Token::VariablePrefix) {
		QString look;
		do {
			look += c;
			c = getChar();
		} while (isWordChar(c) || c.category() == QChar::Number_DecimalDigit || c == '_');
		ungetChar();
		return new Token(Token::Variable, look, startRow, startCol, row, col);
	}

	// catch words (known commands or function calls)
	if (isWordChar(c)) {  // first char has to be a letter
		QString look;
		do {
			look += c;
			c = getChar();
		} while (isWordChar(c) || c.isDigit() || c == '_');  // next chars
		ungetChar();
		int type = translator->look2type(look);
		if (type == Token::Unknown)
			type = Token::FunctionCall;
		return new Token(type, look, startRow, startCol, row, col);
	}

	// catch numbers
	if (c.isDigit() || cType == Token::DecimalSeparator) {
		bool hasDot = false;

		int localType = cType;
		QString look;
		do {
			if (localType == Token::DecimalSeparator) hasDot = true;
			look += c;
			c = getChar();
			localType = translator->look2type(c);
		} while (c.isDigit() || (localType == Token::DecimalSeparator && !hasDot));
		ungetChar();
		
		// if all we got is a dot then this is not a number, so return an Error token here
		if (translator->look2type(look) == Token::DecimalSeparator)
			return new Token(Token::Error, look, startRow, startCol, row, col);
		
		return new Token(Token::Number, look, startRow, startCol, row, col);
	}

	// catch previously uncatched 'double charactered tokens' (tokens that ar not in letters, like: == != >= <=)
	{
		QString look = QString(c).append(getChar());
		int type = translator->look2type(look);
		if (type != Token::Unknown)
			return new Token(type, look, startRow, startCol, row, col);
		ungetChar();
	}

	// catch known tokens of a single character (as last...)
	if (cType != Token::Unknown)
		return new Token(cType, static_cast<QString>(c), startRow, startCol, row, col);

	// this does not neglect calls to functions with a name of length one (checked it)
	return new Token(Token::Error, static_cast<QString>(c), startRow, startCol, row, col);
}
Beispiel #11
0
bool Tokenizer::isSpace(const QChar& c)
{
	return (c.category() == QChar::Separator_Space || c == ' ' || isTab(c));
}
/**
 * \sa format()
 * \sa setFormat(const QString&)
 */
QString AbstractStringAppender::formattedString(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file,
                                                int line, const char* function, const QString& category, const QString& message) const
{
  QString f = format();
  const int size = f.size();

  QString result;

  int i = 0;
  while (i < f.size())
  {
    QChar c = f.at(i);

    // We will silently ignore the broken % marker at the end of string
    if (c != QLatin1Char(formattingMarker) || (i + 2) >= size)
    {
      result.append(c);
    }
    else
    {
      i += 2;
      QChar currentChar = f.at(i);
      QString command;
      int fieldWidth = 0;

      if (currentChar.isLetter())
      {
        command.append(currentChar);
        int j = 1;
        while ((i + j) < size && f.at(i + j).isLetter())
        {
          command.append(f.at(i+j));
          j++;
        }

        i+=j;
        currentChar = f.at(i);

        // Check for the padding instruction
        if (currentChar == QLatin1Char(':'))
        {
          currentChar = f.at(++i);
          if (currentChar.isDigit() || currentChar.category() == QChar::Punctuation_Dash)
          {
            int j = 1;
            while ((i + j) < size && f.at(i + j).isDigit())
              j++;
            fieldWidth = f.mid(i, j).toInt();

            i += j;
          }
        }
      }

      // Log record chunk to insert instead of formatting instruction
      QString chunk;

      // Time stamp
      if (command == QLatin1String("time"))
      {
        if (f.at(i + 1) == QLatin1Char('{'))
        {
          int j = 1;
          while ((i + 2 + j) < size && f.at(i + 2 + j) != QLatin1Char('}'))
            j++;

          if ((i + 2 + j) < size)
          {
            chunk = timeStamp.toString(f.mid(i + 2, j));

            i += j;
            i += 2;
          }
        }

        if (chunk.isNull())
          chunk = timeStamp.toString(QLatin1String("HH:mm:ss.zzz"));
      }

      // Log level
      else if (command == QLatin1String("type"))
        chunk = Logger::levelToString(logLevel);

      // Uppercased log level
      else if (command == QLatin1String("Type"))
        chunk = Logger::levelToString(logLevel).toUpper();

      // One letter log level
      else if (command == QLatin1String("typeOne"))
          chunk = Logger::levelToString(logLevel).left(1).toLower();

      // One uppercase letter log level
      else if (command == QLatin1String("TypeOne"))
          chunk = Logger::levelToString(logLevel).left(1).toUpper();

      // Filename
      else if (command == QLatin1String("File"))
        chunk = QLatin1String(file);

      // Filename without a path
      else if (command == QLatin1String("file"))
        chunk = QString(QLatin1String(file)).section('/', -1);

      // Source line number
      else if (command == QLatin1String("line"))
        chunk = QString::number(line);

      // Function name, as returned by Q_FUNC_INFO
      else if (command == QLatin1String("Function"))
        chunk = QString::fromLatin1(function);

      // Stripped function name
      else if (command == QLatin1String("function"))
        chunk = stripFunctionName(function);

      // Log message
      else if (command == QLatin1String("message"))
        chunk = message;

      else if (command == QLatin1String("category"))
        chunk = category;

      // Application pid
      else if (command == QLatin1String("pid"))
        chunk = QString::number(QCoreApplication::applicationPid());

      // Appplication name
      else if (command == QLatin1String("appname"))
        chunk = QCoreApplication::applicationName();

      // Thread ID (duplicates Qt5 threadid debbuging way)
      else if (command == QLatin1String("threadid"))
        chunk = QLatin1String("0x") + QString::number(qlonglong(QThread::currentThread()->currentThread()), 16);

      // We simply replace the double formatting marker (%) with one
      else if (command == QString(formattingMarker))
        chunk = QLatin1Char(formattingMarker);

      // Do not process any unknown commands
      else
      {
        chunk = QString(formattingMarker);
        chunk.append(command);
      }

      result.append(QString(QLatin1String("%1")).arg(chunk, fieldWidth));
    }

    ++i;
  }

  return result;
}
Beispiel #13
0
void Font::drawText(QPainter *p, int x, int y, QChar *str, int slen, int pos, int len, int toAdd, QPainter::TextDirection d, int from, int to,
                    QColor bg, int uy, int h, int deco) const
{
    if(!str)
        return;
    QConstString cstr = QConstString(str, slen);
    QString qstr = cstr.string();

    // ### fixme for RTL
    if(!scFont && !letterSpacing && !wordSpacing && !toAdd && from == -1)
    {
        // simply draw it
        // Due to some unfounded cause QPainter::drawText traverses the
        // *whole* string when painting, not only the specified
        // [pos, pos + len) segment. This makes painting *extremely* slow for
        // long render texts (in the order of several megabytes).
        // Hence, only hand over the piece of text of the actual inline text box
        QConstString cstr = QConstString(str + pos, len);
        p->drawText(x, y, cstr.string(), 0, len, d);
    }
    else
    {
        if(from < 0)
            from = 0;
        if(to < 0)
            to = len;

        int numSpaces = 0;
        if(toAdd)
        {
            for(int i = 0; i < len; ++i)
                if(str[i + pos].category() == QChar::Separator_Space)
                    ++numSpaces;
        }

        const int totWidth = width(str, slen, pos, len);
        if(d == QPainter::RTL)
        {
            x += totWidth + toAdd;
        }
        QString upper = qstr;
        QFontMetrics sc_fm = fm;
        if(scFont)
        {
            // draw in small caps
            upper = qstr.upper();
            sc_fm = QFontMetrics(*scFont);
        }

        // ### sc could be optimized by only painting uppercase letters extra,
        // and treat the rest WordWise, but I think it's not worth it.
        // Somebody else may volunteer, and implement this ;-) (LS)

        // The mode determines whether the text is displayed character by
        // character, word by word, or as a whole
        enum
        {
            CharacterWise,
            WordWise,
            Whole
        } mode = Whole;
        if(!letterSpacing && !scFont && (wordSpacing || toAdd > 0))
            mode = WordWise;
        else if(letterSpacing || scFont)
            mode = CharacterWise;

        if(mode == Whole)
        { // most likely variant is treated extra

            if(to < 0)
                to = len;
            const QConstString cstr(str + pos, len);
            const QConstString segStr(str + pos + from, to - from);
            const int preSegmentWidth = fm.width(cstr.string(), from);
            const int segmentWidth = fm.width(segStr.string());
            const int eff_x = d == QPainter::RTL ? x - preSegmentWidth - segmentWidth : x + preSegmentWidth;

            // draw whole string segment, with optional background
            if(bg.isValid())
                p->fillRect(eff_x, uy, segmentWidth, h, bg);
            p->drawText(eff_x, y, segStr.string(), -1, d);
            if(deco)
                drawDecoration(p, eff_x, uy, y - uy, segmentWidth - 1, h, deco);
            return;
        }

        // We are using two passes. In the first pass, the widths are collected,
        // and stored. In the second, the actual characters are drawn.

        // For each letter in the text box, save the width of the character.
        // When word-wise, only the first letter contains the width, but of the
        // whole word.
        short *const widthList = (short *)alloca(to * sizeof(short));

        // First pass: gather widths
        int preSegmentWidth = 0;
        int segmentWidth = 0;
        int lastWordBegin = 0;
        bool onSegment = from == 0;
        for(int i = 0; i < to; ++i)
        {
            if(i == from)
            {
                // Also close words on visibility boundary
                if(mode == WordWise)
                {
                    const int width = closeWordAndGetWidth(fm, str, pos, lastWordBegin, i);

                    if(lastWordBegin < i)
                    {
                        widthList[lastWordBegin] = (short)width;
                        lastWordBegin = i;
                        preSegmentWidth += width;
                    }
                }
                onSegment = true;
            }

            const QChar ch = str[pos + i];
            bool lowercase = (ch.category() == QChar::Letter_Lowercase);
            bool is_space = (ch.category() == QChar::Separator_Space);
            int chw = 0;
            if(letterSpacing)
                chw += letterSpacing;
            if((wordSpacing || toAdd) && is_space)
            {
                if(mode == WordWise)
                {
                    const int width = closeWordAndGetWidth(fm, str, pos, lastWordBegin, i);
                    if(lastWordBegin < i)
                    {
                        widthList[lastWordBegin] = (short)width;
                        lastWordBegin = i;
                        (onSegment ? segmentWidth : preSegmentWidth) += width;
                    }
                    ++lastWordBegin; // ignore this space
                }
                chw += wordSpacing;
                if(numSpaces)
                {
                    const int a = toAdd / numSpaces;
                    chw += a;
                    toAdd -= a;
                    --numSpaces;
                }
            }
            if(is_space || mode == CharacterWise)
            {
                chw += lowercase ? sc_fm.charWidth(upper, pos + i) : fm.charWidth(qstr, pos + i);
                widthList[i] = (short)chw;

                (onSegment ? segmentWidth : preSegmentWidth) += chw;
            }
        }

        // close last word
        Q_ASSERT(onSegment);
        if(mode == WordWise)
        {
            const int width = closeWordAndGetWidth(fm, str, pos, lastWordBegin, to);
            segmentWidth += width;
            widthList[lastWordBegin] = (short)width;
        }

        if(d == QPainter::RTL)
            x -= preSegmentWidth;
        else
            x += preSegmentWidth;

        const int startx = d == QPainter::RTL ? x - segmentWidth : x;

        // optionally draw background
        if(bg.isValid())
            p->fillRect(startx, uy, segmentWidth, h, bg);

        // second pass: do the actual drawing
        lastWordBegin = from;
        for(int i = from; i < to; ++i)
        {
            const QChar ch = str[pos + i];
            bool lowercase = (ch.category() == QChar::Letter_Lowercase);
            bool is_space = ch.category() == QChar::Separator_Space;
            if(is_space)
            {
                if(mode == WordWise)
                {
                    closeAndDrawWord(p, d, x, y, widthList, str, pos, lastWordBegin, i);
                    ++lastWordBegin; // jump over space
                }
            }
            if(is_space || mode == CharacterWise)
            {
                const int chw = widthList[i];
                if(d == QPainter::RTL)
                    x -= chw;

                if(scFont)
                    p->setFont(lowercase ? *scFont : f);
                p->drawText(x, y, (lowercase ? upper : qstr), pos + i, 1, d);

                if(d != QPainter::RTL)
                    x += chw;
            }
        }

        // don't forget to draw last word
        if(mode == WordWise)
        {
            closeAndDrawWord(p, d, x, y, widthList, str, pos, lastWordBegin, to);
        }

        if(deco)
            drawDecoration(p, startx, uy, y - uy, segmentWidth - 1, h, deco);

        if(scFont)
            p->setFont(f);
    }
}
static bool isEndOfWordChar(const QChar &c)
{
    return !c.isLetterOrNumber() && c.category() != QChar::Punctuation_Connector;
}
Beispiel #15
0
void
Main_GUI::check_number_set()
{
  QString text = snapping_line->text();
  QString qs;

  // construct ASCII string from arbitrary Unicode data;
  // the idea is to accept, say, CJK fullwidth digits also
  for (int i = 0; i < text.size(); i++)
  {
    QChar c = text.at(i);

    int digit = c.digitValue();
    if (digit >= 0)
      qs += QString::number(digit);
    else if (c.isSpace())
      qs += ' ';
    // U+30FC KATAGANA-HIRAGANA PROLONGED SOUND MARK is assigned
    // to the `-' key in some Japanese input methods
    else if (c.category() == QChar::Punctuation_Dash
             || c == QChar(0x30FC))
      qs += '-';
    // various Unicode COMMA characters,
    // including representation forms
    else if (c == QChar(',')
             || c == QChar(0x055D)
             || c == QChar(0x060C)
             || c == QChar(0x07F8)
             || c == QChar(0x1363)
             || c == QChar(0x1802)
             || c == QChar(0x1808)
             || c == QChar(0x3001)
             || c == QChar(0xA4FE)
             || c == QChar(0xA60D)
             || c == QChar(0xA6F5)
             || c == QChar(0xFE10)
             || c == QChar(0xFE11)
             || c == QChar(0xFE50)
             || c == QChar(0xFE51)
             || c == QChar(0xFF0C)
             || c == QChar(0xFF64))
      qs += ',';
    else
      qs += c; // we do error handling below
  }

  if (x_height_snapping_exceptions)
    number_set_free(x_height_snapping_exceptions);

  QByteArray str = qs.toLocal8Bit();
  const char* s = number_set_parse(str.constData(),
                                   &x_height_snapping_exceptions,
                                   6, 0x7FFF);
  if (s && *s)
  {
    statusBar()->setStyleSheet("color: red;");
    if (x_height_snapping_exceptions == NUMBERSET_ALLOCATION_ERROR)
      statusBar()->showMessage(
        tr("allocation error"));
    else if (x_height_snapping_exceptions == NUMBERSET_INVALID_CHARACTER)
      statusBar()->showMessage(
        tr("invalid character (use digits, dashes, commas, and spaces)"));
    else if (x_height_snapping_exceptions == NUMBERSET_OVERFLOW)
      statusBar()->showMessage(
        tr("overflow"));
    else if (x_height_snapping_exceptions == NUMBERSET_INVALID_RANGE)
      statusBar()->showMessage(
        tr("invalid range (minimum is 6, maximum is 32767)"));
    else if (x_height_snapping_exceptions == NUMBERSET_OVERLAPPING_RANGES)
      statusBar()->showMessage(
        tr("overlapping ranges"));
    else if (x_height_snapping_exceptions == NUMBERSET_NOT_ASCENDING)
      statusBar()->showMessage(
        tr("values und ranges must be specified in ascending order"));

    snapping_line->setText(qs);
    snapping_line->setFocus(Qt::OtherFocusReason);
    snapping_line->setCursorPosition(s - str.constData());

    x_height_snapping_exceptions = NULL;
  }
  else
  {
    // normalize if there is no error
    char* new_str = number_set_show(x_height_snapping_exceptions,
                                    6, 0x7FFF);
    snapping_line->setText(new_str);
    free(new_str);
  }
}
Beispiel #16
0
static inline bool isSentenceSeparator(const QChar &character)
{
    return character.isMark() || character.isPunct() || character.category() == QChar::Separator_Paragraph;
}