From 5244e5803d1d2df539eb001b2b59709fa630daef Mon Sep 17 00:00:00 2001 From: Alexander Borsuk Date: Thu, 16 Feb 2023 23:27:47 +0100 Subject: [PATCH 01/61] Removed likely unnecessary workaround for old clang Signed-off-by: Alexander Borsuk --- base/normalize_unicode.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/base/normalize_unicode.cpp b/base/normalize_unicode.cpp index 93242d9c61..4485ef0bed 100644 --- a/base/normalize_unicode.cpp +++ b/base/normalize_unicode.cpp @@ -7,11 +7,8 @@ namespace strings { -static strings::UniChar const normSymbols[] = {0x635,0x644,0x649,0x20,0x627,0x644,0x644,0x647,0x20,0x639,0x644,0x64a,0x647,0x20,0x648,0x633,0x644,0x645,0x62c,0x644,0x20,0x62c,0x644,0x627,0x644,0x647,0x28,0x110b,0x1169,0x110c,0x1165,0x11ab,0x29,0x28,0x110b,0x1169,0x1112,0x116e,0x29,0x72,0x61,0x64,0x2215,0x73,0x32,0x30ad,0x30ed,0x30e1,0x30fc,0x30c8,0x30eb,0x30ec,0x30f3,0x30c8,0x30b1,0x30f3,0x30d5,0x30a1,0x30e9,0x30c3,0x30c8,0x30d2,0x30a2,0x30b9,0x30c8,0x30eb,0x30cf,0x30fc,0x30bb,0x30f3,0x30c8,0x30b5,0x30f3,0x30c1,0x30fc,0x30e0,0x30df,0x30ea,0x30cf,0x30fc,0x30eb,0x30af,0x30eb,0x30bb,0x30a4,0x30ed,0x30af,0x30e9,0x30e0,0x30c8,0x30f3,0x30ad,0x30ed,0x30ef,0x30c3,0x30c8,0x30ad,0x30ed,0x30af,0x30e9,0x30e0,0x30de,0x30f3,0x30b7,0x30e7,0x30f3,0x30a8,0x30b9,0x30af,0x30fc,0x30c8,0x30d8,0x30af,0x30bf,0x30fc,0x30eb,0x30d5,0x30c3,0x30b7,0x30a7,0x30eb,0x110e,0x1161,0x11b7,0x1100,0x1169,0x30df,0x30af,0x30ed,0x30f3,0x2032,0x2032,0x2032,0x2032,0x30e1,0x30ab,0x30c8,0x30f3,0x30de,0x30a4,0x30af,0x30ed,0x30db,0x30a4,0x30f3,0x30c8,0x30ea,0x30c3,0x30c8,0x30eb,0x30d5,0x30a3,0x30fc,0x30c8,0x30eb,0x30fc,0x30d5,0x30eb,0x31,0x2044,0x31,0x30,0x56,0x49,0x49,0x49,0x76,0x69,0x69,0x69,0x28,0x31,0x30,0x29,0x28,0x31,0x31,0x29,0x28,0x31,0x32,0x29,0x28,0x31,0x33,0x29,0x28,0x31,0x34,0x29,0x28,0x31,0x35,0x29,0x28,0x31,0x36,0x29,0x28,0x31,0x37,0x29,0x28,0x31,0x38,0x29,0x28,0x31,0x39,0x29,0x28,0x32,0x30,0x29,0x110c,0x116e,0x110b,0x1174,0x30a2,0x30cf,0x30fc,0x30c8,0x30a2,0x30eb,0x30d5,0x30a1,0x30a2,0x30f3,0x30d8,0x30a2,0x30a4,0x30cb,0x30f3,0x30af,0x30a8,0x30fc,0x30ab,0x30fc,0x30ab,0x30e9,0x30c3,0x30c8,0x30ab,0x30ed,0x30ea,0x30fc,0x30ad,0x30e5,0x30ea,0x30fc,0x30ad,0x30eb,0x30bf,0x30fc,0x30af,0x30ed,0x30fc,0x30cd,0x30b5,0x30a4,0x30af,0x30eb,0x30b7,0x30ea,0x30f3,0x30af,0x30cf,0x30fc,0x30ec,0x30eb,0x28,0x110c,0x116e,0x29,0x28,0x1112,0x1161,0x29,0x28,0x1111,0x1161,0x29,0x28,0x1110,0x1161,0x29,0x28,0x110f,0x1161,0x29,0x28,0x110e,0x1161,0x29,0x28,0x110c,0x1161,0x29,0x28,0x110b,0x1161,0x29,0x28,0x1109,0x1161,0x29,0x28,0x1107,0x1161,0x29,0x28,0x1106,0x1161,0x29,0x28,0x1105,0x1161,0x29,0x28,0x1103,0x1161,0x29,0x28,0x1102,0x1161,0x29,0x28,0x1100,0x1161,0x29,0x6b,0x63,0x61,0x6c,0x6d,0x2215,0x73,0x32,0x631,0x6cc,0x627,0x644,0x631,0x633,0x648,0x644,0x61,0x2e,0x6d,0x2e,0x635,0x644,0x639,0x645,0x645,0x62d,0x645,0x62f,0x43,0x2215,0x6b,0x67,0x627,0x643,0x628,0x631,0x70,0x2e,0x6d,0x2e,0x222b,0x222b,0x222b,0x222b,0x633,0x645,0x62d,0x633,0x645,0x62c,0x68,0x50,0x61,0x62,0x61,0x72,0x64,0x6d,0x32,0x2e,0x2e,0x2e,0x64,0x6d,0x33,0x639,0x62c,0x645,0x6b,0x48,0x7a,0x4d,0x48,0x7a,0x47,0x48,0x7a,0x54,0x48,0x7a,0x6d,0x6d,0x32,0x63,0x6d,0x32,0x30d2,0x30af,0x30eb,0x6b,0x6d,0x32,0x642,0x644,0x6d2,0x30de,0x30a4,0x30eb,0x30db,0x30fc,0x30f3,0x30db,0x30fc,0x30eb,0x30db,0x30f3,0x30c8,0x30db,0x30eb,0x30c8,0x30de,0x30c3,0x30cf,0x30d8,0x30fc,0x30bf,0x30d8,0x30fc,0x30b7,0x30d8,0x30f3,0x30b9,0x30d8,0x30eb,0x30c4,0x30d8,0x30cb,0x30d2,0x30de,0x30eb,0x30af,0x635,0x644,0x6d2,0x30d5,0x30e9,0x30f3,0x646,0x62c,0x64a,0x633,0x62e,0x64a,0x635,0x645,0x645,0x633,0x62c,0x649,0x43,0x6f,0x2e,0x30ab,0x30a4,0x30ea,0x30aa,0x30fc,0x30e0,0x30aa,0x30f3,0x30b9,0x41,0x2215,0x6d,0x56,0x2215,0x6d,0x30a6,0x30a9,0x30f3,0x30a4,0x30f3,0x30c1,0x6c,0x6f,0x67,0x30a2,0x30fc,0x30eb,0x50,0x50,0x4d,0x6d,0x6f,0x6c,0x4c,0x54,0x44,0x65,0x72,0x67,0x633,0x62c,0x62d,0x633,0x62d,0x62c,0x62d,0x645,0x649,0x62d,0x645,0x64a,0x62c,0x645,0x62d,0x62c,0x645,0x62d,0x62a,0x645,0x62e,0x62a,0x645,0x62d,0x62a,0x645,0x62c,0x6d,0x69,0x6c,0x6d,0x6d,0x33,0x30cf,0x30fc,0x30c4,0x63,0x6d,0x33,0x30cf,0x30a4,0x30c4,0x30ce,0x30c3,0x30c8,0x30bf,0x30fc,0x30b9,0x30bb,0x30f3,0x30c1,0x6b,0x6d,0x33,0x30b3,0x30fc,0x30db,0x30b3,0x30eb,0x30ca,0x30b1,0x30fc,0x30b9,0x6b,0x50,0x61,0x4d,0x50,0x61,0x47,0x50,0x61,0x66,0x66,0x6c,0x66,0x66,0x69,0x67,0x61,0x6c,0x30ad,0x30cb,0x30fc,0x30ab,0x30f3,0x30de,0x30ab,0x30ed,0x30f3,0x62a,0x645,0x64a,0x62a,0x62e,0x649,0x62a,0x62e,0x64a,0x62a,0x62c,0x649,0x62a,0x62c,0x64a,0x628,0x62e,0x64a,0x64a,0x645,0x645,0x64a,0x645,0x645,0x646,0x645,0x649,0x646,0x645,0x64a,0x646,0x62c,0x649,0x646,0x62c,0x645,0x646,0x62c,0x645,0x646,0x62d,0x649,0x646,0x62d,0x645,0x647,0x645,0x645,0x647,0x645,0x62c,0x645,0x62c,0x62e,0x645,0x62e,0x645,0x645,0x62e,0x62c,0x645,0x62c,0x62d,0x645,0x62d,0x64a,0x646,0x62c,0x62d,0x64a,0x645,0x64a,0x64a,0x62c,0x64a,0x64a,0x62d,0x64a,0x644,0x645,0x64a,0x644,0x62c,0x64a,0x636,0x62d,0x64a,0x642,0x645,0x64a,0x646,0x62d,0x64a,0x642,0x645,0x62d,0x644,0x62d,0x645,0x639,0x645,0x64a,0x643,0x645,0x64a,0x645,0x62e,0x64a,0x644,0x62c,0x645,0x643,0x645,0x645,0x634,0x62d,0x64a,0x635,0x62d,0x64a,0x633,0x62e,0x649,0x62c,0x645,0x649,0x62c,0x62d,0x649,0x62c,0x645,0x64a,0x62a,0x645,0x649,0x636,0x62e,0x645,0x636,0x62e,0x645,0x636,0x62d,0x649,0x62d,0x62c,0x64a,0x634,0x645,0x645,0x634,0x645,0x645,0x634,0x645,0x62e,0x634,0x645,0x62e,0x634,0x62c,0x64a,0x634,0x62d,0x645,0x634,0x62d,0x645,0x635,0x62d,0x62d,0x635,0x62d,0x62d,0x633,0x645,0x645,0x633,0x645,0x645,0x645,0x62c,0x64a,0x641,0x645,0x64a,0x30eb,0x30d2,0x30fc,0x628,0x62d,0x64a,0x30e6,0x30a2,0x30f3,0x30e4,0x30fc,0x30eb,0x30e4,0x30fc,0x30c8,0x644,0x645,0x62d,0x644,0x645,0x62d,0x644,0x62e,0x645,0x644,0x62e,0x645,0x644,0x62c,0x62c,0x644,0x62c,0x62c,0x644,0x62d,0x649,0x644,0x62d,0x64a,0x642,0x645,0x645,0x641,0x62e,0x645,0x641,0x62e,0x645,0x63a,0x645,0x649,0x63a,0x645,0x64a,0x63a,0x645,0x645,0x639,0x645,0x649,0x637,0x645,0x64a,0x637,0x645,0x645,0x637,0x645,0x62d,0x637,0x645,0x62d,0x58,0x49,0x49,0x78,0x69,0x69,0x30,0x2044,0x33,0x222e,0x222e,0x222e,0x28,0x31,0x29,0x28,0x32,0x29,0x28,0x33,0x29,0x28,0x34,0x29,0x28,0x35,0x29,0x28,0x36,0x29,0x28,0x37,0x29,0x28,0x38,0x29,0x28,0x39,0x29,0x28,0x41,0x29,0x28,0x42,0x29,0x28,0x43,0x29,0x28,0x44,0x29,0x28,0x45,0x29,0x28,0x46,0x29,0x28,0x47,0x29,0x28,0x48,0x29,0x28,0x49,0x29,0x28,0x4a,0x29,0x28,0x4b,0x29,0x28,0x1106,0x29,0x28,0x1105,0x29,0x28,0x1103,0x29,0x28,0x1102,0x29,0x28,0x1100,0x29,0x61,0x2f,0x63,0x61,0x2f,0x73,0x63,0x2f,0x6f,0x63,0x2f,0x75,0x54,0x45,0x4c,0x62a,0x62d,0x645,0x46,0x41,0x58,0x31,0x2044,0x37,0x31,0x2044,0x39,0x31,0x2044,0x33,0x32,0x2044,0x33,0x31,0x2044,0x35,0x32,0x2044,0x35,0x33,0x2044,0x35,0x34,0x2044,0x35,0x31,0x2044,0x36,0x35,0x2044,0x36,0x31,0x2044,0x38,0x33,0x2044,0x38,0x35,0x2044,0x38,0x37,0x2044,0x38,0x62a,0x62d,0x62c,0x62a,0x62d,0x62c,0x62a,0x62c,0x645,0x28,0x64,0x29,0x28,0x65,0x29,0x28,0x66,0x29,0x28,0x67,0x29,0x28,0x68,0x29,0x28,0x69,0x29,0x28,0x6a,0x29,0x28,0x6b,0x29,0x28,0x6c,0x29,0x28,0x6d,0x29,0x28,0x6e,0x29,0x50,0x50,0x56,0x28,0x6f,0x29,0x28,0x70,0x29,0x28,0x71,0x29,0x28,0x72,0x29,0x28,0x73,0x29,0x33,0x2044,0x34,0x31,0x2044,0x32,0x31,0x2044,0x34,0x28,0x74,0x29,0x28,0x75,0x29,0x28,0x76,0x29,0x28,0x77,0x29,0x28,0x78,0x29,0x28,0x79,0x29,0x28,0x7a,0x29,0x3d,0x3d,0x3d,0x3a,0x3a,0x3d,0x28,0x4c,0x29,0x28,0x4d,0x29,0x28,0x4e,0x29,0x28,0x4f,0x29,0x28,0x50,0x29,0x28,0x51,0x29,0x28,0x52,0x29,0x28,0x53,0x29,0x28,0x54,0x29,0x28,0x55,0x29,0x28,0x56,0x29,0x28,0x57,0x29,0x28,0x58,0x29,0x28,0x59,0x29,0x28,0x5a,0x29,0x3014,0x53,0x3015,0x31,0x30,0x2e,0x31,0x31,0x2e,0x31,0x32,0x2e,0x31,0x33,0x2e,0x31,0x34,0x2e,0x31,0x35,0x2e,0x31,0x36,0x2e,0x31,0x37,0x2e,0x31,0x38,0x2e,0x31,0x39,0x2e,0x32,0x30,0x2e,0x28,0x61,0x29,0x28,0x62,0x29,0x28,0x63,0x29,0x62a,0x62e,0x645,0x28,0x4e00,0x29,0x28,0x1112,0x29,0x28,0x1111,0x29,0x28,0x1110,0x29,0x28,0x110f,0x29,0x50,0x54,0x45,0x28,0x1109,0x29,0x28,0x110e,0x29,0x2035,0x2035,0x2035,0x28,0x110c,0x29,0x28,0x1107,0x29,0x28,0x110b,0x29,0x3bc,0x67,0x3bc,0x46,0x6e,0x46,0x70,0x46,0x34,0x33,0x6d,0x67,0x61,0x2be,0x3bc,0x6d,0x6e,0x6d,0x66,0x6d,0x6b,0x6c,0x64,0x6c,0x6d,0x6c,0x3bc,0x6c,0x33,0x30,0x32,0x39,0x32,0x38,0x34,0x32,0x32,0x37,0x48,0x67,0x35,0x30,0x32,0x33,0x32,0x34,0x34,0x39,0x64,0x61,0x41,0x55,0x47,0x42,0x4d,0x42,0x4b,0x42,0x6b,0x41,0x6d,0x41,0x3bc,0x41,0x6e,0x41,0x70,0x41,0x49,0x55,0x34,0x35,0x34,0x36,0x34,0x37,0x70,0x63,0x6f,0x56,0x34,0x38,0x6d,0x57,0x6b,0x57,0x4d,0x57,0x6b,0x3a9,0x4d,0x3a9,0x42,0x71,0x63,0x63,0x63,0x64,0x64,0x42,0x47,0x79,0x68,0x61,0x48,0x50,0x69,0x6e,0x4b,0x4b,0x4b,0x4d,0x6b,0x74,0x6c,0x6e,0x6c,0x78,0x6d,0x62,0x33,0x33,0x33,0x34,0x33,0x35,0x34,0x30,0x33,0x39,0x33,0x38,0x33,0x37,0x33,0x36,0x110b,0x116e,0x70,0x73,0x6e,0x73,0x3bc,0x73,0x6d,0x73,0x70,0x56,0x6e,0x56,0x3bc,0x56,0x6b,0x56,0x4d,0x56,0x70,0x57,0x6e,0x57,0x3bc,0x57,0x30d8,0x30bd,0x30d2,0x30eb,0x30d2,0x30b3,0x28,0x29,0x28,0x29,0x49,0x56,0x49,0x58,0x30ca,0x30ce,0x69,0x76,0x21,0x3f,0x3f,0x21,0x21,0x21,0x52,0x73,0xb0,0x43,0xb0,0x46,0x30ea,0x30e9,0x4e,0x6f,0x30ec,0x30e0,0x53,0x4d,0x54,0x4d,0x30ad,0x30ab,0x32,0x35,0x32,0x36,0x65,0x56,0x69,0x78,0x30c6,0x30b7,0x30b3,0x30c8,0x3088,0x308a,0x63a,0x62c,0x638,0x645,0x637,0x62d,0x636,0x645,0x636,0x62c,0x635,0x62e,0x628,0x645,0x628,0x647,0x64,0x7a,0x44,0x7a,0x44,0x5a,0x62a,0x647,0x62b,0x645,0x646,0x62e,0x643,0x644,0x643,0x62e,0x641,0x62c,0x641,0x62d,0x642,0x62d,0x643,0x62c,0x643,0x62d,0x6e,0x6a,0x4e,0x6a,0x4e,0x4a,0x6c,0x6a,0x4c,0x6a,0x4c,0x4a,0x62b,0x64a,0x62b,0x649,0x62b,0x646,0x62b,0x632,0x62b,0x631,0x62a,0x64a,0x62a,0x649,0x62a,0x646,0x62a,0x632,0x62a,0x631,0x628,0x64a,0x628,0x649,0x628,0x646,0x647,0x649,0x647,0x64a,0x64a,0x62e,0x64a,0x649,0x64a,0x631,0x64a,0x632,0x628,0x632,0x646,0x646,0x646,0x649,0x646,0x64a,0x628,0x62c,0x641,0x649,0x641,0x64a,0x642,0x649,0x642,0x64a,0x643,0x627,0x643,0x649,0x643,0x64a,0x645,0x627,0x646,0x631,0x646,0x632,0x633,0x631,0x634,0x631,0x634,0x62e,0x636,0x64a,0x636,0x649,0x635,0x64a,0x635,0x649,0x57,0x5a,0x43,0x44,0x39,0x2c,0x633,0x649,0x633,0x64a,0x634,0x649,0x634,0x64a,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x35,0x2c,0x36,0x2c,0x37,0x2c,0x38,0x2c,0x53,0x44,0x53,0x53,0x57,0x43,0x44,0x4a,0x307b,0x304b,0x30b3,0x30b3,0x3014,0x3015,0x3014,0x3015,0x635,0x631,0x636,0x631,0x633,0x647,0x634,0x647,0x48,0x56,0x63a,0x649,0x639,0x64a,0x639,0x649,0x637,0x64a,0x637,0x649,0x647,0x62c,0x62b,0x647,0x69,0x6a,0x49,0x4a,0x63a,0x64a,0x2bc,0x6e,0x6c,0xb7,0x4c,0xb7,0x62e,0x62d,0x62b,0x62c,0x64a,0x674,0x64a,0x6d0,0x64a,0x6d0,0x64a,0x6c8,0x64a,0x6c8,0x64a,0x6c6,0x64a,0x6c6,0x64a,0x6c7,0x64a,0x6c7,0x64a,0x648,0x64a,0x648,0x64a,0x6d5,0x64a,0x6d5,0x64a,0x627,0x64a,0x627,0xeab,0xe99,0xeab,0xea1,0x6c7,0x674,0x5d0,0x5dc,0x73,0x74,0x73,0x74,0x574,0x576,0x574,0x565,0x574,0x56b,0x57e,0x576,0x574,0x56d,0x565,0x582,0x627,0x674,0x648,0x674,0x50,0x48,0x50,0x52,0x73,0x72,0x57,0x62,0x53,0x76,0x5c,0x5e,0x5b,0x5d,0x30f2,0x30a5,0x30e3,0x60,0x7b,0x5f,0x2013,0x2014,0x40,0x3b,0x3001,0x7d,0x23,0x26,0x2a,0x2b,0x2d,0x3c,0x3e,0x7c,0x30fb,0x300f,0x300e,0x300d,0x300c,0x3009,0x3008,0x300b,0x300a,0x3011,0x3010,0x7e,0x2985,0x2986,0x3002,0x640,0x640,0x621,0x630,0x630,0x629,0x629,0x25,0x27,0x3017,0x3016,0x24,0x24,0x22,0x39e,0x39d,0x39c,0x39b,0x39a,0x399,0x398,0x397,0x396,0x395,0x394,0x393,0x392,0x391,0x237,0x131,0x3c0,0x3c1,0x3c6,0x3ba,0x3b8,0x3b5,0x2202,0x3c9,0x3b2,0x3b1,0x2207,0x3a8,0x3a7,0x3a6,0x3a5,0x3a4,0x3a3,0x3a1,0x3a0,0x39f,0x3b6,0x3b4,0x3b3,0x3c8,0x3c7,0x3c5,0x3c4,0x3c3,0x3c2,0x3bf,0x3be,0x3bd,0x3bb,0x3b9,0x3b7,0x3dd,0x3dc,0x11b3,0x11b2,0x11b1,0x11b0,0x1104,0x11ad,0x11ac,0x11aa,0x1101,0x1160,0x110d,0x110a,0x1121,0x1108,0x111a,0x11b5,0x11b4,0x30cc,0x30e8,0x30e2,0x1d1ba,0x1d1b9,0x1d1b9,0x1d158,0x1d158,0x1d157,0x110a5,0x1173,0x1172,0x1171,0x1170,0x116f,0x116d,0x116c,0x116b,0x116a,0x1168,0x1167,0x1166,0x1164,0x1163,0x1162,0x1109b,0x11099,0x25cb,0x25a0,0x2193,0x2192,0x2191,0x2190,0x2502,0x20a9,0xa5,0xa6,0xac,0xa3,0xa2,0x1175,0x292,0x250,0x251,0x1d02,0x259,0x25b,0x25c,0x14b,0x254,0x1d16,0x1d17,0x1d1d,0x26f,0x1025,0x10dc,0x1b05,0x1b07,0x1b09,0x1b0b,0x1b0d,0x1b11,0xc6,0x18e,0x222,0x268,0x269,0x26a,0x1d7b,0x29d,0x26d,0x1d85,0x29f,0x271,0x270,0x272,0x273,0x274,0x275,0x278,0x282,0x283,0x1ab,0x289,0x28a,0x1d1c,0x28b,0x28c,0x290,0x291,0x1d25,0x43d,0x252,0x255,0xf0,0x25f,0x261,0x265,0xe6,0x438,0x443,0x474,0x475,0x416,0x436,0x410,0x430,0x430,0x415,0x435,0x4d8,0x4d9,0x417,0x437,0x418,0x418,0x41e,0x43e,0x4e8,0x4e9,0x413,0x406,0x41a,0x423,0x433,0x456,0x43a,0x91c,0x921,0x922,0x92b,0x92f,0x9a1,0x9a2,0x9af,0xa32,0xa38,0xa16,0xa17,0xa1c,0xa2b,0xb21,0xb22,0xb92,0xe32,0xeb2,0xf0b,0xf42,0xf4c,0xf51,0xf56,0xf5b,0xf40,0x42d,0x44d,0x427,0x447,0x42b,0x44b,0x6c1,0x928,0x930,0x933,0x915,0x916,0x917,0x1b7,0xd8,0xf8,0x266,0x279,0x27b,0x281,0x263,0x295,0x2b9,0x1158,0x1159,0x1184,0x1185,0x1188,0x1191,0x1192,0x1194,0x119e,0x11a1,0x11d3,0x11d7,0x11d9,0x111c,0x11dd,0x11df,0x111d,0x111e,0x1120,0x1122,0x1123,0x1127,0x1129,0x112b,0x112c,0x112d,0x112e,0x112f,0x1132,0x1136,0x1140,0x1147,0x114c,0x11f1,0x11f2,0x1157,0x30f0,0x30f1,0x30fd,0x3068,0x306f,0x306f,0x3072,0x3072,0x3075,0x3075,0x3078,0x3078,0x3046,0x309d,0x1114,0x1115,0x11c7,0x11c8,0x11cc,0x11ce,0x691,0x6a9,0x6a9,0x6af,0x6af,0x6b3,0x6b3,0x6b1,0x6b1,0x6ba,0x6ba,0x6bb,0x6bb,0x684,0x684,0x683,0x683,0x686,0x686,0x687,0x687,0x68d,0x68d,0x68c,0x68c,0x68e,0x68e,0x688,0x688,0x698,0x698,0x6c9,0x6be,0x6be,0x6ad,0x6ad,0x6cb,0x6cb,0x6c5,0x6c5,0x5f2,0x5e2,0x5d3,0x5d4,0x5db,0x5dd,0x5e8,0x5ea,0x5e9,0x5e9,0x5d1,0x5d2,0x5d5,0x5d6,0x5d8,0x5d9,0xa76f,0x67e,0x680,0x680,0x67a,0x67a,0x67f,0x67f,0x679,0x679,0x6a4,0x6a4,0x6a6,0x6a6,0x5da,0x5de,0x5e0,0x5e1,0x5e3,0x5e4,0x5e6,0x5e7,0x671,0x671,0x67b,0x67b,0x2212,0x2010,0x2277,0x227a,0x227b,0x2282,0x2283,0x2286,0x2287,0x22a2,0x22a8,0x22a9,0x22ab,0x227c,0x227d,0x2291,0x2292,0x22b2,0x22b3,0x22b4,0x22b5,0x2add,0x2d61,0x3012,0x304d,0x304f,0x3051,0x3053,0x3055,0x3057,0x3059,0x305b,0x305d,0x305f,0x3061,0x3064,0x3066,0x127,0x190,0x2194,0x21d0,0x21d4,0x21d2,0x2203,0x2208,0x220b,0x2223,0x2225,0x223c,0x2243,0x2245,0x2248,0x2261,0x224d,0x2264,0x2265,0x2272,0x2273,0x2276,0x2211}; +strings::UniChar constexpr normSymbols[] = {0x635,0x644,0x649,0x20,0x627,0x644,0x644,0x647,0x20,0x639,0x644,0x64a,0x647,0x20,0x648,0x633,0x644,0x645,0x62c,0x644,0x20,0x62c,0x644,0x627,0x644,0x647,0x28,0x110b,0x1169,0x110c,0x1165,0x11ab,0x29,0x28,0x110b,0x1169,0x1112,0x116e,0x29,0x72,0x61,0x64,0x2215,0x73,0x32,0x30ad,0x30ed,0x30e1,0x30fc,0x30c8,0x30eb,0x30ec,0x30f3,0x30c8,0x30b1,0x30f3,0x30d5,0x30a1,0x30e9,0x30c3,0x30c8,0x30d2,0x30a2,0x30b9,0x30c8,0x30eb,0x30cf,0x30fc,0x30bb,0x30f3,0x30c8,0x30b5,0x30f3,0x30c1,0x30fc,0x30e0,0x30df,0x30ea,0x30cf,0x30fc,0x30eb,0x30af,0x30eb,0x30bb,0x30a4,0x30ed,0x30af,0x30e9,0x30e0,0x30c8,0x30f3,0x30ad,0x30ed,0x30ef,0x30c3,0x30c8,0x30ad,0x30ed,0x30af,0x30e9,0x30e0,0x30de,0x30f3,0x30b7,0x30e7,0x30f3,0x30a8,0x30b9,0x30af,0x30fc,0x30c8,0x30d8,0x30af,0x30bf,0x30fc,0x30eb,0x30d5,0x30c3,0x30b7,0x30a7,0x30eb,0x110e,0x1161,0x11b7,0x1100,0x1169,0x30df,0x30af,0x30ed,0x30f3,0x2032,0x2032,0x2032,0x2032,0x30e1,0x30ab,0x30c8,0x30f3,0x30de,0x30a4,0x30af,0x30ed,0x30db,0x30a4,0x30f3,0x30c8,0x30ea,0x30c3,0x30c8,0x30eb,0x30d5,0x30a3,0x30fc,0x30c8,0x30eb,0x30fc,0x30d5,0x30eb,0x31,0x2044,0x31,0x30,0x56,0x49,0x49,0x49,0x76,0x69,0x69,0x69,0x28,0x31,0x30,0x29,0x28,0x31,0x31,0x29,0x28,0x31,0x32,0x29,0x28,0x31,0x33,0x29,0x28,0x31,0x34,0x29,0x28,0x31,0x35,0x29,0x28,0x31,0x36,0x29,0x28,0x31,0x37,0x29,0x28,0x31,0x38,0x29,0x28,0x31,0x39,0x29,0x28,0x32,0x30,0x29,0x110c,0x116e,0x110b,0x1174,0x30a2,0x30cf,0x30fc,0x30c8,0x30a2,0x30eb,0x30d5,0x30a1,0x30a2,0x30f3,0x30d8,0x30a2,0x30a4,0x30cb,0x30f3,0x30af,0x30a8,0x30fc,0x30ab,0x30fc,0x30ab,0x30e9,0x30c3,0x30c8,0x30ab,0x30ed,0x30ea,0x30fc,0x30ad,0x30e5,0x30ea,0x30fc,0x30ad,0x30eb,0x30bf,0x30fc,0x30af,0x30ed,0x30fc,0x30cd,0x30b5,0x30a4,0x30af,0x30eb,0x30b7,0x30ea,0x30f3,0x30af,0x30cf,0x30fc,0x30ec,0x30eb,0x28,0x110c,0x116e,0x29,0x28,0x1112,0x1161,0x29,0x28,0x1111,0x1161,0x29,0x28,0x1110,0x1161,0x29,0x28,0x110f,0x1161,0x29,0x28,0x110e,0x1161,0x29,0x28,0x110c,0x1161,0x29,0x28,0x110b,0x1161,0x29,0x28,0x1109,0x1161,0x29,0x28,0x1107,0x1161,0x29,0x28,0x1106,0x1161,0x29,0x28,0x1105,0x1161,0x29,0x28,0x1103,0x1161,0x29,0x28,0x1102,0x1161,0x29,0x28,0x1100,0x1161,0x29,0x6b,0x63,0x61,0x6c,0x6d,0x2215,0x73,0x32,0x631,0x6cc,0x627,0x644,0x631,0x633,0x648,0x644,0x61,0x2e,0x6d,0x2e,0x635,0x644,0x639,0x645,0x645,0x62d,0x645,0x62f,0x43,0x2215,0x6b,0x67,0x627,0x643,0x628,0x631,0x70,0x2e,0x6d,0x2e,0x222b,0x222b,0x222b,0x222b,0x633,0x645,0x62d,0x633,0x645,0x62c,0x68,0x50,0x61,0x62,0x61,0x72,0x64,0x6d,0x32,0x2e,0x2e,0x2e,0x64,0x6d,0x33,0x639,0x62c,0x645,0x6b,0x48,0x7a,0x4d,0x48,0x7a,0x47,0x48,0x7a,0x54,0x48,0x7a,0x6d,0x6d,0x32,0x63,0x6d,0x32,0x30d2,0x30af,0x30eb,0x6b,0x6d,0x32,0x642,0x644,0x6d2,0x30de,0x30a4,0x30eb,0x30db,0x30fc,0x30f3,0x30db,0x30fc,0x30eb,0x30db,0x30f3,0x30c8,0x30db,0x30eb,0x30c8,0x30de,0x30c3,0x30cf,0x30d8,0x30fc,0x30bf,0x30d8,0x30fc,0x30b7,0x30d8,0x30f3,0x30b9,0x30d8,0x30eb,0x30c4,0x30d8,0x30cb,0x30d2,0x30de,0x30eb,0x30af,0x635,0x644,0x6d2,0x30d5,0x30e9,0x30f3,0x646,0x62c,0x64a,0x633,0x62e,0x64a,0x635,0x645,0x645,0x633,0x62c,0x649,0x43,0x6f,0x2e,0x30ab,0x30a4,0x30ea,0x30aa,0x30fc,0x30e0,0x30aa,0x30f3,0x30b9,0x41,0x2215,0x6d,0x56,0x2215,0x6d,0x30a6,0x30a9,0x30f3,0x30a4,0x30f3,0x30c1,0x6c,0x6f,0x67,0x30a2,0x30fc,0x30eb,0x50,0x50,0x4d,0x6d,0x6f,0x6c,0x4c,0x54,0x44,0x65,0x72,0x67,0x633,0x62c,0x62d,0x633,0x62d,0x62c,0x62d,0x645,0x649,0x62d,0x645,0x64a,0x62c,0x645,0x62d,0x62c,0x645,0x62d,0x62a,0x645,0x62e,0x62a,0x645,0x62d,0x62a,0x645,0x62c,0x6d,0x69,0x6c,0x6d,0x6d,0x33,0x30cf,0x30fc,0x30c4,0x63,0x6d,0x33,0x30cf,0x30a4,0x30c4,0x30ce,0x30c3,0x30c8,0x30bf,0x30fc,0x30b9,0x30bb,0x30f3,0x30c1,0x6b,0x6d,0x33,0x30b3,0x30fc,0x30db,0x30b3,0x30eb,0x30ca,0x30b1,0x30fc,0x30b9,0x6b,0x50,0x61,0x4d,0x50,0x61,0x47,0x50,0x61,0x66,0x66,0x6c,0x66,0x66,0x69,0x67,0x61,0x6c,0x30ad,0x30cb,0x30fc,0x30ab,0x30f3,0x30de,0x30ab,0x30ed,0x30f3,0x62a,0x645,0x64a,0x62a,0x62e,0x649,0x62a,0x62e,0x64a,0x62a,0x62c,0x649,0x62a,0x62c,0x64a,0x628,0x62e,0x64a,0x64a,0x645,0x645,0x64a,0x645,0x645,0x646,0x645,0x649,0x646,0x645,0x64a,0x646,0x62c,0x649,0x646,0x62c,0x645,0x646,0x62c,0x645,0x646,0x62d,0x649,0x646,0x62d,0x645,0x647,0x645,0x645,0x647,0x645,0x62c,0x645,0x62c,0x62e,0x645,0x62e,0x645,0x645,0x62e,0x62c,0x645,0x62c,0x62d,0x645,0x62d,0x64a,0x646,0x62c,0x62d,0x64a,0x645,0x64a,0x64a,0x62c,0x64a,0x64a,0x62d,0x64a,0x644,0x645,0x64a,0x644,0x62c,0x64a,0x636,0x62d,0x64a,0x642,0x645,0x64a,0x646,0x62d,0x64a,0x642,0x645,0x62d,0x644,0x62d,0x645,0x639,0x645,0x64a,0x643,0x645,0x64a,0x645,0x62e,0x64a,0x644,0x62c,0x645,0x643,0x645,0x645,0x634,0x62d,0x64a,0x635,0x62d,0x64a,0x633,0x62e,0x649,0x62c,0x645,0x649,0x62c,0x62d,0x649,0x62c,0x645,0x64a,0x62a,0x645,0x649,0x636,0x62e,0x645,0x636,0x62e,0x645,0x636,0x62d,0x649,0x62d,0x62c,0x64a,0x634,0x645,0x645,0x634,0x645,0x645,0x634,0x645,0x62e,0x634,0x645,0x62e,0x634,0x62c,0x64a,0x634,0x62d,0x645,0x634,0x62d,0x645,0x635,0x62d,0x62d,0x635,0x62d,0x62d,0x633,0x645,0x645,0x633,0x645,0x645,0x645,0x62c,0x64a,0x641,0x645,0x64a,0x30eb,0x30d2,0x30fc,0x628,0x62d,0x64a,0x30e6,0x30a2,0x30f3,0x30e4,0x30fc,0x30eb,0x30e4,0x30fc,0x30c8,0x644,0x645,0x62d,0x644,0x645,0x62d,0x644,0x62e,0x645,0x644,0x62e,0x645,0x644,0x62c,0x62c,0x644,0x62c,0x62c,0x644,0x62d,0x649,0x644,0x62d,0x64a,0x642,0x645,0x645,0x641,0x62e,0x645,0x641,0x62e,0x645,0x63a,0x645,0x649,0x63a,0x645,0x64a,0x63a,0x645,0x645,0x639,0x645,0x649,0x637,0x645,0x64a,0x637,0x645,0x645,0x637,0x645,0x62d,0x637,0x645,0x62d,0x58,0x49,0x49,0x78,0x69,0x69,0x30,0x2044,0x33,0x222e,0x222e,0x222e,0x28,0x31,0x29,0x28,0x32,0x29,0x28,0x33,0x29,0x28,0x34,0x29,0x28,0x35,0x29,0x28,0x36,0x29,0x28,0x37,0x29,0x28,0x38,0x29,0x28,0x39,0x29,0x28,0x41,0x29,0x28,0x42,0x29,0x28,0x43,0x29,0x28,0x44,0x29,0x28,0x45,0x29,0x28,0x46,0x29,0x28,0x47,0x29,0x28,0x48,0x29,0x28,0x49,0x29,0x28,0x4a,0x29,0x28,0x4b,0x29,0x28,0x1106,0x29,0x28,0x1105,0x29,0x28,0x1103,0x29,0x28,0x1102,0x29,0x28,0x1100,0x29,0x61,0x2f,0x63,0x61,0x2f,0x73,0x63,0x2f,0x6f,0x63,0x2f,0x75,0x54,0x45,0x4c,0x62a,0x62d,0x645,0x46,0x41,0x58,0x31,0x2044,0x37,0x31,0x2044,0x39,0x31,0x2044,0x33,0x32,0x2044,0x33,0x31,0x2044,0x35,0x32,0x2044,0x35,0x33,0x2044,0x35,0x34,0x2044,0x35,0x31,0x2044,0x36,0x35,0x2044,0x36,0x31,0x2044,0x38,0x33,0x2044,0x38,0x35,0x2044,0x38,0x37,0x2044,0x38,0x62a,0x62d,0x62c,0x62a,0x62d,0x62c,0x62a,0x62c,0x645,0x28,0x64,0x29,0x28,0x65,0x29,0x28,0x66,0x29,0x28,0x67,0x29,0x28,0x68,0x29,0x28,0x69,0x29,0x28,0x6a,0x29,0x28,0x6b,0x29,0x28,0x6c,0x29,0x28,0x6d,0x29,0x28,0x6e,0x29,0x50,0x50,0x56,0x28,0x6f,0x29,0x28,0x70,0x29,0x28,0x71,0x29,0x28,0x72,0x29,0x28,0x73,0x29,0x33,0x2044,0x34,0x31,0x2044,0x32,0x31,0x2044,0x34,0x28,0x74,0x29,0x28,0x75,0x29,0x28,0x76,0x29,0x28,0x77,0x29,0x28,0x78,0x29,0x28,0x79,0x29,0x28,0x7a,0x29,0x3d,0x3d,0x3d,0x3a,0x3a,0x3d,0x28,0x4c,0x29,0x28,0x4d,0x29,0x28,0x4e,0x29,0x28,0x4f,0x29,0x28,0x50,0x29,0x28,0x51,0x29,0x28,0x52,0x29,0x28,0x53,0x29,0x28,0x54,0x29,0x28,0x55,0x29,0x28,0x56,0x29,0x28,0x57,0x29,0x28,0x58,0x29,0x28,0x59,0x29,0x28,0x5a,0x29,0x3014,0x53,0x3015,0x31,0x30,0x2e,0x31,0x31,0x2e,0x31,0x32,0x2e,0x31,0x33,0x2e,0x31,0x34,0x2e,0x31,0x35,0x2e,0x31,0x36,0x2e,0x31,0x37,0x2e,0x31,0x38,0x2e,0x31,0x39,0x2e,0x32,0x30,0x2e,0x28,0x61,0x29,0x28,0x62,0x29,0x28,0x63,0x29,0x62a,0x62e,0x645,0x28,0x4e00,0x29,0x28,0x1112,0x29,0x28,0x1111,0x29,0x28,0x1110,0x29,0x28,0x110f,0x29,0x50,0x54,0x45,0x28,0x1109,0x29,0x28,0x110e,0x29,0x2035,0x2035,0x2035,0x28,0x110c,0x29,0x28,0x1107,0x29,0x28,0x110b,0x29,0x3bc,0x67,0x3bc,0x46,0x6e,0x46,0x70,0x46,0x34,0x33,0x6d,0x67,0x61,0x2be,0x3bc,0x6d,0x6e,0x6d,0x66,0x6d,0x6b,0x6c,0x64,0x6c,0x6d,0x6c,0x3bc,0x6c,0x33,0x30,0x32,0x39,0x32,0x38,0x34,0x32,0x32,0x37,0x48,0x67,0x35,0x30,0x32,0x33,0x32,0x34,0x34,0x39,0x64,0x61,0x41,0x55,0x47,0x42,0x4d,0x42,0x4b,0x42,0x6b,0x41,0x6d,0x41,0x3bc,0x41,0x6e,0x41,0x70,0x41,0x49,0x55,0x34,0x35,0x34,0x36,0x34,0x37,0x70,0x63,0x6f,0x56,0x34,0x38,0x6d,0x57,0x6b,0x57,0x4d,0x57,0x6b,0x3a9,0x4d,0x3a9,0x42,0x71,0x63,0x63,0x63,0x64,0x64,0x42,0x47,0x79,0x68,0x61,0x48,0x50,0x69,0x6e,0x4b,0x4b,0x4b,0x4d,0x6b,0x74,0x6c,0x6e,0x6c,0x78,0x6d,0x62,0x33,0x33,0x33,0x34,0x33,0x35,0x34,0x30,0x33,0x39,0x33,0x38,0x33,0x37,0x33,0x36,0x110b,0x116e,0x70,0x73,0x6e,0x73,0x3bc,0x73,0x6d,0x73,0x70,0x56,0x6e,0x56,0x3bc,0x56,0x6b,0x56,0x4d,0x56,0x70,0x57,0x6e,0x57,0x3bc,0x57,0x30d8,0x30bd,0x30d2,0x30eb,0x30d2,0x30b3,0x28,0x29,0x28,0x29,0x49,0x56,0x49,0x58,0x30ca,0x30ce,0x69,0x76,0x21,0x3f,0x3f,0x21,0x21,0x21,0x52,0x73,0xb0,0x43,0xb0,0x46,0x30ea,0x30e9,0x4e,0x6f,0x30ec,0x30e0,0x53,0x4d,0x54,0x4d,0x30ad,0x30ab,0x32,0x35,0x32,0x36,0x65,0x56,0x69,0x78,0x30c6,0x30b7,0x30b3,0x30c8,0x3088,0x308a,0x63a,0x62c,0x638,0x645,0x637,0x62d,0x636,0x645,0x636,0x62c,0x635,0x62e,0x628,0x645,0x628,0x647,0x64,0x7a,0x44,0x7a,0x44,0x5a,0x62a,0x647,0x62b,0x645,0x646,0x62e,0x643,0x644,0x643,0x62e,0x641,0x62c,0x641,0x62d,0x642,0x62d,0x643,0x62c,0x643,0x62d,0x6e,0x6a,0x4e,0x6a,0x4e,0x4a,0x6c,0x6a,0x4c,0x6a,0x4c,0x4a,0x62b,0x64a,0x62b,0x649,0x62b,0x646,0x62b,0x632,0x62b,0x631,0x62a,0x64a,0x62a,0x649,0x62a,0x646,0x62a,0x632,0x62a,0x631,0x628,0x64a,0x628,0x649,0x628,0x646,0x647,0x649,0x647,0x64a,0x64a,0x62e,0x64a,0x649,0x64a,0x631,0x64a,0x632,0x628,0x632,0x646,0x646,0x646,0x649,0x646,0x64a,0x628,0x62c,0x641,0x649,0x641,0x64a,0x642,0x649,0x642,0x64a,0x643,0x627,0x643,0x649,0x643,0x64a,0x645,0x627,0x646,0x631,0x646,0x632,0x633,0x631,0x634,0x631,0x634,0x62e,0x636,0x64a,0x636,0x649,0x635,0x64a,0x635,0x649,0x57,0x5a,0x43,0x44,0x39,0x2c,0x633,0x649,0x633,0x64a,0x634,0x649,0x634,0x64a,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x35,0x2c,0x36,0x2c,0x37,0x2c,0x38,0x2c,0x53,0x44,0x53,0x53,0x57,0x43,0x44,0x4a,0x307b,0x304b,0x30b3,0x30b3,0x3014,0x3015,0x3014,0x3015,0x635,0x631,0x636,0x631,0x633,0x647,0x634,0x647,0x48,0x56,0x63a,0x649,0x639,0x64a,0x639,0x649,0x637,0x64a,0x637,0x649,0x647,0x62c,0x62b,0x647,0x69,0x6a,0x49,0x4a,0x63a,0x64a,0x2bc,0x6e,0x6c,0xb7,0x4c,0xb7,0x62e,0x62d,0x62b,0x62c,0x64a,0x674,0x64a,0x6d0,0x64a,0x6d0,0x64a,0x6c8,0x64a,0x6c8,0x64a,0x6c6,0x64a,0x6c6,0x64a,0x6c7,0x64a,0x6c7,0x64a,0x648,0x64a,0x648,0x64a,0x6d5,0x64a,0x6d5,0x64a,0x627,0x64a,0x627,0xeab,0xe99,0xeab,0xea1,0x6c7,0x674,0x5d0,0x5dc,0x73,0x74,0x73,0x74,0x574,0x576,0x574,0x565,0x574,0x56b,0x57e,0x576,0x574,0x56d,0x565,0x582,0x627,0x674,0x648,0x674,0x50,0x48,0x50,0x52,0x73,0x72,0x57,0x62,0x53,0x76,0x5c,0x5e,0x5b,0x5d,0x30f2,0x30a5,0x30e3,0x60,0x7b,0x5f,0x2013,0x2014,0x40,0x3b,0x3001,0x7d,0x23,0x26,0x2a,0x2b,0x2d,0x3c,0x3e,0x7c,0x30fb,0x300f,0x300e,0x300d,0x300c,0x3009,0x3008,0x300b,0x300a,0x3011,0x3010,0x7e,0x2985,0x2986,0x3002,0x640,0x640,0x621,0x630,0x630,0x629,0x629,0x25,0x27,0x3017,0x3016,0x24,0x24,0x22,0x39e,0x39d,0x39c,0x39b,0x39a,0x399,0x398,0x397,0x396,0x395,0x394,0x393,0x392,0x391,0x237,0x131,0x3c0,0x3c1,0x3c6,0x3ba,0x3b8,0x3b5,0x2202,0x3c9,0x3b2,0x3b1,0x2207,0x3a8,0x3a7,0x3a6,0x3a5,0x3a4,0x3a3,0x3a1,0x3a0,0x39f,0x3b6,0x3b4,0x3b3,0x3c8,0x3c7,0x3c5,0x3c4,0x3c3,0x3c2,0x3bf,0x3be,0x3bd,0x3bb,0x3b9,0x3b7,0x3dd,0x3dc,0x11b3,0x11b2,0x11b1,0x11b0,0x1104,0x11ad,0x11ac,0x11aa,0x1101,0x1160,0x110d,0x110a,0x1121,0x1108,0x111a,0x11b5,0x11b4,0x30cc,0x30e8,0x30e2,0x1d1ba,0x1d1b9,0x1d1b9,0x1d158,0x1d158,0x1d157,0x110a5,0x1173,0x1172,0x1171,0x1170,0x116f,0x116d,0x116c,0x116b,0x116a,0x1168,0x1167,0x1166,0x1164,0x1163,0x1162,0x1109b,0x11099,0x25cb,0x25a0,0x2193,0x2192,0x2191,0x2190,0x2502,0x20a9,0xa5,0xa6,0xac,0xa3,0xa2,0x1175,0x292,0x250,0x251,0x1d02,0x259,0x25b,0x25c,0x14b,0x254,0x1d16,0x1d17,0x1d1d,0x26f,0x1025,0x10dc,0x1b05,0x1b07,0x1b09,0x1b0b,0x1b0d,0x1b11,0xc6,0x18e,0x222,0x268,0x269,0x26a,0x1d7b,0x29d,0x26d,0x1d85,0x29f,0x271,0x270,0x272,0x273,0x274,0x275,0x278,0x282,0x283,0x1ab,0x289,0x28a,0x1d1c,0x28b,0x28c,0x290,0x291,0x1d25,0x43d,0x252,0x255,0xf0,0x25f,0x261,0x265,0xe6,0x438,0x443,0x474,0x475,0x416,0x436,0x410,0x430,0x430,0x415,0x435,0x4d8,0x4d9,0x417,0x437,0x418,0x418,0x41e,0x43e,0x4e8,0x4e9,0x413,0x406,0x41a,0x423,0x433,0x456,0x43a,0x91c,0x921,0x922,0x92b,0x92f,0x9a1,0x9a2,0x9af,0xa32,0xa38,0xa16,0xa17,0xa1c,0xa2b,0xb21,0xb22,0xb92,0xe32,0xeb2,0xf0b,0xf42,0xf4c,0xf51,0xf56,0xf5b,0xf40,0x42d,0x44d,0x427,0x447,0x42b,0x44b,0x6c1,0x928,0x930,0x933,0x915,0x916,0x917,0x1b7,0xd8,0xf8,0x266,0x279,0x27b,0x281,0x263,0x295,0x2b9,0x1158,0x1159,0x1184,0x1185,0x1188,0x1191,0x1192,0x1194,0x119e,0x11a1,0x11d3,0x11d7,0x11d9,0x111c,0x11dd,0x11df,0x111d,0x111e,0x1120,0x1122,0x1123,0x1127,0x1129,0x112b,0x112c,0x112d,0x112e,0x112f,0x1132,0x1136,0x1140,0x1147,0x114c,0x11f1,0x11f2,0x1157,0x30f0,0x30f1,0x30fd,0x3068,0x306f,0x306f,0x3072,0x3072,0x3075,0x3075,0x3078,0x3078,0x3046,0x309d,0x1114,0x1115,0x11c7,0x11c8,0x11cc,0x11ce,0x691,0x6a9,0x6a9,0x6af,0x6af,0x6b3,0x6b3,0x6b1,0x6b1,0x6ba,0x6ba,0x6bb,0x6bb,0x684,0x684,0x683,0x683,0x686,0x686,0x687,0x687,0x68d,0x68d,0x68c,0x68c,0x68e,0x68e,0x688,0x688,0x698,0x698,0x6c9,0x6be,0x6be,0x6ad,0x6ad,0x6cb,0x6cb,0x6c5,0x6c5,0x5f2,0x5e2,0x5d3,0x5d4,0x5db,0x5dd,0x5e8,0x5ea,0x5e9,0x5e9,0x5d1,0x5d2,0x5d5,0x5d6,0x5d8,0x5d9,0xa76f,0x67e,0x680,0x680,0x67a,0x67a,0x67f,0x67f,0x679,0x679,0x6a4,0x6a4,0x6a6,0x6a6,0x5da,0x5de,0x5e0,0x5e1,0x5e3,0x5e4,0x5e6,0x5e7,0x671,0x671,0x67b,0x67b,0x2212,0x2010,0x2277,0x227a,0x227b,0x2282,0x2283,0x2286,0x2287,0x22a2,0x22a8,0x22a9,0x22ab,0x227c,0x227d,0x2291,0x2292,0x22b2,0x22b3,0x22b4,0x22b5,0x2add,0x2d61,0x3012,0x304d,0x304f,0x3051,0x3053,0x3055,0x3057,0x3059,0x305b,0x305d,0x305f,0x3061,0x3064,0x3066,0x127,0x190,0x2194,0x21d0,0x21d4,0x21d2,0x2203,0x2208,0x220b,0x2223,0x2225,0x223c,0x2243,0x2245,0x2248,0x2261,0x224d,0x2264,0x2265,0x2272,0x2273,0x2276,0x2211}; -#ifdef __clang__ -__attribute__((noinline)) // Fix clang3.6 hanging while compiling with -O2/-O3. -#endif static void w(strings::UniString & r, uint16_t startIndex, int count) { for (int i = 0; i < count; ++i) @@ -4596,4 +4593,4 @@ void NormalizeInplace(strings::UniString & s) s.swap(r); } -} +} // namespace strings -- 2.45.3 From d22fa3477a9131b3b4e2d52671e5cbde8205a939 Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Sun, 12 Feb 2023 13:04:49 -0300 Subject: [PATCH 02/61] Treat "landuse" as _secondary_ type. Signed-off-by: Viktor Govako --- indexer/feature_data.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/indexer/feature_data.cpp b/indexer/feature_data.cpp index c76dad7c50..0cfa591962 100644 --- a/indexer/feature_data.cpp +++ b/indexer/feature_data.cpp @@ -140,6 +140,7 @@ private: {"area:highway"}, {"earthquake:damage"}, {"emergency"}, // used in subway facilities (Barcelona) + {"landuse"}, // used together with more specific types like aerodrome }; base::StringIL const types2[] = { -- 2.45.3 From f2c81c7b9603586c7f782f6d87455474419d242d Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Mon, 13 Feb 2023 13:33:07 -0300 Subject: [PATCH 03/61] Minor code prettify. Signed-off-by: Viktor Govako --- base/uni_string_dfa.cpp | 9 +- base/uni_string_dfa.hpp | 10 +-- coding/reader.cpp | 5 +- generator/feature_processing_layers.cpp | 2 +- indexer/displacement_manager.hpp | 6 +- map/extrapolation/extrapolator.cpp | 22 ++--- platform/get_text_by_id.cpp | 27 ++---- platform/get_text_by_id.hpp | 10 +-- search/feature_offset_match.hpp | 21 ++--- search/features_layer_matcher.hpp | 23 ++--- search/model.cpp | 110 ++++++++++-------------- search/model.hpp | 2 - 12 files changed, 101 insertions(+), 146 deletions(-) diff --git a/base/uni_string_dfa.cpp b/base/uni_string_dfa.cpp index e4faaf2828..bafcbd9619 100644 --- a/base/uni_string_dfa.cpp +++ b/base/uni_string_dfa.cpp @@ -30,12 +30,11 @@ UniStringDFA::Iterator & UniStringDFA::Iterator::Move(UniChar c) } // UniStringDFA::UniStringDFA ---------------------------------------------------------------------- -UniStringDFA::UniStringDFA(UniString const & s) : m_s(s) {} +UniStringDFA::UniStringDFA(std::string const & s) : UniStringDFA(MakeUniString(s)) {} -UniStringDFA::UniStringDFA(std::string const & s): UniStringDFA(MakeUniString(s)) {} - -UniStringDFA::Iterator UniStringDFA::Begin() const +std::string DebugPrint(UniStringDFA const & dfa) { - return Iterator(m_s); + return DebugPrint(dfa.m_s); } + } // namespace strings diff --git a/base/uni_string_dfa.hpp b/base/uni_string_dfa.hpp index 6187e8562a..bca90672e0 100644 --- a/base/uni_string_dfa.hpp +++ b/base/uni_string_dfa.hpp @@ -1,9 +1,7 @@ #pragma once -#include "base/logging.hpp" #include "base/string_utils.hpp" -#include #include namespace strings @@ -24,17 +22,19 @@ public: private: friend class UniStringDFA; - Iterator(UniString const & s); + explicit Iterator(UniString const & s); UniString const & m_s; size_t m_pos; bool m_rejected; }; - explicit UniStringDFA(UniString const & s); + explicit UniStringDFA(UniString const & s) : m_s(s) {} explicit UniStringDFA(std::string const & s); - Iterator Begin() const; + Iterator Begin() const { return Iterator(m_s); } + + friend std::string DebugPrint(UniStringDFA const & dfa); private: UniString const m_s; diff --git a/coding/reader.cpp b/coding/reader.cpp index 2734c02a30..4092e4da65 100644 --- a/coding/reader.cpp +++ b/coding/reader.cpp @@ -3,7 +3,6 @@ void Reader::ReadAsString(std::string & s) const { s.clear(); - size_t const sz = static_cast(Size()); - s.resize(sz); - Read(0, &s[0], sz); + s.resize(static_cast(Size())); + Read(0 /* pos */, s.data(), s.size()); } diff --git a/generator/feature_processing_layers.cpp b/generator/feature_processing_layers.cpp index c34627079e..b151e5090b 100644 --- a/generator/feature_processing_layers.cpp +++ b/generator/feature_processing_layers.cpp @@ -103,7 +103,7 @@ void RepresentationLayer::Handle(FeatureBuilder & fb) // Areal object with types amenity=restaurant + wifi=yes + cuisine=* should be added as areal object with // these types and no extra linear/point objects. // We need extra line object only for case when object has type which is drawable like line: - // amenity=playground + barrier=fence shold be added as areal object with amenity=playground + linear object + // amenity=playground + barrier=fence should be added as area object with amenity=playground + linear object // with barrier=fence. if (CanBeLine(params)) { diff --git a/indexer/displacement_manager.hpp b/indexer/displacement_manager.hpp index 80d1251927..11a33d2645 100644 --- a/indexer/displacement_manager.hpp +++ b/indexer/displacement_manager.hpp @@ -168,10 +168,10 @@ private: drule::MakeUnique(keys); float depth = 0; - for (size_t i = 0, count = keys.size(); i < count; ++i) + for (auto const & k : keys) { - if (depth < keys[i].m_priority) - depth = keys[i].m_priority; + if (depth < k.m_priority) + depth = k.m_priority; } float const kMinDepth = -100000.0f; diff --git a/map/extrapolation/extrapolator.cpp b/map/extrapolation/extrapolator.cpp index 77f7b576e5..bcddb136f8 100644 --- a/map/extrapolation/extrapolator.cpp +++ b/map/extrapolation/extrapolator.cpp @@ -200,17 +200,19 @@ void Extrapolator::RunTaskOnBackgroundThread(bool delayed) if (delayed) { - auto constexpr kExtrapolationPeriod = std::chrono::milliseconds(kExtrapolationPeriodMs); - GetPlatform().RunDelayedTask(Platform::Thread::Background, kExtrapolationPeriod, - [this, locationUpdateCounter] { - ExtrapolatedLocationUpdate(locationUpdateCounter); - }); - return; + auto constexpr period = std::chrono::milliseconds(kExtrapolationPeriodMs); + GetPlatform().RunDelayedTask(Platform::Thread::Background, period, [this, locationUpdateCounter] + { + ExtrapolatedLocationUpdate(locationUpdateCounter); + }); + } + else + { + GetPlatform().RunTask(Platform::Thread::Background, [this, locationUpdateCounter] + { + ExtrapolatedLocationUpdate(locationUpdateCounter); + }); } - - GetPlatform().RunTask(Platform::Thread::Background, [this, locationUpdateCounter] { - ExtrapolatedLocationUpdate(locationUpdateCounter); - }); } bool Extrapolator::DoesExtrapolationWork() const diff --git a/platform/get_text_by_id.cpp b/platform/get_text_by_id.cpp index b3481335da..f409096083 100644 --- a/platform/get_text_by_id.cpp +++ b/platform/get_text_by_id.cpp @@ -7,15 +7,15 @@ #include "cppjansson/cppjansson.hpp" -#include "std/target_os.hpp" - #include +namespace platform +{ using namespace std; namespace { -static constexpr char const * kDefaultLanguage = "en"; +string const kDefaultLanguage = "en"; string GetTextSourceString(platform::TextSource textSource) { @@ -31,12 +31,9 @@ string GetTextSourceString(platform::TextSource textSource) } } // namespace -namespace platform -{ bool GetJsonBuffer(platform::TextSource textSource, string const & localeName, string & jsonBuffer) { - string const pathToJson = - base::JoinPath(GetTextSourceString(textSource), localeName + ".json", "localize.json"); + string const pathToJson = base::JoinPath(GetTextSourceString(textSource), localeName + ".json", "localize.json"); try { @@ -45,14 +42,13 @@ bool GetJsonBuffer(platform::TextSource textSource, string const & localeName, s } catch (RootException const & ex) { - LOG(LWARNING, ("Can't open", localeName, "localization file. pathToJson is", pathToJson, - ex.what())); + LOG(LWARNING, ("Can't open", localeName, "localization file:", pathToJson, ex.what())); return false; // No json file for localeName } return true; } -TGetTextByIdPtr MakeGetTextById(string const & jsonBuffer, string const & localeName) +TGetTextByIdPtr GetTextById::Create(string const & jsonBuffer, string const & localeName) { TGetTextByIdPtr result(new GetTextById(jsonBuffer, localeName)); if (!result->IsValid()) @@ -67,10 +63,10 @@ TGetTextByIdPtr GetTextByIdFactory(TextSource textSource, string const & localeN { string jsonBuffer; if (GetJsonBuffer(textSource, localeName, jsonBuffer)) - return MakeGetTextById(jsonBuffer, localeName); + return GetTextById::Create(jsonBuffer, localeName); if (GetJsonBuffer(textSource, kDefaultLanguage, jsonBuffer)) - return MakeGetTextById(jsonBuffer, kDefaultLanguage); + return GetTextById::Create(jsonBuffer, kDefaultLanguage); ASSERT(false, ("Can't find translate for default language. (Lang:", localeName, ")")); return nullptr; @@ -78,16 +74,11 @@ TGetTextByIdPtr GetTextByIdFactory(TextSource textSource, string const & localeN TGetTextByIdPtr ForTestingGetTextByIdFactory(string const & jsonBuffer, string const & localeName) { - return MakeGetTextById(jsonBuffer, localeName); + return GetTextById::Create(jsonBuffer, localeName); } GetTextById::GetTextById(string const & jsonBuffer, string const & localeName) : m_locale(localeName) -{ - InitFromJson(jsonBuffer); -} - -void GetTextById::InitFromJson(string const & jsonBuffer) { if (jsonBuffer.empty()) { diff --git a/platform/get_text_by_id.hpp b/platform/get_text_by_id.hpp index 4ec2edc2f4..751e5e533c 100644 --- a/platform/get_text_by_id.hpp +++ b/platform/get_text_by_id.hpp @@ -3,7 +3,6 @@ #include #include #include -#include #include namespace platform @@ -32,14 +31,11 @@ public: std::string GetLocale() const { return m_locale; } TTranslations GetAllSortedTranslations() const; -private: - friend TGetTextByIdPtr GetTextByIdFactory(TextSource textSource, std::string const & localeName); - friend TGetTextByIdPtr ForTestingGetTextByIdFactory(std::string const & jsonBuffer, - std::string const & localeName); - friend TGetTextByIdPtr MakeGetTextById(std::string const & jsonBuffer, std::string const & localeName); + static TGetTextByIdPtr Create(std::string const & jsonBuffer, std::string const & localeName); +private: GetTextById(std::string const & jsonBuffer, std::string const & localeName); - void InitFromJson(std::string const & jsonBuffer); + /// \note IsValid is used only in factories and shall be private. bool IsValid() const { return !m_localeTexts.empty(); } diff --git a/search/feature_offset_match.hpp b/search/feature_offset_match.hpp index f9ca26296f..fc336cd16c 100644 --- a/search/feature_offset_match.hpp +++ b/search/feature_offset_match.hpp @@ -1,6 +1,5 @@ #pragma once -#include "search/common.hpp" #include "search/query_params.hpp" #include "search/search_index_values.hpp" #include "search/search_trie.hpp" @@ -10,18 +9,14 @@ #include "base/assert.hpp" #include "base/dfa_helpers.hpp" -#include "base/levenshtein_dfa.hpp" #include "base/stl_helpers.hpp" #include "base/string_utils.hpp" #include "base/uni_string_dfa.hpp" -#include -#include #include #include #include #include -#include #include namespace search @@ -295,21 +290,27 @@ void MatchFeaturesInTrie(SearchTrieRequest const & request, using Value = typename ValueList::Value; TrieValuesHolder categoriesHolder(filter); - bool const categoriesMatched = MatchCategoriesInTrie(request, trieRoot, categoriesHolder); + bool const categoriesExist = MatchCategoriesInTrie(request, trieRoot, categoriesHolder); + /// @todo Not sure why do we have OffsetIntersector here? We are doing aggregation only. impl::OffsetIntersector intersector(filter); ForEachLangPrefix( request, trieRoot, - [&request, &intersector](TrieRootPrefix & langRoot, int8_t /* lang */) { + [&request, &intersector](TrieRootPrefix & langRoot, int8_t /* lang */) + { + // Aggregate for all languages. MatchInTrie(request.m_names, langRoot, intersector); }); - if (categoriesMatched) + if (categoriesExist) + { + // Aggregate categories. categoriesHolder.ForEachValue(intersector); + } intersector.NextStep(); - intersector.ForEachResult(std::forward(toDo)); + intersector.ForEachResult(toDo); } template @@ -340,6 +341,6 @@ void MatchPostcodesInTrie(TokenSlice const & slice, trie::Iterator co intersector.NextStep(); } - intersector.ForEachResult(std::forward(toDo)); + intersector.ForEachResult(toDo); } } // namespace search diff --git a/search/features_layer_matcher.hpp b/search/features_layer_matcher.hpp index 6c85548e77..c69e65053f 100644 --- a/search/features_layer_matcher.hpp +++ b/search/features_layer_matcher.hpp @@ -14,9 +14,7 @@ #include "indexer/feature.hpp" #include "indexer/feature_algo.hpp" -#include "indexer/feature_impl.hpp" #include "indexer/features_vector.hpp" -#include "indexer/ftypes_matcher.hpp" #include "indexer/mwm_set.hpp" #include "geometry/mercator.hpp" @@ -25,18 +23,13 @@ #include "base/cancellable.hpp" #include "base/logging.hpp" -#include "base/macros.hpp" #include "base/stl_helpers.hpp" #include "base/string_utils.hpp" #include -#include -#include -#include #include #include #include -#include #include class DataSource; @@ -89,28 +82,26 @@ public: break; case Model::TYPE_COMPLEX_POI: ASSERT_EQUAL(child.m_type, Model::TYPE_SUBPOI, ()); - MatchPOIsWithParent(child, parent, std::forward(fn)); + MatchPOIsWithParent(child, parent, fn); break; case Model::TYPE_BUILDING: ASSERT(Model::IsPoi(child.m_type), ()); - MatchPOIsWithParent(child, parent, std::forward(fn)); + MatchPOIsWithParent(child, parent, fn); break; case Model::TYPE_STREET: ASSERT(Model::IsPoi(child.m_type) || child.m_type == Model::TYPE_BUILDING, ("Invalid child layer type:", child.m_type)); if (Model::IsPoi(child.m_type)) - MatchPOIsWithStreets(child, parent, std::forward(fn)); + MatchPOIsWithStreets(child, parent, fn); else - MatchBuildingsWithStreets(child, parent, std::forward(fn)); + MatchBuildingsWithStreets(child, parent, fn); break; case Model::TYPE_SUBURB: ASSERT(child.m_type == Model::TYPE_STREET || child.m_type == Model::TYPE_BUILDING || - Model::IsPoi(child.m_type), - ()); + Model::IsPoi(child.m_type), ()); // Avoid matching buildings to suburb without street. - if (child.m_type == Model::TYPE_BUILDING) - break; - MatchChildWithSuburbs(child, parent, std::forward(fn)); + if (child.m_type != Model::TYPE_BUILDING) + MatchChildWithSuburbs(child, parent, fn); break; } } diff --git a/search/model.cpp b/search/model.cpp index ea993c3f47..0173e55cf6 100644 --- a/search/model.cpp +++ b/search/model.cpp @@ -3,16 +3,15 @@ #include "indexer/classificator.hpp" #include "indexer/feature.hpp" -#include "base/macros.hpp" #include "base/stl_helpers.hpp" #include +namespace search +{ using namespace ftypes; using namespace std; -namespace search -{ TwoLevelPOIChecker::TwoLevelPOIChecker() : ftypes::BaseChecker(2 /* level */) { Classificator const & c = classif(); @@ -58,11 +57,7 @@ public: class IsPoiChecker { public: - static IsPoiChecker const & Instance() - { - static const IsPoiChecker inst; - return inst; - } + DECLARE_CHECKER_INSTANCE(IsPoiChecker); bool operator()(FeatureType & ft) const { return m_oneLevel(ft) || m_twoLevel(ft); } @@ -76,51 +71,43 @@ class IsComplexPoiChecker : public ftypes::BaseChecker IsComplexPoiChecker() : ftypes::BaseChecker() { Classificator const & c = classif(); - vector> const paths = {{"aeroway", "aerodrome"}, - {"amenity", "hospital"}, - {"amenity", "university"}, - {"building", "train_station"}, - {"historic", "archaeological_site"}, - {"historic", "castle"}, - {"historic", "fort"}, - {"landuse", "cemetery"}, - {"landuse", "churchyard"}, - {"landuse", "commercial"}, - {"landuse", "forest"}, - {"landuse", "industrial"}, - {"landuse", "retail"}, - {"leisure", "garden"}, - {"leisure", "nature_reserve"}, - {"leisure", "park"}, - {"leisure", "stadium"}, - {"leisure", "water_park"}, - {"natural", "beach"}, - {"office", "company"}, - {"railway", "station"}, - {"shop", "mall"}, - {"tourism", "museum"}, - {"tourism", "gallery"}}; + base::StringIL const paths[] = {{"aeroway", "aerodrome"}, + {"amenity", "hospital"}, + {"amenity", "university"}, + {"building", "train_station"}, + {"historic", "archaeological_site"}, + {"historic", "castle"}, + {"historic", "fort"}, + {"landuse", "cemetery"}, + {"landuse", "churchyard"}, + {"landuse", "commercial"}, + {"landuse", "forest"}, + {"landuse", "industrial"}, + {"landuse", "retail"}, + {"leisure", "garden"}, + {"leisure", "nature_reserve"}, + {"leisure", "park"}, + {"leisure", "stadium"}, + {"leisure", "water_park"}, + {"natural", "beach"}, + {"office", "company"}, + {"railway", "station"}, + {"shop", "mall"}, + {"tourism", "museum"}, + {"tourism", "gallery"}}; for (auto const & path : paths) m_types.push_back(c.GetTypeByPath(path)); } public: - static IsComplexPoiChecker const & Instance() - { - static IsComplexPoiChecker const inst; - return inst; - } + DECLARE_CHECKER_INSTANCE(IsComplexPoiChecker); }; class CustomIsBuildingChecker { public: - static CustomIsBuildingChecker const & Instance() - { - static const CustomIsBuildingChecker inst; - return inst; - } + DECLARE_CHECKER_INSTANCE(CustomIsBuildingChecker); bool operator()(FeatureType & ft) const { @@ -131,43 +118,34 @@ public: Model::Type Model::GetType(FeatureType & feature) const { - static auto const & buildingChecker = CustomIsBuildingChecker::Instance(); - static auto const & streetChecker = IsStreetOrSquareChecker::Instance(); - static auto const & suburbChecker = IsSuburbChecker::Instance(); - static auto const & localityChecker = IsLocalityChecker::Instance(); - static auto const & poiChecker = IsPoiChecker::Instance(); - static auto const & complexPoiChecker = IsComplexPoiChecker::Instance(); - // Check whether object is POI first to mark POIs with address tags as POI. - if (complexPoiChecker(feature)) + if (IsComplexPoiChecker::Instance()(feature)) return TYPE_COMPLEX_POI; - if (poiChecker(feature)) + if (IsPoiChecker::Instance()(feature)) return TYPE_SUBPOI; - if (buildingChecker(feature)) + if (CustomIsBuildingChecker::Instance()(feature)) return TYPE_BUILDING; - if (streetChecker(feature)) + if (IsStreetOrSquareChecker::Instance()(feature)) return TYPE_STREET; - if (suburbChecker(feature)) + if (IsSuburbChecker::Instance()(feature)) return TYPE_SUBURB; - if (localityChecker(feature)) + auto const type = IsLocalityChecker::Instance().GetType(feature); + switch (type) { - auto const type = localityChecker.GetType(feature); - switch (type) - { - case LocalityType::None: ASSERT(false, ("Unknown locality.")); return TYPE_UNCLASSIFIED; - case LocalityType::State: return TYPE_STATE; - case LocalityType::Country: return TYPE_COUNTRY; - case LocalityType::City: - case LocalityType::Town: return TYPE_CITY; - case LocalityType::Village: return TYPE_VILLAGE; - case LocalityType::Count: return TYPE_UNCLASSIFIED; - } + case LocalityType::State: return TYPE_STATE; + case LocalityType::Country: return TYPE_COUNTRY; + case LocalityType::City: + case LocalityType::Town: return TYPE_CITY; + case LocalityType::Village: return TYPE_VILLAGE; + case LocalityType::Count: ASSERT(false, ()); // no break here + case LocalityType::None: return TYPE_UNCLASSIFIED; } + ASSERT(false, ("Unknown locality type:", static_cast(type))); return TYPE_UNCLASSIFIED; } diff --git a/search/model.hpp b/search/model.hpp index 91a6ba9b76..8b6b41ea29 100644 --- a/search/model.hpp +++ b/search/model.hpp @@ -2,8 +2,6 @@ #include "indexer/ftypes_matcher.hpp" -#include "base/macros.hpp" - #include class FeatureType; -- 2.45.3 From 5a5943b145ef43da40cd24a35f5b99713000fcef Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Mon, 13 Feb 2023 22:41:53 -0300 Subject: [PATCH 04/61] Added DebugNote code tags. Signed-off-by: Viktor Govako --- platform/preferred_languages.cpp | 5 +++++ qt/search_panel.cpp | 4 ++++ routing/index_router.cpp | 3 +++ search/pre_ranker.cpp | 3 ++- search/processor.cpp | 2 ++ search/ranker.cpp | 3 ++- search/ranking_utils.cpp | 4 ++-- 7 files changed, 20 insertions(+), 4 deletions(-) diff --git a/platform/preferred_languages.cpp b/platform/preferred_languages.cpp index 7c32bee711..205798c279 100644 --- a/platform/preferred_languages.cpp +++ b/platform/preferred_languages.cpp @@ -41,6 +41,11 @@ namespace languages { void GetSystemPreferred(std::vector & languages) { + /// @DebugNote + // Hardcode draw text language. + //languages.push_back("hi"); + //return; + #if defined(OMIM_OS_MAC) || defined(OMIM_OS_IPHONE) || defined(OMIM_OS_LINUX) // check environment variables char const * p = std::getenv("LANGUAGE"); diff --git a/qt/search_panel.cpp b/qt/search_panel.cpp index c037a70523..0bbb898003 100644 --- a/qt/search_panel.cpp +++ b/qt/search_panel.cpp @@ -201,6 +201,10 @@ bool SearchPanel::TryTrafficSimplifiedColorsCmd(std::string const & str) std::string SearchPanel::GetCurrentInputLocale() { + /// @DebugNote + // Hardcode search input language. + //return "de"; + QString loc = QGuiApplication::inputMethod()->locale().name(); loc.replace('_', '-'); auto res = loc.toStdString(); diff --git a/routing/index_router.cpp b/routing/index_router.cpp index d5f37aa242..8e89651ecb 100644 --- a/routing/index_router.cpp +++ b/routing/index_router.cpp @@ -1091,6 +1091,9 @@ unique_ptr IndexRouter::MakeWorldGraph() { // Use saved routing options for all types (car, bicycle, pedestrian). RoutingOptions const routingOptions = RoutingOptions::LoadCarOptionsFromSettings(); + /// @DebugNote + // Add avoid roads here for debug purpose. + //routingOptions.Add(RoutingOptions::Road::Motorway); LOG(LINFO, ("Avoid next roads:", routingOptions)); auto crossMwmGraph = make_unique( diff --git a/search/pre_ranker.cpp b/search/pre_ranker.cpp index cbb1179629..4f25cc97c2 100644 --- a/search/pre_ranker.cpp +++ b/search/pre_ranker.cpp @@ -253,7 +253,8 @@ void PreRanker::FilterForViewportSearch() return result.SkipForViewportSearch(m_params.m_numQueryTokens); }); - // By VNG: Comment next statements to discard viewport filtering (displacement) for Debug purpose. + /// @DebugNote + // Comment this line to discard viewport filtering (displacement). SweepNearbyResults(m_params.m_minDistanceOnMapBetweenResults, m_prevEmit, m_results); for (auto const & result : m_results) diff --git a/search/processor.cpp b/search/processor.cpp index ac9204062d..edfd878f63 100644 --- a/search/processor.cpp +++ b/search/processor.cpp @@ -505,6 +505,8 @@ void Processor::ForEachCategoryTypeFuzzy(StringSliceBase const & slice, ToDo && void Processor::Search(SearchParams params) { + /// @DebugNote + // Comment this line to run search in a debugger. SetDeadline(chrono::steady_clock::now() + params.m_timeout); if (params.m_onStarted) diff --git a/search/ranker.cpp b/search/ranker.cpp index e03aacac48..d8390791c8 100644 --- a/search/ranker.cpp +++ b/search/ranker.cpp @@ -821,7 +821,8 @@ void Ranker::UpdateResults(bool lastUpdate) auto const & rankerResult = m_tentativeResults[i]; - // Uncomment for debug purpose. + /// @DebugNote + // Uncomment for extended ranking print. //if (!m_params.m_viewportSearch) // LOG(LDEBUG, (rankerResult)); diff --git a/search/ranking_utils.cpp b/search/ranking_utils.cpp index b7ab0819d7..31da4e0b5f 100644 --- a/search/ranking_utils.cpp +++ b/search/ranking_utils.cpp @@ -101,8 +101,8 @@ ErrorsMade GetPrefixErrorsMade(QueryParams::Token const & token, strings::UniStr bool IsStopWord(UniString const & s) { - /// @todo Get all common used stop words and take out this array into - /// search_string_utils.cpp module for example. + /// @todo Get all common used stop words and take out this array into search_string_utils.cpp module for example. + /// Should skip this tokens when building search index? class StopWordsChecker { set m_set; -- 2.45.3 From 9bc58818fbfb627f8ffc087106f6e4b2a3ced0e1 Mon Sep 17 00:00:00 2001 From: Alexander Borsuk Date: Fri, 17 Feb 2023 10:20:11 +0100 Subject: [PATCH 05/61] [tools] Fixed wrong commit hash for twine Signed-off-by: Alexander Borsuk --- tools/twine | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/twine b/tools/twine index 36ceac404a..457c5bbda5 160000 --- a/tools/twine +++ b/tools/twine @@ -1 +1 @@ -Subproject commit 36ceac404aad5620662a84f2c4ebafe15bac769c +Subproject commit 457c5bbda59d2182dc5466554ccbce4f93facf73 -- 2.45.3 From 415122a9683984762aca4b9e4ad658985988fb70 Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Sat, 18 Feb 2023 09:20:50 -0300 Subject: [PATCH 06/61] [editor] Correct diet:vegan, diet:vegetarian. Signed-off-by: Viktor Govako --- editor/editor_tests/xml_feature_test.cpp | 21 ++++++ editor/xml_feature.cpp | 84 ++++++++++++++++++++++-- editor/xml_feature.hpp | 3 +- 3 files changed, 102 insertions(+), 6 deletions(-) diff --git a/editor/editor_tests/xml_feature_test.cpp b/editor/editor_tests/xml_feature_test.cpp index b3b6ba2cfa..5764d7d208 100644 --- a/editor/editor_tests/xml_feature_test.cpp +++ b/editor/editor_tests/xml_feature_test.cpp @@ -459,3 +459,24 @@ UNIT_TEST(XMLFeature_AmenityRecyclingFromAndToXml) } */ } + +UNIT_TEST(XMLFeature_Diet) +{ + XMLFeature ft(XMLFeature::Type::Node); + TEST(ft.GetCuisine().empty(), ()); + + ft.SetCuisine("vegan;vegetarian"); + TEST_EQUAL(ft.GetCuisine(), "vegan;vegetarian", ()); + + ft.SetCuisine("vegan;pasta;vegetarian"); + TEST_EQUAL(ft.GetCuisine(), "pasta;vegan;vegetarian", ()); + + ft.SetCuisine("vegetarian"); + TEST_EQUAL(ft.GetCuisine(), "vegetarian", ()); + + ft.SetCuisine("vegan"); + TEST_EQUAL(ft.GetCuisine(), "vegan", ()); + + ft.SetCuisine(""); + TEST_EQUAL(ft.GetCuisine(), "", ()); +} diff --git a/editor/xml_feature.cpp b/editor/xml_feature.cpp index 8d6d3cc99e..5ac1b1ba85 100644 --- a/editor/xml_feature.cpp +++ b/editor/xml_feature.cpp @@ -28,14 +28,21 @@ constexpr char const * kIndex = "mwm_file_index"; constexpr char const * kUploadTimestamp = "upload_timestamp"; constexpr char const * kUploadStatus = "upload_status"; constexpr char const * kUploadError = "upload_error"; -constexpr char const * kHouseNumber = "addr:housenumber"; -constexpr char const * kCuisine = "cuisine"; + +string_view constexpr kHouseNumber = "addr:housenumber"; +string_view constexpr kCuisine = "cuisine"; +string_view constexpr kDietVegetarian = "diet:vegetarian"; +string_view constexpr kDietVegan = "diet:vegan"; +string_view constexpr kVegetarian = "vegetarian"; +string_view constexpr kVegan = "vegan"; +string_view constexpr kYes = "yes"; constexpr char const * kUnknownType = "unknown"; constexpr char const * kNodeType = "node"; constexpr char const * kWayType = "way"; constexpr char const * kRelationType = "relation"; + pugi::xml_node FindTag(pugi::xml_document const & document, string_view k) { string key = "//tag[@k='"; @@ -300,9 +307,69 @@ string XMLFeature::GetHouse() const { return GetTagValue(kHouseNumber); } void XMLFeature::SetHouse(string const & house) { SetTagValue(kHouseNumber, house); } -string XMLFeature::GetCuisine() const { return GetTagValue(kCuisine); } +/// https://github.com/organicmaps/organicmaps/issues/1118 +/// @todo Make full diet:xxx support. +/// @{ +string XMLFeature::GetCuisine() const +{ + auto res = GetTagValue(kCuisine); + auto const appendCuisine = [&res](std::string_view s) + { + if (!res.empty()) + res += ';'; + res += s; + }; -void XMLFeature::SetCuisine(string const & cuisine) { SetTagValue(kCuisine, cuisine); } + if (GetTagValue(kDietVegan) == kYes) + appendCuisine(kVegan); + if (GetTagValue(kDietVegetarian) == kYes) + appendCuisine(kVegetarian); + return res; +} + +void XMLFeature::SetCuisine(string cuisine) +{ + auto const findAndErase = [&cuisine](std::string_view s) + { + size_t const i = cuisine.find(s); + if (i != std::string_view::npos) + { + size_t from = 0; + size_t sz = s.size(); + if (i > 0) + { + from = i - 1; + ASSERT_EQUAL(cuisine[from], ';', ()); + ++sz; + } + else if (cuisine.size() > sz) + { + ASSERT_EQUAL(cuisine[sz], ';', ()); + ++sz; + } + + cuisine.erase(from, sz); + return true; + } + return false; + }; + + if (findAndErase(kVegan)) + SetTagValue(kDietVegan, kYes); + else + RemoveTag(kDietVegan); + + if (findAndErase(kVegetarian)) + SetTagValue(kDietVegetarian, kYes); + else + RemoveTag(kDietVegetarian); + + if (!cuisine.empty()) + SetTagValue(kCuisine, cuisine); + else + RemoveTag(kCuisine); +} +/// @} time_t XMLFeature::GetModificationTime() const { @@ -379,6 +446,13 @@ void XMLFeature::SetTagValue(string_view key, string_view value) } } +void XMLFeature::RemoveTag(string_view key) +{ + auto tag = FindTag(m_document, key); + if (tag) + GetRootNode().remove_child(tag); +} + string XMLFeature::GetAttribute(string const & key) const { return GetRootNode().attribute(key.data()).value(); @@ -518,7 +592,7 @@ XMLFeature ToXML(osm::EditableMapObject const & object, bool serializeType) if (toFeature.GetTagValue(k).empty()) toFeature.SetTagValue(k, *iter); else - toFeature.SetTagValue(*iter, "yes"); + toFeature.SetTagValue(*iter, kYes); } else { diff --git a/editor/xml_feature.hpp b/editor/xml_feature.hpp index 636ed48692..a3421a2be2 100644 --- a/editor/xml_feature.hpp +++ b/editor/xml_feature.hpp @@ -141,7 +141,7 @@ public: void SetHouse(std::string const & house); std::string GetCuisine() const; - void SetCuisine(std::string const & cuisine); + void SetCuisine(std::string cuisine); /// Our and OSM modification time are equal. time_t GetModificationTime() const; @@ -177,6 +177,7 @@ public: std::string GetTagValue(std::string_view key) const; void SetTagValue(std::string_view key, std::string_view value); + void RemoveTag(std::string_view key); std::string GetAttribute(std::string const & key) const; void SetAttribute(std::string const & key, std::string const & value); -- 2.45.3 From 9b0359d2bb4a5d99a2e4a2a3495c551aee0a76ba Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Sat, 18 Feb 2023 09:21:02 -0300 Subject: [PATCH 07/61] Fixed ASSERT. Signed-off-by: Viktor Govako --- indexer/feature.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indexer/feature.cpp b/indexer/feature.cpp index 5dcb5a4875..ac2230da66 100644 --- a/indexer/feature.cpp +++ b/indexer/feature.cpp @@ -802,10 +802,10 @@ string_view FeatureType::GetName(int8_t lang) ParseCommon(); - // We don't store empty names. + // We don't store empty names. UPD: We do for coast features :) string_view name; if (m_params.name.GetString(lang, name)) - ASSERT(!name.empty(), ()); + ASSERT(!name.empty() || m_id.m_mwmId.GetInfo()->GetType() == MwmInfo::COASTS, ()); return name; } -- 2.45.3 From e300de67664f27fe2f561668a2a826fba510af11 Mon Sep 17 00:00:00 2001 From: Alexander Borsuk Date: Sat, 18 Feb 2023 13:31:15 +0100 Subject: [PATCH 08/61] [ios][editor] Removed duplicated floors and zip code cells Signed-off-by: Alexander Borsuk --- .../Maps/UI/Editor/MWMEditorViewController.mm | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/iphone/Maps/UI/Editor/MWMEditorViewController.mm b/iphone/Maps/UI/Editor/MWMEditorViewController.mm index fa7f871798..d2ac79f392 100644 --- a/iphone/Maps/UI/Editor/MWMEditorViewController.mm +++ b/iphone/Maps/UI/Editor/MWMEditorViewController.mm @@ -37,8 +37,8 @@ NSString * const kCategoryEditorSegue = @"Editor2CategoryEditorSegue"; NSString * const kUDEditorPersonalInfoWarninWasShown = @"PersonalInfoWarningAlertWasShown"; -CGFloat const kDefaultHeaderHeight = 28.; -CGFloat const kDefaultFooterHeight = 32.; +CGFloat constexpr kDefaultHeaderHeight = 28.; +CGFloat constexpr kDefaultFooterHeight = 32.; typedef NS_ENUM(NSUInteger, MWMEditorSection) { MWMEditorSectionCategory, @@ -57,8 +57,7 @@ std::vector const kSectionAddressCellTypes { std::vector const kSectionNoteCellTypes { MWMEditorCellTypeNote }; std::vector const kSectionButtonCellTypes { MWMEditorCellTypeReportButton }; -using MWMEditorCellTypeClassMap = std::map; -MWMEditorCellTypeClassMap const kCellType2Class { +std::map const kCellType2Class { {MWMEditorCellTypeCategory, [MWMEditorCategoryCell class]}, {MWMEditorCellTypeAdditionalName, [MWMEditorAdditionalNameTableViewCell class]}, {MWMEditorCellTypeAddAdditionalName, [MWMEditorAddAdditionalNameTableViewCell class]}, @@ -327,10 +326,15 @@ void registerCellsForTableView(std::vector const & cells, UITab registerCellsForTableView(kSectionCategoryCellTypes, self.tableView); BOOL const isNameEditable = m_mapObject.IsNameEditable(); BOOL const isAddressEditable = m_mapObject.IsAddressEditable(); - BOOL const areEditablePropertiesEmpty = m_mapObject.GetEditableProperties().empty(); + auto editableProperties = m_mapObject.GetEditableProperties(); + // Remove fields that are already displayed in the Address section. + editableProperties.erase(std::remove_if(editableProperties.begin(), editableProperties.end(), [](osm::MapObject::MetadataID mid) + { + return mid == MetadataID::FMD_POSTCODE || mid == MetadataID::FMD_BUILDING_LEVELS; + }), editableProperties.end()); BOOL const isCreating = self.isCreating; BOOL const isThereNotes = - !isCreating && areEditablePropertiesEmpty && !isAddressEditable && !isNameEditable; + !isCreating && editableProperties.empty() && !isAddressEditable && !isNameEditable; if (isNameEditable) { @@ -355,16 +359,12 @@ void registerCellsForTableView(std::vector const & cells, UITab registerCellsForTableView(kSectionAddressCellTypes, self.tableView); } - if (!areEditablePropertiesEmpty) + if (!editableProperties.empty()) { - auto const cells = m_mapObject.GetEditableProperties(); - if (!cells.empty()) - { - m_sections.push_back(MWMEditorSectionDetails); - auto & v = m_cells[MWMEditorSectionDetails]; - v.assign(cells.begin(), cells.end()); - registerCellsForTableView(v, self.tableView); - } + m_sections.push_back(MWMEditorSectionDetails); + auto & v = m_cells[MWMEditorSectionDetails]; + v.assign(editableProperties.begin(), editableProperties.end()); + registerCellsForTableView(v, self.tableView); } if (isThereNotes) -- 2.45.3 From 37277ddd37ac1746a75cad7ff081d1d7edd65884 Mon Sep 17 00:00:00 2001 From: Alexander Borsuk Date: Sat, 18 Feb 2023 14:13:32 +0100 Subject: [PATCH 09/61] [tools] Fixed wrong RTL translations generated by the trans tool Signed-off-by: Alexander Borsuk --- tools/unix/translate_categories.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/unix/translate_categories.sh b/tools/unix/translate_categories.sh index d5ce74d028..06c0017300 100755 --- a/tools/unix/translate_categories.sh +++ b/tools/unix/translate_categories.sh @@ -30,7 +30,8 @@ esac LANGUAGES=( en ar be bg ca cs da de el es et eu fa 'fi' fr he hu id it ja ko mr nb nl pl pt pt-BR ro ru sk sv sw th tr uk vi zh-CN zh-TW ) for lang in "${LANGUAGES[@]}"; do - TRANSLATION=$(trans -b "$SRC:$lang" "$WORD" | sed 's/ *//') + # -no-bidi fixes wrong characters order for RTL languages. + TRANSLATION=$(trans -b -no-bidi "$SRC:$lang" "$WORD" | sed 's/ *//') # Correct language codes to ours. case $lang in zh-CN) lang="zh-Hans" ;; -- 2.45.3 From c1ad5aaa361a3a54ec2c8a9295584a606915cf7a Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Mon, 26 Dec 2022 00:17:22 +0100 Subject: [PATCH 10/61] chore: simplify place page controller Signed-off-by: Arnaud Vergnet --- android/res/layout/activity_map.xml | 1 - android/src/app/organicmaps/MwmActivity.java | 11 +- .../widget/placepage/Closable.java | 6 - .../widget/placepage/PlacePageController.java | 294 ++++++++++++++- .../PlacePageControllerComposite.java | 187 ---------- .../widget/placepage/PlacePageFactory.java | 33 -- .../widget/placepage/PlacePageView.java | 26 +- .../placepage/RichPlacePageController.java | 349 ------------------ .../placepage/SimplePlacePageController.java | 288 --------------- 9 files changed, 293 insertions(+), 902 deletions(-) delete mode 100644 android/src/app/organicmaps/widget/placepage/Closable.java delete mode 100644 android/src/app/organicmaps/widget/placepage/PlacePageControllerComposite.java delete mode 100644 android/src/app/organicmaps/widget/placepage/PlacePageFactory.java delete mode 100644 android/src/app/organicmaps/widget/placepage/RichPlacePageController.java delete mode 100644 android/src/app/organicmaps/widget/placepage/SimplePlacePageController.java diff --git a/android/res/layout/activity_map.xml b/android/res/layout/activity_map.xml index e8484881d2..5ff52639db 100644 --- a/android/res/layout/activity_map.xml +++ b/android/res/layout/activity_map.xml @@ -72,5 +72,4 @@ android:orientation="horizontal" /> - diff --git a/android/src/app/organicmaps/MwmActivity.java b/android/src/app/organicmaps/MwmActivity.java index d47ac999c8..a3d5d17cf1 100644 --- a/android/src/app/organicmaps/MwmActivity.java +++ b/android/src/app/organicmaps/MwmActivity.java @@ -81,11 +81,9 @@ import app.organicmaps.util.log.Logger; import app.organicmaps.widget.menu.MainMenu; import app.organicmaps.widget.placepage.PlacePageController; import app.organicmaps.widget.placepage.PlacePageData; -import app.organicmaps.widget.placepage.PlacePageFactory; import app.organicmaps.widget.placepage.RoutingModeListener; import app.organicmaps.util.Config; import app.organicmaps.util.Counters; -import app.organicmaps.util.LocationUtils; import app.organicmaps.util.SharingUtils; import app.organicmaps.util.ThemeSwitcher; import app.organicmaps.util.ThemeUtils; @@ -98,7 +96,6 @@ import java.util.ArrayList; import java.util.Objects; import java.util.Stack; -import static app.organicmaps.util.concurrency.UiThread.runLater; import static app.organicmaps.widget.placepage.PlacePageButtons.PLACEPAGE_MORE_MENU_ID; public class MwmActivity extends BaseMwmFragmentActivity @@ -384,10 +381,8 @@ public class MwmActivity extends BaseMwmFragmentActivity setContentView(R.layout.activity_map); UiUtils.setupTransparentStatusBar(this); - mPlacePageController = PlacePageFactory.createCompositePlacePageController( - this, this); + mPlacePageController = new PlacePageController(this, this); mPlacePageController.initialize(this); - mPlacePageController.onActivityCreated(this, savedInstanceState); mSearchController = new FloatingSearchToolbarController(this, this); mSearchController.getToolbar() @@ -1008,7 +1003,6 @@ public class MwmActivity extends BaseMwmFragmentActivity mOnmapDownloader.onResume(); mNavigationController.onActivityResumed(this); - mPlacePageController.onActivityResumed(this); refreshLightStatusBar(); } @@ -1035,7 +1029,6 @@ public class MwmActivity extends BaseMwmFragmentActivity TtsPlayer.INSTANCE.stop(); if (mOnmapDownloader != null) mOnmapDownloader.onPause(); - mPlacePageController.onActivityPaused(this); mNavigationController.onActivityPaused(this); super.onPause(); } @@ -1052,7 +1045,6 @@ public class MwmActivity extends BaseMwmFragmentActivity LocationState.nativeSetListener(this); LocationHelper.INSTANCE.addListener(this); onMyPositionModeChanged(LocationState.nativeGetMode()); - mPlacePageController.onActivityStarted(this); mSearchController.attach(this); if (!Config.isScreenSleepEnabled()) Utils.keepScreenOn(true, getWindow()); @@ -1068,7 +1060,6 @@ public class MwmActivity extends BaseMwmFragmentActivity LocationState.nativeRemoveListener(); LocationHelper.INSTANCE.detach(); RoutingController.get().detach(); - mPlacePageController.onActivityStopped(this); IsolinesManager.from(getApplicationContext()).detach(); mSearchController.detach(); Utils.keepScreenOn(false, getWindow()); diff --git a/android/src/app/organicmaps/widget/placepage/Closable.java b/android/src/app/organicmaps/widget/placepage/Closable.java deleted file mode 100644 index 13d80af2de..0000000000 --- a/android/src/app/organicmaps/widget/placepage/Closable.java +++ /dev/null @@ -1,6 +0,0 @@ -package app.organicmaps.widget.placepage; - -public interface Closable -{ - void closePlacePage(); -} diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageController.java b/android/src/app/organicmaps/widget/placepage/PlacePageController.java index e1ffe88057..16e6fa809c 100644 --- a/android/src/app/organicmaps/widget/placepage/PlacePageController.java +++ b/android/src/app/organicmaps/widget/placepage/PlacePageController.java @@ -1,32 +1,298 @@ package app.organicmaps.widget.placepage; +import android.annotation.SuppressLint; import android.app.Activity; -import android.app.Application; +import android.content.res.Resources; +import android.location.Location; import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; import androidx.annotation.NonNull; - import androidx.annotation.Nullable; +import androidx.core.view.GestureDetectorCompat; +import app.organicmaps.Framework; +import app.organicmaps.R; import app.organicmaps.base.Initializable; import app.organicmaps.base.Savable; -import app.organicmaps.base.Supportable; +import app.organicmaps.bookmarks.data.MapObject; +import app.organicmaps.location.LocationHelper; +import app.organicmaps.location.LocationListener; +import app.organicmaps.util.UiUtils; +import app.organicmaps.util.Utils; import app.organicmaps.util.bottomsheet.MenuBottomSheetItem; +import app.organicmaps.util.log.Logger; +import com.google.android.material.bottomsheet.BottomSheetBehavior; import java.util.ArrayList; +import java.util.Objects; -public interface PlacePageController extends Initializable, - Savable, - Application.ActivityLifecycleCallbacks, - Supportable +public class PlacePageController implements Initializable, + Savable, + LocationListener, + PlacePageView.OnPlacePageRequestCloseListener { - void openFor(@NonNull PlacePageData data); - void close(boolean deactivateMapSelection); - boolean isClosed(); - int getPlacePageWidth(); - @Nullable - ArrayList getMenuBottomSheetItems(); + private static final String TAG = PlacePageController.class.getSimpleName(); - interface SlideListener + private static final float PREVIEW_PLUS_RATIO = 0.45f; + @NonNull + private final SlideListener mSlideListener; + @Nullable + private final RoutingModeListener mRoutingModeListener; + @SuppressWarnings("NullableProblems") + @NonNull + private BottomSheetBehavior mPlacePageBehavior; + @SuppressWarnings("NullableProblems") + @NonNull + private View mButtonsLayout; + @SuppressWarnings("NullableProblems") + @NonNull + private PlacePageView mPlacePage; + private int mViewportMinHeight; + private boolean mDeactivateMapSelection = true; + @NonNull + private final BottomSheetChangedListener mBottomSheetChangedListener = new BottomSheetChangedListener() + { + @Override + public void onSheetHidden() + { + onHiddenInternal(); + } + + @Override + public void onSheetDetailsOpened() + { + // No op. + } + + @Override + public void onSheetCollapsed() + { + mPlacePage.resetScroll(); + setPeekHeight(); + } + + @Override + public void onSheetSliding(int top) + { + mSlideListener.onPlacePageSlide(top); + // mPlacePageTracker.onMove(); + } + + @Override + public void onSheetSlideFinish() + { + PlacePageUtils.moveViewportUp(mPlacePage, mViewportMinHeight); + } + }; + @NonNull + private final BottomSheetBehavior.BottomSheetCallback mSheetCallback + = new DefaultBottomSheetCallback(mBottomSheetChangedListener); + + public PlacePageController(@NonNull SlideListener listener, + @Nullable RoutingModeListener routingModeListener) + { + mSlideListener = listener; + mRoutingModeListener = routingModeListener; + } + + private void onHiddenInternal() + { + if (mDeactivateMapSelection) + Framework.nativeDeactivatePopup(); + mDeactivateMapSelection = true; + PlacePageUtils.moveViewportUp(mPlacePage, mViewportMinHeight); + UiUtils.invisible(mButtonsLayout); + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initialize(@Nullable Activity activity) + { + Objects.requireNonNull(activity); + Resources res = activity.getResources(); + mViewportMinHeight = res.getDimensionPixelSize(R.dimen.viewport_min_height); + mPlacePage = activity.findViewById(R.id.placepage); + mPlacePageBehavior = BottomSheetBehavior.from(mPlacePage); + mPlacePageBehavior.addBottomSheetCallback(mSheetCallback); + mPlacePageBehavior.setHideable(true); + mPlacePageBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); + PlacePageGestureListener ppGestureListener = new PlacePageGestureListener(mPlacePageBehavior); + GestureDetectorCompat gestureDetector = new GestureDetectorCompat(activity, ppGestureListener); + mPlacePage.addPlacePageGestureListener(ppGestureListener); + mPlacePage.setOnTouchListener((v, event) -> gestureDetector.onTouchEvent(event)); + mPlacePage.setOnPlacePageRequestCloseListener(this); + mPlacePage.setRoutingModeListener(mRoutingModeListener); + mPlacePage.setOnPlacePageContentChangeListener(this::setPeekHeight); + + mButtonsLayout = activity.findViewById(R.id.pp_buttons_layout); + ViewGroup buttons = mButtonsLayout.findViewById(R.id.container); + mPlacePage.initButtons(buttons); + UiUtils.bringViewToFrontOf(mButtonsLayout, mPlacePage); + LocationHelper.INSTANCE.addListener(this); + + mButtonsLayout.setOnApplyWindowInsetsListener((view, windowInsets) -> { + UiUtils.setViewInsetsPaddingNoTop(mButtonsLayout, windowInsets); + return windowInsets; + }); + mPlacePage.requestApplyInsets(); + } + + public int getPlacePageWidth() + { + return mPlacePage.getWidth(); + } + + @Nullable + public ArrayList getMenuBottomSheetItems() + { + return mPlacePage.getMenuBottomSheetItems(); + } + + @Override + public void destroy() + { + LocationHelper.INSTANCE.removeListener(this); + } + + public void openFor(@NonNull PlacePageData data) + { + mDeactivateMapSelection = true; + MapObject object = (MapObject) data; + mPlacePage.setMapObject(object, (isSameObject) -> { + @BottomSheetBehavior.State + int state = mPlacePageBehavior.getState(); + if (isSameObject && !PlacePageUtils.isHiddenState(state)) + return; + + mPlacePage.resetScroll(); + + if (object.getOpeningMode() == MapObject.OPENING_MODE_DETAILS) + { + mPlacePageBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); + return; + } + + UiUtils.show(mButtonsLayout); + mPlacePage.post(() -> { + setPeekHeight(); + mPlacePageBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); + }); + }); + } + + private void setPeekHeight() + { + final int peekHeight = calculatePeekHeight(); + if (peekHeight == mPlacePageBehavior.getPeekHeight()) + return; + + @BottomSheetBehavior.State + int currentState = mPlacePageBehavior.getState(); + if (PlacePageUtils.isSettlingState(currentState) || PlacePageUtils.isDraggingState(currentState)) + { + Logger.d(TAG, "Sheet state inappropriate, ignore."); + return; + } + + final boolean shouldAnimate = PlacePageUtils.isCollapsedState(currentState) && mPlacePageBehavior.getPeekHeight() > 0; + mPlacePageBehavior.setPeekHeight(peekHeight, shouldAnimate); + } + + private int calculatePeekHeight() + { + // Buttons layout padding is the navigation bar height. + // Bottom sheets are displayed above it so we need to remove it from the computed size + final int organicPeekHeight = mPlacePage.getPreviewHeight() + + mButtonsLayout.getHeight() - mButtonsLayout.getPaddingBottom(); + final MapObject object = mPlacePage.getMapObject(); + if (object != null) + { + @MapObject.OpeningMode + int mode = object.getOpeningMode(); + if (mode == MapObject.OPENING_MODE_PREVIEW_PLUS) + { + View parent = (View) mPlacePage.getParent(); + int promoPeekHeight = (int) (parent.getHeight() * PREVIEW_PLUS_RATIO); + return Math.max(promoPeekHeight, organicPeekHeight); + } + } + + return organicPeekHeight; + } + + public void close(boolean deactivateMapSelection) + { + mDeactivateMapSelection = deactivateMapSelection; + mPlacePageBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); + mPlacePage.reset(); + } + + public boolean isClosed() + { + return PlacePageUtils.isHiddenState(mPlacePageBehavior.getState()); + } + + @Override + public void onLocationUpdated(@NonNull Location location) + { + mPlacePage.refreshLocation(location); + } + + @Override + public void onCompassUpdated(double north) + { + @BottomSheetBehavior.State + int currentState = mPlacePageBehavior.getState(); + if (PlacePageUtils.isHiddenState(currentState)) + return; + + mPlacePage.refreshAzimuth(north); + } + + @Override + public void onSave(@NonNull Bundle outState) + { + outState.putParcelable(PlacePageUtils.EXTRA_PLACE_PAGE_DATA, mPlacePage.getMapObject()); + } + + @Override + public void onRestore(@NonNull Bundle inState) + { + if (mPlacePageBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN) + return; + + if (!Framework.nativeHasPlacePageInfo()) + { + close(false); + return; + } + + MapObject object = Utils.getParcelable(inState, PlacePageUtils.EXTRA_PLACE_PAGE_DATA, MapObject.class); + if (object == null) + return; + + @BottomSheetBehavior.State + int state = mPlacePageBehavior.getState(); + mPlacePage.setMapObject(object, (isSameObject) -> restorePlacePageState(state)); + } + + private void restorePlacePageState(@BottomSheetBehavior.State int state) + { + mPlacePage.post(() -> { + mPlacePageBehavior.setState(state); + UiUtils.show(mButtonsLayout); + setPeekHeight(); + }); + } + + @Override + public void onPlacePageRequestClose() + { + close(true); + } + + public interface SlideListener { void onPlacePageSlide(int top); } diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageControllerComposite.java b/android/src/app/organicmaps/widget/placepage/PlacePageControllerComposite.java deleted file mode 100644 index 5a258f73fa..0000000000 --- a/android/src/app/organicmaps/widget/placepage/PlacePageControllerComposite.java +++ /dev/null @@ -1,187 +0,0 @@ -package app.organicmaps.widget.placepage; - -import android.app.Activity; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import app.organicmaps.util.bottomsheet.MenuBottomSheetItem; -import app.organicmaps.util.Utils; - -import java.util.ArrayList; -import java.util.List; - -class PlacePageControllerComposite implements PlacePageController -{ - @NonNull - private final PlacePageController.SlideListener mSlideListener; - @Nullable - private final RoutingModeListener mRoutingModeListener; - @NonNull - private final List mControllers = new ArrayList<>(); - @SuppressWarnings("NullableProblems") - @NonNull - private PlacePageController mActiveController; - - PlacePageControllerComposite(@NonNull SlideListener slideListener, - @Nullable RoutingModeListener routingModeListener) - { - mSlideListener = slideListener; - mRoutingModeListener = routingModeListener; - } - - @Override - public int getPlacePageWidth() - { - return mActiveController.getPlacePageWidth(); - } - - @Override - @Nullable - public ArrayList getMenuBottomSheetItems() - { - return mActiveController.getMenuBottomSheetItems(); - } - - @Override - public void openFor(@NonNull PlacePageData data) - { - boolean support = mActiveController.support(data); - if (support) - { - mActiveController.openFor(data); - return; - } - - mActiveController.close(false); - PlacePageController controller = findControllerFor(data); - if (controller == null) - throw new UnsupportedOperationException("Place page data '" + data + "' not supported " + - "by existing controllers"); - mActiveController = controller; - mActiveController.openFor(data); - } - - @Override - public void close(boolean deactivateMapSelection) - { - mActiveController.close(deactivateMapSelection); - } - - @Override - public boolean isClosed() - { - return mActiveController.isClosed(); - } - - @Override - public void onActivityCreated(Activity activity, Bundle savedInstanceState) - { - mActiveController.onActivityCreated(activity, savedInstanceState); - } - - @Override - public void onActivityStarted(Activity activity) - { - mActiveController.onActivityStarted(activity); - } - - @Override - public void onActivityResumed(Activity activity) - { - mActiveController.onActivityResumed(activity); - } - - @Override - public void onActivityPaused(Activity activity) - { - mActiveController.onActivityPaused(activity); - } - - @Override - public void onActivityStopped(Activity activity) - { - mActiveController.onActivityStopped(activity); - } - - @Override - public void onActivitySaveInstanceState(Activity activity, Bundle outState) - { - mActiveController.onActivitySaveInstanceState(activity, outState); - } - - @Override - public void onActivityDestroyed(Activity activity) - { - mActiveController.onActivityDestroyed(activity); - } - - @Override - public void initialize(@Nullable Activity activity) - { - if (!mControllers.isEmpty()) - throw new AssertionError("Place page controllers already initialized!"); - - PlacePageController richController = - PlacePageFactory.createRichController(mSlideListener, mRoutingModeListener); - richController.initialize(activity); - mControllers.add(richController); - - PlacePageController elevationProfileController = - PlacePageFactory.createElevationProfilePlacePageController(mSlideListener); - elevationProfileController.initialize(activity); - mControllers.add(elevationProfileController); - - mActiveController = richController; - } - - - @Override - public void destroy() - { - if (mControllers.isEmpty()) - throw new AssertionError("Place page controllers already destroyed!"); - - for (PlacePageController controller: mControllers) - controller.destroy(); - - mControllers.clear(); - } - - @Override - public void onSave(@NonNull Bundle outState) - { - mActiveController.onSave(outState); - } - - @Override - public void onRestore(@NonNull Bundle inState) - { - PlacePageData data = Utils.getParcelable(inState, PlacePageUtils.EXTRA_PLACE_PAGE_DATA, PlacePageData.class); - if (data != null) - { - PlacePageController controller = findControllerFor(data); - if (controller != null) - mActiveController = controller; - } - mActiveController.onRestore(inState); - } - - @Nullable - private PlacePageController findControllerFor(@NonNull PlacePageData object) - { - for (PlacePageController controller : mControllers) - { - if (controller.support(object)) - return controller; - } - - return null; - } - - @Override - public boolean support(@NonNull PlacePageData object) - { - return mActiveController.support(object); - } -} diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageFactory.java b/android/src/app/organicmaps/widget/placepage/PlacePageFactory.java deleted file mode 100644 index 182118e239..0000000000 --- a/android/src/app/organicmaps/widget/placepage/PlacePageFactory.java +++ /dev/null @@ -1,33 +0,0 @@ -package app.organicmaps.widget.placepage; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import app.organicmaps.R; - -public class PlacePageFactory -{ - @NonNull - public static PlacePageController createCompositePlacePageController( - @NonNull PlacePageController.SlideListener slideListener, - @NonNull RoutingModeListener routingModeListener) - { - return new PlacePageControllerComposite(slideListener, routingModeListener); - } - - @NonNull - static PlacePageController createRichController( - @NonNull PlacePageController.SlideListener listener, - @Nullable RoutingModeListener routingModeListener) - { - return new RichPlacePageController(listener, routingModeListener); - } - - @NonNull - static PlacePageController createElevationProfilePlacePageController( - @NonNull PlacePageController.SlideListener listener) - { - ElevationProfileViewRenderer renderer = new ElevationProfileViewRenderer(); - return new SimplePlacePageController(R.id.elevation_profile, renderer, renderer, listener); - } -} diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageView.java b/android/src/app/organicmaps/widget/placepage/PlacePageView.java index 614fda225f..c1bb249856 100644 --- a/android/src/app/organicmaps/widget/placepage/PlacePageView.java +++ b/android/src/app/organicmaps/widget/placepage/PlacePageView.java @@ -195,6 +195,8 @@ public class PlacePageView extends NestedScrollViewClickFixed private OnPlacePageContentChangeListener mOnPlacePageContentChangeListener; + private OnPlacePageRequestCloseListener mOnPlacePageRequestCloseListener; + private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback() { @Override @@ -250,9 +252,6 @@ public class PlacePageView extends NestedScrollViewClickFixed } }; - @Nullable - private Closable mClosable; - @Nullable private PlacePageGestureListener mPlacePageGestureListener; @@ -269,9 +268,9 @@ public class PlacePageView extends NestedScrollViewClickFixed mPlacePageGestureListener = ppGestureListener; } - void addClosable(@NonNull Closable closable) + void setOnPlacePageRequestCloseListener(@NonNull OnPlacePageRequestCloseListener listener) { - mClosable = closable; + mOnPlacePageRequestCloseListener = listener; } @Override @@ -577,11 +576,11 @@ public class PlacePageView extends NestedScrollViewClickFixed if (!controller.isPlanning()) { controller.prepare(mMapObject, null); - close(); + mOnPlacePageRequestCloseListener.onPlacePageRequestClose(); } else if (controller.setStartPoint(mMapObject)) { - close(); + mOnPlacePageRequestCloseListener.onPlacePageRequestClose(); } } @@ -590,7 +589,7 @@ public class PlacePageView extends NestedScrollViewClickFixed if (RoutingController.get().isPlanning()) { RoutingController.get().setEndPoint(mMapObject); - close(); + mOnPlacePageRequestCloseListener.onPlacePageRequestClose(); } else { @@ -1554,12 +1553,6 @@ public class PlacePageView extends NestedScrollViewClickFixed return true; } - private void close() - { - if (mClosable != null) - mClosable.closePlacePage(); - } - void reset() { resetScroll(); @@ -1696,4 +1689,9 @@ public class PlacePageView extends NestedScrollViewClickFixed { void OnPlacePageContentChange(); } + + interface OnPlacePageRequestCloseListener + { + void onPlacePageRequestClose(); + } } diff --git a/android/src/app/organicmaps/widget/placepage/RichPlacePageController.java b/android/src/app/organicmaps/widget/placepage/RichPlacePageController.java deleted file mode 100644 index 0fc63a740d..0000000000 --- a/android/src/app/organicmaps/widget/placepage/RichPlacePageController.java +++ /dev/null @@ -1,349 +0,0 @@ -package app.organicmaps.widget.placepage; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.res.Resources; -import android.location.Location; -import android.os.Bundle; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.view.GestureDetectorCompat; -import com.google.android.material.bottomsheet.BottomSheetBehavior; -import app.organicmaps.Framework; -import app.organicmaps.R; -import app.organicmaps.bookmarks.data.MapObject; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.location.LocationListener; -import app.organicmaps.util.UiUtils; -import app.organicmaps.util.Utils; -import app.organicmaps.util.bottomsheet.MenuBottomSheetItem; -import app.organicmaps.util.log.Logger; - -import java.util.ArrayList; -import java.util.Objects; - -public class RichPlacePageController implements PlacePageController, LocationListener, Closable -{ - private static final String TAG = RichPlacePageController.class.getSimpleName(); - - private static final float PREVIEW_PLUS_RATIO = 0.45f; - @SuppressWarnings("NullableProblems") - @NonNull - private BottomSheetBehavior mPlacePageBehavior; - @SuppressWarnings("NullableProblems") - @NonNull - private View mButtonsLayout; - @SuppressWarnings("NullableProblems") - @NonNull - private PlacePageView mPlacePage; - private int mViewportMinHeight; - @NonNull - private final SlideListener mSlideListener; - @Nullable - private final RoutingModeListener mRoutingModeListener; - @NonNull - private final BottomSheetChangedListener mBottomSheetChangedListener = new BottomSheetChangedListener() - { - @Override - public void onSheetHidden() - { - onHiddenInternal(); - } - - @Override - public void onSheetDetailsOpened() - { - // No op. - } - - @Override - public void onSheetCollapsed() - { - mPlacePage.resetScroll(); - setPeekHeight(); - } - - @Override - public void onSheetSliding(int top) - { - mSlideListener.onPlacePageSlide(top); - // mPlacePageTracker.onMove(); - } - - @Override - public void onSheetSlideFinish() - { - PlacePageUtils.moveViewportUp(mPlacePage, mViewportMinHeight); - } - }; - - @NonNull - private final BottomSheetBehavior.BottomSheetCallback mSheetCallback - = new DefaultBottomSheetCallback(mBottomSheetChangedListener); - - private boolean mDeactivateMapSelection = true; - - private void onHiddenInternal() - { - if (mDeactivateMapSelection) - Framework.nativeDeactivatePopup(); - mDeactivateMapSelection = true; - PlacePageUtils.moveViewportUp(mPlacePage, mViewportMinHeight); - UiUtils.invisible(mButtonsLayout); - } - - RichPlacePageController(@NonNull SlideListener listener, - @Nullable RoutingModeListener routingModeListener) - { - mSlideListener = listener; - mRoutingModeListener = routingModeListener; - } - - @SuppressLint("ClickableViewAccessibility") - @Override - public void initialize(@Nullable Activity activity) - { - Objects.requireNonNull(activity); - Resources res = activity.getResources(); - mViewportMinHeight = res.getDimensionPixelSize(R.dimen.viewport_min_height); - mPlacePage = activity.findViewById(R.id.placepage); - mPlacePageBehavior = BottomSheetBehavior.from(mPlacePage); - mPlacePageBehavior.addBottomSheetCallback(mSheetCallback); - mPlacePageBehavior.setHideable(true); - mPlacePageBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); - PlacePageGestureListener ppGestureListener = new PlacePageGestureListener(mPlacePageBehavior); - GestureDetectorCompat gestureDetector = new GestureDetectorCompat(activity, ppGestureListener); - mPlacePage.addPlacePageGestureListener(ppGestureListener); - mPlacePage.setOnTouchListener((v, event) -> gestureDetector.onTouchEvent(event)); - mPlacePage.addClosable(this); - mPlacePage.setRoutingModeListener(mRoutingModeListener); - mPlacePage.setOnPlacePageContentChangeListener(this::setPeekHeight); - - mButtonsLayout = activity.findViewById(R.id.pp_buttons_layout); - ViewGroup buttons = mButtonsLayout.findViewById(R.id.container); - mPlacePage.initButtons(buttons); - UiUtils.bringViewToFrontOf(mButtonsLayout, mPlacePage); - LocationHelper.INSTANCE.addListener(this); - - mButtonsLayout.setOnApplyWindowInsetsListener((view, windowInsets) -> { - UiUtils.setViewInsetsPaddingNoTop(mButtonsLayout, windowInsets); - return windowInsets; - }); - mPlacePage.requestApplyInsets(); - } - - public int getPlacePageWidth() - { - return mPlacePage.getWidth(); - } - - @Override - @Nullable - public ArrayList getMenuBottomSheetItems() - { - return mPlacePage.getMenuBottomSheetItems(); - } - - @Override - public void destroy() - { - LocationHelper.INSTANCE.removeListener(this); - } - - @Override - public void openFor(@NonNull PlacePageData data) - { - mDeactivateMapSelection = true; - MapObject object = (MapObject) data; - mPlacePage.setMapObject(object, (isSameObject) -> { - @BottomSheetBehavior.State - int state = mPlacePageBehavior.getState(); - if (isSameObject && !PlacePageUtils.isHiddenState(state)) - return; - - mPlacePage.resetScroll(); - - if (object.getOpeningMode() == MapObject.OPENING_MODE_DETAILS) - { - mPlacePageBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); - return; - } - - UiUtils.show(mButtonsLayout); - openPlacePage(); - }); - - } - - private void openPlacePage() - { - mPlacePage.post(() -> { - setPeekHeight(); - mPlacePageBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); - }); - } - - private void setPeekHeight() - { - final int peekHeight = calculatePeekHeight(); - if (peekHeight == mPlacePageBehavior.getPeekHeight()) - return; - - @BottomSheetBehavior.State - int currentState = mPlacePageBehavior.getState(); - if (PlacePageUtils.isSettlingState(currentState) || PlacePageUtils.isDraggingState(currentState)) - { - Logger.d(TAG, "Sheet state inappropriate, ignore."); - return; - } - - final boolean shouldAnimate = PlacePageUtils.isCollapsedState(currentState) && mPlacePageBehavior.getPeekHeight() > 0; - mPlacePageBehavior.setPeekHeight(peekHeight, shouldAnimate); - } - - private int calculatePeekHeight() - { - // Buttons layout padding is the navigation bar height. - // Bottom sheets are displayed above it so we need to remove it from the computed size - final int organicPeekHeight = mPlacePage.getPreviewHeight() + - mButtonsLayout.getHeight() - mButtonsLayout.getPaddingBottom(); - final MapObject object = mPlacePage.getMapObject(); - if (object != null) - { - @MapObject.OpeningMode - int mode = object.getOpeningMode(); - if (mode == MapObject.OPENING_MODE_PREVIEW_PLUS) - { - View parent = (View) mPlacePage.getParent(); - int promoPeekHeight = (int) (parent.getHeight() * PREVIEW_PLUS_RATIO); - return Math.max(promoPeekHeight, organicPeekHeight); - } - } - - return organicPeekHeight; - } - - @Override - public void close(boolean deactivateMapSelection) - { - mDeactivateMapSelection = deactivateMapSelection; - mPlacePageBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); - mPlacePage.reset(); - } - - @Override - public boolean isClosed() - { - return PlacePageUtils.isHiddenState(mPlacePageBehavior.getState()); - } - - @Override - public void onLocationUpdated(@NonNull Location location) - { - mPlacePage.refreshLocation(location); - } - - @Override - public void onCompassUpdated(double north) - { - @BottomSheetBehavior.State - int currentState = mPlacePageBehavior.getState(); - if (PlacePageUtils.isHiddenState(currentState)) - return; - - mPlacePage.refreshAzimuth(north); - } - - @Override - public void onSave(@NonNull Bundle outState) - { - outState.putParcelable(PlacePageUtils.EXTRA_PLACE_PAGE_DATA, mPlacePage.getMapObject()); - } - - @Override - public void onRestore(@NonNull Bundle inState) - { - if (mPlacePageBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN) - return; - - if (!Framework.nativeHasPlacePageInfo()) - { - close(false); - return; - } - - MapObject object = Utils.getParcelable(inState, PlacePageUtils.EXTRA_PLACE_PAGE_DATA, MapObject.class); - if (object == null) - return; - - @BottomSheetBehavior.State - int state = mPlacePageBehavior.getState(); - mPlacePage.setMapObject(object, (isSameObject) -> restorePlacePageState(state)); - } - - private void restorePlacePageState(@BottomSheetBehavior.State int state) - { - mPlacePage.post(() -> { - mPlacePageBehavior.setState(state); - UiUtils.show(mButtonsLayout); - setPeekHeight(); - }); - } - - @Override - public void onActivityCreated(Activity activity, Bundle savedInstanceState) - { - // No op. - } - - @Override - public void onActivityStarted(Activity activity) - { - // No op. - } - - @Override - public void onActivityResumed(Activity activity) - { - // No op. - } - - @Override - public void onActivityPaused(Activity activity) - { - // No op. - } - - @Override - public void onActivityStopped(Activity activity) - { - // No op. - } - - @Override - public void onActivitySaveInstanceState(Activity activity, Bundle outState) - { - // No op. - } - - @Override - public void onActivityDestroyed(Activity activity) - { - // No op. - } - - @Override - public void closePlacePage() - { - close(true); - } - - @Override - public boolean support(@NonNull PlacePageData data) - { - return data instanceof MapObject; - } -} diff --git a/android/src/app/organicmaps/widget/placepage/SimplePlacePageController.java b/android/src/app/organicmaps/widget/placepage/SimplePlacePageController.java deleted file mode 100644 index c7996a6024..0000000000 --- a/android/src/app/organicmaps/widget/placepage/SimplePlacePageController.java +++ /dev/null @@ -1,288 +0,0 @@ -package app.organicmaps.widget.placepage; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.Application; -import android.os.Bundle; -import android.view.MotionEvent; -import android.view.View; - -import androidx.annotation.IdRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.view.GestureDetectorCompat; - -import com.google.android.material.bottomsheet.BottomSheetBehavior; -import app.organicmaps.Framework; -import app.organicmaps.R; -import app.organicmaps.util.UiUtils; -import app.organicmaps.util.bottomsheet.MenuBottomSheetItem; - -import java.util.ArrayList; -import java.util.Objects; - -public class SimplePlacePageController implements PlacePageController -{ - @SuppressWarnings("NullableProblems") - @NonNull - private Application mApplication; - @SuppressWarnings("NullableProblems") - @NonNull - private View mSheet; - @SuppressWarnings("NullableProblems") - @NonNull - private BottomSheetBehavior mSheetBehavior; - @NonNull - private final SlideListener mSlideListener; - private int mViewportMinHeight; - private int mViewPortMinWidth; - @NonNull - private final PlacePageViewRenderer mViewRenderer; - @Nullable - private final PlacePageStateListener mStateListener; - @NonNull - private final BottomSheetChangedListener mBottomSheetChangedListener = - new BottomSheetChangedListener() - { - @Override - public void onSheetHidden() - { - onHiddenInternal(); - if (mStateListener != null) - mStateListener.onPlacePageClosed(); - } - - @Override - public void onSheetDetailsOpened() - { - if (UiUtils.isLandscape(mApplication)) - PlacePageUtils.moveViewPortRight(mSheet, mViewPortMinWidth); - if (mStateListener != null) - mStateListener.onPlacePageDetails(); - } - - @Override - public void onSheetCollapsed() - { - if (UiUtils.isLandscape(mApplication)) - PlacePageUtils.moveViewPortRight(mSheet, mViewPortMinWidth); - if (mStateListener != null) - mStateListener.onPlacePagePreview(); - } - - @Override - public void onSheetSliding(int top) - { - if (UiUtils.isLandscape(mApplication)) - return; - - mSlideListener.onPlacePageSlide(top); - } - - @Override - public void onSheetSlideFinish() - { - if (UiUtils.isLandscape(mApplication)) - return; - - PlacePageUtils.moveViewportUp(mSheet, mViewportMinHeight); - } - }; - - private final BottomSheetBehavior.BottomSheetCallback mSheetCallback - = new DefaultBottomSheetCallback(mBottomSheetChangedListener); - - private boolean mDeactivateMapSelection = true; - @IdRes - private final int mSheetResId; - - SimplePlacePageController(int sheetResId, @NonNull PlacePageViewRenderer renderer, - @Nullable PlacePageStateListener stateListener, - @NonNull SlideListener slideListener) - { - mSheetResId = sheetResId; - mSlideListener = slideListener; - mViewRenderer = renderer; - mStateListener = stateListener; - } - - public int getPlacePageWidth() - { - return mSheet.getWidth(); - } - - @Override - @Nullable - public ArrayList getMenuBottomSheetItems() - { - return null; - } - - @Override - public void openFor(@NonNull PlacePageData data) - { - mDeactivateMapSelection = true; - mViewRenderer.render(data); - if (mSheetBehavior.getSkipCollapsed()) - mSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); - else - mSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); - } - - @Override - public void close(boolean deactivateMapSelection) - { - mDeactivateMapSelection = deactivateMapSelection; - mSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); - } - - @Override - public boolean isClosed() - { - return PlacePageUtils.isHiddenState(mSheetBehavior.getState()); - } - - @Override - public void onActivityCreated(Activity activity, Bundle savedInstanceState) - { - - } - - @Override - public void onActivityStarted(Activity activity) - { - - } - - @Override - public void onActivityResumed(Activity activity) - { - - } - - @Override - public void onActivityPaused(Activity activity) - { - - } - - @Override - public void onActivityStopped(Activity activity) - { - - } - - @Override - public void onActivitySaveInstanceState(Activity activity, Bundle outState) - { - - } - - @Override - public void onActivityDestroyed(Activity activity) - { - - } - - @SuppressLint("ClickableViewAccessibility") - @Override - public void initialize(@Nullable Activity activity) - { - Objects.requireNonNull(activity); - mApplication = activity.getApplication(); - mSheet = activity.findViewById(mSheetResId); - mViewportMinHeight = mSheet.getResources().getDimensionPixelSize(R.dimen.viewport_min_height); - mViewPortMinWidth = mSheet.getResources().getDimensionPixelSize(R.dimen.viewport_min_width); - mSheetBehavior = BottomSheetBehavior.from(mSheet); - mSheetBehavior.addBottomSheetCallback(mSheetCallback); - mSheetBehavior.setHideable(true); - mSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); - boolean isLandscape = UiUtils.isLandscape(mApplication); - GestureDetectorCompat gestureDetector = new GestureDetectorCompat( - activity, new SimplePlacePageGestureListener(mSheetBehavior, isLandscape)); - mSheet.setOnTouchListener((v, event) -> gestureDetector.onTouchEvent(event)); - mViewRenderer.initialize(mSheet); - } - - @Override - public void destroy() - { - mViewRenderer.destroy(); - } - - @Override - public void onSave(@NonNull Bundle outState) - { - mViewRenderer.onSave(outState); - } - - @Override - public void onRestore(@NonNull Bundle inState) - { - if (PlacePageUtils.isHiddenState(mSheetBehavior.getState())) - return; - - if (!Framework.nativeHasPlacePageInfo()) - { - close(false); - return; - } - - mViewRenderer.onRestore(inState); - if (UiUtils.isLandscape(mApplication)) - { - // In case when bottom sheet was collapsed for vertical orientation then after rotation - // we should expand bottom sheet forcibly for horizontal orientation. It's by design. - if (!PlacePageUtils.isHiddenState(mSheetBehavior.getState())) - { - mSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); - } - return; - } - } - - private void onHiddenInternal() - { - mViewRenderer.onHide(); - if (mDeactivateMapSelection) - Framework.nativeDeactivatePopup(); - mDeactivateMapSelection = true; - if (UiUtils.isLandscape(mApplication)) - { - PlacePageUtils.moveViewPortRight(mSheet, mViewPortMinWidth); - return; - } - - PlacePageUtils.moveViewportUp(mSheet, mViewportMinHeight); - } - - @Override - public boolean support(@NonNull PlacePageData data) - { - return mViewRenderer.support(data); - } - - private static class SimplePlacePageGestureListener extends PlacePageGestureListener - { - private final boolean mLandscape; - - SimplePlacePageGestureListener(@NonNull BottomSheetBehavior bottomSheetBehavior, - boolean landscape) - { - super(bottomSheetBehavior); - mLandscape = landscape; - } - - @Override - public boolean onSingleTapConfirmed(MotionEvent e) - { - if (mLandscape) - { - getBottomSheetBehavior().setState(BottomSheetBehavior.STATE_HIDDEN); - return false; - } - - return super.onSingleTapConfirmed(e); - } - } -} -- 2.45.3 From 0969baf696b8ffd642210fb8aef25f995609cdec Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Mon, 26 Dec 2022 11:19:11 +0100 Subject: [PATCH 11/61] android: reduce coupling with place page view and buttons Signed-off-by: Arnaud Vergnet --- .../widget/placepage/PlacePageButtons.java | 18 +++++++++--------- .../widget/placepage/PlacePageView.java | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageButtons.java b/android/src/app/organicmaps/widget/placepage/PlacePageButtons.java index 36222dad56..16d611e9b5 100644 --- a/android/src/app/organicmaps/widget/placepage/PlacePageButtons.java +++ b/android/src/app/organicmaps/widget/placepage/PlacePageButtons.java @@ -12,6 +12,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; +import app.organicmaps.MwmActivity; import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.routing.RoutingController; @@ -29,7 +30,7 @@ public final class PlacePageButtons public static final String PLACEPAGE_MORE_MENU_ID = "PLACEPAGE_MORE_MENU_BOTTOM_SHEET"; private final int mMaxButtons; - private final PlacePageView mPlacePage; + private final MwmActivity mMwmActivity; private final ViewGroup mFrame; private final ItemListener mItemListener; @@ -244,13 +245,13 @@ public final class PlacePageButtons void onItemClick(PlacePageButton item); } - PlacePageButtons(PlacePageView placePage, ViewGroup frame, ItemListener itemListener) + PlacePageButtons(MwmActivity mwmActivity, ViewGroup frame, ItemListener itemListener) { - mPlacePage = placePage; + mMwmActivity = mwmActivity; mFrame = frame; mItemListener = itemListener; - mMaxButtons = mPlacePage.getContext().getResources().getInteger(R.integer.pp_buttons_max); + mMaxButtons = mMwmActivity.getResources().getInteger(R.integer.pp_buttons_max); } private @NonNull List collectButtons(List items) @@ -320,7 +321,7 @@ public final class PlacePageButtons for (int i = mMaxButtons; i < mMoreItems.size(); i++) { final PlacePageButton bsItem = mMoreItems.get(i); - int iconRes = bsItem.getIcon().getEnabledStateResId(mPlacePage.getContext()); + int iconRes = bsItem.getIcon().getEnabledStateResId(mMwmActivity); items.add(new MenuBottomSheetItem(bsItem.getTitle(), iconRes, () -> mItemListener.onItemClick(bsItem))); } return items; @@ -329,21 +330,20 @@ public final class PlacePageButtons private void showPopup() { MenuBottomSheetFragment.newInstance(PLACEPAGE_MORE_MENU_ID) - .show(mPlacePage.requireActivity().getSupportFragmentManager(), PLACEPAGE_MORE_MENU_ID); + .show(mMwmActivity.getSupportFragmentManager(), PLACEPAGE_MORE_MENU_ID); } private View createButton(@NonNull final List items, @NonNull final PlacePageButton current) { - Context context = mPlacePage.getContext(); - LayoutInflater inflater = LayoutInflater.from(context); + LayoutInflater inflater = LayoutInflater.from(mMwmActivity); View parent = inflater.inflate(R.layout.place_page_button, mFrame, false); ImageView icon = parent.findViewById(R.id.icon); TextView title = parent.findViewById(R.id.title); title.setText(current.getTitle()); - icon.setImageResource(current.getIcon().getEnabledStateResId(context)); + icon.setImageResource(current.getIcon().getEnabledStateResId(mMwmActivity)); mItemListener.onPrepareVisibleView(current, parent, icon, title); if (current == Item.MORE) mMoreItems = items; diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageView.java b/android/src/app/organicmaps/widget/placepage/PlacePageView.java index c1bb249856..6e9c2e1563 100644 --- a/android/src/app/organicmaps/widget/placepage/PlacePageView.java +++ b/android/src/app/organicmaps/widget/placepage/PlacePageView.java @@ -447,7 +447,7 @@ public class PlacePageView extends NestedScrollViewClickFixed public void initButtons(@NonNull ViewGroup buttons) { - mButtons = new PlacePageButtons(this, buttons, new PlacePageButtons.ItemListener() + mButtons = new PlacePageButtons(requireActivity(), buttons, new PlacePageButtons.ItemListener() { public void onPrepareVisibleView(@NonNull PlacePageButtons.PlacePageButton item, @NonNull View frame, @NonNull ImageView icon, -- 2.45.3 From 7f62e38996925d80f756dbd42b771e5f5bf9ab7a Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Wed, 28 Dec 2022 17:33:50 +0100 Subject: [PATCH 12/61] android: move place page buttons to fragment Signed-off-by: Arnaud Vergnet --- android/res/layout/activity_map.xml | 16 +- android/res/layout/pp_buttons_fragment.xml | 16 + android/res/values/styles-place_page.xml | 2 + android/src/app/organicmaps/MwmActivity.java | 13 +- .../widget/placepage/PlacePageButton.java | 40 ++ .../placepage/PlacePageButtonFactory.java | 71 +++ .../widget/placepage/PlacePageButtons.java | 458 +++++------------ .../placepage/PlacePageButtonsViewModel.java | 22 + .../widget/placepage/PlacePageController.java | 76 ++- .../widget/placepage/PlacePageView.java | 475 ++++++++---------- 10 files changed, 547 insertions(+), 642 deletions(-) create mode 100644 android/res/layout/pp_buttons_fragment.xml create mode 100644 android/src/app/organicmaps/widget/placepage/PlacePageButton.java create mode 100644 android/src/app/organicmaps/widget/placepage/PlacePageButtonFactory.java create mode 100644 android/src/app/organicmaps/widget/placepage/PlacePageButtonsViewModel.java diff --git a/android/res/layout/activity_map.xml b/android/res/layout/activity_map.xml index 5ff52639db..5a2ea417ea 100644 --- a/android/res/layout/activity_map.xml +++ b/android/res/layout/activity_map.xml @@ -58,18 +58,8 @@ android:layout_height="wrap_content" android:fillViewport="true" app:layout_behavior="@string/placepage_behavior" /> - - - - + android:layout_height="match_parent" /> diff --git a/android/res/layout/pp_buttons_fragment.xml b/android/res/layout/pp_buttons_fragment.xml new file mode 100644 index 0000000000..7a71087ebf --- /dev/null +++ b/android/res/layout/pp_buttons_fragment.xml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/android/res/values/styles-place_page.xml b/android/res/values/styles-place_page.xml index bdddaed873..5e89e69e44 100644 --- a/android/res/values/styles-place_page.xml +++ b/android/res/values/styles-place_page.xml @@ -6,6 +6,7 @@ center true 10sp + ?iconTint