Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2002.11.18;
Скачать: [xml.tar.bz2];

Вниз

Как настрить МастерДетайл виды в QuantumGrid v.4 через TADOQuery   Найти похожие ветки 

 
mvg_first   (2002-10-28 21:46) [0]

Вышел значит недвано новая версия Quantum Grid от DevExpress. И вней есть такая очень красивая возможность по реализации несколькоих Мастер-Дейил отношений в одном гриде. У кого нибудь получилось уже настроить нормальную работу используюя TADOQuery и параметризированные запросы.
Во всех моих попытках получался глюк выражающийся в отражении одинаковых изменений во всех детаилах при редактировании данных в одном из них. Никто не сталкивался с такой проблемой? Как с этим бороться?


 
vuk   (2002-10-28 21:58) [1]

Master-detail построить получилось. Насчет измененяемых датасетов пока проверить не успел. Сегодня попинаю еще - отпишу.


 
Ученик   (2002-10-28 22:19) [2]

Дополнительный вопрос:
Master-Detail работает только для GridMode = False или что-то все-таки можно настроить ?


 
vuk   (2002-10-28 22:24) [3]

Я, честно говоря, не вижу причин по которым не должен работать Master-Detail не в GridMode. Это же не группировки, где необходимо вытягивание всего набора данных. Хотя... Это я тоже до кучи проверю.
Если честно, давно не приходилось запускать QuantumGrid не в режиме LoadAllRecords (GridMode в QG4). :o)


 
Ученик   (2002-10-28 22:28) [4]

>vuk © (28.10.02 22:24)
А как решается проблема быстродействия на больших данных, загрузка это же время


 
vuk   (2002-10-28 22:36) [5]

>А как решается проблема быстродействия на больших данных
Большие объемы данных (на которых все это будет действительно тормозить) запрашивать не имеет смысла, поскольку пользователь не сможет в них ориентироваться. Ну сами посудите, кому охота ковыряться в паре тысяч записей выискивая одну (хотя даже пара тысяч записей втягивается в момент)? Поэтому если пользователю реально необходимо работать с большими объемами, то представление данных нужно оптимизировать так, чтобы информация была каким-либо образом структурирована(тот же master-detail). В этом случае никаких проблем больших объемов просто не возникает. А если же нужен некий отчет, то здесь в любом случае нужно ждать полной обработки набора данных.


 
Ученик   (2002-10-28 22:41) [6]

>vuk © (28.10.02 22:36)
Как раз и хотелось основную таблицу в GridMode=True, подчиненные в любом виде (карточка, таблица), но почему-то подчиненные оказываются пустыми :(


 
vuk   (2002-10-28 22:45) [7]

У меня с этим проблем не было (Master-detail делался исключительно средствами QG4 с использовыанием ADOStoredProc).
Как Вы организуете Master-Detail? Поподробнее, если можно.


 
Ученик   (2002-10-28 23:56) [8]

>vuk © (28.10.02 22:45)
GridMode был в каком режиме ? тут ведь вот было: GridMode=False для Master, все показывается нормально, GridMode=True, подчиненные таблицы пустые :(


 
Tornado   (2002-10-29 07:57) [9]

А где можно взять новую версю Квантума? Я слышал что эти компоненты стоят немалых денег.


 
Ученик   (2002-10-29 08:42) [10]

>Tornado © (29.10.02 07:57)
На www.torry.net продают


 
mvg_first   (2002-10-29 10:21) [11]

Ну так что? Кто нибудь уже решил вопрос?
Кстати со всеми почитал я тут ответы и запутался с определениями :) Давайте расставим точки над и.
GridMode - это режим когда загружается только часть данных, он призван ускорить загрузку "непомерно" больших объемов данных.
LoadAllRecords - это когда GridMode = False, в этом режиме доступны и сортировка и группировка и все прочие фенечки :). Хотя в хелпе написано что в GridMode = True сортировку и группировку необходимо организовывать с помощью соответствующих событий.
Есть еще свойство DataInSQLMode - которое определяет что работа происходит с параметризированным запросом. В моем понимании это нечто вроде этого

