Rapor

Transkript

Rapor
KARADENİZ TEKNİK ÜNİVERSİTESİ
MÜHENDİSLİK FAKÜLTESİ
BİLGİSAYAR MÜHENDİSLİĞİ BÖLÜMÜ
GÖKTÜRKÇE YAZI ÇEVİRİCİ
TASARIM PROJESİ
Muhammed Mehdi USLU
Salih TOPÇU
2015-2016 GÜZ DÖNEMİ
KARADENİZ TEKNİK ÜNİVERSİTESİ
MÜHENDİSLİK FAKÜLTESİ
BİLGİSAYAR MÜHENDİSLİĞİ BÖLÜMÜ
GÖKTÜRKÇE YAZI ÇEVİRİCİ
TASARIM PROJESİ
Muhammed Mehdi USLU
Salih TOPÇU
Bu projenin teslim edilmesi ve sunulması tarafımca uygundur.
Danışman : Yrd. Doç. Tuğrul ÇAVDAR
2015-2016 GÜZ DÖNEMİ
.........................
IEEE Etik Kuralları
IEEE Code of Ethics
Mesleğime karşı şahsi sorumluluğumu kabul ederek, hizmet ettiğim toplumlara ve
üyelerine en yüksek etik ve mesleki davranışta bulunmaya söz verdiğimi ve aşağıdaki etik
kurallarını kabul ettiğimi ifade ederim:
1. Kamu güvenliği, sağlığı ve refahı ile uyumlu kararlar vermenin sorumluluğunu kabul
etmek ve kamu veya çevreyi tehdit edebilecek faktörleri derhal açıklamak;
2. Mümkün olabilecek çıkar çatışması, ister gerçekten var olması isterse sadece algı
olması, durumlarından kaçınmak. Çıkar çatışması olması durumunda, etkilenen
taraflara durumu bildirmek;
3. Mevcut verilere dayalı tahminlerde ve fikir beyan etmelerde gerçekçi ve dürüst olmak;
4. Her türlü rüşveti reddetmek;
5. Mütenasip uygulamalarını ve muhtemel sonuçlarını gözeterek teknoloji anlayışını
geliştirmek;
6. Teknik yeterliliklerimizi sürdürmek ve geliştirmek, yeterli eğitim veya tecrübe olması
veya işin zorluk sınırları ifade edilmesi durumunda ancak başkaları için teknolojik
sorumlulukları üstlenmek;
7. Teknik bir çalışma hakkında yansız bir eleştiri için uğraşmak, eleştiriyi kabul etmek ve
eleştiriyi yapmak; hatları kabul etmek ve düzeltmek; diğer katkı sunanların emeklerini
ifade etmek;
8. Bütün kişilere adilane davranmak; ırk, din, cinsiyet, yaş, milliyet, cinsi tercih, cinsiyet
kimliği, veya cinsiyet ifadesi üzerinden ayırımcılık yapma durumuna girişmemek;
9. Yanlış veya kötü amaçlı eylemler sonucu kimsenin yaralanması, mülklerinin zarar
görmesi, itibarlarının veya istihdamlarının zedelenmesi durumlarının oluşmasından
kaçınmak;
10. Meslektaşlara ve yardımcı personele mesleki gelişimlerinde yardımcı olmak ve onları
desteklemek.
IEEE Yönetim Kurulu tarafından Ağustos 1990’da onaylanmıştır.
II
ÖNSÖZ
Bu projedeki amacımız eski Türkçemizi yaşatan, seven, ilgi duyan kişilerin böyle bir
uygulamaya duydukları ihtiyacı gidermekti. İlk sürümü çıkardığımızda da gerçekten böyle
olduğunu gördük ve onlardan aldığımız geri dönüş ile birlikte uygulamamıza yeni özellik
ekleyerek ikinci sürümünü yaparak eski Türkçe metinlerini paylaşabilmelerini sağladık.
Böyle bir projede yer almamızı, binlerce insana ulaşmamızı ve eski Türkçemizi
yaşatabilme imkanı veren Tuğrul ÇAVDAR hocamıza teşekkürlerimiz sunuyoruz.
Muhammed Mehdi USLU
Salih TOPÇU
Trabzon 2015
III
İÇİNDEKİLER
IEEE ETİK KURALLARI
ÖNSÖZ
İÇİNDEKİLER
ÖZET
1. GENEL BİLGİLER
1.1. Giriş
1.2. Göktürkçe Harflerin Latin Karşılıkları
1.3. Latin Kelimelerin Göktürkçeye Çevrilirken Kullanılan Kurallar
2. YAPILAN ÇALIŞMALAR
2.1. Kullanılan Materyaller
2.2. Font Seçimi
2.3. Android’te Unicode Karakterlerin Yazımı
2.4. Java Kodları
2.4.1. Intro Sınıfı
2.4.2. About Sınıfı
2.4.3. MainActivity Sınıfı
2.4.4. Preprocess Sınıfı
2.4.5. Rules Sınıfı
2.4.6. DBHelper Sınıfı
2.4.7. Save Sınıfı
2.5. Tasarım
2.5.1. Intro Ekranının Tasarımı
2.5.2. Hakkında Ekranının Tasarımı
2.5.3. Ana Ekran Tasarımı
2.5.4. Kaydetme ve Paylaş Ekranının Tasarımı
3. SONUÇLAR
4. ÖNERİLER
5. KAYNAKLAR
STANDARTLAR ve KISITLAR FORMU
IV
Sayfa No
II
III
IV
V
1
1
2
2
4
4
4
4
5
5
8
9
16
23
27
30
35
35
41
41
45
51
52
53
54
ÖZET
Projenin amacı günümüz Latin harflerini kullanarak yazdığımız metinleri eski
Türkçemiz olan Göktürkçe metine çevrilip istenildiğinde görüntü dosyası olarak kaydetmek
veya herhangi bir yerde paylaşılabilmesi sağlamaktır.
Uygulama istenilen düzeye getirildi ve binlerce kullanıcıya ulaştı.
V
1
1. GENEL BİLGİLER
1.1. Giriş
Uygulamada kullanıcıdan alınan Latin harflerle yazılmış Türkçe metin Göktürkçeye
dönüştürülerek tekrar kullanıcıya sunulmaktadır. Bu çeviri işlem Göktürkçe kuralları
uygulanarak yapılmaktadır. Çeviride kullanılan kurallar kok-turk.blogspot.com [2] sitesinden
alınmıştır.
Android işletim sistemli cihazlarda Göktürkçe karakter içiren bir font olmadığı için
uygulama içine bir font gömüldü. Böylece uygulama içinde Göktürkçe karakterlerin sorunsuz
bir şekilde gösterilmesi sağlandı.
Göktürkçede bazı kelimeler özel bir yazıma sahip olmaktadır. Dolayısıyla diğer
kelimelerin çevirisinde kullanılan kurallar bu kelimeleri doğru bir biçimde çevirememektedir.
Bu yüzden program ilk çalıştırıldığında bu özel kelimeler cihazın veri tabanına kaydedilir.
Kullanıcı bu kelimeleri girdiği zaman kelimenin mevcudiyeti veri tabanında kontrol edilir.
Eğer kelime mevcut ise gerekli değişiklikler yapılarak çevirme işlemi başlatılır. Bu farklılık
genellikle dilimizde eskiden var olup günümüz alfabesinde kullanılmayan Nazal n ve Kapalı e
harflerin eksikliğinden kaynaklanmaktadır. Bu harflerin kullanıldığı kelimeleri veri tabanına
ekleyerek bu eksikliği ortadan kaldırmaya çalışılmıştır.
Ayrıca yine bazı kelimeler Göktürkçede günümüz Türkçesinde yazıldığı gibi yazılmaz.
Örneğin komşu kelimesi Göktürkçede konşu olarak yazılmaktadır. Aynı şekilde omurga
kelimesi de onurga olarak yazılmaktadır. Yine bu gibi kelimeler çevrilmeden önce bir ön
işleme tabi tutulması gerekmektedir. Çeviri işlemi yapılmadan önce bu kelimeler tespit edilir
ve gerekli değişiklikler yapılarak çeviri işlemi yapılmaktadır.
Son olarak Göktürkçede bazı iki sesli harfler bulunmaktadır. Örneğin ng, nc, nt gibi.
Çeviri işlemi yapılmadan önce kelimede bu harfler aranır ve Türkçede bulunmayan X, x, W, w
gibi harflere dönüştürülür. Daha sonra çeviri işlemi sırasında bu harflere karşılık düşen gibi
2
harflere dönüştürülür. Çeviri işlemi sırasında bu harflere karşılık düşen Göktürkçe karakterler
yazılır.
1.2. Göktürkçe Harflerin Latin Karşılıkları
Göktürkçede harfler kalın ve ince olarak ayrılmaktadır. Harflerin kalın veya ince olduğu
sessiz harfin yanındaki sesli harfe bakılarak anlaşılmaktadır.
1.3. Latin Kelimelerin Göktürkçeye Çevrilirken Kullanılan Kurallar
1. Yazı sağdan sola yazılır ve kelimeler : ile ayrılır.
2. Kalın harflerden önce a, ince harflerden önce e yazılmaz.
3. Kelime başında ve ortasında a/e yazılmaz ama sonunda yazılır.
4. Kelime başında ı/i/o/ö/u/ü her zaman yazılır. Sadece ık =
iç =
, ok/uk = , ök/ük = ,
ile bitiyorsa istisna olarak bu özel harfler kullanılmıştır.
5. İlk hecedeki sesliye bağlı olarak sonraki hecelerde genellikle küçük ünlü uyumuna
3
uyan sesliler (a/e/ı/i  a/e/ı/i, o/ö/u/ü  a/e/u/ü) yazılmaz. Yani:
•
İlk hecede a/e varsa sonraki hecelerde ı/i yazılmaz; ama yuvarlak sesli
yazılır.
•
İlk hecede olan seslinin aynısı sonraki hecelerde varsa yazılmaz. Yani:

