diff --git a/org.kde.gcompris.appdata.xml b/org.kde.gcompris.appdata.xml index f9abf5a9a..c04b60905 100644 --- a/org.kde.gcompris.appdata.xml +++ b/org.kde.gcompris.appdata.xml @@ -1,830 +1,831 @@ org.kde.gcompris.desktop org.kde.gcompris.desktop org.kde.gcompris.desktop org.kde.gcompris.desktop org.kde.gcompris.desktop org.kde.gcompris.desktop org.kde.gcompris.desktop org.kde.gcompris.desktop org.kde.gcompris.desktop org.kde.gcompris.desktop org.kde.gcompris.desktop org.kde.gcompris.desktop org.kde.gcompris.desktop xxorg.kde.gcompris.desktopxx + org.kde.gcompris.desktop CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 CC0-1.0 xxCC0-1.0xx CC0-1.0 CC0-1.0 GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ GPL-3.0+ xxGPL-3.0+xx GPL-3.0+ GPL-3.0+ GCompris Educational Game لعبة «فهمت» التّعليميّة Xuegu educativu Gcompris Joc educatiu GCompris Joc educatiu GCompris GCompris-Lernspiel Εκπαιδευτικό παιχνίδι GCompris GCompris Educational Game Juego educativo GCompris GCompris, opettavainen peli Jeu éducatif GCompris Xogo educativo GCompris Gioco didattico GCompris GCompris 교육용 게임 Educatief spel GCompris GCompris leik-og-lær-spel Gra edukacyjna GCompris Jogo Educativo GCompris Jogo educacional GCompris Joc educațional GCompris Набор обучающих игр GCompris Výuková hra GCompris Izobraževalna igra GCompris GCompris pedagogiskt spel Освітня гра GCompris xxGCompris Educational Gamexx GCompris 教育游戏 GCompris 教育遊戲 Multi-Activity Educational game for children 2 to 10 لعبة تعليميّة متعدّدة الأنشطة للأطفال من سنتين إلى 10 سنوات Joc educatiu amb múltiples activitats per a nens dels 2 a 10 anys Joc educatiu amb múltiples activitats per a nens dels 2 a 10 anys Lernspiel mit vielen Aktivitäten für Kinder von 2 bis 10 Jahren Εκπαιδευτικό παιχνίδι πολλαπλών δραστηριοτήτων για ηλικίες 2 έως 10 ετών Multi-Activity Educational game for children 2 to 10 Juego educativo multiactividad para niños de 2 a 10 años Useampitoimintoinen opettavainen peli 2–10-vuotiaille lapsille Jeu éducatif multi-activités pour les enfants de 2 à 10 ans Xogo educativo con varias actividades para nenos de entre 2 e 10 anos. Gioco didattico multi-attività per bambini da 2 a 10 anni 2-10세 어린이를 위한 다양한 활동이 있는 교육용 게임 Educatief spel met meerdere activiteiten voor kinderen van 2 tot 10 Leik-og-lærspel med mange aktivitetar – for barn frå 2 til 10 år Gra edukacyjna z wieloma aktywnościami dla dzieci w wieku od 2 do 10 lat Jogo Educativo Multi-Actividades para crianças dos 2 aos 10 anos Jogo educacional com várias atividades para crianças de 2 a 10 anos Joc educațional cu activități multiple pentru copii între 2 și 10 ani Интерактивные обучающие игры для детей от 2 до 10 лет Viac-aktivitová výuková hra pre deti od 2 do 10 rokov Izobraževalna igra z več dejavnostmi za otroke med drugim in desetim letom starosti Pedagogiskt multiaktivitetsspel för barn från 2 till 10 år Набір освітніх ігор для дітей від 2 до 10 років xxMulti-Activity Educational game for children 2 to 10xx 为 2 到 10 岁儿童准备的多功能教育游戏 為 2-10 歲孩子設計的教育遊戲

GCompris is an educational software suite comprising of numerous activities for children aged 2 to 10.

«فهمت» هو طقم برمجيّات تعليميّة يضمّ مختلف الأنشطة للأطفال من سنتين إلى 10 سنوات.

El GCompris és una suite de programari educatiu que consisteix de nombroses activitats per a nens i nenes entre els 2 i els 10 anys.

El GCompris és una suite de programari educatiu que consisteix de nombroses activitats per a nens i nenes entre els 2 i els 10 anys.

GCompris ist eine Lernsoftware, die verschiedene Aktivitäten für Kinder im Alter von 2 bis 10 Jahren anbietet.

Το GCompris είναι μια σουίτα εκπαιδευτικού λογισμικού με πολυάριθμες δραστηριότητες για παιδιά ηλικίας 2 έως 10 ετών.

GCompris is an educational software suite comprising of numerous activities for children aged 2 to 10.

GCompris es una suite de software educativo que consta de numerosas actividades para niños de 2 a 10 años.

GCompris on useista toiminnoista koostuva opetusohjelmisto 2–10-vuotiaille lapsille.

GCompris est une suite éducative comprenant de nombreuses activités pour les enfants de 2 à 10 ans.

GCompris é unha colección de programas educativos composta por numerosas actividades para nenos de entre 2 e 10 anos.

GCompris è una raccolta di programmi didattici che comprende numerose attività per bambini da 2 a 10 anni.

GCompris는 2-10세 어린이를 위한 활동을 모아 놓은 교육용 소프트웨어 모음입니다.

GCompris is suite met educatieve software die bestaat uit vele activiteiten voor kinderen vanaf twee tot tien jaar.

GCompris er eit leik-og-lær spel med mange ulike aktivitetar, laga for ungar frå 2 til 10 år.

GCompris to pakiet oprogramowania edukacyjnego z licznymi aktywnościami dla dzieci w wieku od 2 do 10 lat.

O GCompris é um pacote de aplicações educativas que é composto por diversas actividades para as crianças dos 2 aos 10 anos de idade.

GCompris é uma suíte de software educacional que apresenta uma série de atividades para crianças com idade entre 2 e 10 anos.

GCompris este un pachet de software educațional compus din numeroase activități pentru copii între 2 și 10 ani.

GCompris — это набор обучающих игр, рассчитанных на детей в возрасте от 2 до 10 лет.

GCompris je balík výukového softvéru zložený z rôznych aktivít pre deti od 2 do 10 rokov.

Program GCompris je visokokakovostna zbirka izobraževalnih dejavnosti, namenjenih otrokom med drugim in desetim letom starosti.

GCompris är en pedagogisk programsvit som består av en mängd olika aktiviteter för barn från 2 till 10 år gamla.

GCompris — комплекс навчального програмного забезпечення, що складається з багатьох вправ для дітей від 2 до 10 років.

xxGCompris is an educational software suite comprising of numerous activities for children aged 2 to 10.xx

GCompris 是一款教育套件,由针对 2 到 10 岁孩子的许多活动组成。

GCompris 是一套教育軟體的集合,它提供適合兩歲到十歲兒童各種不同的活動。

Some of the activities are game orientated, but nonetheless still educational.

Algunes de les activitats estan orientades a joc, però sempre són educatives.

Algunes de les activitats estan orientades a joc, però sempre són educatives.

Některé aktivity jsou v podobě her, ale přesto jsou poučné.

Einige Aktivitäten sind eher spielerisch, aber immer lehrreich.

Ορισμένες από τις δραστηριότητες είναι απλώς παιχνίδια, αλλά οπωσδήποτε με εκπαιδευτικό χαρακτήρα.

Some of the activities are game orientated, but nonetheless still educational.

Algunas de las actividades son juegos, aunque siguen siendo educativas.

Jotkin toiminnoista ovat pelimäisiä mutta silti opettavaisia.

Certaines activités sont ludiques mais ont toujours un intérêt pédagogique.

Algunhas das actividades están orientadas ao xogo, pero son aínda así educativas.

Alcune delle attività sono orientate al gioco, ma comunque didattiche.

일부 활동은 기능성 게임을 지향합니다.

Sommige activiteiten zijn spelletjes, maar toch leerzaam.

Nokre av aktivitetane er mest som spel, men er likevel lærerike.

Niektóre z aktywności są bardziej grą, lecz nadal bardzo pouczającą.

Algumas das actividades são apresentadas como jogos, mas são educativas à mesma.

Algumas das atividades são de orientação lúdica, mas mesmo assim ainda educacional.

Unele activități sunt orientate pe joacă, dar totuși educative.

Некоторые из заданий представлены в игровой форме, но и они являются обучающими.

Niektoré z aktivít sú herne orientované, ale stále výukové.

Nekatere dejavnosti so bolj podobne igram, vendar še vedno poučne.

Vissa av aktiviteterna är spelorienterade, men trots det ändå pedagogiska.

Деякі із вправ є суто ігровими, але містять і елементи навчання.

xxSome of the activities are game orientated, but nonetheless still educational.xx

一些活动是游戏导向的,不过尽管如此仍是教育性的。

有些活動是遊戲性質,但還是有很棒的教育意義。

Below you can find a list of categories with some of the activities available in that category.

يمكنك أن تجد أدناه قائمة بالفئات وبعض الأنشطة الموجودة في كلّ فئة.

Embaxo pues alcontrar un llistáu d'estayes con delles de les actividaes disponibles nesta

A continuació trobareu una llista de les categories amb algunes de les activitats disponibles en cadascuna.

A continuació trobareu una llista de les categories amb algunes de les activitats disponibles en cadascuna.

Sie können Aktivitäten aus folgenden Bereichen in GCompris finden:

Παρακάτω θα βρείτε μια λίστα με κατηγορίες που περιέχουν ορισμένες από το σύνολο των δραστηριοτήτων σε κάθε κατηγορία.

Below you can find a list of categories with some of the activities available in that category.

A continuación puede encontrar una lista de categorías con algunas de las actividades disponibles en cada una de ellas.

Alta löydät luettelot luokista sekä maininnan joistakin kuhunkin luokkaan kuuluvista toiminnoista.

Vous pouvez trouver ci-dessous une liste des catégories avec certaines de leurs activités.

A continuación atopará unha lista de categorías e mailas actividades dispoñíbeis en cada unha desas categorías.

Di seguito puoi trovare un elenco di categorie con alcune delle attività disponibili per categoria.

아래에서 분류 목록과 해당 분류의 활동을 찾을 수 있습니다.

Hieronder vindt u een lijst met categorieën met enige van de activiteiten beschikbaar in die categorie.

Nedanfor finn du ei oversikt over kategoriar, saman med nokre av aktivitetane i kvar kategori.

Poniżej znajdziesz wykaz kategorii z niektórymi aktywnościami dostępnymi w tej kategorii.

Em baixo, poderá encontrar uma lista de categorias, com algumas das actividades disponíveis para essa categoria.

Abaixo está relacionada uma lista de categorias com algumas das atividades disponíveis em cada uma delas.

Dedesubt puteți găsi o listă de categorii cu unele din activitățile disponibile în acea categorie.

Ниже представлен список категорий с доступными в этих категориях заданиями.

Tu môžete nájsť zoznam kategórií s niektorými aktivitami dostupnými v kategórii.

Spodaj lahko najdete seznam kategorij in nekaj dejavnosti, ki so na voljo v tisti kategoriji.

Nedan finns en lista över kategorier med några av aktiviteterna tillgängliga i varje kategori.

Нижче наведено список категорій із деякими вправами у цих категоріях.

xxBelow you can find a list of categories with some of the activities available in that category.xx

下面列出了一些分类和对应分类中的活动。

下方您可以看到該類別的活動清單。

Currently GCompris offers in excess of 100 activities and more are being developed. GCompris is free software, that means that you can adapt it to your own needs, improve it and, most importantly, share it with children everywhere.

توفّر «فهمت» حاليًّا أكثر من 100 نشاط وثمّة غيرها يجري تطويرها. «فهمت» برمجيّة حرّة، هذا يعني أنّك تستطيع تطويعها حسب احتياجك، وكذلك تطويرها، والأهم من ذلك هو مشاركتها مع الأطفال في كلّ مكان.

Actualment el GCompris ofereix més de 100 activitats i encara se'n desenvolupen més. El GCompris és programari lliure, el qual vol dir que podeu adaptar-lo a les vostres pròpies necessitats, millorar-lo i, el més important, compartir-lo amb nens de tot arreu.

Actualment el GCompris ofereix més de 100 activitats i encara se'n desenvolupen més. El GCompris és programari lliure, el qual vol dir que podeu adaptar-lo a les vostres pròpies necessitats, millorar-lo i, el més important, compartir-lo amb nens de tot arreu.

Insgesamt beinhaltet GCompris mehr als 100 Aktivitäten und wird ständig weiterentwickelt. GCompris ist freie Software. Sie haben also die Möglichkeit, sie ihren Bedürfnissen anzupassen und zu verbessern, und gerne auch alle Kinder der Welt von Ihrer Arbeit profitieren zu lassen.

Προς το παρόν το GCompris προσφέρει περισσότερες από 100 δραστηριότητες και αναπτύσσονται και άλλες. Το GCompris είναι ελεύθερο λογισμικό, το οποίο σημαίνει ότι μπορείτε να το προσαρμόσετε στις ανάγκες σας, να το βελτιώσετε, και, το σπουδαιότερο, να το μοιραστείτε με παιδιά από όλον τον κόσμο.

Currently GCompris offers in excess of 100 activities and more are being developed. GCompris is free software, that means that you can adapt it to your own needs, improve it and, most importantly, share it with children everywhere.

En la actualidad, GCompris ofrece más de 100 actividades y hay muchas más en desarrollo. GCompris es software libre, lo que significa que puede adaptarlo a sus necesidades, mejorarlo y, lo que es más importante, compartirlo con los niños de todo el mundo.

GComprisissa on nykyisellään yli sata toimintoa, ja lisää kehitetään. GCompris on vapaata ohjelmistoa, mikä tarkoittaa, että voit muokata sitä tarpeisiisi, parannella sitä ja mikä tärkeintä jakaa sitä lapsille kaikkialla.

Actuellement, GCompris contient plus de 100 activités et d'autres sont en cours de développement. GCompris est un logiciel libre, ce qui veut dire que vous pouvez l'adapter à vos propres besoins, le modifier et, le plus important, le partager avec des enfants où que ce soit.

Actualmente GCompris ofrece máis de 100 actividades e hai máis en progreso. GCompris é software libre, o que significa que pode adaptalo para axustalo ás súas necesidades, melloralo e, o máis importante, compartilo con nenos de todo o mundo.

Attualmente GCompris offre più di 100 attività e altre sono in fase di sviluppo. GCompris è software libero, che significa che puoi adattarlo alle tue necessità, migliorarlo e, cosa più importante, condividerlo con tutti i bambini.

GCompris는 100개 이상의 활동을 포함하고 있으며 더 많은 활동을 개발하고 있습니다. GCompris는 자유 소프트웨어이며, 필요에 따라서 활동을 개선할 수 있으며 전 세계의 사람들과 공유할 수 있습니다.

Op dit moment biedt GCompris meer dan 100 activiteiten en meer zijn er in ontwikkeling. GCompris is vrije software, dat betekent dat u het kunt aanpassen aan uw eigen behoeften, het verbeteren en, meest belangrijk, het met kinderen overal kun delen.

GCompris har over 100 aktivitetar, og fleire vert utvikla. GCompris er fri programvare. Det vil seia at du kan tilpassa spelet slik du ønskjer, forbetra det og dela det med andre ungar i heile verda.

Obecnie GCompris zapewnia ponad 100 aktywności, a jeszcze więcej jest opracowywanych. GCompris jest darmowym oprogramowaniem, co oznacza, że możesz je dopasować do własnych potrzeb, ulepszać je i co najważniejsze udostępniać je dzieciom.