SELECT * FROM Customers WHERE CUSTID = :ID

Т.е. при работе моей программы достаточно только менять значение параметра и все должно отражаться правильно. По крайней мере есил механизм Мастер_детаил организовывать через Свойство DataSource в TADOQuery то все именно так и работает.
Что подразумевали разработчики QG4 я не знаю.

В примерах QG4 отражается банальная работа с помощью таблиц. И без параметризированых запросов.А как работать именно с запросами?? Я не знаю.


 
mvg_first   (2002-10-29 10:32) [12]

Более подробно опишу пример на котором у меня не работает Мастер-Детаил.
Есть две таблицы одна - "Таблица товаров" вторая таблица документов по которым этот товар приходил. Обе достаточно большие больше 10000 записей. Вернее в первой таблице их около 2000 во второй соответственно что то около 20 000. Т.е. открытие этих таблиц полностью занятие достаточно геморойное, как вы понимаете.

По этому написал пример в котором Использую параметрический запрос, все сделал как описано в Хелпе. Даже обработал событие OnDetailFirst, что бы обрабатывать установку параметра для фильрования записей.
Запрос ко второй таблице выглядит так

SELECT * FROM TabDoc WHERE IdTov = :ID_TOV

В обработчике указанного события выполняю переоткрытие таблицы

with (ADataSet as TADOQuery) do
begin
DisableControls;
try
Active := False;
Parameters.ParamByName("ID_TOV").Value := AMasterDetailKeyValues;
Active := True;
finally
EnableControls;
end;
AReopened := True;
end;

В результате вполне красиво по "плюсику" открываются детаилы для каждой строки товара. но при установке курсора ячейку с автоматическим включением редактирование в редактируемом поле отображается значение из другого детаила, который был открыт ранее. И когда начинаю редактировать поле, данные изменяются во всех открытых детаилах в той строке на который был в каждом из них последний раз.


 
vuk   (2002-10-29 11:13) [13]