İlk hecede ı/i varsa sonraki hecelerde ı/i yazılmaz.

İlk hecede o/u varsa sonraki hecelerde o/u yazılmaz.

İlk hecede ö/ü varsa sonraki hecelerde ö/ü yazılmaz.
•
İlk hecede yuvarlak sesli varsa sonraki hecelerde ı/i yazılır.
•
İlk hecede düz sesli varsa sonraki hecelerde yuvarlak sesli yazılır.
6. Kelime sonunda tüm sesliler yazılır.
7. Günümüz Türkçesinde F, C/J, H, V yerine sırasıyla P, Ç, K, B kullanılabilir.
8. k harfinin özel hallerinden sonra gelen bazı sesliler için aşağıdaki kullanımlar
mevcuttur.
•
: ok/uk iken,
: ko/ku (sıklıkla)
•
: ök/ük iken,
: kö/kü (nadiren)
•
: ık iken,
: kı
(sıklıkla)
4
2. YAPILAN ÇALIŞMALAR
2.1. Kullanılan Materyaller
Projede IDE olarak Android Studio, emülatör olarak Genymotion, test yapılan mobil
cihazlar olarak Sony Xperia Z3 Compact, Samsung Galaxy Note 2, General Mobile
Discovery 2, Asus Transformer Pad kullanıldı.
2.2. Font Seçimi
Göktürkçe harfleri mobil cihaz ekranında görebilmek için Göktürkçe Unicode aralığını
destekleyen bir font kullanıldı. Font olarak Windows 10 ile birlikte gelen Segoe UI Historic
tercih edildi.
Çoğu sistem fontu Göktürkçe Unicode aralığını desteklemediği ve sistem fontunu mobil
cihazlarda değiştirmek zor ve tehlikeli olduğundan dolayı seçilen font uygulamaya
gömülmüştür. Bu işlem için assets klasörünün içine fonts adında bir klasör oluşturulup
istenilen font bu klasörün içine koyulur.
Tablo 2.1’ de fontun TextView’e uygulanmasını gösteren kod parçası verilmiştir.
Tablo 2.1. Fontun TextView’e uygulanmasını gösteren kod parçası.
Typeface font = Typeface.createFromAsset(getAssets(),"fonts/seguihis.ttf");
Latin_Turk_TextView.setTypeface(font, Typeface.BOLD);
Typeface setlemesi bu fontun kullanılacağı her araçta yapılmalıdır.
2.3. Android’te Unicode Karakterlerin Yazımı
Göktürkçe harfler için ayrılan Unicode aralığı beş karakterden oluşmaktadır. Ancak
Android’te beş karakterli Unicode karakter desteklenmemektedir. Beş karakterli Unicode
karakterler için bir ayırma işlemi yapılmaktadır. Örneğin 10C00 için D803 ve DC00
olmaktadır. Bu ayırma işlemi bir internet sitesi yardımı ile yapılabilmektedir [1]. Bir
5
TextView’ de bu işlemin nasıl gerçekleştirildiği Tablo 2.2.’ de gösterilmiştir.
Tablo 2.2. Beş karakterli Unicode karakterin TextView’ e aktarılması.
GokTurk_Text = "\uD803\uDC00";
2.4. Java Kodları
Yapılan uygulamada hem kodun açık ve anlaşılır olması hem de modüler olmasını
sağlayabilmek için Java sınıflarına (Class) ayrılmıştır. Her bir sınıf genellikle bir görevi
yerine getirmesi için kullanılmıştır.
2.4.1. Intro Sınıfı
Bu sınıf uygulama başlatıldığında yapılacak ilk işlemleri içerir ve giriş ekranın java
sınıfıdır. Bu sınıf bir ekrana karşılık düştüğünden dolayı Activity sınıfından miras alır.
Giriş ekranında önemli bir bilgi verildiği için kullanıcının okumayı bitirdikten sonra bu
ekranı geçmesi için bir buton tanımlanmıştır. Bu butonda Geç yazısının yanında Göktürkçe
Geç kelimesinin karşılığı yazıldığından font setlemesi yapılmıştır.
Tablo 2.3. Buton tanımlanması, font setlemesi ve buton yazısının yerleştirilmesi.
final Button Skip_Button = (Button) findViewById(R.id.Skip_Button);
final Typeface font = Typeface.createFromAsset(getAssets(),
"fonts/seguihis.ttf");
Skip_Button.setTypeface(font);
Skip_Button.setText("Geç / \uD803\uDC0F\uD803\uDC32");
Intro sınıfında bir veri tabanı oluşturulması ve veri tabanına verilerin girilmesi işlemi
yapıldığı için bu işlemin bitmeden geç butonuna basılmasını engellemek için bu işlemler önce
butonu pasif yapacak bir işlem gerçekleştirilmiştir.
6
Tablo 2.4. Butonu pasif hale geçirme.
Skip_Button.setClickable(false);
Her uygulama başlatıldığında tekrardan veri tabanını oluşturup verileri tekrar girmeyi
engellemek için uygulama eğer önceden başlatılmış ise bunu algılayıp bu kısmı atlayacak kod
parçası eklenmiştir.
Tablo 2.5. Uygulamanın daha önce başlatıldığını algılayan kod parçası.
SharedPreferences settings = getSharedPreferences("SQL", 0);
boolean firstTime = settings.getBoolean("firstTime", true);
Veri tabanı oluşturmak için DBHelper sınıfından yararlanılmıştır. 2.4.6 DBHelper
başlığında veri tabanı oluşturma işleminden bahsedilmiştir. dbHelper değişkeni DBHelper
sınıfından oluşturulmuş global nesnedir.
Tablo 2.6. Veri tabanının oluşturulması.
dbHelper = new DBHelper(this);
Eğer uygulama önceden başlatılmış ise verileri tekrar girmesini engellemek için if
koşulu kullanılmıştır. Göktürkçede kapalı n ve kapalı e kullanılması gereken bazı kelimler
olduğu için bu kelimler iki ayrı diziye atanmıştır ve iki for döngüsüyle veri tabanına
eklenmesi sağlanmıştır.
Tablo 2.7. Kelimelerin diziye atanması ve veri tabanına eklenmesi.
7
if (firstTime) {
String[] Nazal_N_Word = new String[]{
"anla",
"and",
.
.
"yön",
"yün"};
String [] Kapali_E_Word = new String[] {
"beş",
"beşik",
.
.
"yegirmi",
"yenlik"};
for (int i=0 ; i < Nazal_N_Word.length ;i++)
{
dbHelper.insert_Nazal_N_Word(Nazal_N_Word[i]);
}
for (int i=0 ; i < Kapali_E_Word.length ;i++)
{
dbHelper.insert_Kapali_E_Word(Kapali_E_Word[i]);
}
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("firstTime", false);
editor.commit();}
Veri tabanı işlemleri bu aşamada bittiği için Geç butonu aktif hale getirilir.
8
Tablo 2.8. Geç butonunun aktif hale getirilmesi.
Skip_Button.setClickable(true);
Son olarak Geç butonun’ a basıldığında ana ekrana geçilmesinin sağlayacak fonksiyon
tanımlanmıştır. Bu fonksiyon bir buton fonksiyonu olduğu için View tipinde bir argüman
almak zorundadır.
Tablo 2.9. Geç Butonu fonksiyonu.
public void Skip_Button_Fonk(View v)
{
Intent main_intent=new Intent(getApplicationContext(),MainActivity.class);
startActivity(main_intent);
this.finish();
}
2.4.2. About Sınıfı
About sınıfı Intro sınıfının görüntü olarak aynısıdır. Herhangi bir veri tabanı işlemi
yapılmamıştır. Ana ekran ve kaydetme ekranlarında Hakkında sekmesine basıldığında
yönlendirilen ekrandır. Sadece bir buton bulunduğu için font setlemesi ve text setlemesi
yapılmıştır.
Tablo 2.10. Font setlemesi ve text setlemesi.
skip_button = (Button) findViewById(R.id.About_Skip_Button);
final Typeface font =
Typeface.createFromAsset(getAssets(),"fonts/seguihis.ttf");
skip_button.setTypeface(font);
skip_button.setText("Geç / \uD803\uDC0F\uD803\uDC32");
9
Butona basıldığında yapılacak işlemleri Skip_Button_Fonk yapmaktadır. Bu
fonksiyonun içinde mobil cihazlardaki geri tuşunun yaptığı görevi yapan fonksiyon
bulunmaktadır. Bunu yapılması amaç ise bir önceki sayfaya dönüldüğünde ordaki bilgilerin
kaybedilmemesidir.
Tablo 2.11. Skip_Button_Fonk fonksiyonu.
public void Skip_Button_Fonk(View v)
{
onBackPressed();
}
2.4.3. MainActivity Sınıfı
Intro sayfasındaki işlemler bittikten sonra uygulamada MainActivity sınıfı çalışmaya
başlamaktadır. Bu bölümde öncelikle Intro ara yüzünden sonra gelen ara yüzdeki görsel
nesneler tanımlanmıştır. Latin metnini yazıldığı ve karşılığında Göktürkçe metnini
gösterildiği birer adet EditText eklenmiştir. Çevirme ve Paylaşma işlemleri için birer buton
eklenmiştir.. Ve son olarak EditText’lerin içerikleri hakkında bilgi bulunduran ikisi Türkçe
ikisi Göktürkçe olmak üzere 4 adet Label eklenmiştir.. Bu nesnelerin ekran düzenleri Tasarım
başlığı altında detaylı olarak anlatılmıştır. Ardından bu nesnelerin fontları yine dinamik olarak
bu bölümde setlenmiştir. Bu nesnelere ait kodlar Tablo 2.12. gösterilmiştir.
Tablo 2.12. Global değişkenlerin tanımlanması.
EditText Latin_Text;
EditText Gokturk_Text;
TextView Latin_Turk_TextView;
10
TextView Turk_Turk_TextView;
Button Translate_Button;
Button Save_Button;
LinearLayout mainLayout;
public Typeface font;
Tablo 2.13. Nesnelerin id’lerle ilişkilendirilmesi ve Temel özelliklerin belirlenmesi.
mainLayout = (LinearLayout) findViewById(R.id.myLayout);
font = Typeface.createFromAsset(getAssets(),"fonts/seguihis.ttf");
Latin_Turk_TextView = (TextView) findViewById(R.id.Latin_Turk_TextView);
Latin_Turk_TextView.setTypeface(font, Typeface.BOLD);
Latin_Turk_TextView.setText("\uD803\uDC1E\uD803\uDC43\uD803\uDC24:");
Latin_Turk_TextView.setGravity(Gravity.BOTTOM | Gravity.RIGHT);
Turk_Turk_TextView = (TextView) findViewById(R.id.Turk_Turk_TextView);
Turk_Turk_TextView.setTypeface(font);
Turk_Turk_TextView.setTypeface(font, Typeface.BOLD);
Turk_Turk_TextView.setText("\uD803\uDC45\uD803\uDC35\uD803\uDC3C\uD803\uDC1C:
");
Turk_Turk_TextView.setGravity(Gravity.BOTTOM | Gravity.RIGHT);
Latin_Text
= (EditText) findViewById(R.id.Latin_Text);
Latin_Text.setTypeface(font);
Latin_Text.setHint("Latin Metin");
Gokturk_Text = (EditText) findViewById(R.id.Gokturk_Text);
Gokturk_Text.setTypeface(font);
Gokturk_Text.setHint("Göktürk Metin");
Gokturk_Text.setTextIsSelectable(true);
Translate_Button = (Button) findViewById(R.id.Translate_Button);
Translate_Button.setTypeface(font);
11
Translate_Button.setText("Çevir / \uD803\uDC32\uD803\uDC0B\uD803\uDC3C");
Save_Button = (Button) findViewById(R.id.Save_Button);
Save_Button.setTypeface(font);
Save_Button.setText("
Kaydét /
Paylaş"+"\n\uD803\uDC2F\uD803\uDC16\uD803\uDC1E\uD803\uDC41 /
\uD803\uDC34\uD803\uDC16\uD803\uDC11:\uD803\uDC03\uD803\uDC45");
Save_Button.setEnabled(false);
Save_Button.setClickable(false);
Uygulamada Gokturk_Text içinde herhangi bir metin olmadan Kaydet/Paylaş ara
yüzüne geçişi engellemek için Gokturk_Text boş olduğu durumda Kaydet/Paylaş butonu
deaktif yapılmaktadır. Bu işlem tablodaki son iki satırla yapılmaktadır.
Çevir ve Kaydet/Paylaş butonları için birer adet fonksiyon tanımlanmıştır. “Çevir” için
tanımlanan Translate fonksiyonu Latin metni Göktürkçe metne dönüştüren asıl fonksiyondur.
Buton nesnesi için kullanıldığı için bir adet View parametresi almıştır. Bu fonksiyonda
öncelikle Göktürkçenin kurallarını içeren Rules sınıfından bir nesne türetilir. Sonra
kullanıcının girmiş olduğu Latin metni bir değişkene aktarır. Buradan itibaren çeviri işlemi bu
değişken referans alınarak yapılmaktadır. Göktürkçede büyük küçük harf olmadığı için
değişken içindeki tüm harfler küçük yapılır. Ardından kelimelerin kökünü bulup veri
tabanında sorgulatmak için DB_control adında geçici olarak kelimenin kökünü tutan bir string
değişkeni tanımlandı. Bu değişken veri tabanında aranır. Eğer aranan kelime Kapalı e
tablosunda mevcut ise flag_kapalı_e adındaki boolean tipindeki değişkeni TRUE yapar.
Nazal_n tablosunda mevcut ise bu kez flag_nazlan_n adındaki boolean değişkeni TRUE
yapılmaktadır. Bu değişkenler referans alınarak kelimedeki e veya n, nazal n veya kapalı e
olarak değiştirilir.
Tablo 2.14. Çeviri öncesi gerekli değişkenlerin setlenmesi.
12
Rules rules = new Rules();
String GokTurk_Text = "";
String Get_Latin_Text = Latin_Text.getText().toString();
Get_Latin_Text = Get_Latin_Text.toLowerCase();
String DB_control = null;
Boolean flag_nazal_n = false;
Boolean flag_kapali_e = false;
Translate fonksiyonu öncelikle Latin metni Preprocess sınıfına aktararak buradan
kelimelere parçalanmış bir string dizisi elde etmektir.
Tablo 2.15. Metnin kelimelere parçalana işlemi.
Preprocess preprocess = new Preprocess();
String[] word = preprocess.Preprocess(Get_Latin_Text);
Bu işlemden sonra her kelime için çevirme işlemi yapılacağı için bir for döngüsü
oluşturulmuştur. Bu döngünün döngü sayısı word.lengt yani metin içindeki kelime sayısı
olarak belirlendi. Döngüde ilk olarak girilen kelimenin veri tabanında mevcut olup olmadığı
kontrol edilir. Veri tabanındaki en kısa kelime 2 harfli olduğundan öncelikle kelimenin ilk iki
harfi veri tabanında sorgulanır. Mevcut değilse bir harf daha eklenir ve tekrar aranır. Bu işlem
kelime veri tabanında bulunana kadar veya eğer veri tabanında yoksa kelimenin tamamı
deneninceye kadar devam edilir. Bu işlem hem Nazal n hem de Kapalı e için ayrı ayrı
döngüler içinde yapılmaktadır. Eğer kelime veri tabanında mevcut ise ilgili bayrak setlenir ve
ilerleyen adımlarda Rules sınıfına gönderilerek kelime çevirisi yapılırken değerlendirilir.
Tablo 2.16. Nazal n / Kapalı e kontrolü.
if (word[i].length() >= 2) {
for (int j = 2; j <= word[i].length(); j++) {
13
if (word[i].length() >= j) {
DB_control = word[i].substring(0, j);
flag_nazal_n = DB_Search_Nazal_n(DB_control);
if (flag_nazal_n) {
}
}
}
break;
for (int j = 3; j <= word[i].length(); j++) {
if (word[i].length() >= j) {
DB_control = word[i].substring(0, j);
flag_kapali_e = DB_Search_Kapali_e(DB_control);
if (flag_kapali_e) {
}
}
}
break;
Sonraki adımda kelimeler Rules sınıfına gönderilerek çevirme işlemi yapılır. Rulse
sınıfında iki adet fonksiyon bulunmaktadır. Bu fonksiyonlardan biri sadece 1 harf
uzunluğundaki kelimelerin çevirisini yaparken kullanılmaktadır (Keyboard_Alphabet). Bu
fonksiyon kullanıcılara harflerin karşılıklarını öğrenme imkanı sunmak için yazılmıştır. Diğer
fonksiyon ise birden çok harf bulunduran kelimelerin çevirisi için kullanılmaktadır
(Text_Size_Length_Bigger_One). Bu fonksiyonların içeriği Rules başlığı altında detaylı
olarak anlatılacaktır. Bu adımda hangi fonksiyonun çağrılacağını belirlemek için bir switch
kullanıldı. Bu switch kelimenin uzunluğuna göre seçim yapacak şekilde programlandı. Eğer
kelime tek harfli ise Keyboard_Alphabet fonksiyonu çağrılarak geri dönen değer
Gokturk_Text
değişkenine
eklenir.
Kelime
uzunluğu
1’den
daha
büyük
ise
Text_Size_Length_Bigger_One fonksiyonu çağrılır ve geri dönen değer GokTurk_Text
değişkenine eklenir.
14
Tablo 2.17. Kelimelerin Rules sınıfına gönderilmesi.
switch (word[i].length()) {
case 0:
Toast.makeText(getApplicationContext(), "Metin Giriniz !...",
Toast.LENGTH_LONG).show();
break;
case 1:
if (isNumeric(word[i])) {
GokTurk_Text += word[i];
} else
GokTurk_Text += rules.Keyboard_Alphabet(word[i]);
Gokturk_Text.setText(GokTurk_Text);
break;
default:
if (isNumeric(word[i]))
GokTurk_Text += word[i];
else
GokTurk_Text += rules.Text_Size_Length_Bigger_One(word[i],
flag_nazal_n, flag_kapali_e);
Gokturk_Text.setText(GokTurk_Text);
break;
}
Bu adımdan sonra tüm kelimeler Göktürkçeye çevrilerek GokTurk_Text değişkeni içine
yazılır. Son olarak Çevrilen metin EditText’e yazılır ve çeviri tamamlanmış olur. Artık
Göktürkçe metin kısmı boş olmadığına göre Kaydet/Paylaş butonunun da aktifleşmesi
gerekir. Bunu için Translate fonksiyonunun sonuna ‘Kaydet/Paylaş’ butonunu aktifleştiren
15
aşağıdaki kodlar eklendi.
Tablo 2.18. Kaydet/Paylaş butonunun aktifleştirilmesi.
Save_Button.setEnabled(true);
Save_Button.setClickable(true);
Kaydet/Paylaş butonuna basıldığında uygulama başka bir ara yüze geçmektedir. Bu ara
yüzde Göktürkçe metin bir resim dosyasına dönüştürülür ve isteğe göre kaydedilir ya da
paylaşılır. Bu işlemin yapılabilmesi için bazı bilgilerin bu ara yüze aktarılması gerekmektedir.
Bilgilerin aktarılması işlemini Kaydet/Paylaş butonuna basılmasıyla çalışan ConvertToBitmap
fonksiyonu sağlamaktadır.
Öncelikle uygulamalar arsında veri aktarmamızı sağlayan bir Bundle nesnesi
oluşturuldu ve bu nesneye Göktürkçe metin, Göktürk EditText’inin genişliği ve yazının boyut
bilgileri kaydedildi. Sonra Bundle nesnesi bir sonraki ara yüz ile ilişkilendirildi ve
startActivitiy ile yeni ara yüze geçildi.
Tablo 2.19. Kaydet/Paylaş butonunun işlevi.
public void ConvertToBitmap(View v){
Bundle bundle = new Bundle();
bundle.putString("Gokturk_Text", Gokturk_Text.getText().toString());
bundle.putInt("Gokturk_Text_Width", Gokturk_Text.getWidth());
bundle.putInt("Gokturk_Text_Size",(int)Gokturk_Text.getTextSize());
Intent save_activity = new Intent(getApplicationContext(),Save.class);
save_activity.putExtras(bundle);
startActivity(save_activity);
}
2.4.4. Preprocess Sınıfı
16
Bu sınıfta Göktürkçe çeviri yapılmadan önce Latin metin üzerinde bir takım ön işlemler
yapılmaktadır.
İlk işlem Göktürkçede olmayan ancak Latin harf olan harflerin değiştirilmesidir. h, j, f, v
harfleri sırasıyla k, c, p, b harfleriyle yer değiştirilir. é harfinin karşılığı olarak i harfi
kullanılmıştır. â, î, û harflerinin yerine şapkasız olan harflerle, a, ı, u, değiştirilmiştir. Yeni
satıra geçiş yapıldığını anlayabilmek içinde \n yerine başında ve sonunda boşluk olacak
şekilde değiştirilmiştir. Böylece metini parçalarken yeni satır karakterini de ayrılmış olacaktır.
Tablo 2.20. Metindeki harflerin değiştirilmesi.
word = word.replace("h","k");
word = word.replace("j","c");
word = word.replace("f","p");
word = word.replace("v","b");
word = word.replace("é","i");
word = word.replace("â","a");
word = word.replace("î","i");
word = word.replace("û","u");
word = word.replace("\n"," \n ");
Klavyedeki harfler dışında kalan tüm karakterlerde metini kelimelere ayırırken
ayrılması için başında ve sonunda boşluklar olacak şekilde yer değiştirilmesi yapılmıştır.
Tablo 2.21. Metindeki karakterlerin değiştirilmesi.
word = word.replace("!"," ! ");
word = word.replace("'"," ' ");
word = word.replace("£"," £ ");
...
17
...
word = word.replace("|"," | ");
Aynı replace fonksiyonu kullanılarak Latin Türkçesindeki bazı kelimelerin eski Türkçe
halleri ile değiştirilmiştir.
Bu işlemlerden sonra metin split fonksiyonuna verilerek boşluklara göre ayırarak yani
metni kelimelerine ayırarak bir diziye kaydeder.
Tablo 2.22. Metinin kelimelere ayrılması.
word_first = word.split(" ");
Kelimelere ayırdıktan sonra dot_parse isimli fonksiyona gönderilerek tırnak işareti
kelimeye birleşikse bunu ayırma işlemi yapılır.
Tablo 2.23. Metinin kelimelere ayrılması.
public String[] dot_parse(String [] first_word)
{
ArrayList<String> word = new ArrayList<String>() ;
for(int i = 0 ; i < first_word.length ; i++)
{
if (!first_word[i].equals("'"))
{
word.add(first_word[i]);
}
else
{
word.set(i-1,first_word[i - 1] + first_word[i + 1] );
i++;
}
}
for (int i = 0 ; i < word.size() ; i++)
{
if (word.get(i).equals(""))
word.remove(i);
}
first_word = new String [word.size()];
word.toArray(first_word);
18
size = word.size();
}
return first_word;
Tırnak işaretinde olduğu gibi sayılarda kelimelere ya da harflere bitişik bir şekilde
olabilir bunun içinde bir takım işlemler yapılmaktadır. Sayılar kelimlerin ya da harflerin
başında, sonunda olabilir. Bunun için indexOf fonksiyonu ile her kelimeye bakılarak sayının
ayrıma işlemi yapılır ve kelime ya da harf Göktürkçeye çevrilir. Çevirme işleminde böyle bir
kelime denk geldiğinde çevirme işlemi yapılmayıp direk yazılır.
Tablo 2.24. Sayıların kelimeden ayrılması.
for (int i = 0; i < word2.length; i++)
{
if (!isNumeric(word2[i]))
{
if ((word2[i].indexOf("0") != -1 || word2[i].indexOf("7") != -1||
word2[i].indexOf("2") != -1
|| word2[i].indexOf("8") != -1|| word2[i].indexOf("6") != -1||
word2[i].indexOf("3") != -1
|| word2[i].indexOf("9") != -1|| word2[i].indexOf("5") != -1||
word2[i].indexOf("4") != -1
|| word2[i].indexOf("1") != -1)) {
word2[i] = word2[i].replace("0"," 0 ");
word2[i] = word2[i].replace("1"," 1 ");
word2[i] = word2[i].replace("2"," 2 ");
word2[i] = word2[i].replace("3"," 3 ");
word2[i] = word2[i].replace("4"," 4 ");
word2[i] = word2[i].replace("5"," 5 ");
word2[i] = word2[i].replace("6"," 6 ");
19
word2[i] = word2[i].replace("7"," 7 ");
word2[i] = word2[i].replace("8"," 8 ");
word2[i] = word2[i].replace("9"," 9 ");
temp_word = word2[i].split(" ");
ArrayList<String> word_list = new ArrayList<String>() ;
for (int m = 0 ; m < temp_word.length ; m++)
{
word_list.add(temp_word[m]);
}
for (int n = 0 ; n < word_list.size() ; n++)
{
if (word_list.get(n).equals(""))
word_list.remove(n);
}
temp_word = new String[word_list.size()];
word_list.toArray(temp_word);
if (!isNumeric(temp_word[0]))
{
temp_word2 = "";
if (temp_word[0].length() > 1) {
temp_word2 += rules.Text_Size_Length_Bigger_One(temp_word[0], false,
false);
for (int p = 1; p < temp_word.length; p++)
{
temp_word2 += temp_word[p];
}
word2[i] = temp_word2;
break;
20
}
else {
temp_word2 += rules.Keyboard_Alphabet(temp_word[0]);
for (int p = 1; p < temp_word.length; p++)
{
temp_word2 += temp_word[p];
}
word2[i] = temp_word2;
break;
}
}
else
{
temp_word2 = "";
temp_word2 += temp_word[0];
for (int k = 1; k < temp_word.length; k++)
{
if (isNumeric(temp_word[k]))
{
temp_word2 += temp_word[k];
}
else
{
if (temp_word[k].length() > 1)
{
temp_word2 += rules.Text_Size_Length_Bigger_One(temp_word[k], false,
false);
word2[i] = temp_word2;
break;
21
}
else
{
temp_word2 += rules.Keyboard_Alphabet(temp_word[k]);
word2[i] = temp_word2;
break;
}}}}}}}
for (int i = 0; i < word2.length; i++)
{
int count = 0;
int temp_index = i;
if (isNumeric(word2[temp_index]))
{
while (temp_index+1 < word2.length && isNumeric(word2[temp_index+1]))
{
count++;
temp_index++;
}
if (count != 0)
{
int last_index = i + count;
int temp_last_index = last_index;
int uzunluk = (last_index - i ) + 1;
String temp;
if (uzunluk % 2 != 0)
{
int ort = (last_index + i) / 2;
while (last_index != ort)
22
{
temp = word2[i];
word2[i] = word2[last_index];
word2[last_index] = temp;
last_index += -1;
i += 1;
}
i = temp_last_index + 1;
}else
{
while (i < last_index)
{
temp = word2[i];
word2[i] = word2[last_index];
word2[last_index] = temp;
last_index += -1;
i += 1;
}
i = temp_last_index + 1;
}}}}
isNumeric fonksiyonu ise kelimenin sayılardan oluşup oluşmadığının kontrol eder.
Tablo 2.25. isNumeric Fonksiyonu.
public static boolean isNumeric(String word)
{
try
{
double d = Double.parseDouble(word);
}
catch(NumberFormatException nfe)
{
23
return false;
}
return true;}
2.4.5. Rules Sınıfı
Bu sınıf Göktürkçe harflerin karşılıklarının bulunduğu ve dil kurallarının uygulandığı
kısımdır. Bu sınıfa sürekli olarak MainActivity sınıfından kelime gönderilir. Gelen kelime
burada dönüştürülür ve tekrar MainActivity sınıfına gönderilir. Rules sınıfında kelime çevirisi
yapan üç fonksiyon bulunmaktadır. Bunlardan ilki kelime tek harfli olduğu durumlarda
çalışan Keyboard_Alphabet fonksiyonudur. Bu fonksiyonda Latin harflere karşılık gelen
harfler bir switch içinde listelenmiştir. Gelen her harf için Göktürkçe karşılığı bulunur ve bu
Göktürkçe karakter geriye döndürülür.
Tablo 2.26. Keyboard_Alphabet fonksiyonu.
public String Keyboard_Alphabet(String Latin_Text)
{
String GokTurk_Text = null;
switch (Latin_Text)
{
case "a":
GokTurk_Text = "\uD803\uDC00";
break;
case "A":
GokTurk_Text = "\uD803\uDC00";
break;
case "b":
GokTurk_Text = "\uD803\uDC0B";
break;
case "B":
GokTurk_Text = "\uD803\uDC09";
break;
24
.
.
.
case "\"":
GokTurk_Text = "\"";
break;
case "\n":
GokTurk_Text = "\n";
break;
default:
GokTurk_Text = " ";
break;
}
return GokTurk_Text;
}
Rules sınıfındaki bir diğer fonksiyon ise Original_Alphabet fonksiyonudur. Bu
fonksiyonun genel yapısı Keyboard_Alphabet fonksiyonun yapısına benzerdir. Farklı olarak
switchteki caseler içinde 1 karakterin yanı sıra 2 karakter de bulunabilmektedir. Bunun sebebi
yazılacak olan harfin duruma göre kalın mı yoksa incemi olacağını anlayabilmektir. Örnek
olarak Tez kelimesini ele alacak olursak; ilk harf T’dir. Ancak Göktürkçede biri kalın diğeri
ince olmak üzere iki adet T bulunmaktadır. Bunu anlamak için T harfinin yanındaki diğer
karaktere yani e’ye bakılarak yazılacak olan T’nin ince olacağına karar verilir ve bu iki harf et
olarak Original_Alphabet fonksiyonuna gönderilir. te yerine et gönderilmektedir çünkü
Göktürkçe karakterler okunurken sesli harf önce söylenmektedir. Yani Türkçede örneğin K
harfini Ke olarak okumaktayız. Göktürkçede ise bu durumun tersi söz konusu olmaktadır.
Tablo 2.27. Original_Alphabet fonksiyonu.
25
public String Original_Alphabet(String Latin_Text)
{
String GokTurk_Text = null;
switch (Latin_Text)
{
case "a":
GokTurk_Text
break;
case "A":
GokTurk_Text
break;
case "eb": //b
GokTurk_Text
break;
case "ab": //B
GokTurk_Text
break;
= "\uD803\uDC00";
= "\uD803\uDC00";
= "\uD803\uDC0B";
= "\uD803\uDC09";
.
.
.
.
}
}
case "eŋ":
GokTurk_Text
break;
case "añ":
GokTurk_Text
break;
case "eñ":
GokTurk_Text
break;
case "é":
GokTurk_Text
break;
default:
GokTurk_Text
break;
= "\uD803\uDC2D";
= "\uD803\uDC2D";
= "\uD803\uDC2D";
= "\uD803\uDC03";
= " ";
return GokTurk_Text;
Original_Alphabet fonksiyonu sadece Rules sınıfındaki üçüncü fonksiyon olan
Text_Size_Length_Bigger_One fonksiyonu tarafından çağrılmaktadır. Bu fonksiyon Asıl
çeviri işlemini yapan kodları içermektedir. Çeviri yapılırken metindeki kelimeler sırayla bu
fonksiyona verilir. Her kelime için bu fonksiyon içindeki dil kuralları uygulanır.
Öncelikle kelimenin ilk iki harfi kontrol edilir. Eğer ilk iki harf sessiz harf ise
26
Head_Of_Word fonksiyonu çağrılır. Bu fonksiyon kelimenin üçüncü harfine bakarak ilk iki
harfin kalın mı yoksa incemi olacağına karar verir, harfleri çevirir ve kelimeyi tekrar
Text_Size_Length_Bigger_One fonksiyonuna gönderir. Ardından sıradaki karakter kontrol
edilir. Göktürkçede a ve e harfleri kelime içinde yazılmaz. Diğer sesli harfler ise kelime
içinde bir kez yazıldıktan sonra aynı harf kelimenin devamında yazılmaz. Bu kuralları
uygulamak için her sesli harf için birer if koşulu tanımlandı. Ayrıca (a,e), (ı,i), (o,u) ve (ö,ü)
harf grupları için birer tane boolean değişkeni setlendi. Bu değişkenler bayrak olarak
kullanıldı. Yani bu harflerden biri yazıldığı takdirde kelimenin devamında bu tekrar yazmayı
engellemek için bu bayraklar setlenir. Bu bayrakların setlenme işlemi her sesli harf için
tanımlanan if koşulları içerisinde yapılmaktadır.
Sessiz harf geldiğinde ise bir sonraki harf kontrol edilerek ona göre ince veya kalın
olacağına karar verilir.
Son olarak kelimenin sonuna gelindiğinde, eğer kelimenin sonunda sesli harf varsa bu
harf ne olursa olsun yazılması gerekmektedir. Bu işlem de Text_Size_Length_Bigger_One
fonksiyonunun son kısmında yapılmaktadır.
2.4.6. DBHelper Sınıfı
Bu sınıf SQLite sorgularının yapıldığı fonksiyonları ve veri tabanın oluşturulması için
kullanıldı. Veri tabanı işlemleri yapabilmek için SQLiteOpenHelper’ı miras alır.
Veri tabanı versiyonu, tablo isimleri bir değişkene atanmıştır ve bir fonksiyon
yardımıyla veri tabanının oluşturulması sağlanmıştır.
Tablo 2.28. Veri Tabanı oluşturma.
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME
= "kokturukDB";
private static final String TABLE_N = "Nazaln";
27
private static final String TABLE_E = "Kapalie";
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
Bu işlemden sonra tabloların oluşturulması sağlanmıştır.
Tablo 2.29. Tabloların oluşturulması.
public void onCreate(SQLiteDatabase db) {
String create_table_nazaln = "CREATE TABLE IF NOT EXISTS " + TABLE_N +
"(Latin_Word TEXT" + ")";
String create_table_kapalie = "CREATE TABLE IF NOT EXISTS " + TABLE_E +
"(Latin_Word TEXT" + ")";
db.execSQL(create_table_nazaln);
db.execSQL(create_table_kapalie);}
Veri tabanının güncellenmesi halinde tabloları silecek fonksiyon tanımlanmıştır.
Tablo 2.30. Veri tabanının güncellenmesi.
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_N);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_E);
onCreate(db);
}
Tablolara verilerin girilmesini sağlayan fonksiyonlar tanımlandı.
28
Tablo 2.31. Veri girişlerini gerçekleştiren fonksiyonlar.
public void insert_Nazal_N_Word(String Latin_Word)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("Latin_Word", Latin_Word);
db.insert(TABLE_N, null, values);
db.close(); }
public void insert_Kapali_E_Word(String Latin_Word)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("Latin_Word", Latin_Word);
db.insert(TABLE_E, null, values);
db.close();}
Veri tabanında sorgu yapılacak fonksiyonlar tanımlanmıştır. Bu fonksiyonlar sadece
değerin olup olmadığını kontrol ettikleri true ya da false olarak geri dönüş yapmaktadırlar.
Tablo 2.32. Veri tabanı sorgusu yapan fonksiyonlar.
public boolean DB_Search_Nazal_n(String Latin_Word)
{
int count = -1;
SQLiteDatabase db = this.getReadableDatabase();
String query = "SELECT COUNT(*) FROM " + TABLE_N + " WHERE Latin_Word = '"
29
+ Latin_Word + "'" ;
Cursor cursor = db.rawQuery(query, null);
cursor.moveToNext();
count = cursor.getInt(0);
db.close();
return count > 0; }
public boolean DB_Search_Kapali_e(String Latin_Word)
{
int count = -1;
SQLiteDatabase db = this.getReadableDatabase();
String query = "SELECT COUNT(*) FROM " + TABLE_E + " WHERE Latin_Word = '"
+ Latin_Word + "'" ;
count = cursor.getInt(0);
db.close();
return count > 0;}
2.4.7. Save Sınıfı
Save sınıfı, çevirisi yapılan metnin Göktürkçe karşılığını bir resim dosyasına
dönüştürerek kaydetme veya paylaşma imkanı vermektedir. Bu işlemin yapılabilmesi için
MainActivity sınıfında çevirisi yapılan metnin ve metinle ilgili bazı bilgilerin Save sınıfına
aktarılması gerekmektedir. Bu işlem MainActivity sınıfında ConvertToBitmap fonksiyonunu
ile yapılır. Veriler bu fonksiyon tarafından Save sınıfına aktarılır. Save sınıfın da Tablo
2.33’deki kodlar ile bu verileri almaktadır.
Tablo 2.33. Metin ile ilgili verilerin Save sınıfına aktarılması.
Bundle data = getIntent().getExtras();
Gokturk_Text = data.getString("Gokturk_Text");
Gokturk_Text_Width = data.getInt("Gokturk_Text_Width");
30
Gokturk_Text_Size = data.getInt("Gokturk_Text_Size");
Resim oluşturulurken kullanıcıya font rengi seçimi imkanı da sunulmaktadır. 6 adet font
rengi kullandığımız için 6 adet ImageButton tanımlandı. Her butonun tıklandığında
çalıştıracağı fonksiyonu clickImageButtons fonksiyonu olarak belirlendi. Bu fonksiyon
butonların tıklanması olayında çağrıldığı için bir adet View parametresi geçirildi. Ayrıca font
rengini tutan bir adet Color değişkeni tanımlandı. Bu değişken kullanıcı hiçbir seçim
yapmadığı için font renginin siyah olmasının sağlanması için siyah değeri verildi. Yani
kullanıcı font rengi seçimi yapmadıysa default olarak font rengi siyah yapılacaktır.
clickImageButtons fonksiyonunda öncelikle fonksiyonun hangi buton tarafından
çağrıldığı kontrol edilir. Hangi buton tarafından çağrıldıysa color değişkeni ilgili butonun
rengine dönüştürülür. Daha sonra drawText fonksiyonu çağrılarak resim oluşturulur ve
ImageView’e aktarılır.
Tablo 2.34. clickImageButtons fonksiyonu.
public void clickImageButtons(View v){
if(v == red)
color = Color.RED;
else if(v == green)
color = Color.argb(255,0,156,0);//0x009c00;
else if(v == blue)
color = Color.argb(255,0,0,156);//0x00009c;
else if(v == white)
color = Color.WHITE;
else if(v == kahve)
color = Color.argb(255,148,74,0);//0x944a00;
else if(v == black) {
31
color = Color.BLACK;
}
img = drawText(Gokturk_Text,2*Gokturk_Text_Width, 2*Gokturk_Text_Size,
font, color);
GokturkImg.setImageBitmap(img);
}
Save sınıfında resmi kaydetme veya paylaşma olmak üzere iki seçenek vardır.
Kaydetme için kullanıcıya arka plan rengini beyaz veya şeffaf yapma seçimi sunulur. Beyaz
seçilirse resim JPEG formatında kaydedilir. Transparan seçilirse PNG formatında kaydedilir.
Paylaşma seçeneğinde ise resim JPEG formatında oluşturulur ve arka plan beyaz yapılır.
Çizim işlemini drawText fonksiyonu yapmaktadır. Bu fonksiyon çizilecek metni, metin
kutusunun genişlik değerini, metnin boyutunu, font tipini ve renk değerini parametre olarak
alır. Öncelikle bir TextPaint nesnesi oluşturulur ve metin bu nesneye çizilir. Ardından genişlik
ve yükseklik değerleri uygun olacak şekilde ayarlanmış bir Bitmap nesnesi oluşturulur.
Ardından bir Canvas nesnesi oluşturulur ve bu nesne bitmap üzerine yerleştirilir. Değişiklikler
artık Canvas nesnesi üzerinde yapılır. Canvas üzerine TextPaint nesnesi ile oluşturulan metin
çizimi yerleştirilir ve işlem tamamlanmış olur. Bu fonksiyon geriye Bitmap nesnesini
döndürür.
Tablo 2.35. drawText fonksiyonu.
public static Bitmap drawText(String text, int textWidth, int textSize,
Typeface font, int textColor) {
TextPaint textPaint;
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG
| Paint.LINEAR_TEXT_FLAG);
textPaint.setTypeface(font);
textPaint.setStyle(Paint.Style.FILL);
32
textPaint.setColor(textColor);
textPaint.setTextSize(textSize);
StaticLayout mTextLayout = new StaticLayout(text, textPaint,
textWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
// Create bitmap and canvas to draw to
Bitmap b = Bitmap.createBitmap(textWidth, mTextLayout.getHeight(),
Bitmap.Config.RGB_565);
Canvas c = new Canvas(b);
// Draw background
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
c.drawPaint(paint);
// Draw text
c.save();
c.translate(0, 0);
mTextLayout.draw(c);
c.restore();
}
return b;
Kaydet butonuna basıldığında Image_Save fonksiyonu çağrılır. Bu fonksiyon ekranda
bir AlertBox penceresi oluşturur ve kullanıcıya arkaplan seçimini sunar. Eğer Transparan
seçilirse Create_Image fonksiyonu çağrılır. Beyaz seçildiğinde ise Create_Image_Jpeg
fonksiyonu çağrılır.
Create_Image fonksiyonu öncelikle resmi drawText fonksiyonu ile arka plan şeffaf
olacak şekilde çizdirir. Ardından string tipinde resmin adını alacak bir değişken oluşturulur ve
DataFormat sınıfı ile o anki tarih bu değişkenin içine yazılır. Bu tarih oluşturulan dosyanın
33
ismi olacaktır. Böylece hiçbir zaman bu isim tekrarlanmayacak dolayısıyla aynı isimde birden
çok resim olma durumu ortadan kaldırılacaktır. Ardından cihazın ana dizinini alan bir
değişken
tanımlanır.
Böylece
ana
dizinden
başlayarak
resim
dosyasını
nereye
kaydedeceğimizi belirleyebilecektik. Daha sonra bir File nesnesi oluşturulup dosyanın tam
yolu verilerek bu nesne çıkışa gönderilir. Sonraki adımda resim PNG formatına
dönüştürülerek %85 oranında sıkıştırılır ve çıkışa gönderilir. Son olarak medya içeriği
yenilenir ve kaydetme işlemi tamamlanmış olur.
Tablo 2.36. Create_Image fonksiyonu.
public void Create_Image(Bitmap img)
{
img = drawTextTransparan(Gokturk_Text,2*Gokturk_Text_Width,
2*Gokturk_Text_Size, font, color);
String filename;
filename =
DateFormat.getDateTimeInstance().format(new Date());
try{
String path = Environment.getExternalStorageDirectory().toString();
OutputStream fOut = null;
file = new File(path, "/Download/"+filename+".png");
fOut = new FileOutputStream(file);
img.compress(Bitmap.CompressFormat.PNG, 85, fOut);
fOut.flush();
fOut.close();
MediaStore.Images.Media.insertImage(getContentResolver()
, file.getAbsolutePath(), file.getName(), file.getName());
Toast.makeText(getApplicationContext(), "Metin arkaplanı saydam
olacak şekilde Download dizinine kaydedilmiştir.", Toast.LENGTH_LONG).show();
return;
}catch (Exception e) {
e.printStackTrace();
34
}
}
Eğer arkaplan beyaz seçilirse bu kez Create_Image_Jpeg fonksiyonu çağrılır. Bu
fonksiyon Create_Image fonksiyonu ile tek farkı resmi PNG formatında kaydetmek yerine
JPEG formatında kaydetmesidir.
Son olarak Paylaş butonuna basıldığında shareFunction fonksiyonu çağrılmaktadır. Bu
fonksiyon önce Create_Image_Jpeg fonksiyonunu çağırarak resim dosyasını oluşturur. Daha
sonra resmin kaydedildiği dizini bir değişkene kaydeder ve bu değişken ile dosyayı bulup
paylaşıma açar.
Tablo 2.37. shareFunction fonksiyonu
public void shareFunction(View v){
Create_Image_Jpeg(img);
String agendaFilename = file.getAbsolutePath();
ContentValues values = new ContentValues(2);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.DATA, agendaFilename);
Uri uri =
getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,valu
es);
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/jpeg");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(shareIntent, "Paylaş"));
}
2.5. Tasarım
35
Uygulamada ekran tasarımlarının adaptif olmasına özen gösterilmiştir. Her ne kadar
adaptif olarak tasarlansa da metnin uzunluğundan ya da size boyutundan kaynaklanan
kaymalar oluşmaktadır. Bunun için yatay, dikeyde ve tablet ekranları olarak üç kısma
ayırılarak tasarım yapılmıştır.
Uygulama kodlanmaya başladığında sadece ana ekran için kabaca bir tasarım
yapılmıştır. Bu kaba tasarım bir buton ve 2 tane editText’ten oluşmaktadır. Bir editText’ten
Latin metin girdisi alınmakta ve diğer editText’e Göktürkçe karşılığı yazdırılmaktaydı.
Kodlama bittikten sonra asıl tasarıma geçilmiştir.
2.5.1. Intro Ekranının Tasarımı
Intro ekranı kullanıcı uygulamayı ilk açtığında çıkan ekrandır.
Bir Activityt oluşturulduğunda otomatik olarak activity_ActivityName.xml bir layout
yani ekran tasarımı için xml dosyası oluşturulur.
Tasarımda LinearLayout(vertical) tasarımın iskeletini oluşturmaktadır. Bu layouta ne
araç eklenirse eklensin alt alta yerleştirmektedir. LinerLayout’un içine üç tane FrameLayout
yerleştirilmiştir. FrameLayout ise içine yerleştirilen araçları ortaya, sağa, sola yaslama gibi
işlemleri yapmamızı sağlamıştır. Bu üç FrameLayot’un içerikleri aşağıdaki gibidir:
1. FrameLayot:
KTU’nun logosunu içeren bir ımageView içerir. Bu logo drawable klasörünün içinden
alınmaktadır.
FrameLayoutun
genişliği
mobil
cihazın
genişliği
kadar
seçilmiştir.
Bu
da
match_parent’a karşılık gelmektedir. Yüksekliği layotun içindeki aracın içeriği kadar
ayarlanması sağlanmıştır. Bu ise wrap_content’e denk gelmektedir.
Tablo 2.38. 1. FrameLayot xml kodları.
<FrameLayout
36
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.009">
<ImageView
android:layout_width="107dp"
android:layout_height="107dp"
android:id="@+id/imageView"
android:layout_gravity="center"
android:background="@drawable/ktulogo" />
</FrameLayout>
2. FrameLayout:
Bu layout bu projeyle ilgilenenlerin adlarının ve önemli bir notun yer aldığı layouttur. Bu
yazılar alt alta olduğu için bu layoutun içine vertical LinearLayout yerleştirilmiştir ve
LinearLayout’un içine ise üç tane textView yerleştirilmiştir.
Tablo 2.39. 2. FrameLayot xml kodları.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
37
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/IntroHead"
android:id="@+id/names_intro"
android:layout_weight="0.53"
android:gravity="center"
android:autoText="false"
android:textSize="15dp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/version"
android:id="@+id/textView2"
android:textSize="15dp"
android:gravity="center"
android:textStyle="bold"
android:textColor="@android:color/black"
android:layout_gravity="center_horizontal" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/Intro"
android:id="@+id/intro_intro"
android:layout_weight="0.53"
android:gravity="center"
android:autoText="false"
android:textSize="14dp" />
38
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/Copyright"
android:id="@+id/info_intro"
android:layout_weight="0.53"
android:gravity="center"
android:autoText="false"
android:textSize="15dp"
android:textStyle="bold" />
</LinearLayout>
</FrameLayout>
3. FrameLayout:
Bu layoutta ise buton vardır.
Tablo 2.40. 2. FrameLayot xml kodları.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_weight="0.009">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
39
android:id="@+id/Skip_Button"
android:layout_gravity="center"
android:onClick="Skip_Button_Fonk"
android:visibility="visible" />
</FrameLayout>
Yukarıda yapılan işlemlerin hepsi dikey ekran görüntüsü içindir.
Şekil 2.1. Intro ekranının dikey görüntüsü.
Yatay ekran görüntüsü için ise layout klasörünün altına layout-land adında bir klasör
oluşturulur ve layout klasörünün içindeki tüm xml dosyaları aynen bunun içerisine
kopyalanır. Tasarımdaki bozulmaların önüne geçmek için logonun boyu ve metnin büyüklüğü
değiştirilmiştir.
40
Şekil 2.2. Intro ekranının yatay görüntüsü.
Tablet ekranlar için ise layout-large klasörü oluşturulur. Daha geniş bir ekran olduğu
için layout_weight değerleri değeri artılarak daha geniş alanlara yayılması sağlanmıştır. Yatay
ekranda yapıldığı gibi metnin büyüklüğü ve logonun büyüklüğü ayarlanmıştır.
2.5.2. Hakkında Ekranının Tasarımı
Hakkında ekranı About ekranının tamamen aynısıdır.
2.5.3. Ana Ekran Tasarımı
Ana ekran tasarımında yatay ve tablet ekranları için ayrı bir değer değiştirme
yapılmamıştır çünkü herhangi bir boyut ve metin boyutu sorunu olmadığı ve dikeyde adaptif
olarak tasarlandığı için mobil cihazlar kendileri ayarlayabilmektedirler.
Bu tasarımda da en dışta bir Vertical LinearLayout kullanılmıştır. Böylece araçların alt
alta sıralanması sağlanmıştır. LinearLayout’a dört tane FrameLayout yerleştirlmiştir.
Birinci FrameLayout’ta iki tane buton vardır ve butonlar biri sola diğer sağa dayalı
olarak yerleştirlmiştir.
41
Tablo 2.41. Birinci FrameLayout xml kodları.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<GridLayout
android:layout_width="match_parent"
android:layout_height="59dp">
<Button
android:layout_width="160dp"
android:layout_height="match_parent"
android:id="@+id/Translate_Button"
android:onClick="Translate"
android:gravity="center"
android:layout_gravity="top|center_vertical"
android:width="173dp" />
<Button
android:layout_width="160dp"
android:layout_height="match_parent"
android:id="@+id/Save_Button"
android:layout_gravity="center_vertical|right"
android:onClick="ConvertToBitmap"
android:enabled="false"
android:textSize="15dp"
android:gravity="center|top"
android:paddingTop="3dp" />
42
</GridLayout>
</FrameLayout>
İkinci layoutta ise Latin editText’in etiketi olan iki tane textView yer almaktadır. Sola
dayalı olarak Latin sağa dayalı olarak Latin’in karşılığı olan Göktürkçe kelime yazmaktadır.
Tablo 2.42. Birinci FrameLayout xml kodları.
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.001"
android:id="@+id/Latin_Layout_Id"
android:layout_gravity="bottom"
android:foregroundGravity="bottom">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Latin:"
android:id="@+id/Latin_Latin_TextView"
android:layout_gravity="left|center_vertical"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
43
android:id="@+id/Latin_Turk_TextView"
android:gravity="bottom|right"
android:layout_gravity="right|center_vertical"
android:textStyle="bold" />
</FrameLayout>
Üçüncü layoutta Latin metinin girildiği editText bulunmaktadır.
Tablo 2.43. Birinci FrameLayout xml kodları.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.48">
<EditText
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:inputType="textMultiLine"
android:ems="10"
android:id="@+id/Latin_Text"
android:clickable="false"
android:background="#ffffff"
android:gravity="top" />
</FrameLayout>
editText’in içeriği ile boyutu değiştirdiği için bu değişikliğin olmaması için
layout_height 0(sıfır) olarak setlenmiştir.
Dördüncü ve beşinci layoutlar üçüncü ve ikinci olarak aynıdır. Üçüncü layoutta Türk
44
kelimesi ve Göktürkçe karşılığı vardır.
Şekil 2.2. Ana ekranının görüntüsü.
2.5.4. Kaydetme ve Paylaş Ekranının Tasarımı
Bu ekranda Intro ekranına oldukça benzemektedir. Yine bir Vertical LinearLayout
kullanılmıştır. Bu layoutun içerisinde de 3 tane FrameLayout bulunmaktadır.
Birinci FrameLayout’ta iki tane buton bulunmaktadır ve bunlardan biri sola diğeri ise
sağa dayalı olarak konumlandırılmıştır.
45
Tablo 2.44. Birinci FrameLayout xml kodları.
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_width="160dp"
android:layout_height="wrap_content"
android:id="@+id/saveButton"
android:onClick="Image_Save"
android:gravity="center"
android:layout_gravity="top|center_vertical"
android:width="173dp" />
<Button
android:layout_width="160dp"
android:layout_height="wrap_content"
android:id="@+id/shareButton"
android:gravity="center"
android:layout_gravity="right|center_vertical"
android:onClick="shareFunction"
/>
</GridLayout>
İkinci FrameLayout’ta imageView konumlandırılmıştır. Bu imageView yüksekliği
içeriği ile aynı olması istendiği için layout_height="wrap_content" olacak şekilde seçilmiştir.
Tablo 2.45. İkinci FrameLayout xml kodları.
<FrameLayout
android:layout_width="match_parent"
46
android:layout_height="wrap_content"
android:layout_above="@+id/linearLayout"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_weight="6">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Gokturk_Img"
android:layout_gravity="center" />
</FrameLayout>
Üçüncü FrameLayout ise metin renginin seçilmesi sağlayan renkler vardır. Bu renkler
resim olarak drawable klasörüne yerleştirilmiştir. ImageButton kullanılarak bunlara butonluk
özelliği verilmiştir. Ayrıca bu FrameLayout’un içerisinde Horizontal LinearLayout
kullanılarak bu resimlerin yan yana konumlandırılması sağlanmıştır.
Tablo 2.46. İkinci FrameLayout xml kodları.
</FrameLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
47
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/black"
android:background="@drawable/dark_button"
android:layout_marginRight="@dimen/abc_action_bar_content_inset_material"
android:onClick="clickImageButtons" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/white"
android:background="@drawable/white_button"
android:onClick="clickImageButtons" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/red"
android:background="@drawable/red_button"
android:layout_marginRight="@dimen/abc_action_bar_content_inset_material"
android:layout_marginLeft="@dimen/abc_action_bar_content_inset_material"
android:onClick="clickImageButtons" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/green"
android:background="@drawable/dark_green_button"
android:layout_marginRight="@dimen/abc_action_bar_content_inset_material"
android:onClick="clickImageButtons" />
48
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/blue"
android:background="@drawable/dark_blue_button"
android:onClick="clickImageButtons" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/kahve"
android:layout_marginLeft="@dimen/abc_action_bar_content_inset_material"
android:background="@drawable/kahve_button"
android:onClick="clickImageButtons" />
</LinearLayout>
49
Şekil 2.3. Kaydet ve paylaş ekranının görüntüsü.
50
3. SONUÇLAR
Kodlama bittikten sonra projenin test aşamasına geçtik ve uygulamanın ne kadar
doğru çalıştığını sınamaya başladık. Uygulama %99 oranında doğru çalışmaktadır. Kalan
%1’lik kısımda ise doğal dil işleme yapılamadığından hatalı sonuç üretebilmektedir. Ancak
kullanıcı Göktürkçe dil kurallarını bilirse ve çevrilecek metinde doğru karakterleri kullanırsa
bu %1’lik hata payını da ortadan kaldırabilmektedir.
Metin çevirisi yapıldığında kullanıcıların oluşturulan Göktürkçe metni kaydetmeleri
yada sosyal paylaşım ortamlarında paylaşmak istemeleri durumunda çoğu platform Göktürkçe
karakterleri desteklemediğinden kopyala/yapıştır tekniğiyle metni paylaşamayacaklardı. Bu
sorunu çevrilen metni bir resim dosyasına dönüştürerek ortadan kaldırdık. Metni paylaşmak
isteyen kullanıcılar Kaydet/Paylaş butonu aracılığıyla istediği font rengini seçtikten sonra
metnin görüntü dosyasına çevrilmiş halini telefon hafızasına kaydedebilmekte yada istediği
sosyal paylaşım ortamında doğrudan paylaşabilmektedir.
51
4. ÖNERİLER
Göktürkçe alfabesi ve dil kurallarının günümüz Türkçesine uygulanması oldukça
kolaydır. Ancak Türkçeye sonradan giren yabancı kökenli kelimeler Türkçenin dil kurallarına
uymadığından dolayı Göktürkçe dil kurallara bu kelimelere uygulanamamaktadır. Bunu
yerine bu projede yabancı kökenli kelimeler için alternatif çeviriler uygulanmaktadır. Projede
bu alternatifler uygulanırken Tuğrul ÇAVDAR hocamızın bloğundaki bilgiler referans
alınmıştır.
Göktürk alfabesi günümüzde kullanılan Latin alfabesine göre daha çok karakter
içermektedir. Ayrıca Türkçede ihtiyaç duyulan bazı sesler Latin alfabesinde olmamasına
karşın Göktürkçede bu ihtiyaçların tamamı karşılanabilmektedir. Bu yüzden de Göktürkçeye
karşı ilgi gün geçtikçe daha da artmaktadır.
52
5. KAYNAKLAR
1. http://www.russellcottrell.com/greek/utilities/SurrogatePairCalculator.htm The Surrogate
Pair Calculator etc. 1 Ekim 2015.
2. http://kok-turk.blogspot.com.tr Nasıl Yazılır. 1 Ekim 2015.
53
STANDARTLAR ve KISITLAR FORMU
Projenin hazırlanmasında uyulan standart ve kısıtlarla ilgili olarak, aşağıdaki soruları
cevaplayınız.
1. Projenizin tasarım boyutu nedir? (Yeni bir proje midir? Var olan bir projenin tekrarı mıdır?
Bir projenin parçası mıdır? Sizin tasarımınız proje toplamının yüzde olarak ne kadarını
oluşturmaktadır?)
Yeni bir projedir. %100 bizim tasarımımızdır.
2. Projenizde bir mühendislik problemini kendiniz formüle edip, çözdünüz mü? Açıklayınız.
Hayır.
3. Önceki derslerde edindiğiniz hangi bilgi ve becerileri kullandınız?
Algoritma ve programlama becerilerimizi kullandık.
4. Kullandığınız veya dikkate aldığınız mühendislik standartları nelerdir? (Proje konunuzla
ilgili olarak kullandığınız ve kullanılması gereken standartları burada kod ve isimleri ile
sıralayınız).
Genel kod yazım kuralları ve yazılımın modüler olması dikkate alındı.
5. Kullandığınız veya dikkate aldığınız gerçekçi kısıtlar nelerdir? Lütfen boşlukları uygun
yanıtlarla doldurunuz.
a) Ekonomi
Tamamen ücretsizdir.
b) Çevre sorunları:
Herhangi bir çevre sorunu vermemektedir.
54
c) Sürdürülebilirlik:
Projeye doğal dil işleme eklenene kadar sürdürülebilir.
d) Üretilebilirlik:
Tamamen ücretsiz olduğu için dağıtımı sınırsızdır.
e) Etik:
Herhangi bir etik kuralı ihlal etmemektedir.
f) Sağlık:
Telefonun SAR değeri ile sınırlıdır.
g) Güvenlik:
Güvenlik zafiyeti çıkaracak herhangi bir unsuru yoktur.
h) Sosyal ve politik sorunlar:
Böyle sorunlarla karşılaşılmamıştır.

Benzer belgeler

1. GÜN Staj boyunca android programlama

1. GÜN Staj boyunca android programlama Verileri çekme ve işleme konusuna bu şekilde bir çözüm bulduktan sonra projenin tasarımı için algoritmaları üzerine düşünmeye başladım. En az iki farklı ekran olması gerektiği, ilk ekranda illerin ...

Detaylı