diff --git a/.tx/config b/.tx/config index 3cf9489f6..cdae01013 100644 --- a/.tx/config +++ b/.tx/config @@ -7,6 +7,12 @@ source_file = lang/calamares_en.ts source_lang = en type = QT +[calamares.tz] +file_filter = lang/tz_.ts +source_file = lang/tz_en.ts +source_lang = en +type = QT + [calamares.dummypythonqt] file_filter = src/modules/dummypythonqt/lang//LC_MESSAGES/dummypythonqt.po source_file = src/modules/dummypythonqt/lang/dummypythonqt.pot diff --git a/CHANGES b/CHANGES index 1f721faca..712bdfeb1 100644 --- a/CHANGES +++ b/CHANGES @@ -9,10 +9,17 @@ This release contains contributions from (alphabetically by first name): - No other contributors this time around. ## Core ## - - No changes to core functionality. + - Timezone support code has migrated into the core of Calamares. This + means that modules now have easier access to timezone information. + Translations for timezones have also been enabled, so it is **possible** + at least to translate the displayed zones in the *welcome* module. ## Modules ## - - No changes to modules. + - The *license* module has seen a significant change to its looks. + Actions are now labeled more clearly, and the URL (or filename) + for each license is displayed. + - The *welcome* module now supports translations for timezone and + location names (e.g. "Berlin" is "Berlijn" in Dutch). # 3.2.17.1 (2019-12-02) # diff --git a/CMakeModules/CalamaresAddTranslations.cmake b/CMakeModules/CalamaresAddTranslations.cmake index 4892cc0f9..d74e4bdfb 100644 --- a/CMakeModules/CalamaresAddTranslations.cmake +++ b/CMakeModules/CalamaresAddTranslations.cmake @@ -67,8 +67,12 @@ macro(add_calamares_translations language) # calamares and qt language files set( calamares_i18n_qrc_content "${calamares_i18n_qrc_content}\n" ) foreach( lang ${CALAMARES_LANGUAGES} ) - set( calamares_i18n_qrc_content "${calamares_i18n_qrc_content}calamares_${lang}.qm\n" ) - list( APPEND TS_FILES "${CMAKE_SOURCE_DIR}/lang/calamares_${lang}.ts" ) + foreach( tlsource "calamares_${lang}" "tz_${lang}" ) + if( EXISTS "${CMAKE_SOURCE_DIR}/lang/${tlsource}.ts" ) + set( calamares_i18n_qrc_content "${calamares_i18n_qrc_content}${tlsource}.qm\n" ) + list( APPEND TS_FILES "${CMAKE_SOURCE_DIR}/lang/${tlsource}.ts" ) + endif() + endforeach() endforeach() set( calamares_i18n_qrc_content "${calamares_i18n_qrc_content}\n" ) diff --git a/ci/txpush.sh b/ci/txpush.sh index 890026417..954e0b4b1 100755 --- a/ci/txpush.sh +++ b/ci/txpush.sh @@ -50,12 +50,17 @@ fi # sources, then push to Transifex export QT_SELECT=5 +lupdate -version > /dev/null 2>&1 || export QT_SELECT=qt5 +lupdate -version > /dev/null 2>&1 || { echo "! No working lupdate" ; lupdate -version ; exit 1 ; } + # Don't pull branding translations in, # those are done separately. _srcdirs="src/calamares src/libcalamares src/libcalamaresui src/modules src/qml" -lupdate $_srcdirs -ts -no-obsolete lang/calamares_en.ts +lupdate -no-obsolete $_srcdirs -ts lang/calamares_en.ts +lupdate -no-obsolete -extensions cxxtr src/libcalamares/locale -ts lang/tz_en.ts tx push --source --no-interactive -r calamares.calamares-master +tx push --source --no-interactive -r calamares.tz tx push --source --no-interactive -r calamares.fdo ### PYTHON MODULES diff --git a/lang/tz_en.ts b/lang/tz_en.ts new file mode 100644 index 000000000..7e46eab3d --- /dev/null +++ b/lang/tz_en.ts @@ -0,0 +1,2617 @@ + + + + + QObject + + + Africa + tz_regions + + + + + America + tz_regions + + + + + Antarctica + tz_regions + + + + + Arctic + tz_regions + + + + + Asia + tz_regions + + + + + Atlantic + tz_regions + + + + + Australia + tz_regions + + + + + Europe + tz_regions + + + + + Indian + tz_regions + + + + + Pacific + tz_regions + + + + + Abidjan + tz_names + + + + + Accra + tz_names + + + + + Adak + tz_names + + + + + Addis Ababa + tz_names + + + + + Adelaide + tz_names + + + + + Aden + tz_names + + + + + Algiers + tz_names + + + + + Almaty + tz_names + + + + + Amman + tz_names + + + + + Amsterdam + tz_names + + + + + Anadyr + tz_names + + + + + Anchorage + tz_names + + + + + Andorra + tz_names + + + + + Anguilla + tz_names + + + + + Antananarivo + tz_names + + + + + Antigua + tz_names + + + + + Apia + tz_names + + + + + Aqtau + tz_names + + + + + Aqtobe + tz_names + + + + + Araguaina + tz_names + + + + + Argentina/Buenos Aires + tz_names + + + + + Argentina/Catamarca + tz_names + + + + + Argentina/Cordoba + tz_names + + + + + Argentina/Jujuy + tz_names + + + + + Argentina/La Rioja + tz_names + + + + + Argentina/Mendoza + tz_names + + + + + Argentina/Rio Gallegos + tz_names + + + + + Argentina/Salta + tz_names + + + + + Argentina/San Juan + tz_names + + + + + Argentina/San Luis + tz_names + + + + + Argentina/Tucuman + tz_names + + + + + Argentina/Ushuaia + tz_names + + + + + Aruba + tz_names + + + + + Ashgabat + tz_names + + + + + Asmara + tz_names + + + + + Astrakhan + tz_names + + + + + Asuncion + tz_names + + + + + Athens + tz_names + + + + + Atikokan + tz_names + + + + + Atyrau + tz_names + + + + + Auckland + tz_names + + + + + Azores + tz_names + + + + + Baghdad + tz_names + + + + + Bahia + tz_names + + + + + Bahia Banderas + tz_names + + + + + Bahrain + tz_names + + + + + Baku + tz_names + + + + + Bamako + tz_names + + + + + Bangkok + tz_names + + + + + Bangui + tz_names + + + + + Banjul + tz_names + + + + + Barbados + tz_names + + + + + Barnaul + tz_names + + + + + Beirut + tz_names + + + + + Belem + tz_names + + + + + Belgrade + tz_names + + + + + Belize + tz_names + + + + + Berlin + tz_names + + + + + Bermuda + tz_names + + + + + Bishkek + tz_names + + + + + Bissau + tz_names + + + + + Blanc-Sablon + tz_names + + + + + Blantyre + tz_names + + + + + Boa Vista + tz_names + + + + + Bogota + tz_names + + + + + Boise + tz_names + + + + + Bougainville + tz_names + + + + + Bratislava + tz_names + + + + + Brazzaville + tz_names + + + + + Brisbane + tz_names + + + + + Broken Hill + tz_names + + + + + Brunei + tz_names + + + + + Brussels + tz_names + + + + + Bucharest + tz_names + + + + + Budapest + tz_names + + + + + Bujumbura + tz_names + + + + + Busingen + tz_names + + + + + Cairo + tz_names + + + + + Cambridge Bay + tz_names + + + + + Campo Grande + tz_names + + + + + Canary + tz_names + + + + + Cancun + tz_names + + + + + Cape Verde + tz_names + + + + + Caracas + tz_names + + + + + Casablanca + tz_names + + + + + Casey + tz_names + + + + + Cayenne + tz_names + + + + + Cayman + tz_names + + + + + Ceuta + tz_names + + + + + Chagos + tz_names + + + + + Chatham + tz_names + + + + + Chicago + tz_names + + + + + Chihuahua + tz_names + + + + + Chisinau + tz_names + + + + + Chita + tz_names + + + + + Choibalsan + tz_names + + + + + Christmas + tz_names + + + + + Chuuk + tz_names + + + + + Cocos + tz_names + + + + + Colombo + tz_names + + + + + Comoro + tz_names + + + + + Conakry + tz_names + + + + + Copenhagen + tz_names + + + + + Costa Rica + tz_names + + + + + Creston + tz_names + + + + + Cuiaba + tz_names + + + + + Curacao + tz_names + + + + + Currie + tz_names + + + + + Dakar + tz_names + + + + + Damascus + tz_names + + + + + Danmarkshavn + tz_names + + + + + Dar es Salaam + tz_names + + + + + Darwin + tz_names + + + + + Davis + tz_names + + + + + Dawson + tz_names + + + + + Dawson Creek + tz_names + + + + + Denver + tz_names + + + + + Detroit + tz_names + + + + + Dhaka + tz_names + + + + + Dili + tz_names + + + + + Djibouti + tz_names + + + + + Dominica + tz_names + + + + + Douala + tz_names + + + + + Dubai + tz_names + + + + + Dublin + tz_names + + + + + DumontDUrville + tz_names + + + + + Dushanbe + tz_names + + + + + Easter + tz_names + + + + + Edmonton + tz_names + + + + + Efate + tz_names + + + + + Eirunepe + tz_names + + + + + El Aaiun + tz_names + + + + + El Salvador + tz_names + + + + + Enderbury + tz_names + + + + + Eucla + tz_names + + + + + Fakaofo + tz_names + + + + + Famagusta + tz_names + + + + + Faroe + tz_names + + + + + Fiji + tz_names + + + + + Fort Nelson + tz_names + + + + + Fortaleza + tz_names + + + + + Freetown + tz_names + + + + + Funafuti + tz_names + + + + + Gaborone + tz_names + + + + + Galapagos + tz_names + + + + + Gambier + tz_names + + + + + Gaza + tz_names + + + + + Gibraltar + tz_names + + + + + Glace Bay + tz_names + + + + + Godthab + tz_names + + + + + Goose Bay + tz_names + + + + + Grand Turk + tz_names + + + + + Grenada + tz_names + + + + + Guadalcanal + tz_names + + + + + Guadeloupe + tz_names + + + + + Guam + tz_names + + + + + Guatemala + tz_names + + + + + Guayaquil + tz_names + + + + + Guernsey + tz_names + + + + + Guyana + tz_names + + + + + Halifax + tz_names + + + + + Harare + tz_names + + + + + Havana + tz_names + + + + + Hebron + tz_names + + + + + Helsinki + tz_names + + + + + Hermosillo + tz_names + + + + + Ho Chi Minh + tz_names + + + + + Hobart + tz_names + + + + + Hong Kong + tz_names + + + + + Honolulu + tz_names + + + + + Hovd + tz_names + + + + + Indiana/Indianapolis + tz_names + + + + + Indiana/Knox + tz_names + + + + + Indiana/Marengo + tz_names + + + + + Indiana/Petersburg + tz_names + + + + + Indiana/Tell City + tz_names + + + + + Indiana/Vevay + tz_names + + + + + Indiana/Vincennes + tz_names + + + + + Indiana/Winamac + tz_names + + + + + Inuvik + tz_names + + + + + Iqaluit + tz_names + + + + + Irkutsk + tz_names + + + + + Isle of Man + tz_names + + + + + Istanbul + tz_names + + + + + Jakarta + tz_names + + + + + Jamaica + tz_names + + + + + Jayapura + tz_names + + + + + Jersey + tz_names + + + + + Jerusalem + tz_names + + + + + Johannesburg + tz_names + + + + + Juba + tz_names + + + + + Juneau + tz_names + + + + + Kabul + tz_names + + + + + Kaliningrad + tz_names + + + + + Kamchatka + tz_names + + + + + Kampala + tz_names + + + + + Karachi + tz_names + + + + + Kathmandu + tz_names + + + + + Kentucky/Louisville + tz_names + + + + + Kentucky/Monticello + tz_names + + + + + Kerguelen + tz_names + + + + + Khandyga + tz_names + + + + + Khartoum + tz_names + + + + + Kiev + tz_names + + + + + Kigali + tz_names + + + + + Kinshasa + tz_names + + + + + Kiritimati + tz_names + + + + + Kirov + tz_names + + + + + Kolkata + tz_names + + + + + Kosrae + tz_names + + + + + Kralendijk + tz_names + + + + + Krasnoyarsk + tz_names + + + + + Kuala Lumpur + tz_names + + + + + Kuching + tz_names + + + + + Kuwait + tz_names + + + + + Kwajalein + tz_names + + + + + La Paz + tz_names + + + + + Lagos + tz_names + + + + + Libreville + tz_names + + + + + Lima + tz_names + + + + + Lindeman + tz_names + + + + + Lisbon + tz_names + + + + + Ljubljana + tz_names + + + + + Lome + tz_names + + + + + London + tz_names + + + + + Longyearbyen + tz_names + + + + + Lord Howe + tz_names + + + + + Los Angeles + tz_names + + + + + Lower Princes + tz_names + + + + + Luanda + tz_names + + + + + Lubumbashi + tz_names + + + + + Lusaka + tz_names + + + + + Luxembourg + tz_names + + + + + Macau + tz_names + + + + + Maceio + tz_names + + + + + Macquarie + tz_names + + + + + Madeira + tz_names + + + + + Madrid + tz_names + + + + + Magadan + tz_names + + + + + Mahe + tz_names + + + + + Majuro + tz_names + + + + + Makassar + tz_names + + + + + Malabo + tz_names + + + + + Maldives + tz_names + + + + + Malta + tz_names + + + + + Managua + tz_names + + + + + Manaus + tz_names + + + + + Manila + tz_names + + + + + Maputo + tz_names + + + + + Mariehamn + tz_names + + + + + Marigot + tz_names + + + + + Marquesas + tz_names + + + + + Martinique + tz_names + + + + + Maseru + tz_names + + + + + Matamoros + tz_names + + + + + Mauritius + tz_names + + + + + Mawson + tz_names + + + + + Mayotte + tz_names + + + + + Mazatlan + tz_names + + + + + Mbabane + tz_names + + + + + McMurdo + tz_names + + + + + Melbourne + tz_names + + + + + Menominee + tz_names + + + + + Merida + tz_names + + + + + Metlakatla + tz_names + + + + + Mexico City + tz_names + + + + + Midway + tz_names + + + + + Minsk + tz_names + + + + + Miquelon + tz_names + + + + + Mogadishu + tz_names + + + + + Monaco + tz_names + + + + + Moncton + tz_names + + + + + Monrovia + tz_names + + + + + Monterrey + tz_names + + + + + Montevideo + tz_names + + + + + Montserrat + tz_names + + + + + Moscow + tz_names + + + + + Muscat + tz_names + + + + + Nairobi + tz_names + + + + + Nassau + tz_names + + + + + Nauru + tz_names + + + + + Ndjamena + tz_names + + + + + New York + tz_names + + + + + Niamey + tz_names + + + + + Nicosia + tz_names + + + + + Nipigon + tz_names + + + + + Niue + tz_names + + + + + Nome + tz_names + + + + + Norfolk + tz_names + + + + + Noronha + tz_names + + + + + North Dakota/Beulah + tz_names + + + + + North Dakota/Center + tz_names + + + + + North Dakota/New Salem + tz_names + + + + + Nouakchott + tz_names + + + + + Noumea + tz_names + + + + + Novokuznetsk + tz_names + + + + + Novosibirsk + tz_names + + + + + Ojinaga + tz_names + + + + + Omsk + tz_names + + + + + Oral + tz_names + + + + + Oslo + tz_names + + + + + Ouagadougou + tz_names + + + + + Pago Pago + tz_names + + + + + Palau + tz_names + + + + + Palmer + tz_names + + + + + Panama + tz_names + + + + + Pangnirtung + tz_names + + + + + Paramaribo + tz_names + + + + + Paris + tz_names + + + + + Perth + tz_names + + + + + Phnom Penh + tz_names + + + + + Phoenix + tz_names + + + + + Pitcairn + tz_names + + + + + Podgorica + tz_names + + + + + Pohnpei + tz_names + + + + + Pontianak + tz_names + + + + + Port Moresby + tz_names + + + + + Port of Spain + tz_names + + + + + Port-au-Prince + tz_names + + + + + Porto Velho + tz_names + + + + + Porto-Novo + tz_names + + + + + Prague + tz_names + + + + + Puerto Rico + tz_names + + + + + Punta Arenas + tz_names + + + + + Pyongyang + tz_names + + + + + Qatar + tz_names + + + + + Qostanay + tz_names + + + + + Qyzylorda + tz_names + + + + + Rainy River + tz_names + + + + + Rankin Inlet + tz_names + + + + + Rarotonga + tz_names + + + + + Recife + tz_names + + + + + Regina + tz_names + + + + + Resolute + tz_names + + + + + Reunion + tz_names + + + + + Reykjavik + tz_names + + + + + Riga + tz_names + + + + + Rio Branco + tz_names + + + + + Riyadh + tz_names + + + + + Rome + tz_names + + + + + Rothera + tz_names + + + + + Saipan + tz_names + + + + + Sakhalin + tz_names + + + + + Samara + tz_names + + + + + Samarkand + tz_names + + + + + San Marino + tz_names + + + + + Santarem + tz_names + + + + + Santiago + tz_names + + + + + Santo Domingo + tz_names + + + + + Sao Paulo + tz_names + + + + + Sao Tome + tz_names + + + + + Sarajevo + tz_names + + + + + Saratov + tz_names + + + + + Scoresbysund + tz_names + + + + + Seoul + tz_names + + + + + Shanghai + tz_names + + + + + Simferopol + tz_names + + + + + Singapore + tz_names + + + + + Sitka + tz_names + + + + + Skopje + tz_names + + + + + Sofia + tz_names + + + + + South Georgia + tz_names + + + + + Srednekolymsk + tz_names + + + + + St Barthelemy + tz_names + + + + + St Helena + tz_names + + + + + St Johns + tz_names + + + + + St Kitts + tz_names + + + + + St Lucia + tz_names + + + + + St Thomas + tz_names + + + + + St Vincent + tz_names + + + + + Stanley + tz_names + + + + + Stockholm + tz_names + + + + + Swift Current + tz_names + + + + + Sydney + tz_names + + + + + Syowa + tz_names + + + + + Tahiti + tz_names + + + + + Taipei + tz_names + + + + + Tallinn + tz_names + + + + + Tarawa + tz_names + + + + + Tashkent + tz_names + + + + + Tbilisi + tz_names + + + + + Tegucigalpa + tz_names + + + + + Tehran + tz_names + + + + + Thimphu + tz_names + + + + + Thule + tz_names + + + + + Thunder Bay + tz_names + + + + + Tijuana + tz_names + + + + + Tirane + tz_names + + + + + Tokyo + tz_names + + + + + Tomsk + tz_names + + + + + Tongatapu + tz_names + + + + + Toronto + tz_names + + + + + Tortola + tz_names + + + + + Tripoli + tz_names + + + + + Troll + tz_names + + + + + Tunis + tz_names + + + + + Ulaanbaatar + tz_names + + + + + Ulyanovsk + tz_names + + + + + Urumqi + tz_names + + + + + Ust-Nera + tz_names + + + + + Uzhgorod + tz_names + + + + + Vaduz + tz_names + + + + + Vancouver + tz_names + + + + + Vatican + tz_names + + + + + Vienna + tz_names + + + + + Vientiane + tz_names + + + + + Vilnius + tz_names + + + + + Vladivostok + tz_names + + + + + Volgograd + tz_names + + + + + Vostok + tz_names + + + + + Wake + tz_names + + + + + Wallis + tz_names + + + + + Warsaw + tz_names + + + + + Whitehorse + tz_names + + + + + Windhoek + tz_names + + + + + Winnipeg + tz_names + + + + + Yakutat + tz_names + + + + + Yakutsk + tz_names + + + + + Yangon + tz_names + + + + + Yekaterinburg + tz_names + + + + + Yellowknife + tz_names + + + + + Yerevan + tz_names + + + + + Zagreb + tz_names + + + + + Zaporozhye + tz_names + + + + + Zurich + tz_names + + + + diff --git a/lang/tz_nl.ts b/lang/tz_nl.ts new file mode 100644 index 000000000..e1eb8d1e5 --- /dev/null +++ b/lang/tz_nl.ts @@ -0,0 +1,2617 @@ + + + + + QObject + + + Africa + tz_regions + Afrika + + + + America + tz_regions + Amerika + + + + Antarctica + tz_regions + + + + + Arctic + tz_regions + + + + + Asia + tz_regions + Azië + + + + Atlantic + tz_regions + Atlantisch + + + + Australia + tz_regions + Australië + + + + Europe + tz_regions + Europa + + + + Indian + tz_regions + + + + + Pacific + tz_regions + Stille Oceaan + + + + Abidjan + tz_names + + + + + Accra + tz_names + + + + + Adak + tz_names + + + + + Addis Ababa + tz_names + + + + + Adelaide + tz_names + + + + + Aden + tz_names + + + + + Algiers + tz_names + + + + + Almaty + tz_names + + + + + Amman + tz_names + + + + + Amsterdam + tz_names + + + + + Anadyr + tz_names + + + + + Anchorage + tz_names + + + + + Andorra + tz_names + + + + + Anguilla + tz_names + + + + + Antananarivo + tz_names + + + + + Antigua + tz_names + + + + + Apia + tz_names + + + + + Aqtau + tz_names + + + + + Aqtobe + tz_names + + + + + Araguaina + tz_names + + + + + Argentina/Buenos Aires + tz_names + + + + + Argentina/Catamarca + tz_names + + + + + Argentina/Cordoba + tz_names + + + + + Argentina/Jujuy + tz_names + + + + + Argentina/La Rioja + tz_names + + + + + Argentina/Mendoza + tz_names + + + + + Argentina/Rio Gallegos + tz_names + + + + + Argentina/Salta + tz_names + + + + + Argentina/San Juan + tz_names + + + + + Argentina/San Luis + tz_names + + + + + Argentina/Tucuman + tz_names + + + + + Argentina/Ushuaia + tz_names + + + + + Aruba + tz_names + + + + + Ashgabat + tz_names + + + + + Asmara + tz_names + + + + + Astrakhan + tz_names + + + + + Asuncion + tz_names + + + + + Athens + tz_names + + + + + Atikokan + tz_names + + + + + Atyrau + tz_names + + + + + Auckland + tz_names + + + + + Azores + tz_names + + + + + Baghdad + tz_names + + + + + Bahia + tz_names + + + + + Bahia Banderas + tz_names + + + + + Bahrain + tz_names + + + + + Baku + tz_names + + + + + Bamako + tz_names + + + + + Bangkok + tz_names + + + + + Bangui + tz_names + + + + + Banjul + tz_names + + + + + Barbados + tz_names + + + + + Barnaul + tz_names + + + + + Beirut + tz_names + + + + + Belem + tz_names + + + + + Belgrade + tz_names + + + + + Belize + tz_names + + + + + Berlin + tz_names + Berlijn + + + + Bermuda + tz_names + + + + + Bishkek + tz_names + + + + + Bissau + tz_names + + + + + Blanc-Sablon + tz_names + + + + + Blantyre + tz_names + + + + + Boa Vista + tz_names + + + + + Bogota + tz_names + + + + + Boise + tz_names + + + + + Bougainville + tz_names + + + + + Bratislava + tz_names + + + + + Brazzaville + tz_names + + + + + Brisbane + tz_names + + + + + Broken Hill + tz_names + + + + + Brunei + tz_names + + + + + Brussels + tz_names + + + + + Bucharest + tz_names + + + + + Budapest + tz_names + + + + + Bujumbura + tz_names + + + + + Busingen + tz_names + + + + + Cairo + tz_names + + + + + Cambridge Bay + tz_names + + + + + Campo Grande + tz_names + + + + + Canary + tz_names + + + + + Cancun + tz_names + + + + + Cape Verde + tz_names + + + + + Caracas + tz_names + + + + + Casablanca + tz_names + + + + + Casey + tz_names + + + + + Cayenne + tz_names + + + + + Cayman + tz_names + + + + + Ceuta + tz_names + + + + + Chagos + tz_names + + + + + Chatham + tz_names + + + + + Chicago + tz_names + + + + + Chihuahua + tz_names + + + + + Chisinau + tz_names + + + + + Chita + tz_names + + + + + Choibalsan + tz_names + + + + + Christmas + tz_names + + + + + Chuuk + tz_names + + + + + Cocos + tz_names + + + + + Colombo + tz_names + + + + + Comoro + tz_names + + + + + Conakry + tz_names + + + + + Copenhagen + tz_names + + + + + Costa Rica + tz_names + + + + + Creston + tz_names + + + + + Cuiaba + tz_names + + + + + Curacao + tz_names + + + + + Currie + tz_names + + + + + Dakar + tz_names + + + + + Damascus + tz_names + + + + + Danmarkshavn + tz_names + + + + + Dar es Salaam + tz_names + + + + + Darwin + tz_names + + + + + Davis + tz_names + + + + + Dawson + tz_names + + + + + Dawson Creek + tz_names + + + + + Denver + tz_names + + + + + Detroit + tz_names + + + + + Dhaka + tz_names + + + + + Dili + tz_names + + + + + Djibouti + tz_names + + + + + Dominica + tz_names + + + + + Douala + tz_names + + + + + Dubai + tz_names + + + + + Dublin + tz_names + + + + + DumontDUrville + tz_names + + + + + Dushanbe + tz_names + + + + + Easter + tz_names + + + + + Edmonton + tz_names + + + + + Efate + tz_names + + + + + Eirunepe + tz_names + + + + + El Aaiun + tz_names + + + + + El Salvador + tz_names + + + + + Enderbury + tz_names + + + + + Eucla + tz_names + + + + + Fakaofo + tz_names + + + + + Famagusta + tz_names + + + + + Faroe + tz_names + + + + + Fiji + tz_names + + + + + Fort Nelson + tz_names + + + + + Fortaleza + tz_names + + + + + Freetown + tz_names + + + + + Funafuti + tz_names + + + + + Gaborone + tz_names + + + + + Galapagos + tz_names + + + + + Gambier + tz_names + + + + + Gaza + tz_names + + + + + Gibraltar + tz_names + + + + + Glace Bay + tz_names + + + + + Godthab + tz_names + + + + + Goose Bay + tz_names + + + + + Grand Turk + tz_names + + + + + Grenada + tz_names + + + + + Guadalcanal + tz_names + + + + + Guadeloupe + tz_names + + + + + Guam + tz_names + + + + + Guatemala + tz_names + + + + + Guayaquil + tz_names + + + + + Guernsey + tz_names + + + + + Guyana + tz_names + + + + + Halifax + tz_names + + + + + Harare + tz_names + + + + + Havana + tz_names + + + + + Hebron + tz_names + + + + + Helsinki + tz_names + + + + + Hermosillo + tz_names + + + + + Ho Chi Minh + tz_names + + + + + Hobart + tz_names + + + + + Hong Kong + tz_names + + + + + Honolulu + tz_names + + + + + Hovd + tz_names + + + + + Indiana/Indianapolis + tz_names + + + + + Indiana/Knox + tz_names + + + + + Indiana/Marengo + tz_names + + + + + Indiana/Petersburg + tz_names + + + + + Indiana/Tell City + tz_names + + + + + Indiana/Vevay + tz_names + + + + + Indiana/Vincennes + tz_names + + + + + Indiana/Winamac + tz_names + + + + + Inuvik + tz_names + + + + + Iqaluit + tz_names + + + + + Irkutsk + tz_names + + + + + Isle of Man + tz_names + + + + + Istanbul + tz_names + + + + + Jakarta + tz_names + + + + + Jamaica + tz_names + + + + + Jayapura + tz_names + + + + + Jersey + tz_names + + + + + Jerusalem + tz_names + + + + + Johannesburg + tz_names + + + + + Juba + tz_names + + + + + Juneau + tz_names + + + + + Kabul + tz_names + + + + + Kaliningrad + tz_names + + + + + Kamchatka + tz_names + + + + + Kampala + tz_names + + + + + Karachi + tz_names + + + + + Kathmandu + tz_names + + + + + Kentucky/Louisville + tz_names + + + + + Kentucky/Monticello + tz_names + + + + + Kerguelen + tz_names + + + + + Khandyga + tz_names + + + + + Khartoum + tz_names + + + + + Kiev + tz_names + + + + + Kigali + tz_names + + + + + Kinshasa + tz_names + + + + + Kiritimati + tz_names + + + + + Kirov + tz_names + + + + + Kolkata + tz_names + + + + + Kosrae + tz_names + + + + + Kralendijk + tz_names + + + + + Krasnoyarsk + tz_names + + + + + Kuala Lumpur + tz_names + + + + + Kuching + tz_names + + + + + Kuwait + tz_names + + + + + Kwajalein + tz_names + + + + + La Paz + tz_names + + + + + Lagos + tz_names + + + + + Libreville + tz_names + + + + + Lima + tz_names + + + + + Lindeman + tz_names + + + + + Lisbon + tz_names + + + + + Ljubljana + tz_names + + + + + Lome + tz_names + + + + + London + tz_names + + + + + Longyearbyen + tz_names + + + + + Lord Howe + tz_names + + + + + Los Angeles + tz_names + + + + + Lower Princes + tz_names + + + + + Luanda + tz_names + + + + + Lubumbashi + tz_names + + + + + Lusaka + tz_names + + + + + Luxembourg + tz_names + + + + + Macau + tz_names + + + + + Maceio + tz_names + + + + + Macquarie + tz_names + + + + + Madeira + tz_names + + + + + Madrid + tz_names + + + + + Magadan + tz_names + + + + + Mahe + tz_names + + + + + Majuro + tz_names + + + + + Makassar + tz_names + + + + + Malabo + tz_names + + + + + Maldives + tz_names + + + + + Malta + tz_names + + + + + Managua + tz_names + + + + + Manaus + tz_names + + + + + Manila + tz_names + + + + + Maputo + tz_names + + + + + Mariehamn + tz_names + + + + + Marigot + tz_names + + + + + Marquesas + tz_names + + + + + Martinique + tz_names + + + + + Maseru + tz_names + + + + + Matamoros + tz_names + + + + + Mauritius + tz_names + + + + + Mawson + tz_names + + + + + Mayotte + tz_names + + + + + Mazatlan + tz_names + + + + + Mbabane + tz_names + + + + + McMurdo + tz_names + + + + + Melbourne + tz_names + + + + + Menominee + tz_names + + + + + Merida + tz_names + + + + + Metlakatla + tz_names + + + + + Mexico City + tz_names + + + + + Midway + tz_names + + + + + Minsk + tz_names + + + + + Miquelon + tz_names + + + + + Mogadishu + tz_names + + + + + Monaco + tz_names + + + + + Moncton + tz_names + + + + + Monrovia + tz_names + + + + + Monterrey + tz_names + + + + + Montevideo + tz_names + + + + + Montserrat + tz_names + + + + + Moscow + tz_names + + + + + Muscat + tz_names + + + + + Nairobi + tz_names + + + + + Nassau + tz_names + + + + + Nauru + tz_names + + + + + Ndjamena + tz_names + + + + + New York + tz_names + + + + + Niamey + tz_names + + + + + Nicosia + tz_names + + + + + Nipigon + tz_names + + + + + Niue + tz_names + + + + + Nome + tz_names + + + + + Norfolk + tz_names + + + + + Noronha + tz_names + + + + + North Dakota/Beulah + tz_names + + + + + North Dakota/Center + tz_names + + + + + North Dakota/New Salem + tz_names + + + + + Nouakchott + tz_names + + + + + Noumea + tz_names + + + + + Novokuznetsk + tz_names + + + + + Novosibirsk + tz_names + + + + + Ojinaga + tz_names + + + + + Omsk + tz_names + + + + + Oral + tz_names + + + + + Oslo + tz_names + + + + + Ouagadougou + tz_names + + + + + Pago Pago + tz_names + + + + + Palau + tz_names + + + + + Palmer + tz_names + + + + + Panama + tz_names + + + + + Pangnirtung + tz_names + + + + + Paramaribo + tz_names + + + + + Paris + tz_names + Parijs + + + + Perth + tz_names + + + + + Phnom Penh + tz_names + + + + + Phoenix + tz_names + + + + + Pitcairn + tz_names + + + + + Podgorica + tz_names + + + + + Pohnpei + tz_names + + + + + Pontianak + tz_names + + + + + Port Moresby + tz_names + + + + + Port of Spain + tz_names + + + + + Port-au-Prince + tz_names + + + + + Porto Velho + tz_names + + + + + Porto-Novo + tz_names + + + + + Prague + tz_names + + + + + Puerto Rico + tz_names + + + + + Punta Arenas + tz_names + + + + + Pyongyang + tz_names + + + + + Qatar + tz_names + + + + + Qostanay + tz_names + + + + + Qyzylorda + tz_names + + + + + Rainy River + tz_names + + + + + Rankin Inlet + tz_names + + + + + Rarotonga + tz_names + + + + + Recife + tz_names + + + + + Regina + tz_names + + + + + Resolute + tz_names + + + + + Reunion + tz_names + + + + + Reykjavik + tz_names + + + + + Riga + tz_names + + + + + Rio Branco + tz_names + + + + + Riyadh + tz_names + + + + + Rome + tz_names + + + + + Rothera + tz_names + + + + + Saipan + tz_names + + + + + Sakhalin + tz_names + + + + + Samara + tz_names + + + + + Samarkand + tz_names + + + + + San Marino + tz_names + + + + + Santarem + tz_names + + + + + Santiago + tz_names + + + + + Santo Domingo + tz_names + + + + + Sao Paulo + tz_names + + + + + Sao Tome + tz_names + + + + + Sarajevo + tz_names + + + + + Saratov + tz_names + + + + + Scoresbysund + tz_names + + + + + Seoul + tz_names + + + + + Shanghai + tz_names + + + + + Simferopol + tz_names + + + + + Singapore + tz_names + + + + + Sitka + tz_names + + + + + Skopje + tz_names + + + + + Sofia + tz_names + + + + + South Georgia + tz_names + + + + + Srednekolymsk + tz_names + + + + + St Barthelemy + tz_names + + + + + St Helena + tz_names + + + + + St Johns + tz_names + + + + + St Kitts + tz_names + + + + + St Lucia + tz_names + + + + + St Thomas + tz_names + + + + + St Vincent + tz_names + + + + + Stanley + tz_names + + + + + Stockholm + tz_names + + + + + Swift Current + tz_names + + + + + Sydney + tz_names + + + + + Syowa + tz_names + + + + + Tahiti + tz_names + + + + + Taipei + tz_names + + + + + Tallinn + tz_names + + + + + Tarawa + tz_names + + + + + Tashkent + tz_names + + + + + Tbilisi + tz_names + + + + + Tegucigalpa + tz_names + + + + + Tehran + tz_names + + + + + Thimphu + tz_names + + + + + Thule + tz_names + + + + + Thunder Bay + tz_names + + + + + Tijuana + tz_names + + + + + Tirane + tz_names + + + + + Tokyo + tz_names + + + + + Tomsk + tz_names + + + + + Tongatapu + tz_names + + + + + Toronto + tz_names + + + + + Tortola + tz_names + + + + + Tripoli + tz_names + + + + + Troll + tz_names + + + + + Tunis + tz_names + + + + + Ulaanbaatar + tz_names + + + + + Ulyanovsk + tz_names + + + + + Urumqi + tz_names + + + + + Ust-Nera + tz_names + + + + + Uzhgorod + tz_names + + + + + Vaduz + tz_names + + + + + Vancouver + tz_names + + + + + Vatican + tz_names + + + + + Vienna + tz_names + + + + + Vientiane + tz_names + + + + + Vilnius + tz_names + + + + + Vladivostok + tz_names + + + + + Volgograd + tz_names + + + + + Vostok + tz_names + + + + + Wake + tz_names + + + + + Wallis + tz_names + + + + + Warsaw + tz_names + + + + + Whitehorse + tz_names + + + + + Windhoek + tz_names + + + + + Winnipeg + tz_names + + + + + Yakutat + tz_names + + + + + Yakutsk + tz_names + + + + + Yangon + tz_names + + + + + Yekaterinburg + tz_names + + + + + Yellowknife + tz_names + + + + + Yerevan + tz_names + + + + + Zagreb + tz_names + + + + + Zaporozhye + tz_names + + + + + Zurich + tz_names + + + + diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index f942dbde1..ffc2e20b6 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -34,6 +34,7 @@ set( libSources locale/Label.cpp locale/LabelModel.cpp locale/Lookup.cpp + locale/TimeZone.cpp locale/TranslatableConfiguration.cpp # Network service diff --git a/src/libcalamares/locale/CountryData_p.cpp b/src/libcalamares/locale/CountryData_p.cpp index f4736fa2e..4382950ec 100644 --- a/src/libcalamares/locale/CountryData_p.cpp +++ b/src/libcalamares/locale/CountryData_p.cpp @@ -15,6 +15,13 @@ * Conditions herein. */ +/* MODIFICATIONS + * + * Edited anyway: + * 20191211 India changed to AnyLanguage, since Hindi doesn't make sense. #1284 + * + */ + // BEGIN Generated from CLDR data // *INDENT-OFF* // clang-format off @@ -115,7 +122,7 @@ static const CountryData country_data_table[] = { { QLocale::Language::Spanish, QLocale::Country::CanaryIslands, 'I', 'C' }, { QLocale::Language::Indonesian, QLocale::Country::Indonesia, 'I', 'D' }, { QLocale::Language::Hebrew, QLocale::Country::Israel, 'I', 'L' }, -{ QLocale::Language::Hindi, QLocale::Country::India, 'I', 'N' }, +{ QLocale::Language::AnyLanguage, QLocale::Country::India, 'I', 'N' }, { QLocale::Language::Arabic, QLocale::Country::Iraq, 'I', 'Q' }, { QLocale::Language::Persian, QLocale::Country::Iran, 'I', 'R' }, { QLocale::Language::Icelandic, QLocale::Country::Iceland, 'I', 'S' }, diff --git a/src/libcalamares/locale/Tests.cpp b/src/libcalamares/locale/Tests.cpp index a9e5e7399..106a77b4c 100644 --- a/src/libcalamares/locale/Tests.cpp +++ b/src/libcalamares/locale/Tests.cpp @@ -19,6 +19,7 @@ #include "Tests.h" #include "locale/LabelModel.h" +#include "locale/TimeZone.h" #include "locale/TranslatableConfiguration.h" #include "CalamaresVersion.h" @@ -199,3 +200,55 @@ LocaleTests::testTranslatableConfig2() QVERIFY( ts3.isEmpty() ); QCOMPARE( ts3.count(), 1 ); // The empty string } + +void +LocaleTests::testSimpleZones() +{ + using namespace CalamaresUtils::Locale; + + { + TZRegion r; + QVERIFY( r.tr().isEmpty() ); + } + { + TZZone n; + QVERIFY( n.tr().isEmpty() ); + } + { + TZRegion r0( "xAmsterdam" ); + QCOMPARE( r0.tr(), QStringLiteral( "xAmsterdam" ) ); + TZRegion r1( r0 ); + QCOMPARE( r0.tr(), QStringLiteral( "xAmsterdam" ) ); + QCOMPARE( r1.tr(), QStringLiteral( "xAmsterdam" ) ); + TZRegion r2( std::move( r0 ) ); + QCOMPARE( r2.tr(), QStringLiteral( "xAmsterdam" ) ); + QCOMPARE( r0.tr(), QString() ); + } + { + TZZone r0( nullptr ); + QVERIFY( r0.tr().isEmpty() ); + TZZone r1( r0 ); + QVERIFY( r1.tr().isEmpty() ); + TZZone r2( std::move( r0 ) ); + QVERIFY( r2.tr().isEmpty() ); + } +} + +void +LocaleTests::testComplexZones() +{ + using namespace CalamaresUtils::Locale; + + { + TZZone r0( "America/New_York" ); + TZZone r1( "America/New York" ); + + QCOMPARE( r0.tr(), r1.tr() ); + QCOMPARE( r0.tr(), QStringLiteral( "America/New York" ) ); + } + { + TZZone r( "zxc,;*_vm" ); + QVERIFY( !r.tr().isEmpty() ); + QCOMPARE( r.tr(), QStringLiteral( "zxc,;* vm" ) ); // Only _ is special + } +} diff --git a/src/libcalamares/locale/Tests.h b/src/libcalamares/locale/Tests.h index c6949f3e4..96ee48b0b 100644 --- a/src/libcalamares/locale/Tests.h +++ b/src/libcalamares/locale/Tests.h @@ -36,6 +36,10 @@ private Q_SLOTS: void testTranslatableLanguages(); void testTranslatableConfig1(); void testTranslatableConfig2(); + + // TimeZone testing + void testSimpleZones(); + void testComplexZones(); }; #endif diff --git a/src/libcalamares/locale/TimeZone.cpp b/src/libcalamares/locale/TimeZone.cpp new file mode 100644 index 000000000..05aeaf885 --- /dev/null +++ b/src/libcalamares/locale/TimeZone.cpp @@ -0,0 +1,279 @@ +/* === This file is part of Calamares - === + * + * Copyright 2019, Adriaan de Groot + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#include "TimeZone.h" + +#include "utils/Logger.h" + +#include +#include +#include + +#include + +static const char TZ_DATA_FILE[] = "/usr/share/zoneinfo/zone.tab"; + +static double +getRightGeoLocation( QString str ) +{ + double sign = 1, num = 0.00; + + // Determine sign + if ( str.startsWith( '-' ) ) + { + sign = -1; + str.remove( 0, 1 ); + } + else if ( str.startsWith( '+' ) ) + { + str.remove( 0, 1 ); + } + + if ( str.length() == 4 || str.length() == 6 ) + { + num = str.mid( 0, 2 ).toDouble() + str.mid( 2, 2 ).toDouble() / 60.0; + } + else if ( str.length() == 5 || str.length() == 7 ) + { + num = str.mid( 0, 3 ).toDouble() + str.mid( 3, 2 ).toDouble() / 60.0; + } + + return sign * num; +} + + +namespace CalamaresUtils +{ +namespace Locale +{ + + +CStringPair::CStringPair( CStringPair&& t ) + : m_human( nullptr ) + , m_key() +{ + // My pointers are initialized to nullptr + std::swap( m_human, t.m_human ); + std::swap( m_key, t.m_key ); +} + +CStringPair::CStringPair( const CStringPair& t ) + : m_human( t.m_human ? strdup( t.m_human ) : nullptr ) + , m_key( t.m_key ) +{ +} + +/** @brief Massage an identifier into a human-readable form + * + * Makes a copy of @p s, caller must free() it. + */ +static char* +munge( const char* s ) +{ + char* t = strdup( s ); + if ( !t ) + { + return nullptr; + } + + // replace("_"," ") in the Python script + char* p = t; + while ( *p ) + { + if ( ( *p ) == '_' ) + { + *p = ' '; + } + ++p; + } + + return t; +} + +CStringPair::CStringPair( const char* s1 ) + : m_human( s1 ? munge( s1 ) : nullptr ) + , m_key( s1 ? QString( s1 ) : QString() ) +{ +} + + +CStringPair::~CStringPair() +{ + free( m_human ); +} + + +QString +TZRegion::tr() const +{ + // NOTE: context name must match what's used in zone-extractor.py + return QObject::tr( m_human, "tz_regions" ); +} + +TZRegion::~TZRegion() +{ + qDeleteAll( m_zones ); +} + +const CStringPairList& +TZRegion::fromZoneTab() +{ + static CStringPairList zoneTab = TZRegion::fromFile( TZ_DATA_FILE ); + return zoneTab; +} + +CStringPairList +TZRegion::fromFile( const char* fileName ) +{ + CStringPairList model; + + QFile file( fileName ); + if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) + { + return model; + } + + TZRegion* thisRegion = nullptr; + QTextStream in( &file ); + while ( !in.atEnd() ) + { + QString line = in.readLine().trimmed().split( '#', QString::KeepEmptyParts ).first().trimmed(); + if ( line.isEmpty() ) + { + continue; + } + + QStringList list = line.split( QRegExp( "[\t ]" ), QString::SkipEmptyParts ); + if ( list.size() < 3 ) + { + continue; + } + + QStringList timezoneParts = list.at( 2 ).split( '/', QString::SkipEmptyParts ); + if ( timezoneParts.size() < 2 ) + { + continue; + } + + QString region = timezoneParts.first().trimmed(); + ; + if ( region.isEmpty() ) + { + continue; + } + + auto keyMatch = [®ion]( const CStringPair* r ) { return r->key() == region; }; + auto it = std::find_if( model.begin(), model.end(), keyMatch ); + if ( it != model.end() ) + { + thisRegion = dynamic_cast< TZRegion* >( *it ); + } + else + { + thisRegion = new TZRegion( region.toUtf8().data() ); + model.append( thisRegion ); + } + + QString countryCode = list.at( 0 ).trimmed(); + if ( countryCode.size() != 2 ) + { + continue; + } + + timezoneParts.removeFirst(); + thisRegion->m_zones.append( + new TZZone( region, timezoneParts.join( '/' ).toUtf8().constData(), countryCode, list.at( 1 ) ) ); + } + + auto sorter = []( const CStringPair* l, const CStringPair* r ) { return *l < *r; }; + std::sort( model.begin(), model.end(), sorter ); + for ( auto& it : model ) + { + TZRegion* r = dynamic_cast< TZRegion* >( it ); + if ( r ) + { + std::sort( r->m_zones.begin(), r->m_zones.end(), sorter ); + } + } + + return model; +} + +TZZone::TZZone( const QString& region, const char* zoneName, const QString& country, QString position ) + : CStringPair( zoneName ) + , m_region( region ) + , m_country( country ) +{ + int cooSplitPos = position.indexOf( QRegExp( "[-+]" ), 1 ); + if ( cooSplitPos > 0 ) + { + m_latitude = getRightGeoLocation( position.mid( 0, cooSplitPos ) ); + m_longitude = getRightGeoLocation( position.mid( cooSplitPos ) ); + } +} + +QString +TZZone::tr() const +{ + // NOTE: context name must match what's used in zone-extractor.py + return QObject::tr( m_human, "tz_names" ); +} + + +CStringListModel::CStringListModel( CStringPairList l ) + : m_list( l ) +{ +} + +CStringListModel::~CStringListModel() {} + +int +CStringListModel::rowCount( const QModelIndex& parent ) const +{ + return m_list.count(); +} + +QVariant +CStringListModel::data( const QModelIndex& index, int role ) const +{ + if ( ( role != Qt::DisplayRole ) && ( role != Qt::UserRole ) ) + { + return QVariant(); + } + + if ( !index.isValid() ) + { + return QVariant(); + } + + const auto* item = m_list.at( index.row() ); + return item ? ( role == Qt::DisplayRole ? item->tr() : item->key() ) : QVariant(); +} + +const CStringPair* +CStringListModel::item( int index ) const +{ + if ( ( index < 0 ) || ( index >= m_list.count() ) ) + { + return nullptr; + } + return m_list[ index ]; +} + +} // namespace Locale +} // namespace CalamaresUtils diff --git a/src/libcalamares/locale/TimeZone.h b/src/libcalamares/locale/TimeZone.h new file mode 100644 index 000000000..567b42241 --- /dev/null +++ b/src/libcalamares/locale/TimeZone.h @@ -0,0 +1,159 @@ +/* === This file is part of Calamares - === + * + * Copyright 2019, Adriaan de Groot + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#ifndef LOCALE_TIMEZONE_H +#define LOCALE_TIMEZONE_H + +#include "DllMacro.h" + +#include "utils/Logger.h" + +#include +#include +#include + +#include + +namespace CalamaresUtils +{ +namespace Locale +{ + +/** @brief A pair of strings, one human-readable, one a key + * + * Given an identifier-like string (e.g. "New_York"), makes + * a human-readable version of that and keeps a copy of the + * identifier itself. + * + * This explicitly uses const char* instead of just being + * QPair because there is API that needs + * C-style strings. + */ +class CStringPair +{ +public: + /// @brief An empty pair + CStringPair() {}; + /// @brief Given an identifier, create the pair + explicit CStringPair( const char* s1 ); + CStringPair( CStringPair&& t ); + CStringPair( const CStringPair& ); + virtual ~CStringPair(); + + /// @brief Give the localized human-readable form + virtual QString tr() const = 0; + QString key() const { return m_key; } + + bool operator<( const CStringPair& other ) const { return m_key < other.m_key; } + +protected: + char* m_human = nullptr; + QString m_key; +}; + +class CStringPairList : public QList< CStringPair* > +{ +public: + template < typename T > + T* find( const QString& key ) const + { + for ( auto* p : *this ) + { + if ( p->key() == key ) + { + return dynamic_cast< T* >( p ); + } + } + return nullptr; + } +}; + +/// @brief A pair of strings for timezone regions (e.g. "America") +class TZRegion : public CStringPair +{ +public: + using CStringPair::CStringPair; + virtual ~TZRegion(); + QString tr() const override; + + QString region() const { return key(); } + + /** @brief Create list from a zone.tab-like file + * + * Returns a list of all the regions; each region has a list + * of zones within that region. Dyamically, the items in the + * returned list are TZRegions; their zones dynamically are + * TZZones even though all those lists have type CStringPairList. + * + * The list owns the regions, and the regions own their own list of zones. + * When getting rid of the list, remember to qDeleteAll() on it. + */ + static CStringPairList fromFile( const char* fileName ); + /// @brief Calls fromFile with the standard zone.tab name + static const CStringPairList& fromZoneTab(); + + const CStringPairList& zones() const { return m_zones; } + +private: + CStringPairList m_zones; +}; + +/// @brief A pair of strings for specific timezone names (e.g. "New_York") +class TZZone : public CStringPair +{ +public: + using CStringPair::CStringPair; + QString tr() const override; + + TZZone( const QString& region, const char* zoneName, const QString& country, QString position ); + + QString region() const { return m_region; } + QString zone() const { return key(); } + QString country() const { return m_country; } + double latitude() const { return m_latitude; } + double longitude() const { return m_longitude; } + +protected: + QString m_region; + QString m_country; + double m_latitude = 0.0, m_longitude = 0.0; +}; + +class CStringListModel : public QAbstractListModel +{ +public: + /// @brief Create empty model + CStringListModel(); + /// @brief Create model from list (non-owning) + CStringListModel( CStringPairList ); + virtual ~CStringListModel() override; + + int rowCount( const QModelIndex& parent ) const override; + + QVariant data( const QModelIndex& index, int role ) const override; + + const CStringPair* item( int index ) const; + +private: + CStringPairList m_list; +}; + +} // namespace Locale +} // namespace CalamaresUtils + +#endif // LOCALE_TIMEZONE_H diff --git a/src/libcalamares/locale/ZoneData_p.cxxtr b/src/libcalamares/locale/ZoneData_p.cxxtr new file mode 100644 index 000000000..b73d17ad3 --- /dev/null +++ b/src/libcalamares/locale/ZoneData_p.cxxtr @@ -0,0 +1,478 @@ +/* GENERATED FILE DO NOT EDIT +* +* === This file is part of Calamares - === +* +* This file is derived from zone.tab, which has its own copyright statement: +* +* This file is in the public domain, so clarified as of +* 2009-05-17 by Arthur David Olson. +* +* From Paul Eggert (2018-06-27): +* This file is intended as a backward-compatibility aid for older programs. +* New programs should use zone1970.tab. This file is like zone1970.tab (see +* zone1970.tab's comments), but with the following additional restrictions: +* +* 1. This file contains only ASCII characters. +* 2. The first data column contains exactly one country code. +* +*/ + +/** THIS FILE EXISTS ONLY FOR TRANSLATIONS PURPOSES **/ + +// *INDENT-OFF* +// clang-format off +/* This returns a reference to local, which is a terrible idea. + * Good thing it's not meant to be compiled. + */ +static const QStringList& tz_regions_table() +{ + return QStringList { + QObject::tr("Africa", "tz_regions"), + QObject::tr("America", "tz_regions"), + QObject::tr("Antarctica", "tz_regions"), + QObject::tr("Arctic", "tz_regions"), + QObject::tr("Asia", "tz_regions"), + QObject::tr("Atlantic", "tz_regions"), + QObject::tr("Australia", "tz_regions"), + QObject::tr("Europe", "tz_regions"), + QObject::tr("Indian", "tz_regions"), + QObject::tr("Pacific", "tz_regions"), + QString() + }; +} + +/* This returns a reference to local, which is a terrible idea. + * Good thing it's not meant to be compiled. + */ +static const QStringList& tz_names_table() +{ + return QStringList { + QObject::tr("Abidjan", "tz_names"), + QObject::tr("Accra", "tz_names"), + QObject::tr("Adak", "tz_names"), + QObject::tr("Addis Ababa", "tz_names"), + QObject::tr("Adelaide", "tz_names"), + QObject::tr("Aden", "tz_names"), + QObject::tr("Algiers", "tz_names"), + QObject::tr("Almaty", "tz_names"), + QObject::tr("Amman", "tz_names"), + QObject::tr("Amsterdam", "tz_names"), + QObject::tr("Anadyr", "tz_names"), + QObject::tr("Anchorage", "tz_names"), + QObject::tr("Andorra", "tz_names"), + QObject::tr("Anguilla", "tz_names"), + QObject::tr("Antananarivo", "tz_names"), + QObject::tr("Antigua", "tz_names"), + QObject::tr("Apia", "tz_names"), + QObject::tr("Aqtau", "tz_names"), + QObject::tr("Aqtobe", "tz_names"), + QObject::tr("Araguaina", "tz_names"), + QObject::tr("Argentina/Buenos Aires", "tz_names"), + QObject::tr("Argentina/Catamarca", "tz_names"), + QObject::tr("Argentina/Cordoba", "tz_names"), + QObject::tr("Argentina/Jujuy", "tz_names"), + QObject::tr("Argentina/La Rioja", "tz_names"), + QObject::tr("Argentina/Mendoza", "tz_names"), + QObject::tr("Argentina/Rio Gallegos", "tz_names"), + QObject::tr("Argentina/Salta", "tz_names"), + QObject::tr("Argentina/San Juan", "tz_names"), + QObject::tr("Argentina/San Luis", "tz_names"), + QObject::tr("Argentina/Tucuman", "tz_names"), + QObject::tr("Argentina/Ushuaia", "tz_names"), + QObject::tr("Aruba", "tz_names"), + QObject::tr("Ashgabat", "tz_names"), + QObject::tr("Asmara", "tz_names"), + QObject::tr("Astrakhan", "tz_names"), + QObject::tr("Asuncion", "tz_names"), + QObject::tr("Athens", "tz_names"), + QObject::tr("Atikokan", "tz_names"), + QObject::tr("Atyrau", "tz_names"), + QObject::tr("Auckland", "tz_names"), + QObject::tr("Azores", "tz_names"), + QObject::tr("Baghdad", "tz_names"), + QObject::tr("Bahia", "tz_names"), + QObject::tr("Bahia Banderas", "tz_names"), + QObject::tr("Bahrain", "tz_names"), + QObject::tr("Baku", "tz_names"), + QObject::tr("Bamako", "tz_names"), + QObject::tr("Bangkok", "tz_names"), + QObject::tr("Bangui", "tz_names"), + QObject::tr("Banjul", "tz_names"), + QObject::tr("Barbados", "tz_names"), + QObject::tr("Barnaul", "tz_names"), + QObject::tr("Beirut", "tz_names"), + QObject::tr("Belem", "tz_names"), + QObject::tr("Belgrade", "tz_names"), + QObject::tr("Belize", "tz_names"), + QObject::tr("Berlin", "tz_names"), + QObject::tr("Bermuda", "tz_names"), + QObject::tr("Bishkek", "tz_names"), + QObject::tr("Bissau", "tz_names"), + QObject::tr("Blanc-Sablon", "tz_names"), + QObject::tr("Blantyre", "tz_names"), + QObject::tr("Boa Vista", "tz_names"), + QObject::tr("Bogota", "tz_names"), + QObject::tr("Boise", "tz_names"), + QObject::tr("Bougainville", "tz_names"), + QObject::tr("Bratislava", "tz_names"), + QObject::tr("Brazzaville", "tz_names"), + QObject::tr("Brisbane", "tz_names"), + QObject::tr("Broken Hill", "tz_names"), + QObject::tr("Brunei", "tz_names"), + QObject::tr("Brussels", "tz_names"), + QObject::tr("Bucharest", "tz_names"), + QObject::tr("Budapest", "tz_names"), + QObject::tr("Bujumbura", "tz_names"), + QObject::tr("Busingen", "tz_names"), + QObject::tr("Cairo", "tz_names"), + QObject::tr("Cambridge Bay", "tz_names"), + QObject::tr("Campo Grande", "tz_names"), + QObject::tr("Canary", "tz_names"), + QObject::tr("Cancun", "tz_names"), + QObject::tr("Cape Verde", "tz_names"), + QObject::tr("Caracas", "tz_names"), + QObject::tr("Casablanca", "tz_names"), + QObject::tr("Casey", "tz_names"), + QObject::tr("Cayenne", "tz_names"), + QObject::tr("Cayman", "tz_names"), + QObject::tr("Ceuta", "tz_names"), + QObject::tr("Chagos", "tz_names"), + QObject::tr("Chatham", "tz_names"), + QObject::tr("Chicago", "tz_names"), + QObject::tr("Chihuahua", "tz_names"), + QObject::tr("Chisinau", "tz_names"), + QObject::tr("Chita", "tz_names"), + QObject::tr("Choibalsan", "tz_names"), + QObject::tr("Christmas", "tz_names"), + QObject::tr("Chuuk", "tz_names"), + QObject::tr("Cocos", "tz_names"), + QObject::tr("Colombo", "tz_names"), + QObject::tr("Comoro", "tz_names"), + QObject::tr("Conakry", "tz_names"), + QObject::tr("Copenhagen", "tz_names"), + QObject::tr("Costa Rica", "tz_names"), + QObject::tr("Creston", "tz_names"), + QObject::tr("Cuiaba", "tz_names"), + QObject::tr("Curacao", "tz_names"), + QObject::tr("Currie", "tz_names"), + QObject::tr("Dakar", "tz_names"), + QObject::tr("Damascus", "tz_names"), + QObject::tr("Danmarkshavn", "tz_names"), + QObject::tr("Dar es Salaam", "tz_names"), + QObject::tr("Darwin", "tz_names"), + QObject::tr("Davis", "tz_names"), + QObject::tr("Dawson", "tz_names"), + QObject::tr("Dawson Creek", "tz_names"), + QObject::tr("Denver", "tz_names"), + QObject::tr("Detroit", "tz_names"), + QObject::tr("Dhaka", "tz_names"), + QObject::tr("Dili", "tz_names"), + QObject::tr("Djibouti", "tz_names"), + QObject::tr("Dominica", "tz_names"), + QObject::tr("Douala", "tz_names"), + QObject::tr("Dubai", "tz_names"), + QObject::tr("Dublin", "tz_names"), + QObject::tr("DumontDUrville", "tz_names"), + QObject::tr("Dushanbe", "tz_names"), + QObject::tr("Easter", "tz_names"), + QObject::tr("Edmonton", "tz_names"), + QObject::tr("Efate", "tz_names"), + QObject::tr("Eirunepe", "tz_names"), + QObject::tr("El Aaiun", "tz_names"), + QObject::tr("El Salvador", "tz_names"), + QObject::tr("Enderbury", "tz_names"), + QObject::tr("Eucla", "tz_names"), + QObject::tr("Fakaofo", "tz_names"), + QObject::tr("Famagusta", "tz_names"), + QObject::tr("Faroe", "tz_names"), + QObject::tr("Fiji", "tz_names"), + QObject::tr("Fort Nelson", "tz_names"), + QObject::tr("Fortaleza", "tz_names"), + QObject::tr("Freetown", "tz_names"), + QObject::tr("Funafuti", "tz_names"), + QObject::tr("Gaborone", "tz_names"), + QObject::tr("Galapagos", "tz_names"), + QObject::tr("Gambier", "tz_names"), + QObject::tr("Gaza", "tz_names"), + QObject::tr("Gibraltar", "tz_names"), + QObject::tr("Glace Bay", "tz_names"), + QObject::tr("Godthab", "tz_names"), + QObject::tr("Goose Bay", "tz_names"), + QObject::tr("Grand Turk", "tz_names"), + QObject::tr("Grenada", "tz_names"), + QObject::tr("Guadalcanal", "tz_names"), + QObject::tr("Guadeloupe", "tz_names"), + QObject::tr("Guam", "tz_names"), + QObject::tr("Guatemala", "tz_names"), + QObject::tr("Guayaquil", "tz_names"), + QObject::tr("Guernsey", "tz_names"), + QObject::tr("Guyana", "tz_names"), + QObject::tr("Halifax", "tz_names"), + QObject::tr("Harare", "tz_names"), + QObject::tr("Havana", "tz_names"), + QObject::tr("Hebron", "tz_names"), + QObject::tr("Helsinki", "tz_names"), + QObject::tr("Hermosillo", "tz_names"), + QObject::tr("Ho Chi Minh", "tz_names"), + QObject::tr("Hobart", "tz_names"), + QObject::tr("Hong Kong", "tz_names"), + QObject::tr("Honolulu", "tz_names"), + QObject::tr("Hovd", "tz_names"), + QObject::tr("Indiana/Indianapolis", "tz_names"), + QObject::tr("Indiana/Knox", "tz_names"), + QObject::tr("Indiana/Marengo", "tz_names"), + QObject::tr("Indiana/Petersburg", "tz_names"), + QObject::tr("Indiana/Tell City", "tz_names"), + QObject::tr("Indiana/Vevay", "tz_names"), + QObject::tr("Indiana/Vincennes", "tz_names"), + QObject::tr("Indiana/Winamac", "tz_names"), + QObject::tr("Inuvik", "tz_names"), + QObject::tr("Iqaluit", "tz_names"), + QObject::tr("Irkutsk", "tz_names"), + QObject::tr("Isle of Man", "tz_names"), + QObject::tr("Istanbul", "tz_names"), + QObject::tr("Jakarta", "tz_names"), + QObject::tr("Jamaica", "tz_names"), + QObject::tr("Jayapura", "tz_names"), + QObject::tr("Jersey", "tz_names"), + QObject::tr("Jerusalem", "tz_names"), + QObject::tr("Johannesburg", "tz_names"), + QObject::tr("Juba", "tz_names"), + QObject::tr("Juneau", "tz_names"), + QObject::tr("Kabul", "tz_names"), + QObject::tr("Kaliningrad", "tz_names"), + QObject::tr("Kamchatka", "tz_names"), + QObject::tr("Kampala", "tz_names"), + QObject::tr("Karachi", "tz_names"), + QObject::tr("Kathmandu", "tz_names"), + QObject::tr("Kentucky/Louisville", "tz_names"), + QObject::tr("Kentucky/Monticello", "tz_names"), + QObject::tr("Kerguelen", "tz_names"), + QObject::tr("Khandyga", "tz_names"), + QObject::tr("Khartoum", "tz_names"), + QObject::tr("Kiev", "tz_names"), + QObject::tr("Kigali", "tz_names"), + QObject::tr("Kinshasa", "tz_names"), + QObject::tr("Kiritimati", "tz_names"), + QObject::tr("Kirov", "tz_names"), + QObject::tr("Kolkata", "tz_names"), + QObject::tr("Kosrae", "tz_names"), + QObject::tr("Kralendijk", "tz_names"), + QObject::tr("Krasnoyarsk", "tz_names"), + QObject::tr("Kuala Lumpur", "tz_names"), + QObject::tr("Kuching", "tz_names"), + QObject::tr("Kuwait", "tz_names"), + QObject::tr("Kwajalein", "tz_names"), + QObject::tr("La Paz", "tz_names"), + QObject::tr("Lagos", "tz_names"), + QObject::tr("Libreville", "tz_names"), + QObject::tr("Lima", "tz_names"), + QObject::tr("Lindeman", "tz_names"), + QObject::tr("Lisbon", "tz_names"), + QObject::tr("Ljubljana", "tz_names"), + QObject::tr("Lome", "tz_names"), + QObject::tr("London", "tz_names"), + QObject::tr("Longyearbyen", "tz_names"), + QObject::tr("Lord Howe", "tz_names"), + QObject::tr("Los Angeles", "tz_names"), + QObject::tr("Lower Princes", "tz_names"), + QObject::tr("Luanda", "tz_names"), + QObject::tr("Lubumbashi", "tz_names"), + QObject::tr("Lusaka", "tz_names"), + QObject::tr("Luxembourg", "tz_names"), + QObject::tr("Macau", "tz_names"), + QObject::tr("Maceio", "tz_names"), + QObject::tr("Macquarie", "tz_names"), + QObject::tr("Madeira", "tz_names"), + QObject::tr("Madrid", "tz_names"), + QObject::tr("Magadan", "tz_names"), + QObject::tr("Mahe", "tz_names"), + QObject::tr("Majuro", "tz_names"), + QObject::tr("Makassar", "tz_names"), + QObject::tr("Malabo", "tz_names"), + QObject::tr("Maldives", "tz_names"), + QObject::tr("Malta", "tz_names"), + QObject::tr("Managua", "tz_names"), + QObject::tr("Manaus", "tz_names"), + QObject::tr("Manila", "tz_names"), + QObject::tr("Maputo", "tz_names"), + QObject::tr("Mariehamn", "tz_names"), + QObject::tr("Marigot", "tz_names"), + QObject::tr("Marquesas", "tz_names"), + QObject::tr("Martinique", "tz_names"), + QObject::tr("Maseru", "tz_names"), + QObject::tr("Matamoros", "tz_names"), + QObject::tr("Mauritius", "tz_names"), + QObject::tr("Mawson", "tz_names"), + QObject::tr("Mayotte", "tz_names"), + QObject::tr("Mazatlan", "tz_names"), + QObject::tr("Mbabane", "tz_names"), + QObject::tr("McMurdo", "tz_names"), + QObject::tr("Melbourne", "tz_names"), + QObject::tr("Menominee", "tz_names"), + QObject::tr("Merida", "tz_names"), + QObject::tr("Metlakatla", "tz_names"), + QObject::tr("Mexico City", "tz_names"), + QObject::tr("Midway", "tz_names"), + QObject::tr("Minsk", "tz_names"), + QObject::tr("Miquelon", "tz_names"), + QObject::tr("Mogadishu", "tz_names"), + QObject::tr("Monaco", "tz_names"), + QObject::tr("Moncton", "tz_names"), + QObject::tr("Monrovia", "tz_names"), + QObject::tr("Monterrey", "tz_names"), + QObject::tr("Montevideo", "tz_names"), + QObject::tr("Montserrat", "tz_names"), + QObject::tr("Moscow", "tz_names"), + QObject::tr("Muscat", "tz_names"), + QObject::tr("Nairobi", "tz_names"), + QObject::tr("Nassau", "tz_names"), + QObject::tr("Nauru", "tz_names"), + QObject::tr("Ndjamena", "tz_names"), + QObject::tr("New York", "tz_names"), + QObject::tr("Niamey", "tz_names"), + QObject::tr("Nicosia", "tz_names"), + QObject::tr("Nipigon", "tz_names"), + QObject::tr("Niue", "tz_names"), + QObject::tr("Nome", "tz_names"), + QObject::tr("Norfolk", "tz_names"), + QObject::tr("Noronha", "tz_names"), + QObject::tr("North Dakota/Beulah", "tz_names"), + QObject::tr("North Dakota/Center", "tz_names"), + QObject::tr("North Dakota/New Salem", "tz_names"), + QObject::tr("Nouakchott", "tz_names"), + QObject::tr("Noumea", "tz_names"), + QObject::tr("Novokuznetsk", "tz_names"), + QObject::tr("Novosibirsk", "tz_names"), + QObject::tr("Ojinaga", "tz_names"), + QObject::tr("Omsk", "tz_names"), + QObject::tr("Oral", "tz_names"), + QObject::tr("Oslo", "tz_names"), + QObject::tr("Ouagadougou", "tz_names"), + QObject::tr("Pago Pago", "tz_names"), + QObject::tr("Palau", "tz_names"), + QObject::tr("Palmer", "tz_names"), + QObject::tr("Panama", "tz_names"), + QObject::tr("Pangnirtung", "tz_names"), + QObject::tr("Paramaribo", "tz_names"), + QObject::tr("Paris", "tz_names"), + QObject::tr("Perth", "tz_names"), + QObject::tr("Phnom Penh", "tz_names"), + QObject::tr("Phoenix", "tz_names"), + QObject::tr("Pitcairn", "tz_names"), + QObject::tr("Podgorica", "tz_names"), + QObject::tr("Pohnpei", "tz_names"), + QObject::tr("Pontianak", "tz_names"), + QObject::tr("Port Moresby", "tz_names"), + QObject::tr("Port of Spain", "tz_names"), + QObject::tr("Port-au-Prince", "tz_names"), + QObject::tr("Porto Velho", "tz_names"), + QObject::tr("Porto-Novo", "tz_names"), + QObject::tr("Prague", "tz_names"), + QObject::tr("Puerto Rico", "tz_names"), + QObject::tr("Punta Arenas", "tz_names"), + QObject::tr("Pyongyang", "tz_names"), + QObject::tr("Qatar", "tz_names"), + QObject::tr("Qostanay", "tz_names"), + QObject::tr("Qyzylorda", "tz_names"), + QObject::tr("Rainy River", "tz_names"), + QObject::tr("Rankin Inlet", "tz_names"), + QObject::tr("Rarotonga", "tz_names"), + QObject::tr("Recife", "tz_names"), + QObject::tr("Regina", "tz_names"), + QObject::tr("Resolute", "tz_names"), + QObject::tr("Reunion", "tz_names"), + QObject::tr("Reykjavik", "tz_names"), + QObject::tr("Riga", "tz_names"), + QObject::tr("Rio Branco", "tz_names"), + QObject::tr("Riyadh", "tz_names"), + QObject::tr("Rome", "tz_names"), + QObject::tr("Rothera", "tz_names"), + QObject::tr("Saipan", "tz_names"), + QObject::tr("Sakhalin", "tz_names"), + QObject::tr("Samara", "tz_names"), + QObject::tr("Samarkand", "tz_names"), + QObject::tr("San Marino", "tz_names"), + QObject::tr("Santarem", "tz_names"), + QObject::tr("Santiago", "tz_names"), + QObject::tr("Santo Domingo", "tz_names"), + QObject::tr("Sao Paulo", "tz_names"), + QObject::tr("Sao Tome", "tz_names"), + QObject::tr("Sarajevo", "tz_names"), + QObject::tr("Saratov", "tz_names"), + QObject::tr("Scoresbysund", "tz_names"), + QObject::tr("Seoul", "tz_names"), + QObject::tr("Shanghai", "tz_names"), + QObject::tr("Simferopol", "tz_names"), + QObject::tr("Singapore", "tz_names"), + QObject::tr("Sitka", "tz_names"), + QObject::tr("Skopje", "tz_names"), + QObject::tr("Sofia", "tz_names"), + QObject::tr("South Georgia", "tz_names"), + QObject::tr("Srednekolymsk", "tz_names"), + QObject::tr("St Barthelemy", "tz_names"), + QObject::tr("St Helena", "tz_names"), + QObject::tr("St Johns", "tz_names"), + QObject::tr("St Kitts", "tz_names"), + QObject::tr("St Lucia", "tz_names"), + QObject::tr("St Thomas", "tz_names"), + QObject::tr("St Vincent", "tz_names"), + QObject::tr("Stanley", "tz_names"), + QObject::tr("Stockholm", "tz_names"), + QObject::tr("Swift Current", "tz_names"), + QObject::tr("Sydney", "tz_names"), + QObject::tr("Syowa", "tz_names"), + QObject::tr("Tahiti", "tz_names"), + QObject::tr("Taipei", "tz_names"), + QObject::tr("Tallinn", "tz_names"), + QObject::tr("Tarawa", "tz_names"), + QObject::tr("Tashkent", "tz_names"), + QObject::tr("Tbilisi", "tz_names"), + QObject::tr("Tegucigalpa", "tz_names"), + QObject::tr("Tehran", "tz_names"), + QObject::tr("Thimphu", "tz_names"), + QObject::tr("Thule", "tz_names"), + QObject::tr("Thunder Bay", "tz_names"), + QObject::tr("Tijuana", "tz_names"), + QObject::tr("Tirane", "tz_names"), + QObject::tr("Tokyo", "tz_names"), + QObject::tr("Tomsk", "tz_names"), + QObject::tr("Tongatapu", "tz_names"), + QObject::tr("Toronto", "tz_names"), + QObject::tr("Tortola", "tz_names"), + QObject::tr("Tripoli", "tz_names"), + QObject::tr("Troll", "tz_names"), + QObject::tr("Tunis", "tz_names"), + QObject::tr("Ulaanbaatar", "tz_names"), + QObject::tr("Ulyanovsk", "tz_names"), + QObject::tr("Urumqi", "tz_names"), + QObject::tr("Ust-Nera", "tz_names"), + QObject::tr("Uzhgorod", "tz_names"), + QObject::tr("Vaduz", "tz_names"), + QObject::tr("Vancouver", "tz_names"), + QObject::tr("Vatican", "tz_names"), + QObject::tr("Vienna", "tz_names"), + QObject::tr("Vientiane", "tz_names"), + QObject::tr("Vilnius", "tz_names"), + QObject::tr("Vladivostok", "tz_names"), + QObject::tr("Volgograd", "tz_names"), + QObject::tr("Vostok", "tz_names"), + QObject::tr("Wake", "tz_names"), + QObject::tr("Wallis", "tz_names"), + QObject::tr("Warsaw", "tz_names"), + QObject::tr("Whitehorse", "tz_names"), + QObject::tr("Windhoek", "tz_names"), + QObject::tr("Winnipeg", "tz_names"), + QObject::tr("Yakutat", "tz_names"), + QObject::tr("Yakutsk", "tz_names"), + QObject::tr("Yangon", "tz_names"), + QObject::tr("Yekaterinburg", "tz_names"), + QObject::tr("Yellowknife", "tz_names"), + QObject::tr("Yerevan", "tz_names"), + QObject::tr("Zagreb", "tz_names"), + QObject::tr("Zaporozhye", "tz_names"), + QObject::tr("Zurich", "tz_names"), + QString() + }; +} + diff --git a/src/libcalamares/locale/zone-extractor.py b/src/libcalamares/locale/zone-extractor.py new file mode 100644 index 000000000..92165d824 --- /dev/null +++ b/src/libcalamares/locale/zone-extractor.py @@ -0,0 +1,108 @@ +#! /usr/bin/env python3 +# +# === This file is part of Calamares - === +# +# Python3 script to scrape some data out of zoneinfo/zone.tab. +# +### BEGIN LICENSES +# +# Copyright 2019 Adriaan de Groot +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +### END LICENSES + +### BEGIN USAGE +# +""" +Python3 script to scrape some data out of zoneinfo/zone.tab. + +To use this script, you must have a zone.tab in a standard location, +/usr/share/zoneinfo/zone.tab (this is usual on FreeBSD and Linux). + +Prints out a few tables of zone names for use in translations. +""" + +def scrape_file(file, regionset, zoneset): + for line in file.readlines(): + if line.startswith("#"): + continue + parts = line.split("\t") + if len(parts) < 3: + continue + + zoneid = parts[2] + if not "/" in zoneid: + continue + + region, zone = zoneid.split("/", 1) + + zone = zone.strip().replace("_", " ") + + regionset.add(region) + assert(zone not in zoneset) + zoneset.add(zone) + +def write_set(file, label, set): + file.write("/* This returns a reference to local, which is a terrible idea.\n * Good thing it's not meant to be compiled.\n */\n") + # Note {{ is an escaped { for Python string formatting + file.write("static const QStringList& {!s}_table()\n{{\n\treturn QStringList {{\n".format(label)) + for x in sorted(set): + file.write("""\t\tQObject::tr("{!s}", "{!s}"),\n""".format(x, label)) + file.write("\t\tQString()\n\t};\n}\n\n") + +cpp_header_comment = """/* GENERATED FILE DO NOT EDIT +* +* === This file is part of Calamares - === +* +* This file is derived from zone.tab, which has its own copyright statement: +* +* This file is in the public domain, so clarified as of +* 2009-05-17 by Arthur David Olson. +* +* From Paul Eggert (2018-06-27): +* This file is intended as a backward-compatibility aid for older programs. +* New programs should use zone1970.tab. This file is like zone1970.tab (see +* zone1970.tab's comments), but with the following additional restrictions: +* +* 1. This file contains only ASCII characters. +* 2. The first data column contains exactly one country code. +* +*/ + +/** THIS FILE EXISTS ONLY FOR TRANSLATIONS PURPOSES **/ + +// *INDENT-OFF* +// clang-format off +""" + +if __name__ == "__main__": + regions=set() + zones=set() + with open("/usr/share/zoneinfo/zone.tab", "r") as f: + scrape_file(f, regions, zones) + with open("ZoneData_p.cpp", "w") as f: + f.write(cpp_header_comment) + write_set(f, "tz_regions", regions) + write_set(f, "tz_names", zones) + diff --git a/src/libcalamares/utils/Retranslator.cpp b/src/libcalamares/utils/Retranslator.cpp index d761263ac..047f642e4 100644 --- a/src/libcalamares/utils/Retranslator.cpp +++ b/src/libcalamares/utils/Retranslator.cpp @@ -25,90 +25,156 @@ #include #include +/** @brief Helper class for loading translations + * + * This is used by the loadSingletonTranslator() function to hand off + * work to translation-type specific code. + */ +struct TranslationLoader +{ + static QString mungeLocaleName( const QLocale& locale ) + { + QString localeName = locale.name(); + localeName.replace( "-", "_" ); + + if ( localeName == "C" ) + { + localeName = "en"; + } + + // Special case of sr@latin + // + // See top-level CMakeLists.txt about special cases for translation loading. + if ( locale.language() == QLocale::Language::Serbian && locale.script() == QLocale::Script::LatinScript ) + { + localeName = QStringLiteral( "sr@latin" ); + } + return localeName; + } + + TranslationLoader( const QLocale& locale ) + : m_locale( locale ) + , m_localeName( mungeLocaleName( locale ) ) + { + } + + virtual ~TranslationLoader() {}; + /// @brief Loads @p translator with the specific translations of this type + virtual bool tryLoad( QTranslator* translator ) = 0; + + const QLocale& m_locale; + QString m_localeName; +}; + +struct BrandingLoader : public TranslationLoader +{ + BrandingLoader( const QLocale& locale, const QString& prefix ) + : TranslationLoader( locale ) + , m_prefix( prefix ) + { + } + + bool tryLoad( QTranslator* translator ) override + { + if ( m_prefix.isEmpty() ) + { + return false; + } + QString brandingTranslationsDirPath( m_prefix ); + brandingTranslationsDirPath.truncate( m_prefix.lastIndexOf( QDir::separator() ) ); + QDir brandingTranslationsDir( brandingTranslationsDirPath ); + if ( brandingTranslationsDir.exists() ) + { + QString filenameBase( m_prefix ); + filenameBase.remove( 0, m_prefix.lastIndexOf( QDir::separator() ) + 1 ); + if ( translator->load( m_locale, filenameBase, "_", brandingTranslationsDir.absolutePath() ) ) + { + cDebug() << Logger::SubEntry << "Branding using locale:" << m_localeName; + return true; + } + else + { + cDebug() << Logger::SubEntry << "Branding using default, system locale not found:" << m_localeName; + // TODO: this loads something completely different + return translator->load( m_prefix + "en" ); + } + } + return false; + } + + QString m_prefix; +}; + +struct CalamaresLoader : public TranslationLoader +{ + using TranslationLoader::TranslationLoader; + + bool tryLoad( QTranslator* translator ) override + { + if ( translator->load( QString( ":/lang/calamares_" ) + m_localeName ) ) + { + cDebug() << Logger::SubEntry << "Calamares using locale:" << m_localeName; + return true; + } + else + { + cDebug() << Logger::SubEntry << "Calamares using default, system locale not found:" << m_localeName; + return translator->load( QString( ":/lang/calamares_en" ) ); + } + } +}; + +struct TZLoader : public TranslationLoader +{ + using TranslationLoader::TranslationLoader; + bool tryLoad( QTranslator* translator ) override + { + if ( translator->load( QString( ":/lang/tz_" ) + m_localeName ) ) + { + cDebug() << Logger::SubEntry << "Calamares Timezones using locale:" << m_localeName; + return true; + } + else + { + cDebug() << Logger::SubEntry + << "Calamares Timezones using default, system locale not found:" << m_localeName; + return translator->load( QString( ":/lang/tz_en" ) ); + } + } +}; + +static void +loadSingletonTranslator( TranslationLoader&& loader, QTranslator*& translator_p ) +{ + QTranslator* translator = new QTranslator(); + loader.tryLoad( translator ); + + if ( translator_p ) + { + QCoreApplication::removeTranslator( translator_p ); + delete translator_p; + } + + QCoreApplication::installTranslator( translator ); + translator_p = translator; +} namespace CalamaresUtils { static QTranslator* s_brandingTranslator = nullptr; static QTranslator* s_translator = nullptr; +static QTranslator* s_tztranslator = nullptr; static QString s_translatorLocaleName; void installTranslator( const QLocale& locale, const QString& brandingTranslationsPrefix, QObject* parent ) { - QString localeName = locale.name(); - localeName.replace( "-", "_" ); + loadSingletonTranslator( BrandingLoader( locale, brandingTranslationsPrefix ), s_brandingTranslator ); + loadSingletonTranslator( TZLoader( locale ), s_tztranslator ); - if ( localeName == "C" ) - { - localeName = "en"; - } - - // Special case of sr@latin - // - // See top-level CMakeLists.txt about special cases for translation loading. - if ( locale.language() == QLocale::Language::Serbian && locale.script() == QLocale::Script::LatinScript ) - { - localeName = QStringLiteral( "sr@latin" ); - } - - cDebug() << "Looking for translations for" << localeName; - - QTranslator* translator = nullptr; - - // Branding translations - if ( !brandingTranslationsPrefix.isEmpty() ) - { - QString brandingTranslationsDirPath( brandingTranslationsPrefix ); - brandingTranslationsDirPath.truncate( brandingTranslationsPrefix.lastIndexOf( QDir::separator() ) ); - QDir brandingTranslationsDir( brandingTranslationsDirPath ); - if ( brandingTranslationsDir.exists() ) - { - QString filenameBase( brandingTranslationsPrefix ); - filenameBase.remove( 0, brandingTranslationsPrefix.lastIndexOf( QDir::separator() ) + 1 ); - translator = new QTranslator( parent ); - if ( translator->load( locale, filenameBase, "_", brandingTranslationsDir.absolutePath() ) ) - { - cDebug() << Logger::SubEntry << "Branding using locale:" << localeName; - } - else - { - cDebug() << Logger::SubEntry << "Branding using default, system locale not found:" << localeName; - translator->load( brandingTranslationsPrefix + "en" ); - } - - if ( s_brandingTranslator ) - { - QCoreApplication::removeTranslator( s_brandingTranslator ); - delete s_brandingTranslator; - } - - QCoreApplication::installTranslator( translator ); - s_brandingTranslator = translator; - } - } - - // Calamares translations - translator = new QTranslator( parent ); - if ( translator->load( QString( ":/lang/calamares_" ) + localeName ) ) - { - cDebug() << Logger::SubEntry << "Calamares using locale:" << localeName; - } - else - { - cDebug() << Logger::SubEntry << "Calamares using default, system locale not found:" << localeName; - translator->load( QString( ":/lang/calamares_en" ) ); - } - - if ( s_translator ) - { - QCoreApplication::removeTranslator( s_translator ); - delete s_translator; - } - - QCoreApplication::installTranslator( translator ); - s_translator = translator; - - s_translatorLocaleName = localeName; + CalamaresLoader l( locale ); // because we want the extracted localeName + loadSingletonTranslator( std::move( l ), s_translator ); + s_translatorLocaleName = l.m_localeName; } diff --git a/src/modules/license/LicensePage.cpp b/src/modules/license/LicensePage.cpp index fc90d843c..237e8d0dc 100644 --- a/src/modules/license/LicensePage.cpp +++ b/src/modules/license/LicensePage.cpp @@ -44,6 +44,12 @@ #include +static const char mustAccept[] = "#acceptFrame { border: 1px solid red;" + "background-color: #fff6f6;" + "border-radius: 4px;" + "padding: 2px; }"; +static const char okAccept[] = "#acceptFrame { padding: 3px }"; + const NamedEnumTable< LicenseEntry::Type >& LicenseEntry::typeNames() { @@ -104,13 +110,8 @@ LicensePage::LicensePage( QWidget* parent ) ui->mainText->setWordWrap( true ); ui->mainText->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ); - ui->additionalText->setWordWrap( true ); - ui->acceptFrame->setFrameStyle( QFrame::NoFrame | QFrame::Plain ); - ui->acceptFrame->setStyleSheet( "#acceptFrame { border: 1px solid red;" - "background-color: #fff6f6;" - "border-radius: 4px;" - "padding: 2px; }" ); + ui->acceptFrame->setStyleSheet( mustAccept ); ui->acceptFrame->layout()->setMargin( CalamaresUtils::defaultFontHeight() / 2 ); updateGlobalStorage( false ); // Have not agreed yet @@ -136,6 +137,7 @@ LicensePage::setEntries( const QList< LicenseEntry >& entriesList ) m_entries.append( w ); m_allLicensesOptional &= !entry.isRequired(); } + ui->licenseEntriesLayout->addSpacerItem( new QSpacerItem( 10, 10, QSizePolicy::Minimum, QSizePolicy::Expanding ) ); ui->acceptCheckBox->setChecked( false ); checkAcceptance( false ); @@ -154,7 +156,8 @@ LicensePage::retranslate() ui->mainText->setText( tr( "This setup procedure will install proprietary " "software that is subject to licensing terms." ) + br + review ); - ui->additionalText->setText( tr( "If you do not agree with the terms, the setup procedure cannot continue." ) ); + QString mustAcceptText( tr( "If you do not agree with the terms, the setup procedure cannot continue." ) ); + ui->acceptCheckBox->setToolTip( mustAcceptText ); } else { @@ -163,8 +166,9 @@ LicensePage::retranslate() "in order to provide additional features and enhance the user " "experience." ) + br + review ); - ui->additionalText->setText( tr( "If you do not agree with the terms, proprietary software will not " - "be installed, and open source alternatives will be used instead." ) ); + QString okAcceptText( tr( "If you do not agree with the terms, proprietary software will not " + "be installed, and open source alternatives will be used instead." ) ); + ui->acceptCheckBox->setToolTip( okAcceptText ); } ui->retranslateUi( this ); @@ -195,14 +199,11 @@ LicensePage::checkAcceptance( bool checked ) m_isNextEnabled = checked || m_allLicensesOptional; if ( !m_isNextEnabled ) { - ui->acceptFrame->setStyleSheet( "#acceptFrame { border: 1px solid red;" - "background-color: #fff8f8;" - "border-radius: 4px;" - "padding: 2px; }" ); + ui->acceptFrame->setStyleSheet( mustAccept ); } else { - ui->acceptFrame->setStyleSheet( "#acceptFrame { padding: 3px }" ); + ui->acceptFrame->setStyleSheet( okAccept ); } emit nextStatusChanged( m_isNextEnabled ); } diff --git a/src/modules/license/LicensePage.ui b/src/modules/license/LicensePage.ui index a81fae2b8..b5936d5de 100644 --- a/src/modules/license/LicensePage.ui +++ b/src/modules/license/LicensePage.ui @@ -15,7 +15,7 @@ - + @@ -87,7 +87,7 @@ 0 0 765 - 81 + 89 @@ -107,22 +107,6 @@ - - - - - 0 - 0 - - - - - - - <additionalText> - - - diff --git a/src/modules/license/LicenseWidget.cpp b/src/modules/license/LicenseWidget.cpp index a4c1dfaaa..09d2230e5 100644 --- a/src/modules/license/LicenseWidget.cpp +++ b/src/modules/license/LicenseWidget.cpp @@ -27,13 +27,9 @@ #include #include #include -#include +#include #include -static constexpr const auto ArrowOpenExternalLink = Qt::RightArrow; -static constexpr const auto ArrowLocalLicenseIsCollapsed = Qt::UpArrow; -static constexpr const auto ArrowLocalLicenseIsExpanded = Qt::DownArrow; - static QString loadLocalFile( const QUrl& u ) { @@ -56,9 +52,9 @@ LicenseWidget::LicenseWidget( LicenseEntry entry, QWidget* parent ) : QWidget( parent ) , m_entry( std::move( entry ) ) , m_label( new QLabel( this ) ) - , m_viewLicenseLabel( new QLabel( this ) ) - , m_expandLicenseButton( nullptr ) - , m_fullText( nullptr ) + , m_viewLicenseButton( new QPushButton( this ) ) + , m_licenceTextLabel( new QLabel( this ) ) + , m_isExpanded( m_entry.expandByDefault() ) { QPalette pal( palette() ); pal.setColor( QPalette::Background, palette().window().color().lighter( 108 ) ); @@ -70,53 +66,40 @@ LicenseWidget::LicenseWidget( LicenseEntry entry, QWidget* parent ) setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ); setContentsMargins( 4, 4, 4, 4 ); + QVBoxLayout* vLayout = new QVBoxLayout; + QWidget* topPart = new QWidget( this ); + topPart->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ); + vLayout->addWidget( topPart ); + QHBoxLayout* wiLayout = new QHBoxLayout; + topPart->setLayout( wiLayout ); m_label->setWordWrap( true ); - m_label->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum ); + m_label->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ); wiLayout->addWidget( m_label ); - m_viewLicenseLabel->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); - m_viewLicenseLabel->setAlignment( Qt::AlignVCenter | Qt::AlignRight ); - wiLayout->addWidget( m_viewLicenseLabel ); + wiLayout->addSpacing( 10 ); + m_viewLicenseButton->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ); + wiLayout->addWidget( m_viewLicenseButton ); + + m_licenceTextLabel->setStyleSheet( "border-top: 1px solid black; margin-top: 0px; padding-top: 1em;" ); + m_licenceTextLabel->setObjectName( "licenseItemFullText" ); - m_expandLicenseButton = new QToolButton( this ); - wiLayout->addWidget( m_expandLicenseButton ); if ( m_entry.isLocal() ) { - QVBoxLayout* vLayout = new QVBoxLayout; - - m_expandLicenseButton->setArrowType( ArrowLocalLicenseIsCollapsed ); - connect( m_expandLicenseButton, &QAbstractButton::clicked, this, &LicenseWidget::expandClicked ); - - vLayout->addLayout( wiLayout ); - m_fullText = new QLabel( this ); - m_fullText->setText( loadLocalFile( m_entry.m_url ) ); - m_fullText->hide(); - m_fullText->setStyleSheet( "border-top: 1px solid black; margin-top: 1em; padding-top: 1em;" ); - m_fullText->setObjectName( "licenseItemFullText" ); - - vLayout->addWidget( m_fullText ); - setLayout( vLayout ); - - if ( m_entry.expandByDefault() ) - { - // Since we started in a collapsed state, toggle it to expand. - // This can only be done once the full text has been added. - expandClicked(); - } + m_fullTextContents = loadLocalFile( m_entry.m_url ); + showLocalLicenseText(); + connect( m_viewLicenseButton, &QAbstractButton::clicked, this, &LicenseWidget::expandClicked ); } else { - m_expandLicenseButton->setArrowType( ArrowOpenExternalLink ); - connect( m_expandLicenseButton, &QAbstractButton::clicked, this, &LicenseWidget::viewClicked ); - - // Normally setOpenExternalLinks( true ) would do, but we need the - // open code anyway for the toolbutton, let's share it. - connect( m_viewLicenseLabel, &QLabel::linkActivated, this, &LicenseWidget::viewClicked ); - - setLayout( wiLayout ); // Only the horizontal layout needed + m_licenceTextLabel->setText( tr( "URL: %1" ).arg( m_entry.m_url.toDisplayString() ) ); + connect( m_viewLicenseButton, &QAbstractButton::clicked, this, &LicenseWidget::viewClicked ); } + m_licenceTextLabel->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ); + + vLayout->addWidget( m_licenceTextLabel ); + setLayout( vLayout ); retranslateUi(); } @@ -172,21 +155,31 @@ LicenseWidget::retranslateUi() } void -LicenseWidget::expandClicked() +LicenseWidget::showLocalLicenseText() { - if ( m_expandLicenseButton->arrowType() == ArrowLocalLicenseIsExpanded ) + if ( m_isExpanded ) { - m_expandLicenseButton->setArrowType( ArrowLocalLicenseIsCollapsed ); + m_licenceTextLabel->setText( m_fullTextContents ); } else { - m_expandLicenseButton->setArrowType( ArrowLocalLicenseIsExpanded ); + QString fileName = m_entry.m_url.toDisplayString(); + if ( fileName.startsWith( "file:" ) ) + { + fileName = fileName.remove( 0, 5 ); + } + m_licenceTextLabel->setText( tr( "File: %1" ).arg( fileName ) ); } +} +void +LicenseWidget::expandClicked() +{ + m_isExpanded = !m_isExpanded; // Show/hide based on the new arrow direction. - if ( m_fullText ) + if ( !m_fullTextContents.isEmpty() ) { - m_fullText->setHidden( m_expandLicenseButton->arrowType() == ArrowLocalLicenseIsCollapsed ); + showLocalLicenseText(); } updateExpandToolTip(); @@ -198,17 +191,11 @@ LicenseWidget::updateExpandToolTip() { if ( m_entry.isLocal() ) { - const bool isNowCollapsed = m_expandLicenseButton->arrowType() == ArrowLocalLicenseIsCollapsed; - - m_expandLicenseButton->setToolTip( isNowCollapsed ? tr( "Shows the complete license text" ) - : tr( "Hide license text" ) ); - m_viewLicenseLabel->setText( isNowCollapsed ? tr( "Show license agreement" ) : tr( "Hide license agreement" ) ); + m_viewLicenseButton->setText( m_isExpanded ? tr( "Hide license text" ) : tr( "Show the license text" ) ); } else { - m_expandLicenseButton->setToolTip( tr( "Opens the license agreement in a browser window." ) ); - m_viewLicenseLabel->setText( - tr( "View license agreement" ).arg( m_entry.m_url.toString() ) ); + m_viewLicenseButton->setText( tr( "Open license agreement in browser." ) ); } } diff --git a/src/modules/license/LicenseWidget.h b/src/modules/license/LicenseWidget.h index e11d7a746..a386ae353 100644 --- a/src/modules/license/LicenseWidget.h +++ b/src/modules/license/LicenseWidget.h @@ -27,7 +27,7 @@ #include #include -class QToolButton; +class QPushButton; class LicenseWidget : public QWidget { @@ -38,14 +38,16 @@ public: void retranslateUi(); private: + void showLocalLicenseText(); // Display (or hide) the local license text void expandClicked(); // "slot" to toggle show/hide of local license text void viewClicked(); // "slot" to open link void updateExpandToolTip(); LicenseEntry m_entry; QLabel* m_label; - QLabel* m_viewLicenseLabel; - QToolButton* m_expandLicenseButton; - QLabel* m_fullText; + QPushButton* m_viewLicenseButton; + QLabel* m_licenceTextLabel; + QString m_fullTextContents; + bool m_isExpanded; }; #endif diff --git a/src/modules/locale/LocalePage.cpp b/src/modules/locale/LocalePage.cpp index 7720a840c..4e43fc177 100644 --- a/src/modules/locale/LocalePage.cpp +++ b/src/modules/locale/LocalePage.cpp @@ -28,6 +28,7 @@ #include "Settings.h" #include "locale/Label.h" +#include "locale/TimeZone.h" #include "utils/CalamaresUtilsGui.h" #include "utils/Logger.h" #include "utils/Retranslator.h" @@ -41,6 +42,8 @@ LocalePage::LocalePage( QWidget* parent ) : QWidget( parent ) , m_blockTzWidgetSet( false ) + , m_regionList( CalamaresUtils::Locale::TZRegion::fromZoneTab() ) + , m_regionModel( std::make_unique< CalamaresUtils::Locale::CStringListModel >( m_regionList ) ) { QBoxLayout* mainLayout = new QVBoxLayout; @@ -109,7 +112,10 @@ LocalePage::LocalePage( QWidget* parent ) } -LocalePage::~LocalePage() {} +LocalePage::~LocalePage() +{ + qDeleteAll( m_regionList ); +} void @@ -127,42 +133,16 @@ LocalePage::updateLocaleLabels() m_formatsLabel->setText( labels.second ); } -static inline bool -containsLocation( const QList< LocaleGlobal::Location >& locations, const QString& zone ) -{ - for ( const LocaleGlobal::Location& location : locations ) - { - if ( location.zone == zone ) - { - return true; - } - } - return false; -} - void LocalePage::init( const QString& initialRegion, const QString& initialZone, const QString& localeGenPath ) { - m_regionCombo->blockSignals( true ); - m_zoneCombo->blockSignals( true ); - - // Setup locations - QHash< QString, QList< LocaleGlobal::Location > > regions = LocaleGlobal::getLocations(); - - QStringList keys = regions.keys(); - keys.sort(); - - foreach ( const QString& key, keys ) - { - m_regionCombo->addItem( LocaleGlobal::Location::pretty( key ), key ); - } - - m_regionCombo->blockSignals( false ); - m_zoneCombo->blockSignals( false ); + using namespace CalamaresUtils::Locale; + m_regionCombo->setModel( m_regionModel.get() ); m_regionCombo->currentIndexChanged( m_regionCombo->currentIndex() ); - if ( keys.contains( initialRegion ) && containsLocation( regions.value( initialRegion ), initialZone ) ) + auto* region = m_regionList.find< TZRegion >( initialRegion ); + if ( region && region->zones().find< TZZone >( initialZone ) ) { m_tzWidget->setCurrentLocation( initialRegion, initialZone ); } @@ -170,7 +150,6 @@ LocalePage::init( const QString& initialRegion, const QString& initialZone, cons { m_tzWidget->setCurrentLocation( "America", "New_York" ); } - emit m_tzWidget->locationChanged( m_tzWidget->getCurrentLocation() ); // Some distros come with a meaningfully commented and easy to parse locale.gen, // and others ship a separate file /usr/share/i18n/SUPPORTED with a clean list of @@ -301,13 +280,13 @@ LocalePage::prettyStatus() const } -QList< Calamares::job_ptr > +Calamares::JobList LocalePage::createJobs() { QList< Calamares::job_ptr > list; - LocaleGlobal::Location location = m_tzWidget->getCurrentLocation(); + const CalamaresUtils::Locale::TZZone* location = m_tzWidget->currentLocation(); - Calamares::Job* j = new SetTimezoneJob( location.region, location.zone ); + Calamares::Job* j = new SetTimezoneJob( location->region(), location->zone() ); list.append( Calamares::job_ptr( j ) ); return list; @@ -340,7 +319,7 @@ LocaleConfiguration LocalePage::guessLocaleConfiguration() const { return LocaleConfiguration::fromLanguageAndLocation( - QLocale().name(), m_localeGenLines, m_tzWidget->getCurrentLocation().country ); + QLocale().name(), m_localeGenLines, m_tzWidget->currentLocation()->country() ); } @@ -358,12 +337,12 @@ LocalePage::updateGlobalStorage() { auto* gs = Calamares::JobQueue::instance()->globalStorage(); - LocaleGlobal::Location location = m_tzWidget->getCurrentLocation(); - bool locationChanged - = ( location.region != gs->value( "locationRegion" ) ) || ( location.zone != gs->value( "locationZone" ) ); + const auto* location = m_tzWidget->currentLocation(); + bool locationChanged = ( location->region() != gs->value( "locationRegion" ) ) + || ( location->zone() != gs->value( "locationZone" ) ); - gs->insert( "locationRegion", location.region ); - gs->insert( "locationZone", location.zone ); + gs->insert( "locationRegion", location->region() ); + gs->insert( "locationZone", location->zone() ); updateGlobalLocale(); @@ -373,7 +352,7 @@ LocalePage::updateGlobalStorage() if ( locationChanged && Calamares::Settings::instance()->doChroot() ) { QProcess::execute( "timedatectl", // depends on systemd - { "set-timezone", location.region + '/' + location.zone } ); + { "set-timezone", location->region() + '/' + location->zone() } ); } #endif @@ -402,31 +381,23 @@ LocalePage::updateGlobalStorage() updateLocaleLabels(); } - void LocalePage::regionChanged( int currentIndex ) { + using namespace CalamaresUtils::Locale; + Q_UNUSED( currentIndex ) - QHash< QString, QList< LocaleGlobal::Location > > regions = LocaleGlobal::getLocations(); - if ( !regions.contains( m_regionCombo->currentData().toString() ) ) + QString selectedRegion = m_regionCombo->currentData().toString(); + + TZRegion* region = m_regionList.find< TZRegion >( selectedRegion ); + if ( !region ) { return; } m_zoneCombo->blockSignals( true ); - - m_zoneCombo->clear(); - - const QList< LocaleGlobal::Location > zones = regions.value( m_regionCombo->currentData().toString() ); - for ( const LocaleGlobal::Location& zone : zones ) - { - m_zoneCombo->addItem( LocaleGlobal::Location::pretty( zone.zone ), zone.zone ); - } - - m_zoneCombo->model()->sort( 0 ); - + m_zoneCombo->setModel( new CStringListModel( region->zones() ) ); m_zoneCombo->blockSignals( false ); - m_zoneCombo->currentIndexChanged( m_zoneCombo->currentIndex() ); } @@ -442,12 +413,12 @@ LocalePage::zoneChanged( int currentIndex ) } void -LocalePage::locationChanged( LocaleGlobal::Location location ) +LocalePage::locationChanged( const CalamaresUtils::Locale::TZZone* location ) { m_blockTzWidgetSet = true; // Set region index - int index = m_regionCombo->findData( location.region ); + int index = m_regionCombo->findData( location->region() ); if ( index < 0 ) { return; @@ -456,7 +427,7 @@ LocalePage::locationChanged( LocaleGlobal::Location location ) m_regionCombo->setCurrentIndex( index ); // Set zone index - index = m_zoneCombo->findData( location.zone ); + index = m_zoneCombo->findData( location->zone() ); if ( index < 0 ) { return; diff --git a/src/modules/locale/LocalePage.h b/src/modules/locale/LocalePage.h index 73097252b..d6aaa6de8 100644 --- a/src/modules/locale/LocalePage.h +++ b/src/modules/locale/LocalePage.h @@ -24,9 +24,12 @@ #include "timezonewidget/localeglobal.h" #include "Job.h" +#include "locale/TimeZone.h" #include +#include + class QComboBox; class QLabel; class QPushButton; @@ -67,10 +70,14 @@ private: void regionChanged( int currentIndex ); void zoneChanged( int currentIndex ); - void locationChanged( LocaleGlobal::Location location ); + void locationChanged( const CalamaresUtils::Locale::TZZone* location ); void changeLocale(); void changeFormats(); + // Dynamically, QList< TZRegion* > + CalamaresUtils::Locale::CStringPairList m_regionList; + std::unique_ptr< CalamaresUtils::Locale::CStringListModel > m_regionModel; + TimeZoneWidget* m_tzWidget; QComboBox* m_regionCombo; QComboBox* m_zoneCombo; diff --git a/src/modules/locale/LocaleViewStep.cpp b/src/modules/locale/LocaleViewStep.cpp index 4acfcb2de..4fa219065 100644 --- a/src/modules/locale/LocaleViewStep.cpp +++ b/src/modules/locale/LocaleViewStep.cpp @@ -142,7 +142,7 @@ LocaleViewStep::isAtEnd() const } -QList< Calamares::job_ptr > +Calamares::JobList LocaleViewStep::jobs() const { return m_jobs; @@ -163,12 +163,9 @@ LocaleViewStep::onActivate() void LocaleViewStep::onLeave() { - m_jobs.clear(); - if ( m_actualWidget ) { - m_jobs.append( m_actualWidget->createJobs() ); - + m_jobs = m_actualWidget->createJobs(); m_prettyStatus = m_actualWidget->prettyStatus(); auto map = m_actualWidget->localesMap(); @@ -182,6 +179,7 @@ LocaleViewStep::onLeave() } else { + m_jobs.clear(); Calamares::JobQueue::instance()->globalStorage()->remove( "localeConf" ); } } diff --git a/src/modules/locale/LocaleViewStep.h b/src/modules/locale/LocaleViewStep.h index ca8ecc3fa..eb8d64177 100644 --- a/src/modules/locale/LocaleViewStep.h +++ b/src/modules/locale/LocaleViewStep.h @@ -33,7 +33,6 @@ #include class LocalePage; -class WaitingWidget; class PLUGINDLLEXPORT LocaleViewStep : public Calamares::ViewStep { @@ -54,7 +53,7 @@ public: bool isAtBeginning() const override; bool isAtEnd() const override; - QList< Calamares::job_ptr > jobs() const override; + Calamares::JobList jobs() const override; void onActivate() override; void onLeave() override; @@ -78,7 +77,7 @@ private: CalamaresUtils::GeoIP::RegionZonePair m_startingTimezone; QString m_localeGenPath; - QList< Calamares::job_ptr > m_jobs; + Calamares::JobList m_jobs; std::unique_ptr< CalamaresUtils::GeoIP::Handler > m_geoip; }; diff --git a/src/modules/locale/timezonewidget/localeconst.h b/src/modules/locale/timezonewidget/localeconst.h deleted file mode 100644 index 3bac6adde..000000000 --- a/src/modules/locale/timezonewidget/localeconst.h +++ /dev/null @@ -1,32 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014, Teo Mrnjavac - * - * Originally from the Manjaro Installation Framework - * by Roland Singer - * Copyright (C) 2007 Free Software Foundation, Inc. - * - * Calamares is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Calamares is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Calamares. If not, see . - */ - -#ifndef LOCALECONST_H -#define LOCALECONST_H - - -#define LOCALESDIR "/usr/share/i18n/locales" -#define TZ_DATA_FILE "/usr/share/zoneinfo/zone.tab" -#define USER_IMAGES_PATH "/usr/share/pixmaps/faces" - - -#endif // LOCALECONST_H diff --git a/src/modules/locale/timezonewidget/localeglobal.cpp b/src/modules/locale/timezonewidget/localeglobal.cpp index 6303ffdcb..d0e889148 100644 --- a/src/modules/locale/timezonewidget/localeglobal.cpp +++ b/src/modules/locale/timezonewidget/localeglobal.cpp @@ -22,14 +22,15 @@ #include "localeglobal.h" +#include "locale/TimeZone.h" + #include //### //### Private variables //### -QHash > > LocaleGlobal::locales; -QHash > LocaleGlobal::locations; +QHash< QString, QHash< QString, QList< LocaleGlobal::Locale > > > LocaleGlobal::locales; //### @@ -37,158 +38,89 @@ QHash > LocaleGlobal::locations; //### -QString -LocaleGlobal::Location::pretty( const QString& s ) -{ - return QString( s ).replace( '_', ' ' ).simplified(); -} - - -QString -LocaleGlobal::Location::comment() const -{ - QTimeZone qtz = QTimeZone( QString( "%1/%2" ) - .arg( region ) - .arg( zone ).toLatin1() ); - return qtz.comment(); -} - - void -LocaleGlobal::init() { +LocaleGlobal::init() +{ // TODO: Error handling initLocales(); - initLocations(); } - QHash< QString, QHash< QString, QList< LocaleGlobal::Locale > > > -LocaleGlobal::getLocales() { +LocaleGlobal::getLocales() +{ return locales; } - -QHash< QString, QList< LocaleGlobal::Location > > -LocaleGlobal::getLocations() { - return locations; -} - - //### //### Private methods //### void -LocaleGlobal::initLocales() { +LocaleGlobal::initLocales() +{ + static const char LOCALESDIR[] = "/usr/share/i18n/locales"; + locales.clear(); - QStringList files = QDir(LOCALESDIR).entryList(QDir::Files, QDir::Name); + QStringList files = QDir( LOCALESDIR ).entryList( QDir::Files, QDir::Name ); - for (int i = 0; i < files.size(); ++i) { - QString filename = files.at(i); - QFile file(QString(LOCALESDIR) + "/" + filename); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + for ( int i = 0; i < files.size(); ++i ) + { + QString filename = files.at( i ); + QFile file( QString( LOCALESDIR ) + "/" + filename ); + if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) + { continue; + } - QTextStream in(&file); + QTextStream in( &file ); QString commentChar = "%"; Locale locale; QString lang, territory; locale.locale = filename; - while (!in.atEnd()) { + while ( !in.atEnd() ) + { QString line = in.readLine().trimmed(); - QStringList split = line.split(commentChar, QString::KeepEmptyParts).first().split(QRegExp(" (?=[^\"]*(\"[^\"]*\"[^\"]*)*$)"), QString::SkipEmptyParts); + QStringList split = line.split( commentChar, QString::KeepEmptyParts ) + .first() + .split( QRegExp( " (?=[^\"]*(\"[^\"]*\"[^\"]*)*$)" ), QString::SkipEmptyParts ); - if (split.size() < 2) + if ( split.size() < 2 ) + { continue; + } - QString sub1 = QString(split.at(0)).remove("\""); - QString sub2 = QString(split.at(1)).remove("\""); + QString sub1 = QString( split.at( 0 ) ).remove( "\"" ); + QString sub2 = QString( split.at( 1 ) ).remove( "\"" ); - if (sub1 == "comment_char") + if ( sub1 == "comment_char" ) + { commentChar = sub2; - else if (sub1 == "title") + } + else if ( sub1 == "title" ) + { locale.description = sub2; - else if (sub1 == "territory") - territory= sub2; - else if (sub1 == "language") + } + else if ( sub1 == "territory" ) + { + territory = sub2; + } + else if ( sub1 == "language" ) + { lang = sub2; + } } - if (lang.isEmpty() || territory.isEmpty()) + if ( lang.isEmpty() || territory.isEmpty() ) + { continue; + } - locales[lang][territory].append(locale); + locales[ lang ][ territory ].append( locale ); } } - - - -void -LocaleGlobal::initLocations() { - locations.clear(); - - QFile file(TZ_DATA_FILE); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - return; - - QTextStream in(&file); - while (!in.atEnd()) { - QString line = in.readLine().trimmed().split('#', QString::KeepEmptyParts).first().trimmed(); - if (line.isEmpty()) - continue; - - QStringList list = line.split(QRegExp("[\t ]"), QString::SkipEmptyParts); - if (list.size() < 3) - continue; - - Location location; - QStringList timezoneParts = list.at(2).split('/', QString::SkipEmptyParts); - int cooSplitPos = QString(list.at(1)).remove(0, 1).indexOf(QRegExp("[-+]")) + 1; - - if (timezoneParts.size() < 2) - continue; - - QString countryCode = list.at(0).trimmed(); - if (countryCode.size() != 2) - continue; - - location.region = timezoneParts.takeFirst(); - location.zone = timezoneParts.join( '/' ); - location.latitude = getRightGeoLocation(list.at(1).mid(0, cooSplitPos)); - location.longitude = getRightGeoLocation(list.at(1).mid(cooSplitPos)); - location.country = countryCode; - - locations[location.region].append(location); - } -} - - - -double -LocaleGlobal::getRightGeoLocation(QString str) { - double sign = 1, num = 0.00; - - // Determind sign - if (str.startsWith('-')) { - sign = -1; - str.remove(0, 1); - } - else if (str.startsWith('+')) { - str.remove(0, 1); - } - - - if (str.length() == 4 || str.length() == 6) - num = str.mid(0, 2).toDouble() + str.mid(2, 2).toDouble() / 60; - else if (str.length() == 5 || str.length() == 7) - num = str.mid(0, 3).toDouble() + str.mid(3, 2).toDouble() / 60; - - return sign * num; -} - diff --git a/src/modules/locale/timezonewidget/localeglobal.h b/src/modules/locale/timezonewidget/localeglobal.h index 1a8f796d4..1dc9548d0 100644 --- a/src/modules/locale/timezonewidget/localeglobal.h +++ b/src/modules/locale/timezonewidget/localeglobal.h @@ -24,17 +24,24 @@ #ifndef LOCALEGLOBAL_H #define LOCALEGLOBAL_H -#include -#include -#include +#include #include -#include -#include +#include #include +#include #include #include -#include -#include "localeconst.h" +#include +#include +#include + +namespace CalamaresUtils +{ +namespace Locale +{ +class TZZone; +} +} // namespace CalamaresUtils class LocaleGlobal { @@ -44,30 +51,13 @@ public: QString description, locale; }; - struct Location - { - QString region, zone, country; - double latitude, longitude; - static QString pretty( const QString& s ); - QString comment() const; - }; - static void init(); - static QHash > > getLocales(); - static QHash > getLocations(); + static QHash< QString, QHash< QString, QList< LocaleGlobal::Locale > > > getLocales(); private: - static QHash > > locales; - static QHash > locations; + static QHash< QString, QHash< QString, QList< LocaleGlobal::Locale > > > locales; static void initLocales(); - static void initLocations(); - static double getRightGeoLocation( QString str ); }; -inline QDebug& operator <<( QDebug& s, const LocaleGlobal::Location& l ) -{ - return s << l.region << '/' << l.zone << '(' << l.country << ") @N" << l.latitude << 'E' << l.longitude; -} - -#endif // LOCALEGLOBAL_H +#endif // LOCALEGLOBAL_H diff --git a/src/modules/locale/timezonewidget/timezonewidget.cpp b/src/modules/locale/timezonewidget/timezonewidget.cpp index 33a8f25ac..a96aaafa3 100644 --- a/src/modules/locale/timezonewidget/timezonewidget.cpp +++ b/src/modules/locale/timezonewidget/timezonewidget.cpp @@ -1,7 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2014-2015, Teo Mrnjavac - * Copyright 2017-2018, Adriaan de Groot + * Copyright 2017-2019, Adriaan de Groot * * Originally from the Manjaro Installation Framework * by Roland Singer @@ -23,10 +23,13 @@ #include +#include "locale/TimeZone.h" #include "utils/Logger.h" #include "timezonewidget.h" +// Pixel value indicating that a spot is outside of a zone +#define RGB_TRANSPARENT 0 static constexpr double MAP_Y_OFFSET = 0.125; static constexpr double MAP_X_OFFSET = -0.0370; @@ -37,8 +40,8 @@ constexpr static double MATH_PI = 3.14159265; constexpr static QLatin1String ZONE_NAME( "zone" ); #endif -TimeZoneWidget::TimeZoneWidget( QWidget* parent ) : - QWidget( parent ) +TimeZoneWidget::TimeZoneWidget( QWidget* parent ) + : QWidget( parent ) { setMouseTracking( false ); setCursor( Qt::PointingHandCursor ); @@ -48,54 +51,67 @@ TimeZoneWidget::TimeZoneWidget( QWidget* parent ) : font.setBold( false ); // Images - background = QImage( ":/images/bg.png" ).scaled( X_SIZE, Y_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); + background = QImage( ":/images/bg.png" ); pin = QImage( ":/images/pin.png" ); +#ifdef DEBUG_TIMEZONES + if ( background.size() != QSize( 780, 340 ) ) + { + cWarning() << "Timezone background size mitsmatch" << background.size(); + } +#endif + // Set size setMinimumSize( background.size() ); setMaximumSize( background.size() ); // Zone images - QStringList zones = QString( ZONES ).split( " ", QString::SkipEmptyParts ); - for ( int i = 0; i < zones.size(); ++i ) + for ( const auto* zoneName : + { "0.0", "1.0", "2.0", "3.0", "3.5", "4.0", "4.5", "5.0", "5.5", "5.75", "6.0", "6.5", "7.0", + "8.0", "9.0", "9.5", "10.0", "10.5", "11.0", "11.5", "12.0", "12.75", "13.0", "-1.0", "-2.0", "-3.0", + "-3.5", "-4.0", "-4.5", "-5.0", "-5.5", "-6.0", "-7.0", "-8.0", "-9.0", "-9.5", "-10.0", "-11.0" } ) { - timeZoneImages.append( QImage( ":/images/timezone_" + zones.at( i ) + ".png" ).scaled( X_SIZE, Y_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) ); + timeZoneImages.append( QImage( QStringLiteral( ":/images/timezone_" ) + zoneName + ".png" ) ); #ifdef DEBUG_TIMEZONES - timeZoneImages.last().setText( ZONE_NAME, zones.at( i ) ); + if ( timeZoneImages.last().size() != background.size() ) + { + cWarning() << "Timezone image size mismatch" << zoneName << timeZoneImages.last().size(); + } + timeZoneImages.last().setText( ZONE_NAME, zoneName ); #endif } } -void TimeZoneWidget::setCurrentLocation( QString region, QString zone ) +void +TimeZoneWidget::setCurrentLocation( QString regionName, QString zoneName ) { - QHash > hash = LocaleGlobal::getLocations(); - - if ( !hash.contains( region ) ) - return; - - QList locations = hash.value( region ); - for ( int i = 0; i < locations.size(); ++i ) + using namespace CalamaresUtils::Locale; + const auto& regions = TZRegion::fromZoneTab(); + auto* region = regions.find< TZRegion >( regionName ); + if ( !region ) { - if ( locations.at( i ).zone == zone ) - { - setCurrentLocation( locations.at( i ) ); - break; - } + return; + } + + auto* zone = region->zones().find< TZZone >( zoneName ); + if ( zone ) + { + setCurrentLocation( zone ); } } -void TimeZoneWidget::setCurrentLocation( LocaleGlobal::Location location ) +void +TimeZoneWidget::setCurrentLocation( const CalamaresUtils::Locale::TZZone* location ) { - currentLocation = location; + m_currentLocation = location; // Set zone - QPoint pos = getLocationPosition( currentLocation.longitude, currentLocation.latitude ); + QPoint pos = getLocationPosition( location ); #ifdef DEBUG_TIMEZONES - cDebug() << "Setting location" << location.region << location.zone << location.country; - cDebug() << Logger::SubEntry << "longitude" << location.longitude << "latitude" << location.latitude; + cDebug() << "Setting location" << location->region() << location->zone() << '(' << location->country() << '@' << location->latitude() << 'N' << location->longitude() << 'E' << ')'; cDebug() << Logger::SubEntry << "pixel x" << pos.x() << "pixel y" << pos.y(); bool found = false; @@ -104,7 +120,7 @@ void TimeZoneWidget::setCurrentLocation( LocaleGlobal::Location location ) for ( int i = 0; i < timeZoneImages.size(); ++i ) { - QImage zone = timeZoneImages[i]; + QImage zone = timeZoneImages[ i ]; // If not transparent set as current if ( zone.pixel( pos ) != RGB_TRANSPARENT ) @@ -119,7 +135,9 @@ void TimeZoneWidget::setCurrentLocation( LocaleGlobal::Location location ) cDebug() << Logger::SubEntry << "First zone found" << i << zone.text( ZONE_NAME ); } else + { cDebug() << Logger::SubEntry << "Also in zone" << i << zone.text( ZONE_NAME ); + } #else currentZoneImage = zone; break; @@ -129,16 +147,17 @@ void TimeZoneWidget::setCurrentLocation( LocaleGlobal::Location location ) // Repaint widget repaint(); + emit locationChanged( m_currentLocation ); } - //### //### Private //### -QPoint TimeZoneWidget::getLocationPosition( double longitude, double latitude ) +QPoint +TimeZoneWidget::getLocationPosition( double longitude, double latitude ) { const int width = this->width(); const int height = this->height(); @@ -152,39 +171,64 @@ QPoint TimeZoneWidget::getLocationPosition( double longitude, double latitude ) // of the different cities / regions looks ok -- at least Thule ends up in the right // country, and Inuvik isn't in the ocean. if ( latitude > 70.0 ) + { y -= sin( MATH_PI * ( latitude - 70.0 ) / 56.0 ) * MAP_Y_OFFSET * height * 0.8; + } if ( latitude > 74.0 ) + { y += 4; + } if ( latitude > 69.0 ) + { y -= 2; + } if ( latitude > 59.0 ) + { y -= 4 * int( ( latitude - 54.0 ) / 5.0 ); + } if ( latitude > 54.0 ) + { y -= 2; + } if ( latitude > 49.0 ) - y -= int ( (latitude - 44.0) / 5.0 ); + { + y -= int( ( latitude - 44.0 ) / 5.0 ); + } // Far south, some stretching occurs as well, but it is less pronounced. // Move down by 1 pixel per 5 degrees past 10 south if ( latitude < 0 ) - y += int( (-latitude) / 5.0 ); + { + y += int( ( -latitude ) / 5.0 ); + } // Antarctica isn't shown on the map, but you could try clicking there if ( latitude < -60 ) + { y = height - 1; + } if ( x < 0 ) - x = width+x; + { + x = width + x; + } if ( x >= width ) + { x -= width; + } if ( y < 0 ) - y = height+y; + { + y = height + y; + } if ( y >= height ) + { y -= height; + } - return QPoint( int(x), int(y) ); + return QPoint( int( x ), int( y ) ); } -void TimeZoneWidget::paintEvent( QPaintEvent* ) +void +TimeZoneWidget::paintEvent( QPaintEvent* ) { const int width = this->width(); const int height = this->height(); @@ -201,90 +245,107 @@ void TimeZoneWidget::paintEvent( QPaintEvent* ) painter.drawImage( 0, 0, currentZoneImage ); #ifdef DEBUG_TIMEZONES - QPoint point = getLocationPosition( currentLocation.longitude, currentLocation.latitude ); + QPoint point = getLocationPosition( m_currentLocation ); // Draw latitude lines - for ( int y_lat = -50; y_lat < 80 ; y_lat+=5 ) + for ( int y_lat = -50; y_lat < 80; y_lat += 5 ) { QPen p( y_lat ? Qt::black : Qt::red ); p.setWidth( 0 ); painter.setPen( p ); QPoint latLine0( getLocationPosition( 0, y_lat ) ); - int llx = latLine0.x() + ((y_lat & 1) ? -10 : 0); + int llx = latLine0.x() + ( ( y_lat & 1 ) ? -10 : 0 ); int lly = latLine0.y(); - for ( int c = 0 ; c < width ; ++c ) + for ( int c = 0; c < width; ++c ) + { painter.drawPoint( c, lly ); + } } // Just a dot in the selected location, no label painter.setPen( Qt::red ); painter.drawPoint( point ); #else // Draw pin at current location - QPoint point = getLocationPosition( currentLocation.longitude, currentLocation.latitude ); + QPoint point = getLocationPosition( m_currentLocation ); - painter.drawImage( point.x() - pin.width()/2, point.y() - pin.height()/2, pin ); + painter.drawImage( point.x() - pin.width() / 2, point.y() - pin.height() / 2, pin ); // Draw text and box - const int textWidth = fontMetrics.horizontalAdvance( LocaleGlobal::Location::pretty( currentLocation.zone ) ); + const int textWidth = fontMetrics.horizontalAdvance( m_currentLocation ? m_currentLocation->tr() : QString() ); const int textHeight = fontMetrics.height(); - QRect rect = QRect( point.x() - textWidth/2 - 5, point.y() - textHeight - 8, textWidth + 10, textHeight - 2 ); + QRect rect = QRect( point.x() - textWidth / 2 - 5, point.y() - textHeight - 8, textWidth + 10, textHeight - 2 ); if ( rect.x() <= 5 ) + { rect.moveLeft( 5 ); - if ( rect.right() >= width-5 ) + } + if ( rect.right() >= width - 5 ) + { rect.moveRight( width - 5 ); + } if ( rect.y() <= 5 ) + { rect.moveTop( 5 ); - if ( rect.y() >= height-5 ) - rect.moveBottom( height-5 ); + } + if ( rect.y() >= height - 5 ) + { + rect.moveBottom( height - 5 ); + } - painter.setPen( QPen() ); // no pen + painter.setPen( QPen() ); // no pen painter.setBrush( QColor( 40, 40, 40 ) ); painter.drawRoundedRect( rect, 3, 3 ); painter.setPen( Qt::white ); - painter.drawText( rect.x() + 5, rect.bottom() - 4, LocaleGlobal::Location::pretty( currentLocation.zone ) ); + painter.drawText( rect.x() + 5, rect.bottom() - 4, m_currentLocation ? m_currentLocation->tr() : QString() ); #endif painter.end(); } - -void TimeZoneWidget::mousePressEvent( QMouseEvent* event ) +void +TimeZoneWidget::mousePressEvent( QMouseEvent* event ) { if ( event->button() != Qt::LeftButton ) + { return; + } // Set nearest location int nX = 999999, mX = event->pos().x(); int nY = 999999, mY = event->pos().y(); - QHash > hash = LocaleGlobal::getLocations(); - QHash >::iterator iter = hash.begin(); - while ( iter != hash.end() ) + using namespace CalamaresUtils::Locale; + const TZZone* closest = nullptr; + for ( const auto* region_p : TZRegion::fromZoneTab() ) { - QList locations = iter.value(); - - for ( int i = 0; i < locations.size(); ++i ) + const auto* region = dynamic_cast< const TZRegion* >( region_p ); + if ( region ) { - LocaleGlobal::Location loc = locations[i]; - QPoint locPos = getLocationPosition( loc.longitude, loc.latitude ); - - if ( ( abs( mX - locPos.x() ) + abs( mY - locPos.y() ) < abs( mX - nX ) + abs( mY - nY ) ) ) + for ( const auto* zone_p : region->zones() ) { - currentLocation = loc; - nX = locPos.x(); - nY = locPos.y(); + const auto* zone = dynamic_cast< const TZZone* >( zone_p ); + if ( zone ) + { + QPoint locPos = getLocationPosition( zone->longitude(), zone->latitude() ); + + if ( ( abs( mX - locPos.x() ) + abs( mY - locPos.y() ) < abs( mX - nX ) + abs( mY - nY ) ) ) + { + closest = zone; + nX = locPos.x(); + nY = locPos.y(); + } + } } } - - ++iter; } - // Set zone image and repaint widget - setCurrentLocation( currentLocation ); - - // Emit signal - emit locationChanged( currentLocation ); + if ( closest ) + { + // Set zone image and repaint widget + setCurrentLocation( closest ); + // Emit signal + emit locationChanged( m_currentLocation ); + } } diff --git a/src/modules/locale/timezonewidget/timezonewidget.h b/src/modules/locale/timezonewidget/timezonewidget.h index dd49b3311..d91c5cf27 100644 --- a/src/modules/locale/timezonewidget/timezonewidget.h +++ b/src/modules/locale/timezonewidget/timezonewidget.h @@ -24,55 +24,48 @@ #ifndef TIMEZONEWIDGET_H #define TIMEZONEWIDGET_H -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "localeglobal.h" +#include "locale/TimeZone.h" -#define RGB_TRANSPARENT 0 -#define ZONES "0.0 1.0 2.0 3.0 3.5 4.0 4.5 5.0 5.5 5.75 6.0 6.5 7.0 8.0 9.0 9.5 10.0 10.5 11.0 11.5 12.0 12.75 13.0 -1.0 -2.0 -3.0 -3.5 -4.0 -4.5 -5.0 -5.5 -6.0 -7.0 -8.0 -9.0 -9.5 -10.0 -11.0" -#define X_SIZE 780 -#define Y_SIZE 340 - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include class TimeZoneWidget : public QWidget { Q_OBJECT public: + using TZZone = CalamaresUtils::Locale::TZZone; + explicit TimeZoneWidget( QWidget* parent = nullptr ); - LocaleGlobal::Location getCurrentLocation() - { - return currentLocation; - } void setCurrentLocation( QString region, QString zone ); - void setCurrentLocation( LocaleGlobal::Location location ); + void setCurrentLocation( const TZZone* location ); + const TZZone* currentLocation() { return m_currentLocation; } + signals: - void locationChanged( LocaleGlobal::Location location ); + void locationChanged( const TZZone* location ); private: QFont font; QImage background, pin, currentZoneImage; - QList timeZoneImages; - LocaleGlobal::Location currentLocation; + QList< QImage > timeZoneImages; + const TZZone* m_currentLocation = nullptr; // Not owned by me - QPoint getLocationPosition( const LocaleGlobal::Location& l ) - { - return getLocationPosition( l.longitude, l.latitude ); - } + QPoint getLocationPosition( const TZZone* l ) { return getLocationPosition( l->longitude(), l->latitude() ); } QPoint getLocationPosition( double longitude, double latitude ); void paintEvent( QPaintEvent* event ); void mousePressEvent( QMouseEvent* event ); }; -#endif // TIMEZONEWIDGET_H +#endif // TIMEZONEWIDGET_H