Files
robo_public/karel/scripts/prikazy-funkce-editor.js
T
vojta@alfred 4e5c55e846 Prvni commit.
2026-02-01 00:00:07 +01:00

421 lines
12 KiB
JavaScript

/*
* [Česky]
* Projekt: Robot Karel
* Copyright: Viz KOPIROVANI v kořenovém adresáři projektu
*
* [English]
* Project: Karel, the Robot
* Copyright: See COPYING in the top level directory
*/
// JavaScript - ovládání editoru
// POZNÁMKA: Řetězec načtený z příkazového pole je vnitřně udržován ve formě
// escape(), protože Konqueror (KDE JavaScript) neumí pracovat s Unicode.
// ===========================================================================
// =~ Globální nastavení ~====================================================
// Ukládat, nebo neukládat syntakticky chybné příkazy?
nastaveni.ukladat_syntakticky_chybne = true;
// ===========================================================================
// =~ Globální proměnné ~=====================================================
// Editor
editor = new Object();
// Panel nástrojů
editor.nastroje = new Array(
[ "novy", "tip-novy", "Nový příkaz", "Vytvoř nový příkaz" ],
null,
[ "ulozit", "tip-ulozit-prikaz", "Ulož příkaz", "Ulož příkaz do slovníku" ],
[ "ulozit-jako", "tip-ulozit-jako", "Ulož příkaz nově", "Ulož příkaz pod novým jménem" ]
);
editor.nastroje.id_prefix = "editor-";
editor.nastroje.mys = "editor.mys_nastroje";
// Myš nad nástroji
editor.mys_nastroje = new Mys(new Tooltip());
// Zobrazený příkaz včetně textového obsahu (pro účely zjištění změny)
editor.zobrazeny = { prikaz: null, obsah: null, zmeneny: false };
// ===========================================================================
// =~ Základní funkce pro práci se slovníkem ~================================
editor.mys_nastroje.proved_zvyrazneni = function(info, detail)
{
return true;
}
editor.mys_nastroje.prekresli_stav = function(nastroj, detail, zvyraznen,
stisknut, vybran)
{
tvoric.zvyraznovac( editor.nastroje.id_prefix+nastroj, zvyraznen, stisknut,
vybran);
}
editor.mys_nastroje.vyber = function(nastroj, detail)
{
switch ( nastroj ) {
case "novy":
editor.prikaz_novy();
break;
case "ulozit":
case "ulozit-jako":
editor.prikaz_uloz( (nastroj == "ulozit-jako") );
break;
default:
ladici_vypis(CHYBA, "editor.mys_nastroje.vyber", nastroj,
"vybrán neznámý příkaz");
}
return false;
}
editor.mys_nastroje.tooltip.obnov = function (tooltip, info, detail)
{
tvoric.obnov_tooltip( tooltip, detail.ikona, detail.nadpis, detail.popis );
}
// Zruš ukazatel změny příkazu
editor.zrus_zmenu = function()
{
nastav_text(document.getElementById('zmeneny-prikaz'), '');
this.zobrazeny.zmeneny = false;
}
// Editovaný text s upravenými konci řádku
editor.editovany_text = function (text)
{
var element = document.getElementById('editace');
if ( text ) {
element.value = unescape(text);
} else {
// Konqueror neumí správně nahrazovat, proto řetězec zpracováváme v escape
// módu
var obsah = escape(element.value);
return obsah.replace(/%0D(%0A)?/g, "%0A");
}
}
// Nastaví jméno zobrazeného příkazu
editor.zobrazene_jmeno = function (text)
{
nastav_text(document.getElementById('zobrazeny-prikaz'),
text);
}
// Nastav (obnov) ukazatel změny příkazu
editor.nastav_zmenu = function ()
{
if ( this.zobrazeny.obsah != this.editovany_text() ) {
nastav_text(document.getElementById('zmeneny-prikaz'), '+');
this.zobrazeny.zmeneny = true;
} else {
this.zrus_zmenu();
}
return this.zobrazeny.zmeneny;
}
// Kontrola změny příkazu a uložení změn. Vrací true, pokud se může pokračovat
editor.kontrola_zmeny = function ()
{
if ( this.nastav_zmenu() ) {
var jmeno = "Nový příkaz";
if ( this.zobrazeny.prikaz ) {
jmeno = "Zobrazený příkaz " + this.zobrazeny.prikaz.jmeno;
}
var uzivatel_chce = window.confirm( jmeno + " byl změněn.\n\nPřejete si ho uložit?\n" +
"(OK=Ano, Storno=Ne)" );
if ( uzivatel_chce ) {
return editor.prikaz_uloz();
} else {
var uzivatel_chce = window.confirm( jmeno +
" nebyl uložen. Přesto pokračovat?" );
if ( !uzivatel_chce ) {
return false;
}
}
}
return true;
}
// ===========================================================================
// =~ Formátování chyb ~======================================================
// Zobrazení chyby při ukládání příkazu
editor.formatuj_chybu_ukladani = function (text, uloz_nove, nove_jmeno,
cislo_radky, telo, ulozit)
{
var text_radky = "";
var prikaz_radky = "";
var varovani = "";
if ( cislo_radky != undefined && cislo_radky != null && cislo_radky >= 0 ) {
text_radky = " na řádce " + (cislo_radky+1);
if ( telo && cislo_radky < telo.length ) {
prikaz_radky = ": " +
prikazy.formatovac.zformatuj_jednu_radku(telo[cislo_radky]);
}
}
if ( !ulozit ) {
varovani = "\n\nZměny příkazu nebyly uloženy.";
}
if ( nove_jmeno ) {
return "Ukládaný příkaz " + nove_jmeno +
" má chybu" + text_radky + prikaz_radky + ".\n" + text + varovani;
} else if ( uloz_nove && this.zobrazeny.prikaz ) {
return "Zobrazený příkaz " + this.zobrazeny.prikaz.jmeno +
" má chybu" + text_radky + prikaz_radky + ".\n" + text + varovani;
} else {
return "Ukládaný příkaz má" + text_radky + " chybu" + prikaz_radky +
".\n" + text + varovani;
}
}
// Zobrazení chyby při zobrazení příkazu
editor.formatuj_chybu_zobrazeni = function (text, jmeno, cislo_radky, telo)
{
var text_radky = "";
var prikaz_radky = "";
if ( cislo_radky != undefined && cislo_radky != null ) {
text_radky = " na řádce " + (cislo_radky+1);
if ( telo && cislo_radky < telo.length ) {
prikaz_radky = ": " +
prikazy.formatovac.zformatuj_jednu_radku(telo[cislo_radky]);
}
}
return "Zobrazovaný příkaz " + jmeno +
" má chybu" + text_radky + prikaz_radky + ".\n" + text;
}
// ===========================================================================
// =~ Příkazy editace ~=======================================================
// Nový příkaz
editor.prikaz_novy = function (bez_kontroly)
{
if ( !bez_kontroly && !this.kontrola_zmeny() ) return;
var jmeno;
var i = 1;
do {
jmeno = "NOVÝ PŘÍKAZ";
if ( i > 1 ) jmeno += " "+i;
for ( var j = prikazy.seznam.length-1;
j >= 0 && !prikazy.seznam[j].systemovy; j-- ) {
if ( jmeno == prikazy.seznam[j].jmeno ) break;
}
if ( j < 0 || j >= 0 && prikazy.seznam[j].systemovy ) break;
i++;
} while ( true );
// Struktura nového příkazu pro zformátování. Zformátování je nutné, protože
// se obsah uchovává ve formě escape()
var prikaz = { jmeno: jmeno };
prikaz.telo = [ [ prikazy.NAZEV, prikaz ], [ prikazy.KONEC ] ];
var obsah = new Obsah();
var vysledek = prikazy.formatovac.zformatuj_prikaz(prikaz, obsah);
this.zobrazene_jmeno(prikazy.zadny_prikaz);
this.zobrazeny.prikaz = null;
this.zobrazeny.obsah = obsah.obsah();
this.editovany_text( this.zobrazeny.obsah );
this.zrus_zmenu();
}
// Zkontroluj, jestli se nepřepisuje nějaký příkaz. Vrací false, pokud se nemá
// přepisovat; true, pokud se normálně pokračuje; nebo příkaz pro smazání, pokud
// se přepisuje
editor.kontrola_prepsani = function (uloz_nove, novy_prikaz)
{
var smaz_prikaz;
for ( var i = prikazy.seznam.length-1; i >= 0; i-- ) {
var prikaz = prikazy.seznam[i];
if ( prikaz.zobrazit ) {
if ( prikaz.jmeno == novy_prikaz.jmeno
&& this.zobrazeny.prikaz != prikaz ) {
if ( !window.confirm("Opravdu má být přepsán příkaz " +
prikaz.jmeno + "?") ) {
return false;
} else {
if ( !uloz_nove && this.zobrazeny.prikaz ) {
// Po změně musíme smazat původní příkaz
smaz_prikaz = this.zobrazeny.prikaz;
this.zobrazeny.prikaz = prikaz;
return smaz_prikaz;
} else {
this.zobrazeny.prikaz = prikaz;
return true;
}
}
}
}
}
return true;
}
// Proveď uložení příkazu
editor.proved_ulozeni = function (uloz_nove, novy_prikaz, obsah)
{
if ( uloz_nove || !this.zobrazeny.prikaz ) {
prikazy.pridej_novy(novy_prikaz);
} else {
prikazy.zmen_prikaz(this.zobrazeny.prikaz, novy_prikaz);
}
this.zobrazeny.obsah = obsah;
this.zobrazeny.prikaz = novy_prikaz;
this.zobrazene_jmeno(novy_prikaz.jmeno);
}
// Ulož příkaz. Vrací true, pokud se může pokračovat
editor.prikaz_uloz = function (uloz_nove)
{
if ( !prikazy.test_spusteni() ) return false;
var text = this.editovany_text();
var vysledek = new Vysledek();
var uloz_nove_prikaz = (!uloz_nove ? this.zobrazeny.prikaz : undefined);
vysledek.nastav( prikazy.rozpoznavac.rozpoznej( text, uloz_nove_prikaz ) );
var novy_prikaz = vysledek.hodnota.prikaz;
var obsah = vysledek.hodnota.obsah;
var cislo_radky = vysledek.hodnota.cislo_radky;
var ulozit = false;
if ( !vysledek.byla_chyba() ) {
var novy_obsah = new Obsah();
vysledek.nastav(
prikazy.formatovac.zformatuj_prikaz(novy_prikaz, novy_obsah) );
obsah = novy_obsah.obsah();
cislo_radky = vysledek.hodnota.cislo_radky;
// Uložit příkaz, stejně jako ve verzi 1.2, nebo neuložit?
if ( nastaveni.ukladat_syntakticky_chybne ) {
ulozit = true;
} else {
ulozit = !vysledek.byla_chyba();
}
}
vysledek.chyba.formatuj = function (text) {
return editor.formatuj_chybu_ukladani(text, uloz_nove, novy_prikaz.jmeno,
cislo_radky, novy_prikaz.telo,
ulozit);
}
// Obnov obsah editovacího pole
if ( obsah != this.editovany_text() ) {
this.editovany_text( obsah );
}
// Kontrola přepsání zobrazeného příkazu
if ( novy_prikaz.jmeno ) {
if ( uloz_nove && this.zobrazeny.prikaz
&& this.zobrazeny.prikaz.jmeno == novy_prikaz.jmeno ) {
uloz_nove = false;
}
}
vysledek.zobraz_chybu();
if ( ulozit ) {
var smaz_prikaz;
var vyber_prikaz;
// Kontrola přepsání
smaz_prikaz = this.kontrola_prepsani(uloz_nove, novy_prikaz);
if ( !smaz_prikaz ) {
ulozit = false;
}
// Zjisti, jestli se má udržet nějaký výběr
if ( ulozit && !uloz_nove && smaz_prikaz instanceof Object
&& prikazy.vybrany_prikaz() == smaz_prikaz.jmeno ) {
vyber_prikaz = novy_prikaz.jmeno;
}
// Smaž příkaz, pokud je co smazat
if ( smaz_prikaz instanceof Object ) {
prikazy.nahrad_telo( smaz_prikaz, novy_prikaz );
prikazy.proved_smazani( smaz_prikaz );
}
// Ulož nový příkaz
if ( ulozit ) {
this.proved_ulozeni( uloz_nove, novy_prikaz, obsah );
}
// Obnov výběr příkazu
if ( vyber_prikaz && vyber_prikaz != prikazy.vybrany_prikaz() ) {
prikazy.vyber_prikaz(vyber_prikaz);
}
} // end if ( !chyba.byla_chyba() )
// Indikuj změnu obsahu a vrať výsledek - true, pokud bylo uloženo
return !this.nastav_zmenu();
}
// Příkaz byl doplněn, obnov zobrazení
editor.prikaz_upraven = function (prikaz)
{
if ( this.zobrazeny.prikaz == prikaz ) {
var obsah = new Obsah();
prikazy.formatovac.zformatuj_prikaz( this.zobrazeny.prikaz, obsah );
this.zobrazeny.obsah = obsah.obsah();
if ( this.nastav_zmenu() ) {
// Pokud nebyl příkaz změněný, zobraz nový obsah
this.editovany_text( obsah.obsah() );
this.nastav_zmenu();
}
}
}
// Zobrazit vybraný příkaz
editor.zobraz_vybrany_prikaz = function ()
{
if ( !this.kontrola_zmeny() ) return;
// Kontrola vybraného příkazu je nutná i zde, protože se výběr mohl
// uložením změnit
var jmeno = prikazy.vybrany_prikaz();
if ( !(jmeno && prikazy.prikaz[jmeno]) ) {
alert( "Není vybrán žádný příkaz.\n\n" +
"Příkaz vyberte klepnutím myši." );
return;
}
var prikaz = prikazy.prikaz[jmeno];
var vysledek = new Vysledek();
var obsah = new Obsah();
var chyba = new Chyba();
vysledek.nastav( prikazy.formatovac.zformatuj_prikaz(prikaz, obsah) );
vysledek.chyba.formatuj = function (text) {
return editor.formatuj_chybu_zobrazeni(text, prikaz.jmeno,
vysledek.hodnota.cislo_radky,
prikaz.telo);
}
this.zobrazeny.prikaz = prikaz;
this.zobrazene_jmeno(prikaz.jmeno);
this.zobrazeny.obsah = obsah.obsah();
this.editovany_text( obsah.obsah() );
this.nastav_zmenu();
vysledek.zobraz_chybu();
}
// Příkaz byl smazán
editor.smaz_prikaz = function (prikaz)
{
if ( this.zobrazeny.prikaz == prikaz ) {
this.zobrazeny.prikaz = null;
this.zobrazeny.obsah = null;
this.zobrazene_jmeno(prikazy.zadny_prikaz);
this.nastav_zmenu();
}
}