campo-sirio/include/text.cpp
villa a0136bf864 *** empty log message ***
git-svn-id: svn://10.65.10.50/trunk@19 c028cbd2-c16b-5b4b-a496-9718f37d4682
1994-08-17 09:21:00 +00:00

473 lines
9.9 KiB
C++
Executable File

#include <text.h>
#include <fstream.h>
#include <ctype.h>
static char mytmpstr[257];
class _HotSpot : public TObject
{
public:
// TArray _spots; // tokenstrings
char _bg, _fg;
_HotSpot (char fg, char bg)
{
_fg = fg;
_bg = bg;
}
virtual ~ _HotSpot ()
{
}
};
void TTextfile::set_hotspots (char fg, char bg)
{
_HotSpot *hp = new _HotSpot (fg, bg);
_hotspots.add (hp);
}
style TTextfile::_trans_style (char ch)
{
switch (ch)
{
case 'r':
return normal;
break;
case 'i':
return italic;
break;
case 'b':
return bold;
break;
case 'u':
return underlined;
break;
case 'o':
return overstrike;
break;
case 'k':
return smallcaps;
break;
default:
return normal;
break;
}
}
void TTextfile::_read_page (long n)
{
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 (mytmpstr, sizeof (mytmpstr), _instr);
mytmpstr[strlen (mytmpstr) - 1] = '\0';
TString & ts = (TString &) _page[(int) (i - _page_start)];
ts = mytmpstr;
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);
}
}
}
void TTextfile::read_line (long n, long pos, bool pg)
{
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 == '@' || (ch == '$' && *(sp) == '['))
{
if (!first && p >= pos)
{
_styles[_item++] = stl;
mytmpstr[ndx] = '\0';
_line.add (mytmpstr);
ndx = 0;
}
while (ch && (ch == '@' || (ch == '$' && *sp == '[')))
{
if (ch == '@') // font style change ?
{
style sss = _trans_style (*sp++);
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;
mytmpstr[ndx++] = ch;
}
p++;
}
_styles[_item++] = stl;
mytmpstr[ndx] = '\0';
_line.add (mytmpstr);
_item = 0;
}
const char *TTextfile::line (long j, long pos)
{
if (_cur_line != j)
read_line (j);
*mytmpstr = '\0';
_line.restart ();
for (int i = 0; i < _line.items (); i++)
strcat (mytmpstr, (const char *) _line.get ());
return strlen (mytmpstr) > (word) pos ? &(mytmpstr[pos]) : "";
}
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 ())
{
x += strlen (c);
stl = _styles[nd++];
if ((x - 1) >= pos)
break;
}
}
return stl;
}
int TTextfile::get_style (int pos)
{
long x = get_attribute (pos);
return (int) (x & 0x0000ffff);
}
char TTextfile::get_background (int pos)
{
long x = get_attribute (pos);
return (char) (x >> 24);
}
char TTextfile::get_foreground (int pos)
{
long x = get_attribute (pos);
return (char) ((x >> 16) & 0x000000ff);
}
const char *TTextfile::piece ()
{
if (_item >= _line.items ())
return NULL;
return strcpy (mytmpstr, (const char *) _line.get (_item++));
}
const char *TTextfile::word_at (long x, long y)
{
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]))
mytmpstr[x2++] = s[(int) x++];
}
mytmpstr[x2] = '\0';
return mytmpstr;
}
bool TTextfile::append (const char *l)
{
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))
{
TString *ll = new TString (l);
_page.add (ll);
_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
}
bool TTextfile::write (const char *path, TPoint * from, TPoint * to)
{
bool ok = FALSE;
FILE *fp;
if ((fp = fopen (path, "w")) != NULL)
{
ok = TRUE;
TString256 s;
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;
}
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):
_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)
{
// open file & build index
if (file == NULL)
{
_filename.temp ();
_istemp = TRUE;
}
_instr = fopen (_filename, "a+");
_indname.temp ();
_index = fopen (_indname, "w+b");
if (_index == NULL || _instr == NULL)
{
error_box ("Impossibile aprire files temporanei");
freeze ();
}
if (file != NULL)
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 ();
}
fgets (mytmpstr, sizeof (mytmpstr), _instr);
_lines++;
}
_isopen = TRUE;
}
TTextfile::~TTextfile ()
{
if (_index)
fclose (_index);
if (_instr)
fclose (_instr);
if (_istemp)
remove ((const char *) _filename);
remove ((const char *) _indname);
}