76d2e43293
printer.cpp Vietao il registra di configurazioni utente text.cpp Modificati include inutili text.h Cambiati valori di un enum per compatibilita con release 4.5 viswin.cpp Tolto bottone di chiusura window.cpp Aggiunti controlli sulla chiusura/distruzione delle finestre. git-svn-id: svn://10.65.10.50/trunk@3804 c028cbd2-c16b-5b4b-a496-9718f37d4682
902 lines
22 KiB
C++
Executable File
902 lines
22 KiB
C++
Executable File
#include <ctype.h>
|
|
|
|
#include <regexp.h>
|
|
#include <relation.h>
|
|
#include <text.h>
|
|
#include <window.h>
|
|
#include <xvtility.h>
|
|
|
|
static char TEXT_TMP[513];
|
|
|
|
class _HotSpot : public TObject
|
|
{
|
|
public:
|
|
// TArray _spots; // tokenstrings
|
|
char _bg, _fg;
|
|
|
|
_HotSpot (char fg, char bg)
|
|
{
|
|
_fg = fg;
|
|
_bg = bg;
|
|
}
|
|
virtual ~ _HotSpot ()
|
|
{
|
|
}
|
|
};
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Permette di settare gli hot_spot
|
|
void TTextfile::set_hotspots (
|
|
char fg, // @parm Colore di foreground da utilizzare per l'hotspot
|
|
char bg) // @parm Colore di background da utilizzare per l'hotspot
|
|
|
|
// @comm Aggiunge all'array gli hotspots relativi alla pagina in memoria
|
|
// (come <c TToken_string> con x<pipe>y<pipe>text)
|
|
{
|
|
_HotSpot *hp = new _HotSpot (fg, bg);
|
|
_hotspots.add (hp);
|
|
}
|
|
|
|
style TTextfile::_trans_style (char ch)
|
|
{
|
|
switch (ch)
|
|
{
|
|
case 'r':
|
|
return normal;
|
|
case 'i':
|
|
return italic;
|
|
case 'b':
|
|
return bold;
|
|
case 'u':
|
|
return underlined;
|
|
case 't':
|
|
return tabbed;
|
|
default:
|
|
return normal;
|
|
}
|
|
}
|
|
|
|
|
|
void TTextfile::_save_changes()
|
|
{
|
|
begin_wait();
|
|
// fa i dovuti replace anche sul disco (solo replace di linee esistenti)
|
|
long line = 0l;
|
|
|
|
fclose(_index);
|
|
remove(_indname);
|
|
|
|
TString oldfile(_filename);
|
|
_filename.temp("txtf");
|
|
|
|
FILE* newf = fopen(_filename, "a+");
|
|
|
|
if ((_index = fopen(_indname, "w+b")) == NULL || newf == NULL)
|
|
{
|
|
yesnofatal_box ("Impossibile aprire files temporanei");
|
|
freeze();
|
|
return;
|
|
}
|
|
|
|
fseek(_instr, 0l, SEEK_SET);
|
|
|
|
while (!feof(_instr))
|
|
{
|
|
const long l = ftell(newf);
|
|
fwrite (&l, sizeof(long), 1, _index);
|
|
|
|
if (ferror(_index) || ferror(newf))
|
|
{
|
|
error_box ("Errore di scrittura file temporaneo: scrittura interrotta");
|
|
freeze ();
|
|
}
|
|
|
|
if (fgets(TEXT_TMP, sizeof(TEXT_TMP), _instr) == NULL)
|
|
break;
|
|
|
|
if (line >= _page_start && line <= _page_end)
|
|
{
|
|
TString& lin = (TString&)(_page[(int)(line - _page_start)]);
|
|
if (_dirty_lines[line - _page_start])
|
|
{
|
|
strcpy(TEXT_TMP, lin);
|
|
strcat(TEXT_TMP, "\n");
|
|
}
|
|
}
|
|
|
|
fprintf(newf, "%s", TEXT_TMP);
|
|
line++;
|
|
}
|
|
|
|
fflush(_index);
|
|
fclose(_instr);
|
|
fclose(newf);
|
|
remove(oldfile);
|
|
rename(_filename, oldfile);
|
|
_filename = oldfile;
|
|
_instr = fopen(_filename, "a+");
|
|
|
|
end_wait();
|
|
}
|
|
|
|
void TTextfile::_read_page (long n)
|
|
{
|
|
if (_dirty_lines.ones() > 0l)
|
|
{
|
|
_save_changes();
|
|
_dirty_lines.reset();
|
|
}
|
|
|
|
switch (_direction)
|
|
{
|
|
case down:
|
|
_page_start = n;
|
|
break;
|
|
case up:
|
|
_page_start = n + _page_size;
|
|
break;
|
|
case updown:
|
|
_page_start = n - (_page_size / 2l);
|
|
break;
|
|
}
|
|
|
|
if (_page_start < 0l)
|
|
_page_start = 0l;
|
|
if ((_page_start + _page_size) > _lines)
|
|
_page_end = _lines - 1;
|
|
else
|
|
_page_end = _page_start + _page_size - 1;
|
|
|
|
// zap hotspots
|
|
_spots.destroy ();
|
|
|
|
long l = 0l;
|
|
fseek (_index, _page_start * (long) sizeof (long), SEEK_SET);
|
|
if (_page_start != 0l)
|
|
fread (&l, sizeof (long), 1, _index);
|
|
fseek (_instr, l, SEEK_SET);
|
|
|
|
for (long i = _page_start; i <= _page_end; i++)
|
|
{
|
|
if (feof (_instr))
|
|
break;
|
|
fgets (TEXT_TMP, sizeof (TEXT_TMP), _instr);
|
|
TEXT_TMP[strlen (TEXT_TMP) - 1] = '\0';
|
|
TString & ts = (TString &) _page[(int) (i - _page_start)];
|
|
ts = TEXT_TMP;
|
|
if (_interactive)
|
|
{
|
|
TString hcol (6);
|
|
// find hotspots and compile list
|
|
|
|
int len = 0;
|
|
const char *cp;
|
|
read_line (i, 0, FALSE);
|
|
while (cp = piece ())
|
|
{
|
|
for (int z = 0; z < _hotspots.items (); z++)
|
|
{
|
|
_HotSpot & hs = (_HotSpot &) _hotspots[z];
|
|
if (hs._fg == get_foreground () && hs._bg == get_background ())
|
|
{
|
|
TToken_string *tts = new TToken_string (50);
|
|
tts->add (i); // line number
|
|
|
|
tts->add (len);
|
|
tts->add (len + (int) strlen (cp));
|
|
tts->add (cp);
|
|
tts->add (z);
|
|
_spots.add (tts);
|
|
break;
|
|
}
|
|
}
|
|
len += strlen (cp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Legge il testo formattato
|
|
void TTextfile::read_line (
|
|
long n, // @parm Numero della linea da leggere
|
|
long pos, // @parm Numero della colonna da leggere (mai utilizzata)
|
|
bool pg) // @parm Fa si' che se la linea non e' nella pagina corrente non si faccia nulla,
|
|
// diversamente rilegge una nuova pagina dal file.
|
|
|
|
{
|
|
CHECK (_isopen, "Attempt operation on closed file");
|
|
CHECKD (n >= 0 && n < _lines, "Line not present", n);
|
|
|
|
if (pg && !_in_page (n))
|
|
_read_page (n);
|
|
|
|
TString *tp = (TString *) _page.objptr (int (n - _page_start));
|
|
if (tp == NULL)
|
|
return;
|
|
|
|
const char *sp = (const char *) (*tp);
|
|
_item = 0;
|
|
_line = "";
|
|
int ndx = 0, p = 0;
|
|
bool first = TRUE;
|
|
_cur_line = n;
|
|
char ch;
|
|
|
|
int col = ((int) 'w' << 8) | (int) 'n';
|
|
long stl = (long) col << 16;
|
|
|
|
while (ch = *sp++)
|
|
{
|
|
if (ch == '<' && *(sp) == '@')
|
|
{
|
|
// merge field if rel != NULL;
|
|
// else fill with whitespace
|
|
TToken_string id(80, '@');
|
|
sp++;
|
|
bool terminated = FALSE;
|
|
while ((ch = *sp++) != '>' && !terminated)
|
|
if (ch != '\0')
|
|
id << ch;
|
|
else terminated = TRUE;
|
|
if (terminated) break; // Esce dal ciclo se non trova la matching >
|
|
// id contains tokenstring separated by @
|
|
// but with casinations for possible lack of spacing
|
|
// add spaces if needed
|
|
for (int i = 0; i < id.len(); i++)
|
|
{
|
|
if (id[i] == '@' && id [i+1] == '@')
|
|
{
|
|
id.insert(" ", i+1);
|
|
i+= 2;
|
|
}
|
|
}
|
|
// parse string
|
|
int len;
|
|
TString80 file;
|
|
TString16 field;
|
|
TString80 format;
|
|
char just;
|
|
|
|
file = id.get();
|
|
format = id.get();
|
|
len = (int)id.get_long();
|
|
just = id.get_char();
|
|
|
|
int pos = 0;
|
|
if ((pos = file.find("->")) == -1)
|
|
error_box("field specification error");
|
|
else
|
|
{
|
|
file.cut(pos);
|
|
field = file.mid(pos+2);
|
|
}
|
|
|
|
if (len == 0) len = id.len();
|
|
|
|
TString txt(512);
|
|
TFieldtypes type;
|
|
|
|
if (_rel != NULL)
|
|
{
|
|
// retrieve file and field
|
|
if (atoi(file) == 0)
|
|
{
|
|
// tabella
|
|
TLocalisamfile& t = _rel->lfile(file);
|
|
txt = t.get(field);
|
|
type = t.curr().type(field);
|
|
}
|
|
else
|
|
{
|
|
TLocalisamfile& f = _rel->lfile(atoi(file));
|
|
txt = f.get(field);
|
|
type = f.curr().type(field);
|
|
}
|
|
// apply format to date and number
|
|
switch (type)
|
|
{
|
|
case _longfld:
|
|
case _realfld:
|
|
{
|
|
real r(txt);
|
|
txt = r.string(format);
|
|
}
|
|
break;
|
|
case _datefld:
|
|
{
|
|
TDate dd(txt);
|
|
TFormatted_date d(dd, format);
|
|
txt = d.string();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
// justify as requested
|
|
if (txt.len() < len)
|
|
{
|
|
switch(type)
|
|
{
|
|
case _longfld:
|
|
case _realfld:
|
|
txt.right_just(len);
|
|
break;
|
|
default:
|
|
txt.left_just(len);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
txt.left_just(len);
|
|
}
|
|
// ficca il testo cola' dove si puote
|
|
for (int k = 0; k < txt.len(); k++)
|
|
TEXT_TMP[ndx++] = txt[k];
|
|
}
|
|
|
|
if (ch == '@' || (ch == '$' && *(sp) == '['))
|
|
{
|
|
if (!first && p >= pos)
|
|
{
|
|
_styles[_item++] = stl;
|
|
TEXT_TMP[ndx] = '\0';
|
|
_line.add (TEXT_TMP);
|
|
ndx = 0;
|
|
}
|
|
while (ch && (ch == '@' || (ch == '$' && *sp == '[')))
|
|
{
|
|
if (ch == '@') // font style change ?
|
|
{
|
|
const char c = *sp++;
|
|
|
|
style sss = _trans_style (c);
|
|
if (sss == normal)
|
|
stl = (long) col << 16;
|
|
else
|
|
stl |= (long) sss;
|
|
}
|
|
else if (ch == '$' && *sp == '[') // color change
|
|
|
|
{
|
|
++sp; // eat '['
|
|
|
|
col = *sp++;
|
|
++sp; // eat ','
|
|
|
|
col |= ((int) (*sp++) << 8);
|
|
++sp; // eat ']'
|
|
|
|
stl = (stl & 0x0000ffff) | ((long) col << 16);
|
|
}
|
|
ch = *sp++;
|
|
} // while
|
|
|
|
}
|
|
if (ch && p >= pos)
|
|
{
|
|
first = FALSE;
|
|
TEXT_TMP[ndx++] = ch;
|
|
}
|
|
p++;
|
|
}
|
|
_styles[_item++] = stl;
|
|
TEXT_TMP[ndx] = '\0';
|
|
_line.add(TEXT_TMP);
|
|
_item = 0;
|
|
}
|
|
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Ritorna la stringa di caratteri senza formattazione
|
|
//
|
|
// @rdesc Ritorna la stringa di caratteri ed eventualmente con i campi sostituiti
|
|
// se la relazione non e' NULL
|
|
const char *TTextfile::line(
|
|
long j, // @parm Riga di cui ritornare la stringa
|
|
long pos, // @parm Colonna di cui ritornare la stringa
|
|
int howmuch) // @parm Numero di caratteri utili della stringa da ritornare (default -1)
|
|
|
|
// @comm Se <p howmuch> assume valore -1 ritorna tutta la pagina
|
|
{
|
|
if (_cur_line != j)
|
|
read_line (j);
|
|
*TEXT_TMP = '\0';
|
|
_line.restart ();
|
|
for (int i = 0; i < _line.items (); i++)
|
|
strcat (TEXT_TMP, (const char *) _line.get ());
|
|
if (howmuch != -1)
|
|
{
|
|
if (((unsigned int)pos+howmuch) < strlen(TEXT_TMP))
|
|
TEXT_TMP[pos+howmuch] = '\0';
|
|
}
|
|
return strlen(TEXT_TMP) > (word)pos ? &(TEXT_TMP[pos]) : "";
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Cerca una stringa di testo all'interno di una riga
|
|
//
|
|
// @rdesc Ritorna la posizione in cui e' stato rintracciato il testo. Ritorna -1 se non e' stato
|
|
// trovato il testo passato.
|
|
long TTextfile::search(
|
|
const char* txt, // @parm Testo da cercare
|
|
int& ret, // @parm Intero in cui posizionare la posizne del carattere
|
|
long from, // @parm Posizione all'interno della riga da cui iniziare la ricerca (default 0)
|
|
bool down, // @parm Indica se la ricerca va effettuata all'indietro:
|
|
//
|
|
// @flag TRUE | Ricerca dalla posizione indicata all'inizio della riga (default)
|
|
// @flag FALSE | Ricerca dalla posizione indicata alla fine della riga
|
|
bool casesens, // @parm Indica se ricerca il testo con criterio case sensitive (default FALSE)
|
|
bool regexp) // @parm indica se considerare la stringa un'espressione regolare (def. FALSE)
|
|
|
|
// @comm Cerca in una riga per volta rispettando i formati
|
|
{
|
|
TString lin(512); TString80 text(txt);
|
|
if (!casesens)
|
|
text.lower();
|
|
|
|
for (long i = from; down ? (i < lines()) : (i >= 0); down ? i++ : i--)
|
|
{
|
|
lin = line(i);
|
|
if (regexp)
|
|
{
|
|
if (match(txt, lin))
|
|
return i;
|
|
}
|
|
else
|
|
{
|
|
if (!casesens) lin.lower();
|
|
if ((ret = lin.find(text)) != -1)
|
|
return i;
|
|
}
|
|
}
|
|
return -1l;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Sostituisce un testo all'interno di una riga
|
|
//
|
|
// @rdesc Ritorna la posizione in cui e' stato sostituito il testo. Ritorna -1 se non e' stata
|
|
// fatto nessuna operazione di sostituzione.
|
|
int TTextfile::replace(
|
|
long l, // @parm Numero della riga nella quale sostituire il testo
|
|
const char* txt, // @parm Test da inserire nella riga
|
|
int pos, // @parm Posizione nella quale inserire il testo (default 0)
|
|
int len) // @parm Lunghezza del testo da sostituire (default 0)
|
|
{
|
|
if (_cur_line != l)
|
|
read_line(l);
|
|
|
|
TString& line = (TString&)_page[int(l-_page_start)];
|
|
|
|
char ch; int i = 0, cnt = 0, skip = 0;
|
|
bool sforating = FALSE;
|
|
|
|
// here's a nice casin
|
|
while(i < 256)
|
|
{
|
|
if (!sforating)
|
|
{
|
|
ch = line[i++];
|
|
if (ch == '\0')
|
|
sforating = TRUE;
|
|
else if (ch == '@' && strchr("ribuokt",line[i]) != NULL)
|
|
{
|
|
skip +=2; i++; cnt--;
|
|
}
|
|
else if (ch == '$' && line[i] == '[')
|
|
{
|
|
skip +=3; i++; cnt--;
|
|
while(line[i++] != ']')
|
|
if (line[i] == '\0')
|
|
return -1;
|
|
else skip++;
|
|
}
|
|
}
|
|
|
|
if (cnt == pos)
|
|
{
|
|
line.overwrite(txt, cnt+skip);
|
|
_dirty_lines.set(l-_page_start);
|
|
return cnt;
|
|
}
|
|
else cnt++;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Ritorna la stringa di caratteri con la formattazione
|
|
//
|
|
// @rdesc La stringa ritornata ha la formattazione (ovvere tutti i @codes, in modo che anche
|
|
// la printer la possa utilizzare)
|
|
const char *TTextfile::line_formatted(
|
|
long j) //parm Numero della riga da ritornare
|
|
{
|
|
if (_cur_line != j)
|
|
read_line (j);
|
|
TString* tp = (TString*)_page.objptr(int(j-_page_start));
|
|
strcpy(TEXT_TMP, (const char*)(*tp));
|
|
return TEXT_TMP;
|
|
}
|
|
|
|
long TTextfile::get_attribute (int pos)
|
|
{
|
|
long stl = 0;
|
|
if (pos == -1)
|
|
{
|
|
CHECK (_item > 0, "must execute piece() before style()!");
|
|
stl = _styles[_item - 1];
|
|
}
|
|
else
|
|
{
|
|
int x = 0, nd = 0;
|
|
const char *c;
|
|
_line.restart ();
|
|
while ((c = _line.get ()) != NULL)
|
|
{
|
|
x += strlen (c);
|
|
stl = _styles[nd++];
|
|
if ((x - 1) >= pos)
|
|
break;
|
|
}
|
|
}
|
|
return stl;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Ritorna lo stile del piece
|
|
//
|
|
// @rdesc Ritorna un numero (vedi <t style>) indicante lo stile
|
|
int TTextfile::get_style (
|
|
int pos) // @parm Posizione del carattere di cui ritornare lo stile (default -1)
|
|
|
|
// @comm Se viene passato a <p pos> valore -1 ritorna lo stile di tutta la piece, altrimente
|
|
// solamente quello del carattere selezionato.
|
|
{
|
|
const long x = get_attribute(pos) & ~tabbed;
|
|
return (int) (x & 0x0000ffff);
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Ritorna il colore di background del piece
|
|
//
|
|
// @rdesc Ritorna il codice del colore, NULL se il carattere non esiste
|
|
char TTextfile::get_background (
|
|
int pos) // @parm Posizione del carattere di cui conoscere il colore di background (default -1)
|
|
|
|
// @comm Se <p pos> e' minore di 0 ritorna il colore dell'intero piece, altrimenti solamente
|
|
// quello del carattere selezionato.
|
|
//
|
|
// @xref <mf TTextfile::get_foreground>
|
|
{
|
|
long x = get_attribute (pos);
|
|
return (char) (x >> 24);
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Ritorna il colore di foreground del piece
|
|
//
|
|
// @rdesc Ritorna il codice del colore, NULL se il carattere non esiste
|
|
char TTextfile::get_foreground (
|
|
int pos) // @parm Posizione del carattere di cui conoscere il colore di background (default -1)
|
|
|
|
// @comm Se <p pos> e' minore di 0 ritorna il colore dell'intero piece, altrimenti solamente
|
|
// quello del carattere selezionato.
|
|
//
|
|
// @xref <mf TTextfile::get_bakcground>
|
|
{
|
|
long x = get_attribute (pos);
|
|
return (char) ((x >> 16) & 0x000000ff);
|
|
}
|
|
|
|
const char* TTextfile::piece()
|
|
{
|
|
const char* l = _line.get(_item);
|
|
if (l == NULL)
|
|
return NULL;
|
|
_item++;
|
|
return strcpy(TEXT_TMP, l);
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Ritorna la parola alla posizione indicata
|
|
//
|
|
// @rdesc Stringa indicante la parola cercate
|
|
const char *TTextfile::word_at (
|
|
long x, // @parm Numero della parola da ritornare
|
|
long y) // @parm Numero della linea su cui cercare la parole
|
|
{
|
|
CHECK (_isopen, "Attempt operation on closed file");
|
|
TString s (line (y));
|
|
int x2 = 0;
|
|
|
|
if (x < s.len ())
|
|
{
|
|
while (isspace (s[(int) x]))
|
|
{
|
|
if (x == (s.len () - 1) && y < (_lines - 1l))
|
|
{
|
|
s = line (++y);
|
|
x = 0l;
|
|
}
|
|
else if (x < (s.len () - 1))
|
|
x++;
|
|
else
|
|
break;
|
|
}
|
|
while (isalnum (s[(int) x]))
|
|
TEXT_TMP[x2++] = s[(int) x++];
|
|
}
|
|
TEXT_TMP[x2] = '\0';
|
|
return TEXT_TMP;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Aggiunge una riga al text (con i formati del caso)
|
|
//
|
|
// @rdesc Ritorna il risultato dell'operazione:
|
|
//
|
|
// @flag TRUE | Se la riga e' stat aggiuntac correttamente
|
|
// @flag FALSE | Se non e' riuscot ad aggiungere la riga
|
|
bool TTextfile::append (
|
|
const char *l) // @parm Riga da aggiungere
|
|
{
|
|
CHECK (_isopen, "Attempt operation on closed file");
|
|
|
|
if (!_accept)
|
|
return FALSE;
|
|
|
|
fseek (_instr, 0l, SEEK_END);
|
|
fseek (_index, 0l, SEEK_END);
|
|
long cpos = ftell (_instr);
|
|
fprintf (_instr, "%s\n", l);
|
|
fwrite (&cpos, sizeof (long), 1, _index);
|
|
if (ferror (_index) || ferror (_instr))
|
|
{
|
|
error_box ("Errore di scrittura file temporaneo: scrittura interrotta");
|
|
freeze ();
|
|
}
|
|
fflush (_index);
|
|
fflush (_instr);
|
|
|
|
_lines++;
|
|
_dirty = TRUE;
|
|
|
|
if ((_lines) < (_page_start + _page_size))
|
|
{
|
|
if (_interactive)
|
|
{
|
|
_page.add (new TString(l), int(_lines - _page_start - 1));
|
|
_page_end++;
|
|
|
|
int len = 0;
|
|
const char *cp;
|
|
read_line (_lines - 1);
|
|
while (cp = piece ())
|
|
{
|
|
for (int z = 0; z < _hotspots.items (); z++)
|
|
{
|
|
_HotSpot & hs = (_HotSpot &) _hotspots[z];
|
|
if (hs._fg == get_foreground () && hs._bg == get_background ())
|
|
{
|
|
TToken_string *tts = new TToken_string (50);
|
|
tts->add (_lines - 1l); // line number
|
|
//
|
|
|
|
tts->add (len);
|
|
tts->add (len + (int) strlen (cp));
|
|
tts->add (cp);
|
|
tts->add (z);
|
|
_spots.add (tts);
|
|
break;
|
|
}
|
|
}
|
|
len += strlen (cp);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void TTextfile::close ()
|
|
{
|
|
CHECK (_isopen,"Attempt operation on closed file");
|
|
fclose (_instr);
|
|
fclose (_index);
|
|
_instr = _index = NULL;
|
|
_isopen = FALSE;
|
|
}
|
|
|
|
void TTextfile::print ()
|
|
{
|
|
CHECK (_isopen, "Attempt operation on closed file");
|
|
warning_box ("Funzione non ancora implementata");
|
|
// TBI istanzia una printer inibendo la scelta di video
|
|
// add all lines (maybe new method: print_txt)
|
|
// print
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Scrive il testo (non formattato) su file
|
|
//
|
|
// @rdesc Ritorna il risultato dell'operazione di scrittura
|
|
//
|
|
// @flag TRUE | Se e' riuscito a scrivere il testo
|
|
// @flag FALSE | Se ha avuto qualche problema nella gestione del file in cui scrivere
|
|
bool TTextfile::write (
|
|
const char *path, // @parm Nome del file in cui scrivere il testo
|
|
TPoint * from, // @parm Punto da cui iniziare a scrivere il testo
|
|
TPoint * to) // @parm Punto a cui terminare di scrivere il testo
|
|
{
|
|
bool ok = FALSE;
|
|
FILE *fp;
|
|
if ((fp = fopen (path, "w")) != NULL)
|
|
{
|
|
ok = TRUE;
|
|
TString s(512);
|
|
long starty = from == NULL ? 0l : from->y;
|
|
int startx = from == NULL ? 0 : (int) from->x;
|
|
long endy = to == NULL ? _lines - 1l : to->y;
|
|
int endx = to == NULL ? -1 : (int) to->x;
|
|
for (long j = starty; j <= endy; j++)
|
|
{
|
|
s = line(j);
|
|
if (j == endy && endx == -1)
|
|
endx = s.len();
|
|
|
|
if (j == starty && j == endy)
|
|
s = s.sub(startx, endx);
|
|
else if (j == starty)
|
|
s = s.mid(startx);
|
|
else if (j == endy)
|
|
s = s.left(endx);
|
|
|
|
fprintf(fp, "%s\n", (const char *) s);
|
|
}
|
|
fclose (fp);
|
|
}
|
|
else
|
|
warning_box ("Impossibile scrivere il file %s; scrittura fallita", path);
|
|
return ok;
|
|
}
|
|
|
|
// @doc EXTERNAL
|
|
|
|
// @mfunc Scrive il testo da punto a punto (non formattato) su string_array
|
|
void TTextfile::write(
|
|
TString_array& arr, // @parm Array in cui scrivere il testo
|
|
TPoint * from, // @parm Punto da cui iniziare a scrivere il testo
|
|
TPoint * to) // @parm Punto a cui terminare di scrivere il testo
|
|
{
|
|
arr.destroy();
|
|
TString s(512);
|
|
long starty = from == NULL ? 0l : from->y;
|
|
int startx = from == NULL ? 0 : (int) from->x;
|
|
long endy = to == NULL ? _lines - 1l : to->y;
|
|
int endx = to == NULL ? -1 : (int) to->x;
|
|
for (long j = starty; j <= endy; j++)
|
|
{
|
|
s = line(j);
|
|
if (j == endy && endx == -1)
|
|
endx = s.len();
|
|
|
|
if (j == starty && j == endy)
|
|
s = s.sub(startx, endx);
|
|
else if (j == starty)
|
|
s = s.mid(startx);
|
|
else if (j == endy)
|
|
s = s.left(endx);
|
|
|
|
arr.add(s);
|
|
}
|
|
}
|
|
|
|
void TTextfile::destroy ()
|
|
{
|
|
CHECK (_istemp, "destroy() chiamata su testo permanente!");
|
|
if (_page.items () > 0)
|
|
{
|
|
if (_index)
|
|
fclose (_index);
|
|
if (_instr)
|
|
fclose (_instr);
|
|
remove ((const char *) _filename);
|
|
remove ((const char *) _indname);
|
|
_page_start = _lines = 0l;
|
|
_page_end = _cur_line = -1l;
|
|
_accept = TRUE;
|
|
_instr = fopen (_filename, "a+");
|
|
_indname.temp ();
|
|
_index = fopen (_indname, "w+b");
|
|
if (_index == NULL || _instr == NULL)
|
|
{
|
|
error_box ("Impossibile aprire files temporanei");
|
|
freeze ();
|
|
}
|
|
_isopen = TRUE;
|
|
// _page.destroy ();
|
|
_spots.destroy ();
|
|
}
|
|
}
|
|
|
|
TTextfile ::TTextfile (const char *file, int pagesize, direction preferred,
|
|
bool interactive):
|
|
_page_size (pagesize), _page (pagesize), _filename (file), _lines (0l),
|
|
_index (NULL), _page_start (0l), _page_end (-1l), _direction (preferred),
|
|
_dirty (FALSE), _istemp (FALSE), _item (0), _line (256), _cur_line (-1),
|
|
_hotspots (4), _accept (TRUE), _dirty_lines(pagesize),
|
|
_interactive(interactive), _rel(NULL)
|
|
|
|
{
|
|
// open file & build index
|
|
if (file == NULL || *file <= ' ')
|
|
{
|
|
_filename.temp("txtf");
|
|
_istemp = TRUE;
|
|
}
|
|
for (int i = 0; i < pagesize; i++)
|
|
_page.add(new TString(132));
|
|
_isopen = TRUE;
|
|
|
|
_instr = fopen (_filename, "a+");
|
|
_indname.temp("txti");
|
|
_index = fopen (_indname, "w+b");
|
|
|
|
if (_index == NULL || _instr == NULL)
|
|
{
|
|
yesnofatal_box ("Impossibile aprire files temporanei");
|
|
freeze ();
|
|
}
|
|
if (!_istemp)
|
|
while (!feof(_instr))
|
|
{
|
|
const long l = ftell (_instr);
|
|
fwrite (&l, sizeof (long), 1, _index);
|
|
if (ferror(_index) || ferror(_instr))
|
|
{
|
|
error_box("Errore di scrittura file temporaneo: scrittura interrotta");
|
|
freeze();
|
|
}
|
|
if (fgets (TEXT_TMP, sizeof (TEXT_TMP), _instr) == NULL)
|
|
break;
|
|
// if (TEXT_TMP[strlen(TEXT_TMP)-1] == '\n')
|
|
// TEXT_TMP[strlen(TEXT_TMP)-1] = '\0';
|
|
// if ((_lines) < (_page_start + _page_size))
|
|
// {
|
|
// TString *ll = new TString (TEXT_TMP);
|
|
// _page.add(ll);
|
|
// _page_end++;
|
|
|
|
// TBI process links
|
|
// }
|
|
_lines++;
|
|
}
|
|
}
|
|
|
|
TTextfile::~TTextfile ()
|
|
{
|
|
if (_index)
|
|
fclose (_index);
|
|
if (_instr)
|
|
fclose (_instr);
|
|
if (_istemp) remove ((const char *) _filename);
|
|
remove ((const char *) _indname);
|
|
}
|