to Ученик:
>тут ведь вот было: GridMode=False для Master, все показывается
>нормально, GridMode=True, подчиненные таблицы пустые :(
Похоже все-таки да, не работает это все в GridMode. Что это, особенность работы или баг, пока не знаю, надо будет DevExpress трясти на эту тему...


to mvg_first:
>Давайте расставим точки над и.
Вы поняли все совершенно верно.

Там же есть нужно написать обработчик OnDetailIsCurrentQuery, который определяет, является ди текущий набор данных в подчиненном наборе данных именно тем набором, который нужно отобразить. Проверяется это по значениям пареметров (в принципе, можног и не проверять, а просто вернуть false). Возможно это решит проблему.


 
mvg_first   (2002-10-29 11:46) [14]

Нмчего не помогает, я даже больше скажу. Только что внимательнее присмотрелся к поведению Детаил-грида. У меня стоят параметры по умолчанию, т.е. ДатаСет в авторедактировании, у грида стоит опция "сразу показывать редактор". Так вот, открываю первый детаил грид в нем допустим 5 строк, на первой записи в колонке цена указано 0,91 на второй вижу 0,86 при перемещении фокуса на вторую строку в ней значение меняется на 0,91. Т.е. значение берется из первой записи, и так при хождении по всем строкам :(
Это 100% глюк. Если это не так, скажите как сделать правильно.

Второй глюк который я заметил - это если не ставить галку в свойстве DetailInSQLMode и организовывать мастердетаил используюя TAdoQuery то в детаилах отображается только первая запись хотя их конкретно больше.

Вот такой глюк.


 
mvg_first   (2002-10-29 11:47) [15]


> который определяет, является ди текущий набор данных в подчиненном
> наборе данных именно тем набором, который нужно отобразить.
> Проверяется это по значениям пареметров (в принципе, можног
> и не проверять, а просто вернуть false).

А вы это сами проверяли? У меня вот не сработало почему то :(


 
vuk   (2002-10-29 12:04) [16]

to mvg_first:
>Нмчего не помогает, я даже больше скажу.
У меня такого не было. Все работает как часы (если не в GridMode).


>А вы это сами проверяли? У меня вот не сработало почему то :(
А то как же? Вот только что еще раз проверил. Все работает как и должно.

А у Вас свойства KeyFieldNames/ MasterKeyFieldNames/ DetailKeyFieldNames правильно установлены?


 
mvg_first   (2002-10-29 12:17) [17]

Все стоит правильно.
Первая таблица - Все по умолчанию, только установил DataSource на TAdoQuery с запросом SELECT * FROM TovTab (т.е. полная выборка) это таблица мастер. У нее же установил DetailInSQLMode=true.
Добавил подуровень и в в нем в установил DataSource на TAdoQuery с запросом SELECT * FROM DocTab WHERE IdTov = :ID_TOV (т.е. параметризированный запрос).
Свойство DetailKeyFieldNames Установил на поле IdTov - в моей таблице указывает на идентификатор товара
Свойство MasterKeyFieldNames установил на поле ID - поле из первой таблицы указывает на уникальный идентификатор товара
Свойство KeyFieldNames установил на поле ROW_ID - поле второй таблицы указывает на уникальный идентификторо строки во втрой таблице


 
vuk   (2002-10-29 12:22) [18]

У Вас BD какая? Если MSSQL, то могу попробовать набросать пример на демонстрационной базе MS и сюда выложить...


 
mvg_first   (2002-10-29 12:34) [19]

БД у меня MSSQL 7.0 Насчет примера возражать не буду. Так что б уж совесем все понятно стало.

Может у меня версия QG4 не корректная :) Надо бы сверить :) У меня версия 1.0.0.0


 
mvg_first   (2002-10-29 13:57) [20]

Алло vuk так где же пример? Или очень сложно?


 
vuk   (2002-10-29 14:58) [21]

Оно не сложно, в принципе, я его уже сделал, просто я сейчас занят на работе... Там только одна тонкость вылезла, которой сразу не заметил (возможно это небольшой баг). Дело в том, что уже загруженный подчиненный набор данных переоткрывается не при активизации соответствующего GridView, а только после навигации по записям в нем.

Пример будет чуть позжее...


 
vuk   (2002-10-29 18:22) [22]

Собственно пример. D6 + ADO. Сначала модуль, потом файл формы.
Необходимо поправить ConnectionString.

unit1.pas


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, cxStyles, cxCustomData, cxGraphics, cxFilter, cxData, cxEdit,
DB, cxDBData, cxGridLevel, cxClasses, cxControls, cxGridCustomView,
cxGridCustomTableView, cxGridTableView, cxGridDBTableView, cxGrid, ADODB,
Grids, DBGrids;

type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
qryCategories: TADOQuery;
qryProducts: TADOQuery;
dsCategories: TDataSource;
dsProducts: TDataSource;
tvCategories: TcxGridDBTableView;
lvCategories: TcxGridLevel;
cxGrid1: TcxGrid;
qryCategoriesCategoryID: TAutoIncField;
qryCategoriesCategoryName: TWideStringField;
qryCategoriesDescription: TMemoField;
qryCategoriesPicture: TBlobField;
qryProductsProductID: TAutoIncField;
qryProductsProductName: TWideStringField;
qryProductsSupplierID: TIntegerField;
qryProductsCategoryID: TIntegerField;
qryProductsQuantityPerUnit: TWideStringField;
qryProductsUnitPrice: TBCDField;
qryProductsUnitsInStock: TSmallintField;
qryProductsUnitsOnOrder: TSmallintField;
qryProductsReorderLevel: TSmallintField;
qryProductsDiscontinued: TBooleanField;
lvProducts: TcxGridLevel;
tvProducts: TcxGridDBTableView;
tvCategoriesCategoryID: TcxGridDBColumn;
tvCategoriesCategoryName: TcxGridDBColumn;
tvCategoriesDescription: TcxGridDBColumn;
tvCategoriesPicture: TcxGridDBColumn;
tvProductsProductID: TcxGridDBColumn;
tvProductsProductName: TcxGridDBColumn;
tvProductsSupplierID: TcxGridDBColumn;
tvProductsCategoryID: TcxGridDBColumn;
tvProductsQuantityPerUnit: TcxGridDBColumn;
tvProductsUnitPrice: TcxGridDBColumn;
tvProductsUnitsInStock: TcxGridDBColumn;
tvProductsUnitsOnOrder: TcxGridDBColumn;
tvProductsReorderLevel: TcxGridDBColumn;
tvProductsDiscontinued: TcxGridDBColumn;
DBGrid1: TDBGrid;
DBGrid2: TDBGrid;
procedure ReopenProducts(
Sender: TcxDBDataModeController; ADataSet: TDataSet;
const AMasterDetailKeyFieldNames: String;
const AMasterDetailKeyValues: Variant; var AReopened: Boolean);
function CheckProductsDS(
Sender: TcxDBDataModeController; ADataSet: TDataSet;
const AMasterDetailKeyFieldNames: String;
const AMasterDetailKeyValues: Variant): Boolean;
procedure FormCreate(Sender: TObject);
private
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ReopenProducts(
Sender: TcxDBDataModeController; ADataSet: TDataSet;
const AMasterDetailKeyFieldNames: String;
const AMasterDetailKeyValues: Variant; var AReopened: Boolean);
begin
with (ADataSet as TADOQuery) do
begin
if Parameters.ParamValues["Category"] = AMasterDetailKeyValues then

begin
First;
Exit;
end;
DisableControls;
try
Active := False;
Parameters.ParamValues["Category"] := AMasterDetailKeyValues;
Active := True;
finally
EnableControls;
end;
AReopened := True;
end;
end;

function TForm1.CheckProductsDS(
Sender: TcxDBDataModeController; ADataSet: TDataSet;
const AMasterDetailKeyFieldNames: String;
const AMasterDetailKeyValues: Variant): Boolean;
begin
Result := false;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
qryCategories.Open;
qryProducts.Open;
end;

end.



 
vuk   (2002-10-29 18:24) [23]

unit1.dfm

object Form1: TForm1
Left = 347
Top = 151
Width = 605
Height = 460
Caption = "Form1"
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = "MS Sans Serif"
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object cxGrid1: TcxGrid
Left = 0
Top = 0
Width = 597
Height = 193
Align = alClient
TabOrder = 0
object tvCategories: TcxGridDBTableView
DataController.DataSource = dsCategories
DataController.DetailKeyFieldNames = "CategoryID"
DataController.Filter.Criteria = {00000000}
DataController.KeyFieldNames = "CategoryID"
DataController.Summary.DefaultGroupSummaryItems = <>
DataController.Summary.FooterSummaryItems = <>
DataController.Summary.SummaryGroups = <>
OptionsBehavior.ImmediateEditor = False
object tvCategoriesCategoryID: TcxGridDBColumn
DataBinding.FieldName = "CategoryID"
end
object tvCategoriesCategoryName: TcxGridDBColumn
DataBinding.FieldName = "CategoryName"
end
object tvCategoriesDescription: TcxGridDBColumn
DataBinding.FieldName = "Description"
end
object tvCategoriesPicture: TcxGridDBColumn
DataBinding.FieldName = "Picture"
end
end
object tvProducts: TcxGridDBTableView
DataController.DataModeController.DetailInSQLMode = True
DataController.DataModeController.OnDetailFirst = ReopenProducts
DataController.DataModeController.OnDetailIsCurrentQuery = CheckProductsDS
DataController.DataSource = dsProducts
DataController.DetailKeyFieldNames = "CategoryID"
DataController.Filter.Criteria = {00000000}
DataController.KeyFieldNames = "ProductID"
DataController.MasterKeyFieldNames = "CategoryID"
DataController.Summary.DefaultGroupSummaryItems = <>
DataController.Summary.FooterSummaryItems = <>
DataController.Summary.SummaryGroups = <>
OptionsBehavior.ImmediateEditor = False
object tvProductsProductID: TcxGridDBColumn
DataBinding.FieldName = "ProductID"
end
object tvProductsProductName: TcxGridDBColumn
DataBinding.FieldName = "ProductName"
end
object tvProductsSupplierID: TcxGridDBColumn
DataBinding.FieldName = "SupplierID"
end
object tvProductsCategoryID: TcxGridDBColumn
DataBinding.FieldName = "CategoryID"
end
object tvProductsQuantityPerUnit: TcxGridDBColumn
DataBinding.FieldName = "QuantityPerUnit"
end
object tvProductsUnitPrice: TcxGridDBColumn
DataBinding.FieldName = "UnitPrice"
end
object tvProductsUnitsInStock: TcxGridDBColumn
DataBinding.FieldName = "UnitsInStock"
end
object tvProductsUnitsOnOrder: TcxGridDBColumn
DataBinding.FieldName = "UnitsOnOrder"
end
object tvProductsReorderLevel: TcxGridDBColumn
DataBinding.FieldName = "ReorderLevel"
end
object tvProductsDiscontinued: TcxGridDBColumn
DataBinding.FieldName = "Discontinued"
end
end
object lvCategories: TcxGridLevel
GridView = tvCategories
object lvProducts: TcxGridLevel
GridView = tvProducts
end
end
end
object DBGrid1: TDBGrid
Left = 0
Top = 313
Width = 597
Height = 120
Align = alBottom
DataSource = dsProducts
TabOrder = 1
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = "MS Sans Serif"
TitleFont.Style = []
end
object DBGrid2: TDBGrid
Left = 0
Top = 193
Width = 597
Height = 120
Align = alBottom
DataSource = dsCategories
TabOrder = 2
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = "MS Sans Serif"
TitleFont.Style = []
end


 
vuk   (2002-10-29 18:25) [24]

продолжение unit1.dfm

object ADOConnection1: TADOConnection
Connected = True
ConnectionString =
"Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security In" +
"fo=False;Initial Catalog=Northwind;Data Source=FCS---S05"
LoginPrompt = False
Provider = "SQLOLEDB.1"
Left = 32
Top = 70
end
object qryCategories: TADOQuery
Connection = ADOConnection1
CursorType = ctStatic
Parameters = <>
SQL.Strings = (
"SELECT CategoryID, CategoryName, Description, Picture"
"FROM Categories")
Left = 32
Top = 98
object qryCategoriesCategoryID: TAutoIncField
FieldName = "CategoryID"
ReadOnly = True
end
object qryCategoriesCategoryName: TWideStringField
FieldName = "CategoryName"
Size = 15
end
object qryCategoriesDescription: TMemoField
FieldName = "Description"
BlobType = ftMemo
end
object qryCategoriesPicture: TBlobField
FieldName = "Picture"
end
end
object qryProducts: TADOQuery
Connection = ADOConnection1
CursorType = ctStatic
Parameters = <
item
Name = "Category"
DataType = ftString
Size = 4
Value = Null
end>
SQL.Strings = (
"SELECT ProductID, ProductName, SupplierID, "
" CategoryID, QuantityPerUnit, UnitPrice,"
" UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued"
"FROM Products"
"WHERE CategoryID = :Category")
Left = 32
Top = 126
object qryProductsProductID: TAutoIncField
FieldName = "ProductID"
ReadOnly = True
end
object qryProductsProductName: TWideStringField
FieldName = "ProductName"
Size = 40
end
object qryProductsSupplierID: TIntegerField
FieldName = "SupplierID"
end
object qryProductsCategoryID: TIntegerField
FieldName = "CategoryID"
end
object qryProductsQuantityPerUnit: TWideStringField
FieldName = "QuantityPerUnit"
end
object qryProductsUnitPrice: TBCDField
FieldName = "UnitPrice"
Precision = 19
end
object qryProductsUnitsInStock: TSmallintField
FieldName = "UnitsInStock"
end
object qryProductsUnitsOnOrder: TSmallintField
FieldName = "UnitsOnOrder"
end
object qryProductsReorderLevel: TSmallintField
FieldName = "ReorderLevel"
end
object qryProductsDiscontinued: TBooleanField
FieldName = "Discontinued"
end
end
object dsCategories: TDataSource
DataSet = qryCategories
Left = 60
Top = 98
end
object dsProducts: TDataSource
DataSet = qryProducts
Left = 60
Top = 126
end
end



 
mvg_first   (2002-10-29 20:08) [25]

Ок, пример себе скопировал, но посмотрю уже завтра. И вопросы понятное дело завтра продолжаться :)


 
vuk   (2002-10-29 20:13) [26]

Когда будете смотреть, обратите внимания на два обычных (TDBGrid) грида внизу формы. Они там для того, чтобы было видно, что происходит с наборами данных при навигации по QG.


 
mvg_first   (2002-10-30 12:11) [27]

Вообщем как я и предполагал, глюк остался :)
Как повторить чтоб было понятнее.
Пример скомпилил без изменений (только подправил имя сервера)
Запустил, все заработало, гриды открываются, как положено.
Нажал, на "плюсик" в строке с CategoryId = 4
и так же нажал на "плюсик" в строке с CategoryId = 5
Передо мной картина из двух вложенных таблиц содержащих совершенно разные данные. Как и должно быть. Т.е. пока все нормально.