De momento, o GCompris oferece mais de 100 actividades, estando ainda mais em desenvolvimento. O GCompris é uma aplicação de 'software' livre, o que significa que o poderá adaptar às suas próprias necessidades, melhorá-lo e, o mais importante, partilhá-lo com as crianças em todo o lado.

Atualmente o GCompris oferece mais de 100 atividades e outras mais estão sendo desenvolvidas. O GCompris é um software livre, o que significa que você pode adaptá-lo para as suas próprias necessidades, melhorá-lo e, mais importante, compartilhar com as crianças de todo o mundo.

Momentan GCompris oferă peste 100 de activități și multe altele sunt în lucru. GCompris este software liber, ceea ce înseamnă că poate fi adaptat nevoilor dumneavoastră, îmbunătățit, dar mai ales, partajat cu copii de pretutindeni.

В настоящее время GCompris содержит более 100 упражнений, и новые находятся в разработке. GCompris — свободное ПО, и это значит, что вы можете приспособить его для своих нужд, улучшить, а самое главное — поделиться им с детьми во всём мире.

Aktuálne GCompris ponúka vyše 100 aktivít a ďalšie sa vyvíjajú. GCompris je slobodný softvér, čo znamená, že si ho môžete prispôsobiť na vlastné potreby, zlepšiť, a hlavne zdieľať s deťmi všade.

GCompris trenutno ponuja več kot 100 dejavnosti, še več pa jih je v razvoju. GCompris je prosta programska oprema, kar pomeni, da jo lahko prilagodite po svoje, še pomembneje pa je, da jo lahko delite z otroki širom sveta.

För närvarande erbjuder GCompris över 100 aktiviteter och ännu fler håller på att utvecklas. GCompris är fri programvara, vilket betyder att man kan anpassa det till sina egna behov, och viktigast av allt, dela det med barn överallt.

У поточній версії GCompris понад 100 вправ. Розробники постійно працюють над новими вправами. GCompris є вільним програмним забезпеченням, це означає, що ви можете адаптувати програму до власних потреб, покращувати її і, що найважливіше, ділитися вашими творіннями із усіма дітьми.

xxCurrently GCompris offers in excess of 100 activities and more are being developed. GCompris is free software, that means that you can adapt it to your own needs, improve it and, most importantly, share it with children everywhere.xx

当前 GCompris 提供超过100个活动,还有更多的正在开发中。GCompris 是自由软件,这意味着你可以根据你的需要进行调整、改进,以及最重要的一点,和世界各地的孩子们分享。

目前 GCompris 提供超過 100 個活動,還有更多正在開發中。GCompris 是一套自由軟體,表示您可以根據您自己的需求來改進,並分享給所有的孩子們。

