From b28b209af45f1592bb6ed071ed0f5fab431916bd Mon Sep 17 00:00:00 2001 From: villa Date: Thu, 22 Jun 1995 09:30:05 +0000 Subject: [PATCH] Campi memo e merge tra text e relazione, non completamente implementate ne' meno che mai funzionanti git-svn-id: svn://10.65.10.50/trunk@1493 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- include/isam.cpp | 5 +- include/isam.h | 4 +- include/maskfld.cpp | 1 + include/memo.cpp | 15 +++++- include/stack.cpp | 1 + include/text.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++- include/text.h | 15 ++++++ 7 files changed, 144 insertions(+), 8 deletions(-) diff --git a/include/isam.cpp b/include/isam.cpp index 3f6f05185..38fc20b64 100755 --- a/include/isam.cpp +++ b/include/isam.cpp @@ -1857,9 +1857,10 @@ void TRectype::put(const char* fieldname, TTextfile& txt) TMemo_file memo(f.filename()); long id = memo.set_field(txt, isnew ? -1 : val); - if (isnew) id = val; + if (isnew) val = id; + TString16 str; str << val; - if (CPutField((char*) fieldname, rec_des(), &val, _rec) == -1) + if (CPutFieldBuff((char*) fieldname, rec_des(), (char*)(const char*)str, _rec) == -1) UNKNOWN_FIELD(num(), fieldname); setempty(FALSE); } diff --git a/include/isam.h b/include/isam.h index e0d26339f..d29d9a4cc 100755 --- a/include/isam.h +++ b/include/isam.h @@ -30,7 +30,7 @@ #endif #ifndef __TEXT_H -#include +class TTextfile; #endif // @M @@ -88,7 +88,7 @@ public: int length(const char* fieldname) const; // Ritorna lunghezza campo int ndec(const char* fieldname) const; // Ritorna numero di decimali bool exist(const char* fieldname) const; // Ritorna l'esistenza del campo - const char* fieldname(int i) const; // Ritorna il nome del campo i + const char* fieldname(int i) const; // Ritorna il nome del campo i const char* get_str(const char* fieldname) const ; #ifndef FOXPRO diff --git a/include/maskfld.cpp b/include/maskfld.cpp index 1989dd9b3..c227da96f 100755 --- a/include/maskfld.cpp +++ b/include/maskfld.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #if XVT_OS == XVT_OS_WIN #include diff --git a/include/memo.cpp b/include/memo.cpp index 459927c79..b5124554e 100755 --- a/include/memo.cpp +++ b/include/memo.cpp @@ -1,12 +1,15 @@ #include #include +#include #define HEADER_SIZE (sizeof(long)+sizeof(char)) #define INFO_SIZE (sizeof(long)+sizeof(long)) // block size used in writes // must not exceed sizeof(__tmp_string) -#define BLOCK_SIZE 1024 +#define BLOCK_SIZE (1024) +// max allowed size for locking is 100k +#define MAX_SIZE (100000l) TMemo_file::TMemo_file(const char* a) : _fname(a), _fp(NULL), _isnew(NULL) @@ -169,6 +172,10 @@ long TMemo_file::set_field(TTextfile& t, long id) // append test, update info long cnt = 0l; fseek(_fp, 0, SEEK_END); + + // lock file + _locking(_fileno(_fp), _LK_LOCK, MAX_SIZE); + fwrite(&id, sizeof(long), 1, _fp); // will overwrite later with byte count long cpos = ftell(_fp); @@ -199,7 +206,10 @@ long TMemo_file::set_field(TTextfile& t, long id) fseek(_fp, cpos, SEEK_SET); fwrite(&cnt, sizeof(long), 1, _fp); fseek(_fp, 0, SEEK_SET); - fwrite(&_id_max, sizeof(long), 1, _fp); + fwrite(&_id_max, sizeof(long), 1, _fp); + + _locking(_fileno(_fp), _LK_UNLCK, MAX_SIZE); + fflush(_fp); ret = _find_id(id) ? id : -1; } @@ -332,6 +342,7 @@ bool TMemo_file::remove_field(long id) return ok; } + bool TMemo_file::edit_field(long id) { return TRUE; diff --git a/include/stack.cpp b/include/stack.cpp index 3f46a98bf..f6ec2b7e3 100755 --- a/include/stack.cpp +++ b/include/stack.cpp @@ -8,6 +8,7 @@ void TStack::push(const TObject& o) add(o, _sp++); } + TObject& TStack::pop() { CHECK(count() > 0, "Stack underflow!"); diff --git a/include/text.cpp b/include/text.cpp index a1d03f9b4..8245891e2 100755 --- a/include/text.cpp +++ b/include/text.cpp @@ -210,7 +210,112 @@ void TTextfile::read_line (long n, long pos, bool pg) 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++; + while ((ch = *sp++) != '>') + id << ch; + // 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(); + + TString256 txt; + 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) @@ -573,7 +678,9 @@ 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), _dirty_lines(pagesize), _interactive(interactive) + _hotspots (4), _accept (TRUE), _dirty_lines(pagesize), + _interactive(interactive), _rel(NULL) + { // open file & build index if (file == NULL || *file <= ' ') diff --git a/include/text.h b/include/text.h index 5381b863c..8300a8ba0 100755 --- a/include/text.h +++ b/include/text.h @@ -14,6 +14,10 @@ #include #endif +#ifndef __RELATION_H +//class TRelation; +#include +#endif enum direction {up, down, updown}; enum style {normal = XVT_FS_NONE, bold = XVT_FS_BOLD, italic = XVT_FS_ITALIC, @@ -49,6 +53,9 @@ class TTextfile: public TObject bool _accept; bool _interactive; + // for merging with database fields + TRelation* _rel; + void _read_page(long line); bool _in_page(long l) { return l >= _page_start && l < _page_end; } @@ -63,6 +70,8 @@ public: bool changed() { return _dirty; } // line() ritorna la stringa di caratteri senza formattazione + // ed eventualmente con i campi sostituiti se la relazione + // non e' NULL const char* line(long row, long column = 0, int howmuch = -1); // line_formatted() la ritorna, come e' logico attendersi, con // la formattazione @@ -97,6 +106,7 @@ public: // ritorna la parola alla posizione indicata const char* word_at(long x, long y); + // TBI ritorna il pezzo di testo da x a y // allochera' un altro TText che deve essere disfatto dall'utente TTextfile* section(TPoint& from, TPoint& to) { return this; } @@ -124,6 +134,11 @@ public: void set_hotspots(char fg, char bg = 'w'); TArray& hotspots() { return _spots; } + // associa una relazione che viene usata (nello stato corrente) per + // risolvere eventuali campi per merge (marcati nel testo come + // <@file->fieldname@[format]@[len]@[just]> + void set_relation(TRelation* r) { _rel = r; } + TTextfile(const char* file = NULL, int pagesize = DEFAULT_PAGESIZE, direction preferred = updown, bool interactive = TRUE); virtual ~TTextfile();