void TestQgsField::convertCompatible() { //test string field QgsField stringField( QStringLiteral( "string" ), QVariant::String, QStringLiteral( "string" ) ); QVariant stringVar( "test string" ); QVERIFY( stringField.convertCompatible( stringVar ) ); QCOMPARE( stringVar.toString(), QString( "test string" ) ); QVariant nullString = QVariant( QVariant::String ); QVERIFY( stringField.convertCompatible( nullString ) ); QCOMPARE( nullString.type(), QVariant::String ); QVERIFY( nullString.isNull() ); QVariant intVar( 5 ); QVERIFY( stringField.convertCompatible( intVar ) ); QCOMPARE( intVar.type(), QVariant::String ); QCOMPARE( intVar, QVariant( "5" ) ); QVariant nullInt = QVariant( QVariant::Int ); QVERIFY( stringField.convertCompatible( nullInt ) ); QCOMPARE( nullInt.type(), QVariant::String ); QVERIFY( nullInt.isNull() ); QVariant doubleVar( 1.25 ); QVERIFY( stringField.convertCompatible( doubleVar ) ); QCOMPARE( doubleVar.type(), QVariant::String ); QCOMPARE( doubleVar, QVariant( "1.25" ) ); QVariant nullDouble = QVariant( QVariant::Double ); QVERIFY( stringField.convertCompatible( nullDouble ) ); QCOMPARE( nullDouble.type(), QVariant::String ); QVERIFY( nullDouble.isNull() ); //test double QgsField doubleField( QStringLiteral( "double" ), QVariant::Double, QStringLiteral( "double" ) ); stringVar = QVariant( "test string" ); QVERIFY( !doubleField.convertCompatible( stringVar ) ); QCOMPARE( stringVar.type(), QVariant::Double ); QVERIFY( stringVar.isNull() ); nullString = QVariant( QVariant::String ); QVERIFY( doubleField.convertCompatible( nullString ) ); QCOMPARE( nullString.type(), QVariant::Double ); QVERIFY( nullString.isNull() ); intVar = QVariant( 5 ); QVERIFY( doubleField.convertCompatible( intVar ) ); QCOMPARE( intVar.type(), QVariant::Double ); QCOMPARE( intVar, QVariant( 5.0 ) ); nullInt = QVariant( QVariant::Int ); QVERIFY( doubleField.convertCompatible( nullInt ) ); QCOMPARE( nullInt.type(), QVariant::Double ); QVERIFY( nullInt.isNull() ); doubleVar = QVariant( 1.25 ); QVERIFY( doubleField.convertCompatible( doubleVar ) ); QCOMPARE( doubleVar.type(), QVariant::Double ); QCOMPARE( doubleVar, QVariant( 1.25 ) ); nullDouble = QVariant( QVariant::Double ); QVERIFY( doubleField.convertCompatible( nullDouble ) ); QCOMPARE( nullDouble.type(), QVariant::Double ); QVERIFY( nullDouble.isNull() ); //test special rules //conversion of double to int QgsField intField( QStringLiteral( "int" ), QVariant::Int, QStringLiteral( "int" ) ); //small double, should be rounded QVariant smallDouble( 45.7 ); QVERIFY( intField.convertCompatible( smallDouble ) ); QCOMPARE( smallDouble.type(), QVariant::Int ); QCOMPARE( smallDouble, QVariant( 46 ) ); QVariant negativeSmallDouble( -9345.754534525235235 ); QVERIFY( intField.convertCompatible( negativeSmallDouble ) ); QCOMPARE( negativeSmallDouble.type(), QVariant::Int ); QCOMPARE( negativeSmallDouble, QVariant( -9346 ) ); //large double, cannot be converted QVariant largeDouble( 9999999999.99 ); QVERIFY( !intField.convertCompatible( largeDouble ) ); QCOMPARE( largeDouble.type(), QVariant::Int ); QVERIFY( largeDouble.isNull() ); //conversion of string double value to int QVariant notNumberString( "notanumber" ); QVERIFY( !intField.convertCompatible( notNumberString ) ); QCOMPARE( notNumberString.type(), QVariant::Int ); QVERIFY( notNumberString.isNull() ); //small double, should be rounded QVariant smallDoubleString( "45.7" ); QVERIFY( intField.convertCompatible( smallDoubleString ) ); QCOMPARE( smallDoubleString.type(), QVariant::Int ); QCOMPARE( smallDoubleString, QVariant( 46 ) ); QVariant negativeSmallDoubleString( "-9345.754534525235235" ); QVERIFY( intField.convertCompatible( negativeSmallDoubleString ) ); QCOMPARE( negativeSmallDoubleString.type(), QVariant::Int ); QCOMPARE( negativeSmallDoubleString, QVariant( -9346 ) ); //large double, cannot be converted QVariant largeDoubleString( "9999999999.99" ); QVERIFY( !intField.convertCompatible( largeDoubleString ) ); QCOMPARE( largeDoubleString.type(), QVariant::Int ); QVERIFY( largeDoubleString.isNull() ); //conversion of longlong to int QVariant longlong( 99999999999999999LL ); QVERIFY( !intField.convertCompatible( longlong ) ); QCOMPARE( longlong.type(), QVariant::Int ); QVERIFY( longlong.isNull() ); QVariant smallLonglong( 99LL ); QVERIFY( intField.convertCompatible( smallLonglong ) ); QCOMPARE( smallLonglong.type(), QVariant::Int ); QCOMPARE( smallLonglong, QVariant( 99 ) ); //conversion of longlong to longlong field QgsField longlongField( QStringLiteral( "long" ), QVariant::LongLong, QStringLiteral( "longlong" ) ); longlong = QVariant( 99999999999999999LL ); QVERIFY( longlongField.convertCompatible( longlong ) ); QCOMPARE( longlong.type(), QVariant::LongLong ); QCOMPARE( longlong, QVariant( 99999999999999999LL ) ); //string representation of an int QVariant stringInt( "123456" ); QVERIFY( intField.convertCompatible( stringInt ) ); QCOMPARE( stringInt.type(), QVariant::Int ); QCOMPARE( stringInt, QVariant( 123456 ) ); // now with group separator for english locale stringInt = QVariant( "123,456" ); QVERIFY( intField.convertCompatible( stringInt ) ); QCOMPARE( stringInt.type(), QVariant::Int ); QCOMPARE( stringInt, QVariant( "123456" ) ); //string representation of a longlong QVariant stringLong( "99999999999999999" ); QVERIFY( longlongField.convertCompatible( stringLong ) ); QCOMPARE( stringLong.type(), QVariant::LongLong ); QCOMPARE( stringLong, QVariant( 99999999999999999LL ) ); // now with group separator for english locale stringLong = QVariant( "99,999,999,999,999,999" ); QVERIFY( longlongField.convertCompatible( stringLong ) ); QCOMPARE( stringLong.type(), QVariant::LongLong ); QCOMPARE( stringLong, QVariant( 99999999999999999LL ) ); //string representation of a double QVariant stringDouble( "123456.012345" ); QVERIFY( doubleField.convertCompatible( stringDouble ) ); QCOMPARE( stringDouble.type(), QVariant::Double ); QCOMPARE( stringDouble, QVariant( 123456.012345 ) ); // now with group separator for english locale stringDouble = QVariant( "1,223,456.012345" ); QVERIFY( doubleField.convertCompatible( stringDouble ) ); QCOMPARE( stringDouble.type(), QVariant::Double ); QCOMPARE( stringDouble, QVariant( 1223456.012345 ) ); // This should not convert stringDouble = QVariant( "1.223.456,012345" ); QVERIFY( ! doubleField.convertCompatible( stringDouble ) ); //double with precision QgsField doubleWithPrecField( QStringLiteral( "double" ), QVariant::Double, QStringLiteral( "double" ), 10, 3 ); doubleVar = QVariant( 10.12345678 ); //note - this returns true! QVERIFY( doubleWithPrecField.convertCompatible( doubleVar ) ); QCOMPARE( doubleVar.type(), QVariant::Double ); QCOMPARE( doubleVar.toDouble(), 10.123 ); //truncating string length QgsField stringWithLen( QStringLiteral( "string" ), QVariant::String, QStringLiteral( "string" ), 3 ); stringVar = QVariant( "longstring" ); QVERIFY( !stringWithLen.convertCompatible( stringVar ) ); QCOMPARE( stringVar.type(), QVariant::String ); QCOMPARE( stringVar.toString(), QString( "lon" ) ); ///////////////////////////////////////////////////////// // German locale tests //double with ',' as decimal separator for German locale QLocale::setDefault( QLocale::German ); QVariant doubleCommaVar( "1,2345" ); QVERIFY( doubleField.convertCompatible( doubleCommaVar ) ); QCOMPARE( doubleCommaVar.type(), QVariant::Double ); QCOMPARE( doubleCommaVar.toString(), QString( "1.2345" ) ); //string representation of an int stringInt = QVariant( "123456" ); QVERIFY( intField.convertCompatible( stringInt ) ); QCOMPARE( stringInt.type(), QVariant::Int ); QCOMPARE( stringInt, QVariant( 123456 ) ); // now with group separator for german locale stringInt = QVariant( "123.456" ); QVERIFY( intField.convertCompatible( stringInt ) ); QCOMPARE( stringInt.type(), QVariant::Int ); QCOMPARE( stringInt, QVariant( "123456" ) ); //string representation of a longlong stringLong = QVariant( "99999999999999999" ); QVERIFY( longlongField.convertCompatible( stringLong ) ); QCOMPARE( stringLong.type(), QVariant::LongLong ); QCOMPARE( stringLong, QVariant( 99999999999999999LL ) ); // now with group separator for german locale stringLong = QVariant( "99.999.999.999.999.999" ); QVERIFY( longlongField.convertCompatible( stringLong ) ); QCOMPARE( stringLong.type(), QVariant::LongLong ); QCOMPARE( stringLong, QVariant( 99999999999999999LL ) ); //string representation of a double stringDouble = QVariant( "123456,012345" ); QVERIFY( doubleField.convertCompatible( stringDouble ) ); QCOMPARE( stringDouble.type(), QVariant::Double ); QCOMPARE( stringDouble, QVariant( 123456.012345 ) ); // For doubles we also want to accept dot as a decimal point stringDouble = QVariant( "123456.012345" ); QVERIFY( doubleField.convertCompatible( stringDouble ) ); QCOMPARE( stringDouble.type(), QVariant::Double ); QCOMPARE( stringDouble, QVariant( 123456.012345 ) ); // now with group separator for german locale stringDouble = QVariant( "1.223.456,012345" ); QVERIFY( doubleField.convertCompatible( stringDouble ) ); QCOMPARE( stringDouble.type(), QVariant::Double ); QCOMPARE( stringDouble, QVariant( 1223456.012345 ) ); // Be are good citizens and we also accept english locale stringDouble = QVariant( "1,223,456.012345" ); QVERIFY( doubleField.convertCompatible( stringDouble ) ); QCOMPARE( stringDouble.type(), QVariant::Double ); QCOMPARE( stringDouble, QVariant( 1223456.012345 ) ); // Test that wrongly formatted decimal separator are also accepted QLocale::setDefault( QLocale::German ); stringDouble = QVariant( "12.23.456,012345" ); QVERIFY( doubleField.convertCompatible( stringDouble ) ); QCOMPARE( stringDouble.type(), QVariant::Double ); QCOMPARE( stringDouble, QVariant( 1223456.012345 ) ); }
// преобразование словаря групп времени в удобный для поиска вид bool CSemanticsHolder::InitTimeUnits() { // инициализация констант BYTE GramFunctDomNo = GetRoss(TimeRoss)->GetDomenNoByDomStr("D_GRAM_FUNCT"); int AbbrFunctName = GetRoss(TimeRoss)->GetItemNoByItemStr("СОКР", GramFunctDomNo); int AbbrFunctPluralName = GetRoss(TimeRoss)->GetItemNoByItemStr("СОКР_мн", GramFunctDomNo); m_TimeAbbrPairs.clear(); m_TimeUnits.clear(); // идем по всем статьям словаря групп времени for (size_t UnitNo =0; UnitNo < GetRoss(TimeRoss)->GetUnitsSize(); UnitNo++) { try { CTimeUnit U; U.m_UnitNo = UnitNo; if (!GetRoss(TimeRoss)->IsEmptyArticle(UnitNo)) // по словарной статье for (size_t i = GetRoss(TimeRoss)->GetUnitStartPos(UnitNo); i<= GetRoss(TimeRoss)->GetUnitEndPos(UnitNo); i++) { TCortege C = GetCortege(GetRoss(TimeRoss), i); //незаполненное поле? if (C.m_DomItemNos[0] == -1) continue; // строю массив U.m_Places по полю CONTENT string FieldStr = (const char*)GetRoss(TimeRoss)->Fields[C.m_FieldNo].FieldStr; if ( (FieldStr == "CONTENT") && (C.m_LeafId == 0) && (C.m_BracketLeafId == 0) ) { string Lemma; string Contents = GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[0]); for (BYTE PlaceNo =0; GetLemmaFromTitle(Contents, PlaceNo, Lemma); PlaceNo++) U.m_Places.push_back(Lemma); }; if ( (FieldStr == "RESTR") && (C.m_LeafId == 0) && (C.m_BracketLeafId == 0) ) { string Contents = GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[0]); if (Contents == "свобод") U.m_bCanFillNotTimeValency = true; }; // инициализирую перечень всех необходимых синтаксических отношений их поля SYNREP if ( (FieldStr == "SYNREP") && (C.m_LeafId == 0) && (C.m_BracketLeafId == 0) ) { long PlaceNo1 = atoi(GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[1])); long PlaceNo2 = atoi(GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[2])); if (!PlaceNo1 || !PlaceNo2) continue; string SynGrp = GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[0]); rml_TRACE (SynGrp.c_str()); U.m_Rels.push_back(CSynRelation(PlaceNo1-1, PlaceNo2-1, SynGrp)); }; // инициализирую глобальный перечень наборов (полное временное слово, аббревиатура, аббревиатурная функция), // который называется m_TimeAbbrPairs // аббревиатурная функция = АББР_мн, АББР, АББР_ед // например:(год, гг.,АББР_мн) // (год, г., АББР_ед) if ( (FieldStr == "DERIV") && (C.m_LeafId == 0) && (C.m_BracketLeafId == 0) ) { if ( (C.m_DomItemNos[0] != AbbrFunctPluralName) && (C.m_DomItemNos[0] != AbbrFunctName) ) continue; string FullForm = GetRoss(TimeRoss)->GetEntryStr(UnitNo); EngRusMakeUpper(FullForm); string AbbrForm = GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[1]); EngRusMakeUpper(AbbrForm); m_TimeAbbrPairs.push_back(CAbbrFunct(AbbrForm, FullForm, GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[0]))); }; // инициализирую перечень лексического заполнения дырок, который берется из // полей LEX и PREP if (FieldStr == "LEX") { string S = GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[0]); EngRusMakeUpper(S); long LexFillingNoNo = U.GetLexicalFillingNo(CTimeLexicalFilling(C.m_LeafId, C.m_BracketLeafId)); U.m_LexicalFillings[LexFillingNoNo].m_LexFets.push_back(stringLong(S,C.m_LevelId)); } else if (FieldStr == "PREP") { string Prep = GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[0]); WORD PrepNo = GetRossHolder(OborRoss)->LocateUnit(Prep.c_str(),1); if (PrepNo == ErrUnitNo) { string Q =Format ("Предлог %s в статье %s не найден в словаре оборотов", Prep.c_str(), GetRoss(TimeRoss)->GetEntryStr(UnitNo).c_str()); ErrorMessage (Q); continue; }; long LexFillingNoNo = U.GetLexicalFillingNo(CTimeLexicalFilling(C.m_LeafId, C.m_BracketLeafId)); U.m_LexicalFillings[LexFillingNoNo].m_Preps.push_back(LongLong(PrepNo,C.m_LevelId)); }; }; m_TimeUnits.push_back(U); } catch (...) { ErrorMessage (Format("Cannot index article \"%s\"", GetRoss(TimeRoss)->GetEntryStr(UnitNo).c_str())); return false; }; }; return true; };