http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png xxhttp://gcompris.net/screenshots-qt/middle/canal_lock.pngxx http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/canal_lock.png http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ xxhttp://gcompris.net/screenshots-qt/middle/xx http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/ http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png xxhttp://gcompris.net/screenshots-qt/middle/click_on_letter_up.pngxx http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/click_on_letter_up.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame-nn.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png xxhttp://gcompris.net/screenshots-qt/middle/clockgame.pngxx http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/clockgame.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix-nn.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png xxhttp://gcompris.net/screenshots-qt/middle/color_mix.pngxx http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/color_mix.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors-nn.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png xxhttp://gcompris.net/screenshots-qt/middle/colors.pngxx http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/colors.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png xxhttp://gcompris.net/screenshots-qt/middle/enumerate.pngxx http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/enumerate.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png xxhttp://gcompris.net/screenshots-qt/middle/fifteen.pngxx http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/fifteen.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png xxhttp://gcompris.net/screenshots-qt/middle/hexagon.pngxx http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/hexagon.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png xxhttp://gcompris.net/screenshots-qt/middle/redraw_symmetrical.pngxx http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/redraw_symmetrical.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png xxhttp://gcompris.net/screenshots-qt/middle/scalesboard.pngxx http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/scalesboard.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png xxhttp://gcompris.net/screenshots-qt/middle/traffic.pngxx http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/screenshots-qt/middle/traffic.png http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ http://gcompris.net/ xxhttp://gcompris.net/xx http://gcompris.net/ http://gcompris.net/ https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris xxhttps://bugs.kde.org/enter_bug.cgi?format=guided&product=gcomprisxx https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris https://bugs.kde.org/enter_bug.cgi?format=guided&product=gcompris bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net xxbruno.coudoin@gcompris.netxx bruno.coudoin@gcompris.net bruno.coudoin@gcompris.net
diff --git a/src/activities/baby_wordprocessor/BabyWordprocessor.qml b/src/activities/baby_wordprocessor/BabyWordprocessor.qml index 4be3cbb27..f9a1952a3 100644 --- a/src/activities/baby_wordprocessor/BabyWordprocessor.qml +++ b/src/activities/baby_wordprocessor/BabyWordprocessor.qml @@ -1,261 +1,259 @@ /* GCompris - baby_wordprocessor.qml * * Copyright (C) 2015 Bruno Coudoin * * Authors: * Bruno Coudoin (GTK+ version) * Bruno Coudoin (Qt Quick port) * * This program 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. * * This program 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 this program; if not, see . */ import QtQuick 2.1 import GCompris 1.0 import QtQuick.Controls 1.0 import "../../core" ActivityBase { id: activity onStart: focus = true onStop: {} pageComponent: Rectangle { id: background anchors.fill: parent color: 'white' signal start signal stop Component.onCompleted: { activity.start.connect(start) } onStart: { keyboard.populate(); edit.forceActiveFocus(); } Column { id: controls - width: 200 * ApplicationInfo.ratio + width: 120 * ApplicationInfo.ratio anchors { right: parent.right top: parent.top bottom: bar.top margins: 10 } spacing: 10 Button { - style: GCButtonStyle {} - height: 30 * ApplicationInfo.ratio - width: parent.width + style: GCButtonStyle { textSize: "title"} text: qsTr("Title") + width: parent.width onClicked: edit.formatLineWith('h2') } Button { - style: GCButtonStyle {} - height: 30 * ApplicationInfo.ratio - width: parent.width + style: GCButtonStyle { textSize: "subtitle"} text: qsTr("Subtitle") + width: parent.width onClicked: edit.formatLineWith('h3') } Button { - style: GCButtonStyle {} - height: 30 * ApplicationInfo.ratio + style: GCButtonStyle { textSize: "regular"} width: parent.width text: qsTr("Paragraph") onClicked: edit.formatLineWith('p') } } Flickable { id: flick anchors { left: parent.left right: controls.left top: parent.top bottom: bar.top margins: 10 } contentWidth: edit.paintedWidth contentHeight: edit.paintedHeight clip: true flickableDirection: Flickable.VerticalFlick function ensureVisible(r) { if (contentX >= r.x) contentX = r.x; else if (contentX+width <= r.x+r.width) contentX = r.x+r.width-width; if (contentY >= r.y) contentY = r.y; else if (contentY+height <= r.y+r.height) contentY = r.y+r.height-height; } TextEdit { id: edit width: flick.width height: flick.height focus: true wrapMode: TextEdit.Wrap onCursorRectangleChanged: flick.ensureVisible(cursorRectangle) textFormat: TextEdit.RichText + color: "#373737" font { pointSize: (18 + ApplicationSettings.baseFontSize) * ApplicationInfo.fontRatio capitalization: ApplicationSettings.fontCapitalization weight: Font.DemiBold family: GCSingletonFontLoader.fontLoader.name letterSpacing: ApplicationSettings.fontLetterSpacing wordSpacing: 10 } cursorDelegate: Rectangle { id: cursor width: 10 // height should be set automatically as mention in cursorRectangle property // documentation but it does not work height: parent.cursorRectangle.height - color: 'red' + color: '#DF543D' SequentialAnimation on opacity { running: true loops: Animation.Infinite PropertyAnimation { to: 0.2 duration: 1000 } PropertyAnimation { to: 1 duration: 1000 } } } function insertText(text) { edit.insert(cursorPosition, text) } function backspace() { if(cursorPosition > 0) { moveCursorSelection(cursorPosition - 1, TextEdit.SelectCharacters) cut() } } function formatLineWith(tag) { var text = getText(0, length) var initialPosition = cursorPosition var first = cursorPosition - 1 for(; first >= 0; first--) { if(text.charCodeAt(first) === 8233) break } first++ var last = cursorPosition for(; last < text.length; last++) { if(text.charCodeAt(last) === 8233) break } var line = getText(first, last) remove(first, last) insert(first, '<' + tag + '>' + line + '') cursorPosition = initialPosition } } } DialogHelp { id: dialogHelp onClose: home() } Bar { id: bar anchors.bottom: keyboard.top content: BarEnumContent { value: help | home | reload } onHelpClicked: { displayDialog(dialogHelp) } onHomeClicked: activity.home() onReloadClicked: edit.text = '' } VirtualKeyboard { id: keyboard anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter width: parent.width visible: ApplicationSettings.isVirtualKeyboard && !ApplicationInfo.isMobile onKeypress: { if(text == backspace) edit.backspace() else edit.insertText(text) } onError: console.log("VirtualKeyboard error: " + msg); function populate() { layout = [ [ { label: "0" }, { label: "1" }, { label: "2" }, { label: "3" }, { label: "4" }, { label: "5" }, { label: "6" }, { label: "7" }, { label: "8" }, { label: "9" } ], [ { label: "A" }, { label: "B" }, { label: "C" }, { label: "D" }, { label: "E" }, { label: "F" }, { label: "G" }, { label: "H" }, { label: "I" } ], [ { label: "J" }, { label: "K" }, { label: "L" }, { label: "M" }, { label: "N" }, { label: "O" }, { label: "P" }, { label: "Q" }, { label: "R" } ], [ { label: "S" }, { label: "T" }, { label: "U" }, { label: "V" }, { label: "W" }, { label: "X" }, { label: "Y" }, { label: "Z" }, { label: " " }, { label: backspace } ] ] } } } } diff --git a/src/activities/baby_wordprocessor/baby_wordprocessor.svg b/src/activities/baby_wordprocessor/baby_wordprocessor.svg index ff1e4dbb6..b8247ed42 100644 --- a/src/activities/baby_wordprocessor/baby_wordprocessor.svg +++ b/src/activities/baby_wordprocessor/baby_wordprocessor.svg @@ -1,721 +1,903 @@ + + id="linearGradient4844"> + style="stop-color:#4f6ba1;stop-opacity:1;" + offset="0" + id="stop4846" /> + style="stop-color:#8c9ebe;stop-opacity:1" + offset="1" + id="stop4848" /> + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + id="g4447" + transform="translate(2,18)"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + id="g4639" + transform="translate(16,-2)"> + + + + + + + + + + + + + + + + + + + + image/svg+xml Openclipart - tango input keyboard + 2010-03-27T10:17:43 - "Keyboard" icon from <a href="http://tango.freedesktop.org/Tango_Desktop_Project"> Tango Project </a> \n<br><br> \nSince version 0.8.90 Tango Project icons are Public Domain: <a href="http://tango.freedesktop.org/Frequently_Asked_Questions#Terms_of_Use.3F"> Tango Project FAQ </a> + "Keyboard" icon from <a href="http://tango.freedesktop.org/Tango_Desktop_Project"> Tango Project </a> +\n<br><br> +\nSince version 0.8.90 Tango Project icons are Public Domain: <a href="http://tango.freedesktop.org/Frequently_Asked_Questions#Terms_of_Use.3F"> Tango Project FAQ </a> https://openclipart.org/detail/34561/tango-input-keyboard-by-warszawianka warszawianka device externalsource hardware icon input keyboard tango diff --git a/src/activities/lang/resource/content-ro.json b/src/activities/lang/resource/content-ro.json index eaf2000ae..56da76423 100644 --- a/src/activities/lang/resource/content-ro.json +++ b/src/activities/lang/resource/content-ro.json @@ -1,577 +1,585 @@ { - "alligator.ogg": "aligator", - "anchor.ogg": "ancoră", - "angel.ogg": "înger", - "animal.ogg": "animal", "ate.ogg": "mâncat", - "athlete.ogg": "atlet", - "back.ogg": "spate", - "badge.ogg": "insignă", - "bag.ogg": "geantă", - "bait.ogg": "momeală", - "bake.ogg": "coacere", - "balance.ogg": "echilibru", - "ballet.ogg": "balet", - "ball.ogg": "minge", - "bank.ogg": "bancă", + "bake.ogg": "copt", "bark.ogg": "lătrat", - "barn.ogg": "hambar", - "bath.ogg": "baie", - "bat.ogg": "liliac", - "bay.ogg": "golf", - "beach.ogg": "plajă", - "bead.ogg": "mărgea", - "bed.ogg": "pat", - "bee.ogg": "albină", - "beetle.ogg": "gândac", "beg.ogg": "cerșit", - "bench.ogg": "bancă", - "bib.ogg": "bavețică", - "big.ogg": "mare", - "bike.ogg": "bicicletă", - "bird.ogg": "pasăre", "bite.ogg": "mușcat", - "bit.ogg": "bucățică", - "black.ogg": "negru", - "blind.ogg": "orb", "blink.ogg": "clipit", - "block.ogg": "(mono)bloc", - "blond.ogg": "blond", - "blue.ogg": "albastru", - "board.ogg": "scândură", - "boat.ogg": "barcă", "boil.ogg": "fiert", - "bomb.ogg": "bombă", - "bone.ogg": "os", - "book.ogg": "carte", - "box.ogg": "cutie", - "boy.ogg": "băiat", - "braid.ogg": "codiță împletită", - "brain.ogg": "creier", - "branch.ogg": "ramură", - "bread.ogg": "pâine", "break.ogg": "spart", - "brick.ogg": "cărămidă", - "bride.ogg": "mireasă", - "bridge.ogg": "pod", - "bright.ogg": "strălucitor", - "brother.ogg": "frate", - "brown.ogg": "maro", - "brush.ogg": "pensulă", - "bud.ogg": "mugur", - "bug.ogg": "insectă", - "bump.ogg": "cucui", - "bun.ogg": "chiflă", - "bush.ogg": "tufiș", - "cabin.ogg": "cabană", - "cage.ogg": "cușcă", - "cake.ogg": "tort", "call.ogg": "chemat", - "camel.ogg": "cămilă", - "camp.ogg": "tabără", - "candle.ogg": "lumânare", - "candy.ogg": "bomboană", - "cane.ogg": "baston", - "canoe.ogg": "canoe", - "can.ogg": "cutie de conserve", - "cape.ogg": "robă", - "cap.ogg": "șapcă", - "card.ogg": "carte poștală", - "car.ogg": "mașină", - "carrot.ogg": "morcov", - "cart.ogg": "cărucior de cumpărături", - "cash.ogg": "bani în numerar", - "castle.ogg": "castel", "catch.ogg": "prins", - "cat.ogg": "pisică", - "cave.ogg": "peșteră", "centipede.ogg": "centiped", - "chair.ogg": "scaun", - "chalk.ogg": "cretă", - "chat.ogg": "conversație ușoară", - "cheer.ogg": "înveselire", - "cheese.ogg": "brânză", - "cherry.ogg": "cireașă", - "chest.ogg": "cufăr", - "chicken.ogg": "pui de găină", - "chick.ogg": "puișor de găină", - "chief.ogg": "căpetenie", - "child.ogg": "copil", - "chimp.ogg": "cimpanzeu", - "chin.ogg": "bărbie", - "chocolate.ogg": "ciocolată", + "chat.ogg": "pălăvrăgeală", "chop.ogg": "retezat", - "clam.ogg": "scoică", "clap.ogg": "aplaudat", - "class.ogg": "oră de curs", - "claw.ogg": "gheară", - "clay.ogg": "lut", "clean.ogg": "curățat", - "cliff.ogg": "faleză", - "climb.ogg": "urcare", - "clock.ogg": "ceas", - "cloth.ogg": "pânză", - "cloud.ogg": "nor", - "clown.ogg": "clovn", - "coach.ogg": "antrenor", - "coat.ogg": "palton", - "coin.ogg": "monedă", - "cold.ogg": "rece", - "color.ogg": "culoare", - "comb.ogg": "pieptene", - "cone.ogg": "con", - "cookie.ogg": "fursecuri", - "corn.ogg": "porumb", - "couch.ogg": "canapea", - "cowboy.ogg": "cowboy", - "cow.ogg": "vacă", - "crab.ogg": "crab", "crawl.ogg": "târât", - "crazy.ogg": "nebun", - "crib.ogg": "pătuț de bebeluș", "croak.ogg": "orăcăit", - "crocodile.ogg": "crocodil", - "crown.ogg": "coroană", - "crow.ogg": "cioară", - "crumb.ogg": "fărâmitură", - "crust.ogg": "crustă", "cry.ogg": "plâns", - "cube.ogg": "cub", - "cucumber.ogg": "castravete", - "cute.ogg": "drăguț", "cut.ogg": "tăiat", - "dad.ogg": "tată", - "dance.ogg": "dans", - "danger.ogg": "pericol", - "den.ogg": "bârlog", - "desk.ogg": "masă", "dig.ogg": "săpat", - "dirt.ogg": "murdărie", - "dirty.ogg": "murdar", - "dish.ogg": "vas de mâncare", - "dive.ogg": "scufundare", - "dog.ogg": "câine", - "door.ogg": "ușă", - "dot.ogg": "punct", - "dragon.ogg": "dragon", "drank.ogg": "băut", "draw.ogg": "desen", "dream.ogg": "vis", - "dress.ogg": "rochie", - "drink.ogg": "băutură", "drive.ogg": "condus", "drool.ogg": "salivat", - "drum.ogg": "tobă", - "dry.ogg": "uscare", - "duck.ogg": "rață", - "dune.ogg": "dună", - "ear.ogg": "ureche", - "earth.ogg": "pământ", + "dry.ogg": "uscat", "eat.ogg": "mâncat", - "empty.ogg": "gol", - "explore.ogg": "explorare", - "face.ogg": "față", - "fair.ogg": "târg", - "fan.ogg": "ventilator", - "farm.ogg": "fermă", - "fat.ogg": "gras", - "feast.ogg": "festin", - "feet.ogg": "labele picioarelor", "fell.ogg": "căzut", "fetch.ogg": "aport", "find.ogg": "găsit", - "fin.ogg": "aripioară înotătoare", - "fire.ogg": "foc", - "fish.ogg": "pește", - "fist.ogg": "pumn", - "flag.ogg": "steag", - "flame.ogg": "flacără", - "flash.ogg": "lanternă", - "flat.ogg": "plan", - "flies.ogg": "muște", "float.ogg": "plutit", - "flour.ogg": "făină", - "flower.ogg": "floare", - "flute.ogg": "fluier", "fly.ogg": "zbor", - "food.ogg": "mâncare", - "foot.ogg": "laba piciorului", - "fork.ogg": "furculiță", - "fountain.ogg": "fântână", - "fox.ogg": "vulpe", "freeze.ogg": "îngheț", - "friend.ogg": "prieten", - "frog.ogg": "broască", - "front.ogg": "în față", - "frown.ogg": "încruntat", - "fruit.ogg": "fruct", - "fudge.ogg": "caramele", - "full.ogg": "plin", - "fun.ogg": "distractiv", - "fur.ogg": "blană", - "game.ogg": "joc", - "garden.ogg": "grădină", - "gem.ogg": "piatră prețioasă", - "giant.ogg": "gigant", - "gift.ogg": "cadou", - "giraffe.ogg": "girafă", - "girl.ogg": "fată", - "glass.ogg": "pahar", - "glove.ogg": "mănușă", - "glue.ogg": "lipici", - "gnome.ogg": "spiriduș", - "goat.ogg": "capră", - "grass.ogg": "iarbă", - "grave.ogg": "mormânt", - "gray.ogg": "gri", - "green.ogg": "verde", - "grin.ogg": "rânjet", - "ground.ogg": "sol", "growl.ogg": "mârâit", - "gum.ogg": "gumă", - "hair.ogg": "păr", - "hand.ogg": "mână", - "happy.ogg": "fericit", "hatch.ogg": "eclozat", - "hat.ogg": "pălărie", - "hay.ogg": "fân", - "head.ogg": "cap", "hear.ogg": "auzit", - "heat.ogg": "căldură", - "hedge.ogg": "gard viu", - "hen.ogg": "găină", - "herd.ogg": "turmă", - "high.ogg": "înalt", - "hike.ogg": "drumeție", - "hip.ogg": "șold", - "hit.ogg": "lovire", - "hole.ogg": "gaură", - "home.ogg": "casă", - "hook.ogg": "cârlig", - "hop.ogg": "sărit", - "hose.ogg": "furtun", - "hot.ogg": "fierbinte", - "hound.ogg": "ogar", "howl.ogg": "urlat", - "huge.ogg": "uriaș", "hug.ogg": "îmbrățișat", - "hunter.ogg": "vânător", - "hut.ogg": "colibă", - "ice.ogg": "gheață", - "ink.ogg": "cerneală", - "jewel.ogg": "piatră prețioasă", - "jog.ogg": "alergat", - "judge.ogg": "judecător", - "juice.ogg": "suc", "jump.ogg": "sărit", - "kite.ogg": "zmeu", "kneel.ogg": "îngenuncheat", - "knee.ogg": "genunchi", - "knife.ogg": "cuțit", - "knight.ogg": "cavaler", "knit.ogg": "tricotat", - "knot.ogg": "nod", - "lad.ogg": "flăcău", - "lake.ogg": "lac", - "lamb.ogg": "miel", - "lamp.ogg": "lampă", - "land.ogg": "teren", - "lane.ogg": "bandă de circulație", - "lap.ogg": "poală", - "lawn.ogg": "gazon", - "ledge.ogg": "cornișă", - "left.ogg": "stânga", - "lick.ogg": "lins", - "lid.ogg": "capac", - "lift.ogg": "ridicat", - "light.ogg": "lumină", - "lime.ogg": "lămâie verde", - "line.ogg": "linie", - "link.ogg": "verigă", - "lip.ogg": "buză", - "liquid.ogg": "lichid", - "log.ogg": "buștean", + "lick.ogg": "llins", "look.ogg": "privit", - "lunch.ogg": "prânz", - "mad.ogg": "turbat", - "magic.ogg": "magic", - "mane.ogg": "coamă", - "map.ogg": "hartă", - "mask.ogg": "mască", - "match.ogg": "chibrit", - "mate.ogg": "coleg", - "mat.ogg": "rogojină", "meet.ogg": "întâlnit", - "men.ogg": "oameni", - "mice.ogg": "șoareci", - "mole.ogg": "cârtiță", - "mop.ogg": "mop", - "mosquito.ogg": "țânțar", - "mouth.ogg": "gură", - "mud.ogg": "noroi", - "mug.ogg": "cană mare", - "mule.ogg": "catâr", - "mushroom.ogg": "ciupercă", "nap.ogg": "ațipit", - "neck.ogg": "gât", - "nest.ogg": "cuib", - "net.ogg": "plasă", - "night.ogg": "noapte", - "nose.ogg": "nas", - "nut.ogg": "nucă", - "oar.ogg": "vâslă", - "ocean.ogg": "ocean", - "on.ogg": "pe", - "orange-color.ogg": "portocaliu", - "orange.ogg": "portocală", - "owl.ogg": "bufniță", - "ox.ogg": "bou", - "page.ogg": "pagină", - "pair.ogg": "pereche", - "pal.ogg": "prieten", - "pan.ogg": "tigaie", - "patch.ogg": "petic", - "path.ogg": "cărare", - "paw.ogg": "labă", - "peach.ogg": "piersică", "peck.ogg": "ciugulit", - "pencil.ogg": "creion", - "pen.ogg": "stilou", - "pet.ogg": "animal de companie", - "picture.ogg": "pictură", - "pig.ogg": "porc", - "pine.ogg": "pin", - "pink.ogg": "roz", - "plane.ogg": "avion", - "plant.ogg": "plantă", - "plate.ogg": "farfurie plată", "play.ogg": "jucat", "plow.ogg": "arat", - "plum.ogg": "prună", - "pole.ogg": "prăjină", - "pool.ogg": "bazin", - "pope.ogg": "papă", - "pop.ogg": "pop corn", - "pot.ogg": "oală", "pounce.ogg": "înhățat", - "pretty.ogg": "frumoasă", - "price.ogg": "preț", - "prince.ogg": "prinț", - "princess.ogg": "prințesă", - "prize.ogg": "premiu", - "pug.ogg": "mops", - "puppy.ogg": "cățeluș", "quarrel.ogg": "certat", - "queen.ogg": "regină", - "question.ogg": "întrebare", - "quilt.ogg": "plapumă", - "quiz.ogg": "test", - "rage.ogg": "furie", - "rag.ogg": "cârpă", - "rake.ogg": "greblă", - "ramp.ogg": "rampă", - "ran.ogg": "fugă", - "rat.ogg": "șobolan", "read.ogg": "citit", - "red.ogg": "roșu", - "rice.ogg": "orez", - "ride.ogg": "mers cu bicicleta", - "right.ogg": "dreapta", "rip.ogg": "rupt", - "rock.ogg": "rocă", - "roof.ogg": "acoperiș", - "rope.ogg": "coardă", - "rose.ogg": "trandafir", - "round.ogg": "rotund", - "royal.ogg": "regal", - "rug.ogg": "covoraș", "run.ogg": "fugit", - "sad.ogg": "trist", - "sail.ogg": "velă", - "sand.ogg": "nisip", - "sandwich.ogg": "sandwich", "sat.ogg": "șezut", - "sauce.ogg": "sos", - "scale.ogg": "cântar", "scared.ogg": "speriat", - "scarf.ogg": "eșarfă", - "scar.ogg": "cicatrice", - "school.ogg": "școală", - "science.ogg": "știință", "scratch.ogg": "zgâriat", - "scream.ogg": "strigat", - "screw.ogg": "șurub", + "scream.ogg": "țipat", "scribble.ogg": "mâzgălit", - "seat.ogg": "scaun", - "seed.ogg": "sămânță", "see.ogg": "văzut", "shake.ogg": "scuturat", - "shark.ogg": "rechin", - "shed.ogg": "șură", - "shelf.ogg": "raft", - "shell.ogg": "scoică", - "ship.ogg": "vas de navigat", - "shirt.ogg": "cămașă", - "shoe.ogg": "pantof", - "shop.ogg": "magazin", - "shore.ogg": "țărm", - "short.ogg": "pantalon scurt", - "shower.ogg": "duș", - "shrimp.ogg": "crevete", - "shrub.ogg": "tufiș", - "shut.ogg": "închis", - "sick.ogg": "bolnav", - "sign.ogg": "semn", "sing.ogg": "cântat", - "sink.ogg": "chiuvetă", "sip.ogg": "sorbit", "sit.ogg": "șezut", - "skate.ogg": "patinat", - "skin.ogg": "piele", - "ski.ogg": "ski", - "skirt.ogg": "fustă", - "skunk.ogg": "sconcs", - "sky.ogg": "cer", - "sled.ogg": "sanie", "sleep.ogg": "dormit", - "sleeve.ogg": "mânecă", - "sleigh.ogg": "sanie trasă de cai", - "slide.ogg": "tobogan", - "slime.ogg": "mâzgă", - "slope.ogg": "pantă", - "small.ogg": "mic", "smell.ogg": "mirosit", - "smile.ogg": "zâmbet", - "smock.ogg": "bluză", - "smoke.ogg": "fum", "smooch.ogg": "drăgălit", - "snack.ogg": "gustare", - "snail.ogg": "melc", - "snake.ogg": "șarpe", - "sneaker.ogg": "adidas", "sniff.ogg": "adulmecat", - "snow.ogg": "zăpadă", - "sock.ogg": "șosetă", - "spaghetti.ogg": "spaghete", - "spear.ogg": "suliță", - "spider.ogg": "păianjen", - "spike.ogg": "țeapă", "spill.ogg": "vărsat", "splash.ogg": "împroșcat", - "splatter.ogg": "împroșcat", - "sponge.ogg": "burete", - "spoon.ogg": "lingură", - "sport.ogg": "sport", - "spot.ogg": "pată", "spray.ogg": "pulverizat", "spread.ogg": "întins", "spring.ogg": "săltat", - "sprinkle.ogg": "presărat", - "square.ogg": "pătrat", - "squash.ogg": "dovlecel", "squat.ogg": "ghemuit", - "squid.ogg": "calmar", - "squirrel.ogg": "veveriță", - "squirt.ogg": "stropitor cu jet", - "stack.ogg": "stivă", - "stage.ogg": "scenă", - "stamp.ogg": "timbru", - "stand.ogg": "stând", - "stare.ogg": "holbat", - "starfish.ogg": "stea de mare", - "star.ogg": "stea", - "stem.ogg": "tulpină", - "stew.ogg": "tocăniță", - "stick.ogg": "băț", "sting.ogg": "înțepat", - "stone.ogg": "piatră", "stop.ogg": "oprit", - "store.ogg": "magazin", - "stove.ogg": "aragaz", - "straight.ogg": "drept", - "strawberry.ogg": "căpșună", - "straw.ogg": "pai", - "stream.ogg": "curent", - "street.ogg": "stradă", "stretch.ogg": "întins", - "string.ogg": "șir", - "stripe.ogg": "dungă", - "strong.ogg": "puternic", "study.ogg": "studiat", - "stump.ogg": "ciot", - "suit.ogg": "costum", - "summer.ogg": "vară", - "sun.ogg": "soare", - "swan.ogg": "lebădă", - "sweat.ogg": "transpirație", - "swim.ogg": "înotat", - "tag.ogg": "etichetă", - "tall.ogg": "înalt", - "teacher.ogg": "profesoară", "teach.ogg": "predat", "tear.ogg": "rupt", - "teeth.ogg": "dinți", - "thick.ogg": "gros", - "thigh.ogg": "coapsă", "think.ogg": "gândit", - "thread.ogg": "fir", - "throat.ogg": "gâtlej", - "throw.ogg": "aruncat", - "tick.ogg": "căpușă", - "time.ogg": "timp", - "tired.ogg": "obosit", - "toilet.ogg": "toaletă", - "tool.ogg": "unealtă", - "top.ogg": "vârf", - "torch.ogg": "torță", "touch.ogg": "atins", - "towel.ogg": "prosop", - "toy.ogg": "jucărie", - "trail.ogg": "traseu", - "train.ogg": "tren", - "trap.ogg": "capcană", - "trash.ogg": "gunoi", - "tray.ogg": "tavă", - "treat.ogg": "bomboane de servit", - "tree.ogg": "copac", - "truck.ogg": "camion", - "tube.ogg": "tub", - "tune.ogg": "melodie", - "under.ogg": "sub", - "van.ogg": "dubă", - "vet.ogg": "veterinar", "wag.ogg": "dat din coadă", "walk.ogg": "mers pe jos", "wash.ogg": "spălat", - "watch.ogg": "ceas de mână", - "water.ogg": "apă", - "wedge.ogg": "pană", - "wet.ogg": "ud", - "wheat.ogg": "grâu", - "wheel.ogg": "roată", - "whisk.ogg": "tel", "whisper.ogg": "șoptit", - "white.ogg": "alb", - "wig.ogg": "perucă", - "wind.ogg": "vânt", - "wing.ogg": "aripă", "win.ogg": "câștigat", - "wood.ogg": "lemn", - "wrench.ogg": "cheie", + "back.ogg": "spate", + "braid.ogg": "codiță împletită", + "brain.ogg": "creier", + "bump.ogg": "cucui", + "chin.ogg": "bărbie", + "ear.ogg": "ureche", + "face.ogg": "față", + "feet.ogg": "labele picioarelor", + "fist.ogg": "pumn", + "foot.ogg": "laba piciorului", + "grin.ogg": "rânjet", + "hair.ogg": "păr", + "hand.ogg": "mână", + "head.ogg": "cap", + "hip.ogg": "șold", + "knee.ogg": "genunchi", + "lap.ogg": "poală", + "lip.ogg": "buză", + "mouth.ogg": "gură", + "neck.ogg": "gât", + "nose.ogg": "nas", + "scar.ogg": "cicatrice", + "skin.ogg": "piele", + "stare.ogg": "holbat", + "sweat.ogg": "transpirație", + "teeth.ogg": "dinți", + "thigh.ogg": "coapsă", + "throat.ogg": "gâtlej", "wrist.ogg": "încheietura mâinii", - "write.ogg": "scris", - "yarn.ogg": "ghem pentru împletit", - "yum.ogg": "apetisant", + "bib.ogg": "bavețică", + "cap.ogg": "șapcă", + "cape.ogg": "robă", + "coat.ogg": "palton", + "dress.ogg": "rochie", + "glove.ogg": "mănușă", + "hat.ogg": "pălărie", + "patch.ogg": "petic", + "scarf.ogg": "eșarfă", + "shirt.ogg": "cămașă", + "shoe.ogg": "pantof", + "short.ogg": "pantalon scurt", + "skirt.ogg": "fustă", + "sleeve.ogg": "mânecă", + "smock.ogg": "bluză", + "sneaker.ogg": "adidas", + "sock.ogg": "șosetă", + "suit.ogg": "costum", "zoo.ogg": "grădină zoologică", + "danger.ogg": "pericol", + "frown.ogg": "încruntat", + "fun.ogg": "distractiv", + "mad.ogg": "turbat", + "rage.ogg": "furie", + "sad.ogg": "trist", + "smile.ogg": "zâmbet", + "whisk.ogg": "tel", + "chief.ogg": "căpetenie", + "clown.ogg": "clovn", + "coach.ogg": "antrenor", + "cowboy.ogg": "cowboy", + "hunter.ogg": "vânător", + "judge.ogg": "judecător", + "knight.ogg": "cavaler", + "lad.ogg": "flăcău", + "pope.ogg": "papă", + "prince.ogg": "prinț", + "princess.ogg": "prințesă", + "queen.ogg": "regină", + "teacher.ogg": "profesoară", + "vet.ogg": "veterinar", + "boy.ogg": "băiat", + "bride.ogg": "mireasă", + "brother.ogg": "frate", + "child.ogg": "copil", + "dad.ogg": "tată", + "friend.ogg": "prieten", + "girl.ogg": "fată", + "gnome.ogg": "spiriduș", + "mate.ogg": "coleg", + "men.ogg": "oameni", + "pal.ogg": "prieten", + "athlete.ogg": "atlet", + "ballet.ogg": "balet", + "camp.ogg": "tabără", + "cheer.ogg": "înveselire", + "climb.ogg": "urcare", + "dance.ogg": "dans", + "dive.ogg": "scufundare", + "explore.ogg": "explorare", + "hike.ogg": "drumeție", + "hit.ogg": "lovire", + "hop.ogg": "sărit", + "jog.ogg": "alergat", + "lift.ogg": "ridicat", + "ran.ogg": "fugă", + "ride.ogg": "mers așezat pe ceva", + "skate.ogg": "patinat", + "ski.ogg": "ski", + "sport.ogg": "sport", + "swim.ogg": "înotat", + "write.ogg": "scris", + "alligator.ogg": "aligator", + "animal.ogg": "animal", + "bait.ogg": "momeală", + "bat.ogg": "liliac", + "bee.ogg": "albină", + "beetle.ogg": "gândac", + "bird.ogg": "pasăre", + "bug.ogg": "insectă", + "camel.ogg": "cămilă", + "cat.ogg": "pisică", + "chick.ogg": "puișor de găină", + "chicken.ogg": "pui de găină", + "chimp.ogg": "cimpanzeu", + "clam.ogg": "scoică", + "claw.ogg": "gheară", + "cow.ogg": "vacă", + "crab.ogg": "crab", + "crocodile.ogg": "crocodil", + "crow.ogg": "cioară", + "den.ogg": "bârlog", + "dog.ogg": "câine", + "dragon.ogg": "dragon", + "duck.ogg": "rață", + "fin.ogg": "aripioară înotătoare", + "fish.ogg": "pește", + "flies.ogg": "muște", + "fox.ogg": "vulpe", + "frog.ogg": "broască", + "fur.ogg": "blană", + "giraffe.ogg": "girafă", + "goat.ogg": "capră", + "hen.ogg": "găină", + "herd.ogg": "turmă", + "hound.ogg": "ogar", + "lamb.ogg": "lmiel", + "mane.ogg": "coamă", + "mice.ogg": "șoareci", + "mole.ogg": "cârtiță", + "mosquito.ogg": "țânțar", + "mule.ogg": "catâr", + "owl.ogg": "bufniță", + "ox.ogg": "bou", + "paw.ogg": "labă", + "pet.ogg": "animal de companie", + "pig.ogg": "porc", + "pug.ogg": "mops", + "puppy.ogg": "cățeluș", + "rat.ogg": "șobolan", + "shark.ogg": "rechin", + "shell.ogg": "scoică", + "shrimp.ogg": "crevete", + "skunk.ogg": "sconcs", + "slime.ogg": "mâzgă", + "snail.ogg": "melc", + "snake.ogg": "șarpe", + "spider.ogg": "păianjen", + "spike.ogg": "țeapă", + "squid.ogg": "calmar", + "squirrel.ogg": "veveriță", + "starfish.ogg": "stea de mare", + "swan.ogg": "lebădă", + "tick.ogg": "căpușă", + "wing.ogg": "aripă", + "yum.ogg": "apetisant", + "bone.ogg": "os", + "bread.ogg": "pâine", + "bun.ogg": "chiflă", + "cake.ogg": "tort", + "candy.ogg": "bomboană", + "cheese.ogg": "brânză", + "chocolate.ogg": "ciocolată", + "cookie.ogg": "fursec", + "crumb.ogg": "fărâmitură", + "crust.ogg": "crustă", + "drink.ogg": "băutură", + "feast.ogg": "festin", + "flour.ogg": "făină", + "food.ogg": "mâncare", + "fudge.ogg": "caramele", + "gum.ogg": "gumă", + "ice.ogg": "gheață", + "juice.ogg": "suc", + "lunch.ogg": "prânz", + "pop.ogg": "pop corn", + "rice.ogg": "orez", + "sandwich.ogg": "sandwich", + "sauce.ogg": "sos", + "snack.ogg": "gustare", + "spaghetti.ogg": "spaghete", + "sprinkle.ogg": "presărat", + "stew.ogg": "tocăniță", + "treat.ogg": "tratație", + "cherry.ogg": "cireașă", + "fruit.ogg": "fruct", + "lime.ogg": "lămâie verde", + "orange.ogg": "portocală", + "peach.ogg": "piersică", + "plum.ogg": "prună", + "bay.ogg": "golf", + "beach.ogg": "plajă", + "cave.ogg": "peșteră", + "cliff.ogg": "faleză", + "cloud.ogg": "nor", + "cold.ogg": "rece", + "dirt.ogg": "murdărie", + "dune.ogg": "dună", + "earth.ogg": "pământ", + "fire.ogg": "foc", + "flame.ogg": "flacără", + "garden.ogg": "grădină", + "gem.ogg": "piatră prețioasă", + "ground.ogg": "sol", + "heat.ogg": "căldură", + "hole.ogg": "gaură", + "lake.ogg": "lac", + "land.ogg": "teren", + "ledge.ogg": "cornișă", + "mud.ogg": "noroi", + "night.ogg": "noapte", + "ocean.ogg": "ocean", + "path.ogg": "cărare", + "rock.ogg": "rocă", + "sand.ogg": "nisip", + "shore.ogg": "țărm", + "sky.ogg": "cer", + "slope.ogg": "pantă", + "smoke.ogg": "fum", + "snow.ogg": "zăpadă", + "star.ogg": "stea", + "stone.ogg": "piatră", + "stream.ogg": "curent", + "summer.ogg": "vară", + "sun.ogg": "soare", + "time.ogg": "timp", + "top.ogg": "vârf", + "trail.ogg": "traseu", + "water.ogg": "apă", + "wind.ogg": "vânt", + "yarn.ogg": "ghem", + "angel.ogg": "înger", + "bit.ogg": "bucățică", + "class.ogg": "oră de curs", + "price.ogg": "preț", + "question.ogg": "întrebare", + "quiz.ogg": "test", + "science.ogg": "știință", + "splatter.ogg": "împroșcat", + "tune.ogg": "melodie", + "branch.ogg": "ramură", + "bud.ogg": "mugur", + "bush.ogg": "tufiș", + "flower.ogg": "floare", + "grass.ogg": "iarbă", + "hay.ogg": "fân", + "hedge.ogg": "gard viu", + "lawn.ogg": "gazon", + "pine.ogg": "pin", + "plant.ogg": "plantă", + "rose.ogg": "trandafir", + "seed.ogg": "sămânță", + "shrub.ogg": "tufă", + "stem.ogg": "tulpină", + "stick.ogg": "băț", + "stump.ogg": "ciot", + "tree.ogg": "copac", + "carrot.ogg": "morcov", + "corn.ogg": "porumb", + "cucumber.ogg": "castravete", + "mushroom.ogg": "ciupercă", + "nut.ogg": "nut ~ nucă", + "squash.ogg": "dovlecel", + "bank.ogg": "bancă", + "barn.ogg": "hambar", + "bridge.ogg": "pod", + "cabin.ogg": "cabană", + "cage.ogg": "cușcă", + "castle.ogg": "castel", + "door.ogg": "ușă", + "fair.ogg": "târg", + "fountain.ogg": "fântână", + "grave.ogg": "mormânt", + "home.ogg": "casă", + "hut.ogg": "colibă", + "lane.ogg": "bandă de circulație", + "pool.ogg": "bazin", + "ramp.ogg": "rampă", + "roof.ogg": "acoperiș", + "school.ogg": "școală", + "shed.ogg": "șură", + "shop.ogg": "magazin", + "stage.ogg": "scenă", + "store.ogg": "magazin", + "street.ogg": "stradă", + "strawberry.ogg": "căpșună", + "bath.ogg": "baie", + "bed.ogg": "pat", + "bench.ogg": "bancă", + "chair.ogg": "scaun", + "chest.ogg": "cufăr", + "couch.ogg": "canapea", + "crib.ogg": "pătuț de bebeluș", + "desk.ogg": "masă", + "fan.ogg": "ventilator", + "lamp.ogg": "lampă", + "light.ogg": "lumină", + "mat.ogg": "rogojină", + "quilt.ogg": "plapumă", + "rug.ogg": "covoraș", + "seat.ogg": "scaun", + "shelf.ogg": "raft", + "shower.ogg": "duș", + "sink.ogg": "chiuvetă", + "stove.ogg": "plită", + "toilet.ogg": "toaletă", + "balance.ogg": "echilibru", + "can.ogg": "conservă", + "clock.ogg": "ceas", + "dish.ogg": "vas de mâncare", + "fork.ogg": "furculiță", + "glass.ogg": "pahar", + "knife.ogg": "cuțit", + "lid.ogg": "capac", + "mop.ogg": "mop", + "mug.ogg": "cană mare", + "pan.ogg": "tigaie", + "plate.ogg": "farfurie plată", + "pot.ogg": "oală", + "scale.ogg": "cântar", + "sponge.ogg": "burete", + "spoon.ogg": "lingură", + "trash.ogg": "gunoi", + "tray.ogg": "tavă", + "farm.ogg": "fermă", + "anchor.ogg": "ancoră", + "badge.ogg": "insignă", + "bag.ogg": "geantă", + "ball.ogg": "minge", + "bead.ogg": "mărgea", + "block.ogg": "(mono)bloc", + "board.ogg": "scândură", + "bomb.ogg": "bombă", + "book.ogg": "carte", + "box.ogg": "cutie", + "candle.ogg": "lumânare", + "cane.ogg": "baston", + "card.ogg": "carte poștală", + "cart.ogg": "cărucior de cumpărături", + "cash.ogg": "bani în numerar", + "chalk.ogg": "cretă", + "clay.ogg": "lut", + "cloth.ogg": "pânză", + "coin.ogg": "monedă", + "comb.ogg": "pieptene", + "cone.ogg": "con", + "crown.ogg": "coroană", + "cube.ogg": "cub", + "drum.ogg": "tobă", + "flag.ogg": "steag", + "flute.ogg": "fluier", + "game.ogg": "joc", + "gift.ogg": "cadou", + "glue.ogg": "lipici", + "hook.ogg": "cârlig", + "hose.ogg": "furtun", + "ink.ogg": "cerneală", + "jewel.ogg": "piatră prețioasă", + "kite.ogg": "zmeu", + "knot.ogg": "nod", + "log.ogg": "buștean", + "map.ogg": "hartă", + "mask.ogg": "mască", + "match.ogg": "chibrit", + "nest.ogg": "cuib", + "net.ogg": "plasă", + "oar.ogg": "vâslă", + "page.ogg": "pagină", + "pair.ogg": "pereche", + "pen.ogg": "stilou", + "pencil.ogg": "creion", + "picture.ogg": "imagine", + "pole.ogg": "prăjină", + "prize.ogg": "premiu", + "rag.ogg": "zdreanță", + "rope.ogg": "coardă", + "sign.ogg": "semn", + "sleigh.ogg": "sanie trasă de cai", + "slide.ogg": "tobogan", + "squirt.ogg": "stropitor cu jet", + "stack.ogg": "stivă", + "stamp.ogg": "timbru", + "straw.ogg": "pai", + "string.ogg": "șir", + "tag.ogg": "etichetă", + "thread.ogg": "fir", + "torch.ogg": "torță", + "towel.ogg": "prosop", + "toy.ogg": "jucărie", + "trap.ogg": "capcană", + "tube.ogg": "tub", + "watch.ogg": "ceas de mână", + "wheel.ogg": "roată", + "wig.ogg": "perucă", + "wood.ogg": "lemn", + "link.ogg": "verigă", + "dirty.ogg": "murdar", + "throw.ogg": "aruncat", + "brick.ogg": "cărămidă", + "brush.ogg": "pensulă", + "flash.ogg": "lanternă", + "rake.ogg": "greblă", + "screw.ogg": "șurub", + "spear.ogg": "suliță", + "tool.ogg": "unealtă", + "wedge.ogg": "pană", + "wrench.ogg": "cheie", + "bike.ogg": "bicicletă", + "boat.ogg": "barcă", + "canoe.ogg": "canoe", + "car.ogg": "mașină", + "plane.ogg": "avion", + "sail.ogg": "velă", + "ship.ogg": "vas de navigat", + "sled.ogg": "sanie", + "train.ogg": "tren", + "truck.ogg": "camion", + "black.ogg": "negru", + "blue.ogg": "albastru", + "brown.ogg": "maro", + "color.ogg": "culoare", + "gray.ogg": "gri", + "green.ogg": "verde", + "orange-color.ogg": "portocaliu", + "pink.ogg": "roz", + "red.ogg": "roșu", + "white.ogg": "alb", + "five.ogg": "cinci", + "one.ogg": "unu", + "ten.ogg": "zece", + "three.ogg": "trei", + "two.ogg": "doi", + "van.ogg": "dubă", + "big.ogg": "mare", + "blind.ogg": "orb", + "blond.ogg": "blond", + "bright.ogg": "strălucitor", + "crazy.ogg": "nebun", + "cute.ogg": "drăguț", + "dot.ogg": "punct", + "empty.ogg": "gol", + "fat.ogg": "gras", + "flat.ogg": "plan", + "front.ogg": "în față", + "full.ogg": "plin", + "giant.ogg": "gigant", + "happy.ogg": "fericit", + "high.ogg": "înalt", + "hot.ogg": "fierbinte", + "huge.ogg": "uriaș", + "left.ogg": "stânga", + "line.ogg": "linie", + "liquid.ogg": "lichid", + "magic.ogg": "magic", + "on.ogg": "pe", + "pretty.ogg": "frumoasă", + "right.ogg": "dreapta", + "round.ogg": "rotund", + "royal.ogg": "regal", + "shut.ogg": "închis", + "sick.ogg": "bolnav", + "small.ogg": "mic", + "spot.ogg": "pată", + "square.ogg": "pătrat", + "stand.ogg": "stând", + "straight.ogg": "drept", + "stripe.ogg": "dungă", + "strong.ogg": "puternic", + "tall.ogg": "înalt", + "thick.ogg": "gros", + "tired.ogg": "obosit", + "under.ogg": "sub", + "wet.ogg": "ud", + "wheat.ogg": "grâu", "U0030.ogg": "zero", "U0031.ogg": "unu", "U0032.ogg": "doi", "U0033.ogg": "trei", "U0034.ogg": "patru", "U0035.ogg": "cinci", "U0036.ogg": "șase", "U0037.ogg": "șapte", "U0038.ogg": "opt", "U0039.ogg": "nouă", - "10.ogg": "zece" + "10.ogg": "zece", + "11.ogg": "unsprezece", + "12.ogg": "doisprezece", + "16.ogg": "șaisprezece" } diff --git a/src/activities/menu/ConfigurationItem.qml b/src/activities/menu/ConfigurationItem.qml index 29ba69434..1a9a0a7f2 100644 --- a/src/activities/menu/ConfigurationItem.qml +++ b/src/activities/menu/ConfigurationItem.qml @@ -1,700 +1,700 @@ /* GCompris - ConfigurationItem.qml * * Copyright (C) 2014-2016 Johnny Jazeix * * Authors: * Johnny Jazeix * * This program 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. * * This program 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 this program; if not, see . */ import QtQuick 2.2 import QtQuick.Controls 1.0 import QtQuick.Controls.Styles 1.0 import GCompris 1.0 import "../../core" import "qrc:/gcompris/src/core/core.js" as Core Item { id: dialogConfig property var languages: allLangs.languages height: column.height LanguageList { id: allLangs } Column { id: column spacing: 10 width: parent.width move: Transition { NumberAnimation { properties: "x,y"; duration: 120 } } // Put configuration here Row { id: demoModeBox width: parent.width spacing: 10 property bool checked: !ApplicationSettings.isDemoMode Image { sourceSize.height: 50 * ApplicationInfo.ratio source: demoModeBox.checked ? "qrc:/gcompris/src/core/resource/apply.svg" : "qrc:/gcompris/src/core/resource/cancel.svg" MouseArea { anchors.fill: parent onClicked: { if(ApplicationSettings.isDemoMode) ApplicationSettings.isDemoMode = false } } } Button { width: parent.parent.width - 50 * ApplicationInfo.ratio - 10 * 2 height: parent.height enabled: ApplicationSettings.isDemoMode anchors.leftMargin: 10 anchors.verticalCenter: parent.verticalCenter text: demoModeBox.checked ? qsTr("You have the full version") : qsTr("Buy the full version").toUpperCase() style: ButtonStyle { background: Rectangle { implicitWidth: 100 implicitHeight: 25 border.width: control.activeFocus ? 4 : 2 border.color: "black" radius: 10 gradient: Gradient { GradientStop { position: 0 ; color: control.pressed ? "#87ff5c" : ApplicationSettings.isDemoMode ? "#ffe85c" : "#EEEEEE"} GradientStop { position: 1 ; color: control.pressed ? "#44ff00" : ApplicationSettings.isDemoMode ? "#f8d600" : "#AAAAAA"} } } label: GCText { text: control.text horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter wrapMode: Text.WordWrap } } onClicked: { if(ApplicationSettings.activationMode == 1) { if(ApplicationSettings.isDemoMode) ApplicationSettings.isDemoMode = false } else if(ApplicationSettings.activationMode == 2) { activationCodeEntry.visible = !activationCodeEntry.visible } } } } Column { id: activationCodeEntry width: parent.width spacing: 10 visible: false opacity: 0 Behavior on opacity { NumberAnimation { duration: 200 } } onVisibleChanged: { if(visible) { activationInput.forceActiveFocus() activationInput.cursorPosition = 0 opacity = 1 } else { activationInput.focus = false opacity = 0 } } GCText { id: activationInstruction fontSize: regularSize color: "black" style: Text.Outline styleColor: "white" horizontalAlignment: Text.AlignHCenter width: parent.width wrapMode: TextEdit.WordWrap text: qsTr("On http://gcompris.net " + "you will find the instructions to obtain an activation code.") Component.onCompleted: ApplicationInfo.isDownloadAllowed ? linkActivated.connect(Qt.openUrlExternally) : null } TextInput { id: activationInput width: parent.width focus: true font.weight: Font.DemiBold font.pointSize: ApplicationSettings.baseFontSize + 14 * ApplicationInfo.fontRatio color: 'black' horizontalAlignment: Text.AlignHCenter inputMask: '>HHHH-HHHH-HHHH;#' text: ApplicationSettings.codeKey onTextChanged: { var code = text.replace(/-/g,'') var codeValidity = ApplicationSettings.checkActivationCode(code); switch (codeValidity) { case 0: activationMsg.text = qsTr('Enter your activation code'); break; case 1: activationMsg.text = qsTr('Sorry, your code is too old for this version of GCompris'); break; case 2: - activationMsg.text = qsTr('You code is valid, thanks a lot for your support'); + activationMsg.text = qsTr('Your code is valid, thanks a lot for your support'); activationCodeEntry.visible = false ApplicationSettings.codeKey = code break; } } } GCText { id: activationMsg width: parent.width color: "black" fontSize: regularSize horizontalAlignment: TextInput.AlignHCenter wrapMode: TextEdit.WordWrap } } GCDialogCheckBox { id: displayLockedActivitiesBox text: qsTr("Show locked activities") visible: ApplicationSettings.isDemoMode checked: showLockedActivities onCheckedChanged: { showLockedActivities = checked; } } GCDialogCheckBox { id: enableAudioVoicesBox text: qsTr("Enable audio voices") checked: isAudioVoicesEnabled onCheckedChanged: { isAudioVoicesEnabled = checked; } } GCDialogCheckBox { id: enableAudioEffectsBox text: qsTr("Enable audio effects") checked: isAudioEffectsEnabled onCheckedChanged: { isAudioEffectsEnabled = checked; } } GCDialogCheckBox { id: enableFullscreenBox text: qsTr("Fullscreen") checked: isFullscreen onCheckedChanged: { isFullscreen = checked; } visible: !ApplicationInfo.isMobile } GCDialogCheckBox { id: enableVirtualKeyboardBox text: qsTr("Virtual Keyboard") checked: isVirtualKeyboard onCheckedChanged: { isVirtualKeyboard = checked; } } GCDialogCheckBox { id: enableAutomaticDownloadsBox checked: isAutomaticDownloadsEnabled text: qsTr("Enable automatic downloads/updates of sound files") visible: ApplicationInfo.isDownloadAllowed onCheckedChanged: { isAutomaticDownloadsEnabled = checked; } } /* Technically wordset config is a string that holds the wordset name or '' for the * internal wordset. But as we support only internal and words its best to show the * user a boolean choice. */ GCDialogCheckBox { id: wordsetBox checked: wordset text: qsTr("Use external large word image set") visible: ApplicationInfo.isDownloadAllowed onCheckedChanged: { wordset = checked ? 'data2/words/words.rcc' : ''; } } GCDialogCheckBox { id: sectionVisibleBox checked: sectionVisible text: qsTr("The activity section menu is visible") onCheckedChanged: { sectionVisible = checked; } } Flow { spacing: 5 width: parent.width GCComboBox { id: fontBox model: fonts background: dialogActivityConfig label: qsTr("Font selector") } } Flow { spacing: 5 width: parent.width Slider { id: baseFontSizeSlider width: 250 * ApplicationInfo.ratio style: GCSliderStyle {} maximumValue: ApplicationSettings.baseFontSizeMax minimumValue: ApplicationSettings.baseFontSizeMin stepSize: 1.0 tickmarksEnabled: true updateValueWhileDragging: true value: baseFontSize onValueChanged: ApplicationSettings.baseFontSize = value; } GCText { id: baseFontSizeText text: qsTr("Font size") fontSize: mediumSize wrapMode: Text.WordWrap } Button { height: 30 * ApplicationInfo.ratio text: qsTr("Default"); style: GCButtonStyle {} onClicked: baseFontSizeSlider.value = 0.0 } } Flow { spacing: 5 width: parent.width GCComboBox { id: fontCapitalizationBox model: fontCapitalizationModel background: dialogActivityConfig label: qsTr("Font Capitalization") } } Flow { spacing: 5 width: parent.width Slider { id: fontLetterSpacingSlider width: 250 * ApplicationInfo.ratio style: GCSliderStyle {} maximumValue: ApplicationSettings.fontLetterSpacingMax minimumValue: ApplicationSettings.fontLetterSpacingMin stepSize: 1.0 tickmarksEnabled: true updateValueWhileDragging: true value: fontLetterSpacing onValueChanged: ApplicationSettings.fontLetterSpacing = value } GCText { id: fontLetterSpacingText text: qsTr("Font letter spacing") fontSize: mediumSize wrapMode: Text.WordWrap } Button { height: 30 * ApplicationInfo.ratio text: qsTr("Default"); style: GCButtonStyle {} onClicked: fontLetterSpacingSlider.value = ApplicationSettings.fontLetterSpacingMin } } Flow { spacing: 5 width: parent.width GCComboBox { id: languageBox model: dialogConfig.languages background: dialogActivityConfig onCurrentIndexChanged: voicesRow.localeChanged(); label: qsTr("Language selector") } } Flow { id: voicesRow width: parent.width spacing: 5 * ApplicationInfo.ratio property bool haveLocalResource: false function localeChanged() { var language = dialogConfig.languages[languageBox.currentIndex].text; voicesRow.haveLocalResource = DownloadManager.isDataRegistered( "voices-" + ApplicationInfo.CompressedAudio + "/" + ApplicationInfo.getVoicesLocale(dialogConfig.languages[languageBox.currentIndex].locale) ) } Connections { target: DownloadManager onDownloadFinished: voicesRow.localeChanged() } GCText { id: voicesText text: qsTr("Localized voices") fontSize: mediumSize wrapMode: Text.WordWrap } Image { id: voicesImage sourceSize.height: 30 * ApplicationInfo.ratio source: voicesRow.haveLocalResource ? "qrc:/gcompris/src/core/resource/apply.svg" : "qrc:/gcompris/src/core/resource/cancel.svg" } Button { id: voicesButton height: 30 * ApplicationInfo.ratio visible: ApplicationInfo.isDownloadAllowed text: voicesRow.haveLocalResource ? qsTr("Check for updates") : qsTr("Download") style: GCButtonStyle {} onClicked: { if (DownloadManager.downloadResource( DownloadManager.getVoicesResourceForLocale(dialogConfig.languages[languageBox.currentIndex].locale))) { var downloadDialog = Core.showDownloadDialog(dialogConfig.parent.rootItem, {}); } } } } Flow { width: parent.width spacing: 5 * ApplicationInfo.ratio GCText { text: qsTr("Difficulty filter:") fontSize: mediumSize height: 50 * ApplicationInfo.ratio } // Padding Item { height: 1 width: 10 * ApplicationInfo.ratio } Image { source: "qrc:/gcompris/src/core/resource/bar_next.svg" sourceSize.height: Math.min(50 * ApplicationInfo.ratio, parent.width / 8) MouseArea { anchors.fill: parent onClicked: { filterRepeater.setMin(filterRepeater.min + 1) } } } // Padding Item { height: 1 width: 5 * ApplicationInfo.ratio } // Level filtering Repeater { id: filterRepeater model: 6 property int min: ApplicationSettings.filterLevelMin property int max: ApplicationSettings.filterLevelMax function setMin(value) { var newMin if(min < 1) newMin = 1 else if(min > 6) newMin = 6 else if(max >= value) newMin = value if(newMin) ApplicationSettings.filterLevelMin = newMin } function setMax(value) { var newMax if(max < 1) newMax = 1 else if(max > 6) newMax = 6 else if(min <= value) newMax = value if(newMax) ApplicationSettings.filterLevelMax = newMax } Image { source: "qrc:/gcompris/src/core/resource/difficulty" + (modelData + 1) + ".svg"; sourceSize.width: Math.min(50 * ApplicationInfo.ratio, parent.width / 8) opacity: modelData + 1 >= filterRepeater.min && modelData + 1 <= filterRepeater.max ? 1 : 0.4 property int value: modelData + 1 MouseArea { anchors.fill: parent onClicked: { if(parent.value < filterRepeater.max) { if(parent.opacity == 1) filterRepeater.setMin(parent.value + 1) else filterRepeater.setMin(parent.value) } else if(parent.value > filterRepeater.min) { if(parent.opacity == 1) filterRepeater.setMax(parent.value - 1) else filterRepeater.setMax(parent.value) } } } } } // Padding Item { height: 1 width: 5 * ApplicationInfo.ratio } Image { source: "qrc:/gcompris/src/core/resource/bar_previous.svg" sourceSize.height: Math.min(50 * ApplicationInfo.ratio, parent.width / 8) MouseArea { anchors.fill: parent onClicked: { filterRepeater.setMax(filterRepeater.max - 1) } } } } } property bool showLockedActivities: ApplicationSettings.showLockedActivities property bool isAudioVoicesEnabled: ApplicationSettings.isAudioVoicesEnabled property bool isAudioEffectsEnabled: ApplicationSettings.isAudioEffectsEnabled property bool isFullscreen: ApplicationSettings.isFullscreen property bool isVirtualKeyboard: ApplicationSettings.isVirtualKeyboard property bool isAutomaticDownloadsEnabled: ApplicationSettings.isAutomaticDownloadsEnabled property bool sectionVisible: ApplicationSettings.sectionVisible property string wordset: ApplicationSettings.wordset property int baseFontSize // don't bind to ApplicationSettings.baseFontSize property real fontLetterSpacing // don't bind to ApplicationSettings.fontLetterSpacing // or we get a binding loop warning function loadFromConfig() { // Synchronize settings with data showLockedActivities = ApplicationSettings.showLockedActivities isAudioVoicesEnabled = ApplicationSettings.isAudioVoicesEnabled enableAudioVoicesBox.checked = isAudioVoicesEnabled isAudioEffectsEnabled = ApplicationSettings.isAudioEffectsEnabled enableAudioEffectsBox.checked = isAudioEffectsEnabled isFullscreen = ApplicationSettings.isFullscreen enableFullscreenBox.checked = isFullscreen isVirtualKeyboard = ApplicationSettings.isVirtualKeyboard enableVirtualKeyboardBox.checked = isVirtualKeyboard isAutomaticDownloadsEnabled = ApplicationSettings.isAutomaticDownloadsEnabled enableAutomaticDownloadsBox.checked = isAutomaticDownloadsEnabled sectionVisible = ApplicationSettings.sectionVisible sectionVisibleBox.checked = sectionVisible wordset = ApplicationSettings.wordset wordsetBox.checked = (wordset != '') baseFontSize = ApplicationSettings.baseFontSize; fontLetterSpacing = ApplicationSettings.fontLetterSpacing; // Set locale for(var i = 0 ; i < dialogConfig.languages.length ; i ++) { if(dialogConfig.languages[i].locale === ApplicationSettings.locale) { languageBox.currentIndex = i; break; } } // Set font for(var i = 0 ; i < fonts.count ; i ++) { if(fonts.get(i).text == ApplicationSettings.font) { fontBox.currentIndex = i; break; } } // Set font capitalization for(var i = 0 ; i < fontCapitalizationModel.length ; i ++) { if(fontCapitalizationModel[i].value == ApplicationSettings.fontCapitalization) { fontCapitalizationBox.currentIndex = i; break; } } } function save() { ApplicationSettings.showLockedActivities = showLockedActivities ApplicationSettings.isAudioVoicesEnabled = isAudioVoicesEnabled ApplicationSettings.isAudioEffectsEnabled = isAudioEffectsEnabled ApplicationSettings.isFullscreen = isFullscreen ApplicationSettings.isVirtualKeyboard = isVirtualKeyboard ApplicationSettings.isAutomaticDownloadsEnabled = isAutomaticDownloadsEnabled ApplicationSettings.sectionVisible = sectionVisible ApplicationSettings.wordset = wordset ApplicationSettings.isEmbeddedFont = fonts.get(fontBox.currentIndex).isLocalResource; ApplicationSettings.font = fonts.get(fontBox.currentIndex).text ApplicationSettings.fontCapitalization = fontCapitalizationModel[fontCapitalizationBox.currentIndex].value ApplicationSettings.saveBaseFontSize(); ApplicationSettings.notifyFontLetterSpacingChanged(); if (ApplicationSettings.locale != dialogConfig.languages[languageBox.currentIndex].locale) { ApplicationSettings.locale = dialogConfig.languages[languageBox.currentIndex].locale if(ApplicationInfo.isDownloadAllowed && !DownloadManager.isDataRegistered( "voices-" + ApplicationInfo.CompressedAudio + "/" + ApplicationInfo.getVoicesLocale(dialogConfig.languages[languageBox.currentIndex].locale) )) { // ask for downloading new voices Core.showMessageDialog(main, qsTr("You selected a new locale. You need to restart GCompris to play in your new locale.
Do you want to download the corresponding sound files now?"), qsTr("Yes"), function() { // yes -> start download if (DownloadManager.downloadResource( DownloadManager.getVoicesResourceForLocale(ApplicationSettings.locale))) var downloadDialog = Core.showDownloadDialog(main, {}); }, qsTr("No"), null, null ); } else { // check for updates or/and register new voices DownloadManager.updateResource( DownloadManager.getVoicesResourceForLocale(ApplicationSettings.locale)) } } } ListModel { id: fonts Component.onCompleted: { var systemFonts = Qt.fontFamilies(); var rccFonts = ApplicationInfo.getFontsFromRcc(); // Remove explicitly all *symbol* and *ding* fonts var excludedFonts = ApplicationInfo.getSystemExcludedFonts(); excludedFonts.push("ding"); excludedFonts.push("symbol"); for(var i = 0 ; i < systemFonts.length ; ++ i) { var isExcluded = false; // Remove symbol fonts for(var j = 0 ; j < excludedFonts.length ; ++ j) { if(systemFonts[i].toLowerCase().indexOf(excludedFonts[j].toLowerCase()) != -1) { isExcluded = true; break; } } // Remove fonts from rcc (if you have a default font from rcc, Qt will add it to systemFonts) for(var j = 0 ; j < rccFonts.length ; ++ j) { if(rccFonts[j].toLowerCase().indexOf(systemFonts[i].toLowerCase()) != -1) { isExcluded = true; break; } } // Finally, we know if we add this font or not if(!isExcluded) { fonts.append({ "text": systemFonts[i], "isLocalResource": false }); } } for(var i = 0 ; i < rccFonts.length ; ++ i) { // Append fonts from resources fonts.append({ "text": rccFonts[i], "isLocalResource": true }); } } } property variant fontCapitalizationModel: [ { text: qsTr("Mixed case (default)"), value: Font.MixedCase }, { text: qsTr("All uppercase"), value: Font.AllUppercase }, { text: qsTr("All lowercase"), value: Font.AllLowercase } ] function hasConfigChanged() { return (ApplicationSettings.locale !== dialogConfig.languages[languageBox.currentIndex].locale || (ApplicationSettings.sectionVisible != sectionVisible) || (ApplicationSettings.wordset != wordset) || (ApplicationSettings.font != fonts.get(fontBox.currentIndex).text) || (ApplicationSettings.isEmbeddedFont != fonts.get(fontBox.currentIndex).isLocalResource) || (ApplicationSettings.isEmbeddedFont != fonts.get(fontBox.currentIndex).isLocalResource) || (ApplicationSettings.fontCapitalization != fontCapitalizationModel[(fontcapitalizationBox.currentIndex)].value) || (ApplicationSettings.fontLetterSpacing != fontLetterSpacing) || (ApplicationSettings.isAudioVoicesEnabled != isAudioVoicesEnabled) || (ApplicationSettings.isAudioEffectsEnabled != isAudioEffectsEnabled) || (ApplicationSettings.isFullscreen != isFullscreen) || (ApplicationSettings.isVirtualKeyboard != isVirtualKeyboard) || (ApplicationSettings.isAutomaticDownloadsEnabled != isAutomaticDownloadsEnabled) || (ApplicationSettings.baseFontSize != baseFontSize) || (ApplicationSettings.showLockedActivities != showLockedActivities) ); } } diff --git a/src/core/BuyMeOverlay.qml b/src/core/BuyMeOverlay.qml index be9fa3b09..7b288e222 100644 --- a/src/core/BuyMeOverlay.qml +++ b/src/core/BuyMeOverlay.qml @@ -1,119 +1,121 @@ -/* GCompris - BuyMeOverlayInapp.qml +/* GCompris - BuyMeOverlay.qml * * Copyright (C) 2014 Bruno Coudoin * * Authors: * Bruno Coudoin * * This program 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. * * This program 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 this program; if not, see . */ import QtQuick 2.2 import QtQuick.Controls 1.0 import GCompris 1.0 Item { anchors { fill: parent bottomMargin: bar.height * 1.2 } Rectangle { anchors.fill: parent opacity: 0.5 color: "grey" } /* Activation Instruction */ Rectangle { id: instruction z: 99 anchors { horizontalCenter: parent.horizontalCenter horizontalCenterOffset: - cancelButton.width / 2 top: parent.top topMargin: 40 } width: parent.width - cancelButton.width * 2 - height: instructionTxt.height + height: parent.height/2 radius: 10 border.width: 2 border.color: "black" color: 'white' Row { + id: row anchors { fill: parent margins: 10 } Image { id: lock source: "qrc:/gcompris/src/activities/menu/resource/lock.svg" sourceSize.width: 30 * ApplicationInfo.ratio } GCText { id: instructionTxt - fontSize: mediumSize + fontSizeMode: Text.Fit color: "black" style: Text.Outline styleColor: "white" horizontalAlignment: Text.AlignHCenter width: parent.width - lock.width + height: instruction.height - row.anchors.margins/2 wrapMode: TextEdit.WordWrap z: 2 text: qsTr("This activity is only available in the full version of GCompris." + "
" + "On http://gcompris.net " + "you will find the instructions to obtain an activation code." + " " + "Then go to the main configuration dialog to enter the code.") } } } MultiPointTouchArea { // Just to catch mouse events anchors.fill: parent } Keys.onEscapePressed: home() Keys.onPressed: { event.accepted = true if (event.modifiers === Qt.ControlModifier && event.key === Qt.Key_Q) { // Ctrl+Q exit the application Core.quit(page); } else if (event.modifiers === Qt.ControlModifier && event.key === Qt.Key_B) { // Ctrl+B toggle the bar ApplicationSettings.isBarHidden = !ApplicationSettings.isBarHidden; } else if (event.modifiers === Qt.ControlModifier && event.key === Qt.Key_F) { // Ctrl+F toggle fullscreen ApplicationSettings.isFullscreen = !ApplicationSettings.isFullscreen } else if (event.modifiers === Qt.ControlModifier && event.key === Qt.Key_M) { // Ctrl+M toggle sound ApplicationSettings.isAudioEffectsEnabled = !ApplicationSettings.isAudioEffectsEnabled } else if (event.modifiers === Qt.ControlModifier && event.key === Qt.Key_W) { // Ctrl+W exit the current activity home() } } // The cancel button GCButtonCancel { id: cancelButton onClose: home() } } diff --git a/src/core/BuyMeOverlayInapp.qml b/src/core/BuyMeOverlayInapp.qml index 9c92eab35..00028efb6 100644 --- a/src/core/BuyMeOverlayInapp.qml +++ b/src/core/BuyMeOverlayInapp.qml @@ -1,134 +1,136 @@ /* GCompris - BuyMeOverlayInapp.qml * * Copyright (C) 2014 Bruno Coudoin * * Authors: * Bruno Coudoin * * This program 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. * * This program 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 this program; if not, see . */ import QtQuick 2.2 import QtQuick.Controls 1.0 import GCompris 1.0 Item { anchors { fill: parent bottomMargin: bar.height * 1.2 } Rectangle { anchors.fill: parent opacity: 0.5 color: "grey" } /* Activation Instruction */ Rectangle { id: instructionsArea z: 99 anchors { horizontalCenter: parent.horizontalCenter horizontalCenterOffset: - cancelButton.width / 2 top: parent.top topMargin: 40 } width: parent.width - cancelButton.width * 2 - height: instructionTxt.height + height: Math.max(instructionTxt.height, lock.height) + 2*row.anchors.margins radius: 10 border.width: 2 border.color: "black" color: 'white' Row { + id: row anchors { fill: parent margins: 10 } Image { id: lock source: "qrc:/gcompris/src/activities/menu/resource/lock.svg" sourceSize.width: 30 * ApplicationInfo.ratio } GCText { id: instructionTxt fontSize: mediumSize color: "black" style: Text.Outline styleColor: "white" horizontalAlignment: Text.AlignHCenter width: parent.width - lock.width wrapMode: TextEdit.WordWrap z: 2 text: qsTr("This activity is only available in the full version of GCompris.") } } Button { width: instructionsArea.width * 0.9 height: 60 * ApplicationInfo.ratio anchors { horizontalCenter: parent.horizontalCenter top: instructionsArea.bottom topMargin: 10 } text: qsTr("Buy the full version").toUpperCase() style: GCButtonStyle { - } + theme: "highContrast" + } onClicked: { if(ApplicationSettings.isDemoMode) ApplicationSettings.isDemoMode = false } } } MultiPointTouchArea { // Just to catch mouse events anchors.fill: parent } Keys.onEscapePressed: home() Keys.onPressed: { event.accepted = true if (event.modifiers === Qt.ControlModifier && event.key === Qt.Key_Q) { // Ctrl+Q exit the application Core.quit(page); } else if (event.modifiers === Qt.ControlModifier && event.key === Qt.Key_B) { // Ctrl+B toggle the bar ApplicationSettings.isBarHidden = !ApplicationSettings.isBarHidden; } else if (event.modifiers === Qt.ControlModifier && event.key === Qt.Key_F) { // Ctrl+F toggle fullscreen ApplicationSettings.isFullscreen = !ApplicationSettings.isFullscreen } else if (event.modifiers === Qt.ControlModifier && event.key === Qt.Key_M) { // Ctrl+M toggle sound ApplicationSettings.isAudioEffectsEnabled = !ApplicationSettings.isAudioEffectsEnabled } else if (event.modifiers === Qt.ControlModifier && event.key === Qt.Key_W) { // Ctrl+W exit the current activity home() } } // The cancel button GCButtonCancel { id: cancelButton onClose: home() } } diff --git a/src/core/DialogActivityConfig.qml b/src/core/DialogActivityConfig.qml index 22abe55de..68737dba2 100644 --- a/src/core/DialogActivityConfig.qml +++ b/src/core/DialogActivityConfig.qml @@ -1,232 +1,230 @@ /* GCompris - DialogActivityConfig.qml * * Copyright (C) 2014 Johnny Jazeix * * Authors: * Johnny Jazeix * * This program 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. * * This program 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 this program; if not, see . */ import QtQuick 2.2 import GCompris 1.0 /** * A QML component for a full screen configuration dialog. * @ingroup components * * All user editable settings are presented to the user in a * DialogActivityConfig dialog. The global configuration can be accessed * through the Bar in the main menu, activity specific configuration from the * respective activity. * * All config items that are shown in this dialog are persisted * using ApplicationSettings. * * For an example have a look at Menu.qml. * * For more details on how to add configuration to an activity cf. * [the wiki](http://gcompris.net/wiki/Qt_Quick_development_process#Adding_a_configuration_for_a_specific_activity) * * @sa ApplicationSettings * @inherit QtQuick.Item */ Rectangle { id: dialogActivityContent visible: false /* Public interface: */ /** * type:object * The content object as loaded dynamically. */ property alias configItem: loader.item /** * type:Component * Content component which holds the visual presentation of the * config settings in the QML scene. */ property Component content /** * type:string * The name of the activity in case of per-activity config. * * Will be autogenerated unless set by the caller. */ property string activityName: "" /** * type:object * Map containing all settings as key/value-pairs. * * Will be populated from ApplicationSettings.loadActivityConfiguration * and can be passed to ApplicationSettings.saveActivityConfiguration. */ property var dataToSave property var dataValidationFunc: null /// @cond INTERNAL_DOCS property bool isDialog: true /** * type:string * Title of the configuration dialog. * Global configuration name is "Configuration". * For activities, it is "activity name configuration". */ readonly property string title: { if(activityName != "") qsTr("%1 configuration").arg(activityInfo.title) else qsTr("Configuration") } property alias active: loader.active property alias loader: loader property QtObject activityInfo: ActivityInfoTree.currentActivity property ActivityBase currentActivity /// @endcond /** * Emitted when the config dialog has been closed. */ signal close /** * Emitted when the config dialog has been started. */ signal start /** * Emitted when the settings are to be saved. * * The actual persisting of the settings in the settings file is done by * DialogActivityConfig. The activity has to take care to update its * internal state. */ signal saveData /** * Emitted when the config settings have been loaded. */ signal loadData signal stop - color: "#696da3" border.color: "black" border.width: 1 - z: 1000 function getInitialConfiguration() { if(activityName == "") { activityName = ActivityInfoTree.currentActivity.name.split('/')[0]; } dataToSave = ApplicationSettings.loadActivityConfiguration(activityName) loadData() } function saveDatainConfiguration() { saveData() ApplicationSettings.saveActivityConfiguration(activityName, dataToSave) } Row { visible: dialogActivityContent.active spacing: 2 Item { width: 10; height: 1 } Column { spacing: 10 anchors.top: parent.top Item { width: 1; height: 10 } Rectangle { color: "#e6e6e6" radius: 6.0 width: dialogActivityContent.width - 30 height: title.height * 1.2 border.color: "black" border.width: 2 Image { id: titleIcon anchors { left: parent.left top: parent.top margins: 4 * ApplicationInfo.ratio } } GCText { id: title text: dialogActivityContent.title width: dialogActivityContent.width - 30 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter color: "black" fontSize: 20 font.weight: Font.DemiBold wrapMode: Text.WordWrap } } Rectangle { color: "#e6e6e6" radius: 6.0 width: dialogActivityContent.width - 30 height: dialogActivityContent.height - 100 border.color: "black" border.width: 2 anchors.margins: 100 Flickable { id: flick anchors.margins: 8 anchors.fill: parent flickableDirection: Flickable.VerticalFlick clip: true contentHeight: contentItem.childrenRect.height + 40 * ApplicationInfo.ratio Loader { id: loader active: false sourceComponent: dialogActivityContent.content property alias rootItem: dialogActivityContent } } } Item { width: 1; height: 10 } } } // The cancel button GCButtonCancel { onClose: { if (dialogActivityContent.dataValidationFunc && ! dialogActivityContent.dataValidationFunc()) { console.log("Configuration data is invalid, not saving!"); return; } saveData() ApplicationSettings.saveActivityConfiguration(activityName, dataToSave) parent.close() } } } diff --git a/src/core/DownloadDialog.qml b/src/core/DownloadDialog.qml index 6f3d7ec8a..9e9612af3 100644 --- a/src/core/DownloadDialog.qml +++ b/src/core/DownloadDialog.qml @@ -1,297 +1,299 @@ /* GCompris - DownloadDialog.qml * * Copyright (C) 2014 Holger Kaelberer * * Authors: * Holger Kaelberer * * This program 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. * * This program 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 this program; if not, see . */ import QtQuick 2.2 import GCompris 1.0 import QtQuick.Layouts 1.1 import QtQuick.Controls 1.0 import "qrc:/gcompris/src/core/core.js" as Core /** * A QML component visualizing download progress. * @ingroup infrastructure * * A GCDialog style dialog providing visual feedback for download progress. * Uses DownloadManager for download control. * * Can be conveniently instantiated dynamically using showDownloadDialog * from core.js. * * @inherit QtQuick.Item * @sa DownloadManager, showDownloadDialog */ Item { id: downloadDialog opacity: 0 anchors { fill: parent } /** * type:Item * Parent object for the dialog in the qml hierarchy. */ property Item main /** * type:bool * Whether to close the dialog automatically when download has finished. * Default is false. */ property bool autohide: false; /** * type:bool * Whether to report download success in a Dialog. * Default is true. */ property bool reportSuccess: true; /** * type:bool * Whether to report download errors in a Dialog. * Default is true. */ property bool reportError: true; /** * type:bool * Whether the dialog has been created dynamically. If set to true, the * component takes care of destroying itself after finished. * Default is false. * * @sa Core.destroyDialog */ property bool dynamic: false /** * type:bool * Whether the 'Background' button should be visible. * Default is true. */ property alias backgroundButtonVisible: backgroundButton.visible /** * type:bool * Whether the 'Abort' button should be visible. * Default is true. */ property alias abortButtonVisible: abortButton.visible /** * type:bool * Fixed font size used in this dialog. Note, fixed font-sizes should be * used in dialog components, to make sure they stay within bounds when * user increases font size. * Default is 14. */ property int fixedFontSize: 14 /// @cond INTERNAL_DOCS // start and stop trigs the animation FIXME: need to document? signal start signal stop // emitted at stop animation end signal close signal finished onStart: opacity = 1 onStop: opacity = 0 onClose: destroy() Behavior on opacity { NumberAnimation { duration: 200 } } onOpacityChanged: opacity === 0 ? close() : null function shutdown() { if (downloadDialog.dynamic) Core.destroyDialog(downloadDialog); else downloadDialog.close(); } /// @endcond Rectangle { anchors.fill: parent opacity: 0.8 color: "grey" MouseArea { // Empty mouseArea to prevent clicking "behind" the Dialog anchors.fill: parent enabled: downloadDialog.opacity != 0 } } Item { id: instruction anchors { horizontalCenter: parent.horizontalCenter top: parent.top topMargin: parent.height * 0.1 } width: parent.width * 0.8 GCText { id: instructionTxt fontSize: mediumSize color: "black" horizontalAlignment: Text.AlignHCenter width: parent.width wrapMode: TextEdit.WordWrap z: 2 height: 60 * ApplicationInfo.ratio text: qsTr("Downloading ...") } Rectangle { anchors.fill: instructionTxt z: 1 opacity: 0.9 radius: 10 border.width: 2 border.color: "white" gradient: Gradient { GradientStop { position: 0.0; color: "#fff" } GradientStop { position: 0.9; color: "#fff" } GradientStop { position: 1.0; color: "#ddd" } } } ProgressBar { id: downloadDialogProgress width: parent.width anchors { horizontalCenter: parent.horizontalCenter top: instructionTxt.bottom topMargin: 10 } visible: true Layout.alignment: Qt.AlignHCenter Layout.rowSpan: 1 Layout.fillWidth: true minimumValue: 0 maximumValue: 100 value: 0 } Button { id: backgroundButton width: parent.width height: 60 * ApplicationInfo.ratio anchors { horizontalCenter: parent.horizontalCenter top: downloadDialogProgress.bottom topMargin: 10 } //: Run this task in background text: qsTr("Background") style: GCButtonStyle { fixedFontSize: downloadDialog.fixedFontSize + theme: "highContrast" } visible: true onClicked: downloadDialog.shutdown(); } Button { id: abortButton width: parent.width height: 60 * ApplicationInfo.ratio anchors { horizontalCenter: parent.horizontalCenter top: backgroundButton.bottom topMargin: 10 } text: qsTr("Abort") style: GCButtonStyle { fixedFontSize: downloadDialog.fixedFontSize + theme: "highContrast" } visible: true onClicked: { if (DownloadManager.downloadIsRunning()) DownloadManager.abortDownloads(); downloadDialog.finished(); downloadDialog.shutdown(); } } } Connections { target: DownloadManager onError: { //console.warn("DownloadDialog: DM reports error: " + code + ": " + msg); downloadDialog.finished(); if (downloadDialog.reportError && code != 5) { // no error: OperationCanceledError // show error message var messageDialog = Core.showMessageDialog(main, qsTr("Download error") + code + ": " + msg, "", null, "", null, function() { downloadDialog.shutdown(); } ); } else downloadDialog.shutdown(); } onDownloadProgress: downloadDialogProgress.value = 100 * bytesReceived / bytesTotal; onDownloadStarted: { //console.log("dialog: DM reports started: " + resource); downloadDialogProgress.value = 0; } onDownloadFinished: { //console.log("dialog: DM reports finished: " + code); downloadDialog.finished(); if (downloadDialog.reportSuccess && code != 1) // note: errors will be reported by the onError handler { // report success downloadDialog.stop(); var infText = ""; if (code == 0) { // Success infText = qsTr("Your download finished successfully. The data files are now available.") + '\n' + qsTr("Restart any currently active activity."); } else if (code == 2) // NoChange infText = qsTr("Your local data files are up-to-date.") var messageDialog = Core.showMessageDialog(main, infText, "", null, "", null, null ); } else if (downloadDialog.autohide) downloadDialog.shutdown(); } } } diff --git a/src/core/GCButtonCancel.qml b/src/core/GCButtonCancel.qml index 66faa0bfd..45bb9e81d 100644 --- a/src/core/GCButtonCancel.qml +++ b/src/core/GCButtonCancel.qml @@ -1,64 +1,63 @@ /* GCompris - GCButtonCancel.qml * * Copyright (C) 2015 Bruno Coudoin * * Authors: * Bruno Coudoin * * This program 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. * * This program 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 this program; if not, see . */ import QtQuick 2.2 import GCompris 1.0 /** * A QML component representing GCompris' cancel button. * @ingroup components * * @inherit QtQuick.Image */ Image { id: cancel source: "qrc:/gcompris/src/core/resource/cancel.svg"; anchors.right: parent.right anchors.top: parent.top smooth: true sourceSize.width: 60 * ApplicationInfo.ratio anchors.margins: 10 - z: 200 signal close SequentialAnimation { id: anim running: true loops: Animation.Infinite NumberAnimation { target: cancel property: "rotation" from: -10; to: 10 duration: 500 easing.type: Easing.InOutQuad } NumberAnimation { target: cancel property: "rotation" from: 10; to: -10 duration: 500 easing.type: Easing.InOutQuad } } MouseArea { anchors.fill: parent onClicked: close() } } diff --git a/src/core/GCButtonStyle.qml b/src/core/GCButtonStyle.qml index acb21564e..c0aef0cf6 100644 --- a/src/core/GCButtonStyle.qml +++ b/src/core/GCButtonStyle.qml @@ -1,111 +1,138 @@ /* GCompris - GCButtonStyle.qml * * Copyright (C) 2014 Bruno Coudoin * * Authors: * Bruno Coudoin * * This program 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. * * This program 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 this program; if not, see . */ import QtQuick 2.2 import QtQuick.Controls 1.0 import QtQuick.Controls.Styles 1.0 import GCompris 1.0 /** * Provides styling for GCompris' Buttons. * @ingroup components * * @inherit QtQuick.Controls.Styles.ButtonStyle */ ButtonStyle { /** * type:real * Fixed font size of the label in pt. * * Set to a value > 0 for enforcing a fixed font.pointSize for the label, * that won't be updated with ApplicationSettings.baseFontSize. * @sa ApplicationSettings.baseFontSize, GCText.fixFontSize */ property real fixedFontSize: -1 /** * type:string - * theme of the button. For now, two themes are accepted: "light" and "dark" + * theme of the button. For now, three themes are accepted: "light" and "dark" and "highContrast" * * Default is dark. */ property string theme: "dark" /** * type:variant * existing themes for the button. * A theme is composed of: * the colors of the button when selected: selectedColorGradient0 and selectedColorGradient1. * the colors of the button when not selected: backgroundColorGradient0 and backgroundColorGradient1. * the button's border color * the text color */ property variant themes: { "dark": { backgroundColorGradient0: "#23373737", selectedColorGradient0: "#C03ACAFF", backgroundColorGradient1: "#13373737", selectedColorGradient1: "#803ACAFF", borderColor: "#FF373737", textColor: "#FF373737" }, "light": { backgroundColorGradient0: "#42FFFFFF", selectedColorGradient0: "#C03ACAFF", backgroundColorGradient1: "#23FFFFFF", selectedColorGradient1: "#803ACAFF", borderColor: "white", textColor: "white" + }, + "highContrast": { + backgroundColorGradient0: "#EEFFFFFF", + selectedColorGradient0: "#C03ACAFF", + backgroundColorGradient1: "#AAFFFFFF", + selectedColorGradient1: "#803ACAFF", + borderColor: "white", + textColor: "373737" + } } + property string textSize: "regular" + + property variant textSizes: { + "regular": { + fontSize: 14, + fontBold: false + }, + "subtitle": { + fontSize: 16, + fontBold: true + }, + "title": { + fontSize: 24, + fontBold: true + } + } + background: Rectangle { border.width: control.activeFocus ? 4 : 2 border.color: themes[theme].borderColor radius: 10 gradient: Gradient { GradientStop { position: 0 ; color: control.pressed ? themes[theme].selectedColorGradient0 : themes[theme].backgroundColorGradient0 } GradientStop { position: 1 ; color: control.pressed ? themes[theme].selectedColorGradient1 : themes[theme].backgroundColorGradient1 } } } label: Item { id: labelItem anchors.fill: parent implicitWidth: labelText.implicitWidth implicitHeight: labelText.implicitHeight GCText { id: labelText color: themes[theme].textColor text: control.text - fontSize: regularSize + fontSize: textSizes[textSize].fontSize + font.bold: textSizes[textSize].fontBold anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter wrapMode: Text.WordWrap Component.onCompleted: { if (fixedFontSize > 0) { labelText.fixFontSize = true; labelText.fontSize = fixedFontSize; } } } } } diff --git a/src/core/GCComboBox.qml b/src/core/GCComboBox.qml index ff354af33..5fae74439 100644 --- a/src/core/GCComboBox.qml +++ b/src/core/GCComboBox.qml @@ -1,323 +1,322 @@ /* GCompris - GCComboBox.qml * * Copyright (C) 2015 Johnny Jazeix * * Authors: * Johnny Jazeix * * This program 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. * * This program 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 this program; if not, see . */ import QtQuick 2.2 import QtQuick.Controls 1.0 import GCompris 1.0 /** * A QML component unifying comboboxes in GCompris. * @ingroup components * * GCComboBox contains a combobox and a label. * When the combobox isn't active, it is displayed as a button containing the current value * and the combobox label (its description). * Once the button is clicked, the list of all available choices is displayed. * Also, above the list is the combobox label. * * Navigation can be done with keys and mouse/gestures. * As Qt comboboxes, you can either have a js Array or a Qml model as model. * GCComboBox should now be used wherever you'd use a QtQuick combobox. It has * been decided to implement comboboxes ourselves in GCompris because of * some integration problems on some OSes (native dialogs unavailable). */ Item { id: gccombobox focus: true width: parent.width height: flow.height /** * type:Item * Where the list containing all choices will be displayed. * Should be the dialogActivityConfig item if used on config. */ property Item background /** * type:int * Current index of the combobox. */ property int currentIndex: -1 /** * type:string * Current text displayed in the combobox when inactive. */ property string currentText /** * type:alias * Model for the list (user has to specify one). */ property alias model: gridview.model /** * type:string * Text besides the combobox, used to describe what the combobox is for. */ property string label /** * type:bool * Internal value. * If model is an js Array, we access data using modelData and [] else qml Model, we need to use model and get(). */ readonly property bool isModelArray: model.constructor === Array // start and stop trigs the animation signal start signal stop // emitted at stop animation end signal close onCurrentIndexChanged: { currentText = isModelArray ? model[currentIndex].text : (model && model.get(currentIndex) ? model.get(currentIndex).text : "") } /** * type:Flow * Combobox display when inactive: the button with current choice and its label besides. */ Flow { id: flow width: parent.width spacing: 5 * ApplicationInfo.ratio Rectangle { id: button visible: true // Add radius to add some space between text and borders implicitWidth: Math.max(200, currentTextBox.width+radius) implicitHeight: 50 * ApplicationInfo.ratio border.width: 2 border.color: "#373737" radius: 10 gradient: Gradient { GradientStop { position: 0 ; color: mouseArea.pressed ? "#C03ACAFF" : "#23373737" } GradientStop { position: 1 ; color: mouseArea.pressed ? "#803ACAFF" : "#13373737" } } // Current value of combobox GCText { id: currentTextBox anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter text: currentText fontSize: mediumSize color: "#373737" } MouseArea { id: mouseArea anchors.fill: parent onReleased: { popup.visible = true } } } Item { width: labelText.width height: button.height GCText { id: labelText text: label anchors.verticalCenter: parent.verticalCenter fontSize: mediumSize wrapMode: Text.WordWrap } } } /** * type:Item * Combobox display when active: header with the description and the gridview containing all the available choices. */ Item { id: popup visible: false width: parent.width height: parent.height parent: background - + z: 100 focus: visible // Forward event to activity if key pressed is not one of the handled key // (ctrl+F should still resize the window for example) Keys.onPressed: { if(event.key !== Qt.Key_Back) { background.currentActivity.Keys.onPressed(event) } } Keys.onReleased: { if(event.key === Qt.Key_Back) { // Keep the old value discardChange(); hidePopUpAndRestoreFocus(); event.accepted = true } } Keys.onRightPressed: gridview.moveCurrentIndexRight(); Keys.onLeftPressed: gridview.moveCurrentIndexLeft(); Keys.onDownPressed: gridview.moveCurrentIndexDown(); Keys.onUpPressed: gridview.moveCurrentIndexUp(); Keys.onEscapePressed: { // Keep the old value discardChange(); hidePopUpAndRestoreFocus(); } Keys.onEnterPressed: { acceptChange(); hidePopUpAndRestoreFocus(); } Keys.onReturnPressed: { acceptChange(); hidePopUpAndRestoreFocus(); } Keys.onSpacePressed: { acceptChange(); hidePopUpAndRestoreFocus(); } // Don't accept the list value, restore previous value function discardChange() { if(isModelArray) { for(var i = 0 ; i < model.count ; ++ i) { if(model[currentIndex].text === currentText) { currentIndex = i; break; } } } else { for(var i = 0 ; i < model.length ; ++ i) { if(model.get(currentIndex).text === currentText) { currentIndex = i; break; } } } gridview.currentIndex = currentIndex; } // Accept the change. Updates the currentIndex and text of the button function acceptChange() { currentIndex = gridview.currentIndex; currentText = isModelArray ? model[currentIndex].text : (model && model.get(currentIndex) ? model.get(currentIndex).text : "") } function hidePopUpAndRestoreFocus() { popup.visible = false; // Restore focus on previous activity for keyboard input background.currentActivity.forceActiveFocus(); } Rectangle { id: listBackground anchors.fill: parent radius: 10 color: "grey" Rectangle { id : headerDescription - z: 10 + z: 10 width: gridview.width height: gridview.elementHeight GCText { text: label fontSize: mediumSize wrapMode: Text.WordWrap anchors.horizontalCenter: parent.horizontalCenter } GCButtonCancel { id: discardIcon anchors.right: headerDescription.right anchors.top: headerDescription.top - MouseArea { anchors.fill: parent onClicked: { popup.acceptChange(); popup.hidePopUpAndRestoreFocus(); } } } } GridView { id: gridview z: 4 readonly property int elementHeight: 40 * ApplicationInfo.ratio // each element has a 300 width size minimum. If the screen is larger than it, // we do a grid with cases with 300px for width at minimum. // If you have a better idea/formula to have a different column number, don't hesitate, change it :). readonly property int numberOfColumns: Math.max(1, Math.floor(width / (300 * ApplicationInfo.ratio))) contentHeight: isModelArray ? elementHeight*model.count/numberOfColumns : elementHeight*model.length/numberOfColumns width: listBackground.width height: listBackground.height-headerDescription.height currentIndex: gccombobox.currentIndex flickableDirection: Flickable.VerticalFlick clip: true anchors.top: headerDescription.bottom cellWidth: width / numberOfColumns cellHeight: elementHeight delegate: Component { Rectangle { width: gridview.cellWidth height: gridview.elementHeight color: GridView.isCurrentItem ? "darkcyan" : "beige" border.width: GridView.isCurrentItem ? 3 : 2 radius: 5 Image { id: isSelectedIcon visible: parent.GridView.isCurrentItem source: "qrc:/gcompris/src/core/resource/apply.svg" anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter anchors.leftMargin: 10 sourceSize.width: (gridview.elementHeight * 0.8) } GCText { id: textValue text: isModelArray ? modelData.text : model.text anchors.centerIn: parent } MouseArea { anchors.fill: parent onClicked: { currentIndex = index popup.acceptChange(); popup.hidePopUpAndRestoreFocus(); } } } } } } } } diff --git a/src/core/GCDialog.qml b/src/core/GCDialog.qml index a7c279344..7b9cfcc89 100644 --- a/src/core/GCDialog.qml +++ b/src/core/GCDialog.qml @@ -1,223 +1,225 @@ /* GCompris - GCDialog.qml * * Copyright (C) 2014 Bruno Coudoin * * Authors: * Bruno Coudoin * * This program 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. * * This program 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 this program; if not, see . */ import QtQuick 2.2 import QtQuick.Controls 1.0 import GCompris 1.0 /** * A QML component for GCompris dialogs. * @ingroup components * * Contains the following basic layout elements: Title (message), a GCompris * cancel button (GCButtonCancel) at the top right and two optional buttons. * * Can be conveniently instantiated dynamically in conjunction with * showMessageDialog from core.js. * * GCDialog should now be used wherever you'd use a QtQuick dialog. It has * been decided to implement dialogs ourselves in GCompris because of * missing translations of labels of Qt's standard buttons for some language * supported by GCompris, as well as integration problems on some OSes * (Sailfish OS). * * @inherit QtQuick.Item * @sa showMessageDialog */ Item { id: gcdialog /** * type:string * Heading instruction text. */ property alias message: instructionTxt.textIn /** * type:string * Label of the first button. */ property alias button1Text: button1.text /** * type:string * Label of the second button. */ property alias button2Text: button2.text /** * Emitted when the dialog should be started. * * Triggers fading in. */ signal start /** * Emitted when the dialog should be stopped. * * Triggers fading out. */ signal stop /** * Emitted when the dialog has stopped. */ signal close /** * Emitted when the first button has been clicked. */ signal button1Hit /** * Emitted when the second button has been clicked. */ signal button2Hit focus: true opacity: 0 anchors { fill: parent } onStart: opacity = 1 onStop: opacity = 0 onClose: destroy() Behavior on opacity { NumberAnimation { duration: 200 } } onOpacityChanged: opacity === 0 ? close() : null z: 1500 Rectangle { anchors.fill: parent opacity: 0.8 color: "grey" } MultiPointTouchArea { // Just to catch mouse events anchors.fill: parent } /* Message */ Item { id: instruction anchors { horizontalCenter: parent.horizontalCenter top: parent.top topMargin: buttonCancel.height } width: parent.width * 0.8 Rectangle { id: instructionTxtBg anchors.top: instruction.top z: 1 width: parent.width height: gcdialog.height - button1.height * 5 opacity: 0.9 radius: 10 border.width: 2 border.color: "white" gradient: Gradient { GradientStop { position: 0.0; color: "#fff" } GradientStop { position: 0.9; color: "#fff" } GradientStop { position: 1.0; color: "#ddd" } } Flickable { id: flick anchors.margins: 8 anchors.fill: parent contentWidth: instructionTxt.contentWidth contentHeight: instructionTxt.contentHeight flickableDirection: Flickable.VerticalFlick clip: true GCText { id: instructionTxt fontSize: regularSize color: "black" // @FIXME This property breaks the wrapping // horizontalAlignment: Text.AlignHCenter // need to remove the anchors (left and right) else sometimes text is hidden on the side width: instruction.width - 2*flick.anchors.margins wrapMode: TextEdit.WordWrap textFormat: TextEdit.RichText z: 2 text: style + "" + textIn + "" property string textIn property string style: "" } } } Button { id: button1 width: parent.width height: (visible ? 60 : 30) * ApplicationInfo.ratio anchors { horizontalCenter: parent.horizontalCenter top: instructionTxtBg.bottom topMargin: 10 } style: GCButtonStyle { + theme: "highContrast" } visible: text != "" onClicked: { gcdialog.button1Hit() gcdialog.stop() } } Button { id: button2 width: parent.width height: (visible ? 60 : 30) * ApplicationInfo.ratio anchors { horizontalCenter: parent.horizontalCenter top: button1.bottom topMargin: 10 } style: GCButtonStyle { + theme: "highContrast" } visible: text != "" onClicked: { gcdialog.button2Hit() gcdialog.stop() } } } // Fixme not working, need to properly get the focus on this dialog Keys.onEscapePressed: { stop() event.accepted = true; } // The cancel button GCButtonCancel { id: buttonCancel onClose: parent.stop() } } diff --git a/src/core/main.qml b/src/core/main.qml index cfd3f63c3..c02c0ff90 100644 --- a/src/core/main.qml +++ b/src/core/main.qml @@ -1,355 +1,365 @@ /* GCompris - main.qml * * Copyright (C) 2014 Bruno Coudoin * * Authors: * Bruno Coudoin * * This program 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. * * This program 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 this program; if not, see . */ import QtQuick 2.2 import QtQuick.Controls 1.0 import QtQuick.Window 2.1 import QtQml 2.2 import GCompris 1.0 import "qrc:/gcompris/src/core/core.js" as Core /** * GCompris' main QML file defining the top level window. * @ingroup infrastructure * * Handles application start (Component.onCompleted) and shutdown (onClosing) * on the QML layer. * * Contains the central GCAudio objects audio effects and audio voices. * * Contains the top level StackView presenting and animating GCompris' * full screen views. * * @sa BarButton, BarEnumContent * @inherit QtQuick.Window */ Window { id: main // Start in window mode at full screen size width: ApplicationSettings.previousWidth height: ApplicationSettings.previousHeight minimumWidth: 400 * ApplicationInfo.ratio minimumHeight: 400 * ApplicationInfo.ratio title: "GCompris" /// @cond INTERNAL_DOCS property var applicationState: Qt.application.state onApplicationStateChanged: { if (ApplicationInfo.isMobile && applicationState != Qt.ApplicationActive) { audioVoices.stop(); audioEffects.stop(); } } onClosing: Core.quit(main) GCAudio { id: audioVoices muted: !ApplicationSettings.isAudioVoicesEnabled Timer { id: delayedWelcomeTimer interval: 10000 /* Make sure, that playing welcome.ogg if delayed * because of not yet registered voices, will only * happen max 10sec after startup */ repeat: false onTriggered: { DownloadManager.voicesRegistered.disconnect(playWelcome); } function playWelcome() { audioVoices.append(ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/misc/welcome.$CA")); } } Component.onCompleted: { if(ApplicationSettings.isAudioEffectsEnabled) append(ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/core/resource/intro.$CA")) if (DownloadManager.areVoicesRegistered()) delayedWelcomeTimer.playWelcome(); else { DownloadManager.voicesRegistered.connect( delayedWelcomeTimer.playWelcome); delayedWelcomeTimer.start(); } } } GCAudio { id: audioEffects muted: !ApplicationSettings.isAudioEffectsEnabled } function playIntroVoice(name) { name = name.split("/")[0] audioVoices.append(ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/intro/" + name + ".$CA")) } function checkWordset() { - if(ApplicationSettings.wordset == '') - return + var wordset = ApplicationSettings.wordset + if(wordset == '') + // Maybe the wordset has been bundled or copied manually + // we have to register it if we find it. + wordset = 'data2/words/words.rcc' // check for words.rcc: if (DownloadManager.isDataRegistered("words")) { // words.rcc is already registered -> nothing to do - } else if(DownloadManager.haveLocalResource(ApplicationSettings.wordset)) { + } else if(DownloadManager.haveLocalResource(wordset)) { // words.rcc is there -> register old file first // then try to update in the background - DownloadManager.updateResource(ApplicationSettings.wordset); - } else { + if(DownloadManager.updateResource(wordset)) { + DownloadManager.resourceRegistered.connect(function() { + // not sure if needed, we check if the resource registered is the one we updated here? + if(wordset === arguments[0]) { + DownloadManager.resourceRegistered.disconnect(arguments.callee); + // force configuration to use the local wordset + ApplicationSettings.wordset = wordset + } + }) + } + + + } else if(ApplicationSettings.wordset) { // Only if wordset specified // words.rcc has not been downloaded yet -> ask for download Core.showMessageDialog( main, qsTr("The images for several activities are not yet installed.") + qsTr("Do you want to download them now?"), qsTr("Yes"), function() { - if (DownloadManager.downloadResource(ApplicationSettings.wordset)) + if (DownloadManager.downloadResource(wordset)) var downloadDialog = Core.showDownloadDialog(pageView.currentItem, {}); }, qsTr("No"), null, function() { pageView.currentItem.focus = true } ); } } ChangeLog { id: changelog } Component.onCompleted: { console.log("enter main.qml (run #" + ApplicationSettings.exeCount + ", ratio=" + ApplicationInfo.ratio + ", fontRatio=" + ApplicationInfo.fontRatio + ", dpi=" + Math.round(Screen.pixelDensity*25.4) + ", sharedWritablePath=" + ApplicationInfo.getSharedWritablePath() + ")"); if (ApplicationSettings.exeCount === 1 && !ApplicationSettings.isKioskMode) { // first run var dialog; dialog = Core.showMessageDialog( main, qsTr("Welcome to GCompris!") + '\n' + qsTr("You are running GCompris for the first time.") + '\n' + qsTr("You should verify that your application settings especially your language is set correctly, and that all language specific sound files are installed. You can do this in the Preferences Dialog.") + "\n" + qsTr("Have Fun!") + "\n" + qsTr("Your current language is %1 (%2).") .arg(Qt.locale(ApplicationInfo.getVoicesLocale(ApplicationSettings.locale)).nativeLanguageName) .arg(ApplicationInfo.getVoicesLocale(ApplicationSettings.locale)) + "\n" + qsTr("Do you want to download the corresponding sound files now?"), qsTr("Yes"), function() { if (DownloadManager.downloadResource( DownloadManager.getVoicesResourceForLocale(ApplicationSettings.locale))) var downloadDialog = Core.showDownloadDialog(pageView.currentItem, {}); }, qsTr("No"), null, function() { pageView.currentItem.focus = true checkWordset() } ); } else { // Register voices-resources for current locale, updates/downloads only if // not prohibited by the settings if (!DownloadManager.areVoicesRegistered()) { if (DownloadManager.updateResource( DownloadManager.getVoicesResourceForLocale(ApplicationSettings.locale))) { - DownloadManager.downloadFinished.connect(function() { - checkWordset(); - DownloadManager.downloadFinished.disconnect(arguments.callee); - }); DownloadManager.resourceRegistered.connect(function() { // not sure if needed, we check if the resource registered is the one we updated here? if(DownloadManager.getVoicesResourceForLocale(ApplicationSettings.locale) === arguments[0]) { DownloadManager.resourceRegistered.disconnect(arguments.callee); checkWordset(); } }); } else { checkWordset() } } else { checkWordset() } if(changelog.isNewerVersion(ApplicationSettings.lastGCVersionRan, ApplicationInfo.GCVersionCode)) { // display log between ApplicationSettings.lastGCVersionRan and ApplicationInfo.GCVersionCode var dialog; dialog = Core.showMessageDialog( main, qsTr("GCompris has been updated! Here are the new changes:
") + changelog.getLogBetween(ApplicationSettings.lastGCVersionRan, ApplicationInfo.GCVersionCode), "", null, "", null, function() { pageView.currentItem.focus = true } ); // Store new version ApplicationSettings.lastGCVersionRan = ApplicationInfo.GCVersionCode; } } } Loading { id: loading } StackView { id: pageView anchors.fill: parent initialItem: { "item": "qrc:/gcompris/src/activities/" + ActivityInfoTree.rootMenu.name, "properties": { 'audioVoices': audioVoices, 'audioEffects': audioEffects, 'loading': loading } } focus: ApplicationInfo.QTVersion >= "5.4.0" delegate: StackViewDelegate { id: root function getTransition(properties) { audioVoices.clearQueue() if(!properties.exitItem.isDialog && // if coming from menu and !properties.enterItem.isDialog) // going into an activity then playIntroVoice(properties.enterItem.activityInfo.name); // play intro if (!properties.exitItem.isDialog || // if coming from menu or properties.enterItem.alwaysStart) // start signal enforced (for special case like transition from config-dialog to editor) properties.enterItem.start(); if(properties.name === "pushTransition") { if(properties.enterItem.isDialog) { return pushVTransition } else { return pushHTransition } } else { if(properties.exitItem.isDialog) { return popVTransition } else { return popHTransition } } } function transitionFinished(properties) { properties.exitItem.opacity = 1 if(!properties.enterItem.isDialog) { properties.exitItem.stop() } } property Component pushHTransition: StackViewTransition { PropertyAnimation { target: enterItem property: "x" from: target.width to: 0 duration: 500 easing.type: Easing.OutSine } PropertyAnimation { target: exitItem property: "x" from: 0 to: -target.width duration: 500 easing.type: Easing.OutSine } } property Component popHTransition: StackViewTransition { PropertyAnimation { target: enterItem property: "x" from: -target.width to: 0 duration: 500 easing.type: Easing.OutSine } PropertyAnimation { target: exitItem property: "x" from: 0 to: target.width duration: 500 easing.type: Easing.OutSine } } property Component pushVTransition: StackViewTransition { PropertyAnimation { target: enterItem property: "y" from: -target.height to: 0 duration: 500 easing.type: Easing.OutSine } PropertyAnimation { target: exitItem property: "y" from: 0 to: target.height duration: 500 easing.type: Easing.OutSine } } property Component popVTransition: StackViewTransition { PropertyAnimation { target: enterItem property: "y" from: target.height to: 0 duration: 500 easing.type: Easing.OutSine } PropertyAnimation { target: exitItem property: "y" from: 0 to: -target.height duration: 500 easing.type: Easing.OutSine } } property Component replaceTransition: pushHTransition } } /// @endcond }