После чего изменяю знчение в колонке UnitPrice второго детаила в первой строке. После изменения нажимаю Enter и вижу ту же значение в первой строке первого детаила. В результате - явная бочина. Может это так и должно быть??? Но я никогда не докажу этого пользователям моей программы :)


 
mvg_first   (2002-10-30 12:18) [28]

Уточню данные, изменения отражаются не обязательно в первой строке, если допустим в первом детаиле переместится на 3-ю запись а потом перейти на второй детаил и сделать изменения в первой (или во второй или в любой) записи то изменения отразятся в первом детаиле в той строке в которой мы находились перед тем как перешли во втрой детаил.

Причем строка первого детаила (который как бы не активный) выглядит совершенно точно по всем полям так же как и строка второго детаила которую мы только что изменили.

Если перейти обратно в первый детаил все становится на свои места :) Значения возвращаются в норму :).


 
vuk   (2002-10-30 14:47) [29]

Да, действительно, баг присутствует, я просто даже сначала на него внимания не обратил. Надо будет багрепорт отправить...


 
mvg_first   (2002-10-30 14:59) [30]

Все таки я добился своего !!! Хоть кто то баг подтвердил.

А можно ли считать багом то что в GridMode = True не работает мастер детаил???

И если можно, результат общения мне на мыло mvgfirst@nm.ru если не затруднит.

Заранее спасибо :)


 
vuk   (2002-10-30 15:05) [31]

>А можно ли считать багом то что в GridMode = True не работает
>мастер детаил???
Не знаю, пока с этим вопрос не ясен, в ньюсгруппе у DevExpress уже есть сообщения по этому поводу...

Результат (если он будет) можно будет смотреть там же. Пока же нужно еще на это время найти.




Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2002.11.18;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.009 c
14-59372
Anatoly Podgoretsky
2002-10-26 23:58
2002.11.18
Ура нас опять более 10000


14-59348
Igorek
2002-10-25 10:40
2002.11.18
Непереведенные издания


14-59439
Yuraz
2002-10-28 20:53
2002.11.18
Программа для изготовления индексной страницы локального форума


14-59406
ZZ
2002-10-31 09:46
2002.11.18
Требуются...


1-59210
Pesh
2002-11-06 13:59
2002.11.18
ShBrowseFolder с Initial Dir





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский