diff --git a/xvaga/fstrcmp.c b/xvaga/fstrcmp.c index 7a33bc094..b95dc38ad 100755 --- a/xvaga/fstrcmp.c +++ b/xvaga/fstrcmp.c @@ -547,7 +547,7 @@ static void compareseq (int xoff, int xlim, int yoff, int ylim, int minimal) symbol tables occur. RETURNS - double; 0 if the strings are entirly dissimilar, 1 if the + double; 0 if the strings are entirely dissimilar, 1 if the strings are identical, and a number in between if they are similar. */ diff --git a/xvaga/fstrcmp.h b/xvaga/fstrcmp.h index 6239e2212..e5d134b14 100755 --- a/xvaga/fstrcmp.h +++ b/xvaga/fstrcmp.h @@ -20,6 +20,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _FSTRCMP_H #define _FSTRCMP_H - double fstrcmp(const char * string1, const char *string2); +#ifdef __cplusplus +extern "C" { // No mangling! +#endif + +double fstrcmp(const char * string1, const char *string2); + +#ifdef __cplusplus +} +#endif #endif diff --git a/xvaga/matche.cpp b/xvaga/matche.cpp new file mode 100755 index 000000000..35ac2fb9e --- /dev/null +++ b/xvaga/matche.cpp @@ -0,0 +1,197 @@ +#include + +#include "matche.h" + +// codici di ritorno della matche() +#define regexp_MATCH_PATTERN (6) // pattern non valido +#define regexp_MATCH_LITERAL (5) // il pattern non coincide su un carattere comune +#define regexp_MATCH_RANGE (4) // il pattern non coincide in un costrutto [..] +#define regexp_MATCH_ABORT (3) // il stringa da confrontare è terminata anticipatamente +#define regexp_MATCH_END (2) // il pattern è terminato anticipatamente +#define regexp_MATCH_VALID (1) // pattern e stringa coincidono + +// codici di ritorno della is_valid_pattern() +#define regexp_PATTERN_VALID (0) // il pattern è valido +#define regexp_PATTERN_ESC (-1) // è presente un escape aperto a fine pattern +#define regexp_PATTERN_RANGE (-2) // c'è un range non chiuso all'interno di un costrutto [..] +#define regexp_PATTERN_CLOSE (-3) // manca la parentesi di chiusura in un costrutto [..] +#define regexp_PATTERN_EMPTY (-4) // c'è un costrutto vuoto + +// prototipi delle funzioni interne +static int matche(const char *pat, const char *str); // ritorna un codice della classe regexp_MATCH che indica se e in che modo pattern e stringa coincidono +static int matche_after_star(const char *pat, const char *str); // chiama ricorsivamente la matche() con i segmenti puri del pattern e della stringa +static bool is_pattern(const char *pat); // ritorna true se la stringa è un pattern +static bool is_valid_pattern(const char *pat, int *err= NULL); // ritorna true se la stringa è un pattern valido, indica un codice di ritorno della classe regexp_PATTERN nel secondo parametro + +static bool is_pattern(const char *p) { + while (*p) { + switch (*p++) { + case '?': + case '*': + case '[': + case '\\': + return true; + } + } + return false; +} + +static bool is_valid_pattern(const char *p, int *error_type) { + if (error_type != NULL) *error_type= regexp_PATTERN_VALID; // inizializzazione del tipo d'errore + while (*p) { // ciclo all'interno del pattern fino a fine stringa + switch(*p) { // determinazione del tipo di wild card nel pattern + case '\\': // controllo dell'escape, non può essere a fine pattern + if (!*++p) { + if (error_type != NULL) *error_type= regexp_PATTERN_ESC; + return false; + } + p++; + break; + case '[': // controllo della costruzione del costrutto [..] + p++; + if (*p == ']') { // se il prossimo carattere è ']' il costrutto è vuoto + if (error_type != NULL) *error_type= regexp_PATTERN_EMPTY; + return false; + } + if (!*p) { // se si è a fine stringa il costrutto non è chiuso + if (error_type != NULL) *error_type= regexp_PATTERN_CLOSE; + return false; + } + while (*p != ']') { // ciclo fino a fine costrutto [..] + if (*p == '\\') { // controllo per gli escape + p++; + if (!*p++) { // controllo che l'escape non sia a fine pattern + if (error_type != NULL) *error_type= regexp_PATTERN_ESC; + return false; + } + } else p++; + if (!*p) { // se si è a fine stringa il costrutto non è chiuso + if (error_type != NULL) *error_type= regexp_PATTERN_CLOSE; + return false; + } + if (*p == '-') { // controllo di un eventuale range + if (!*++p || *p == ']') { // deve esistere una fine del range + if (error_type != NULL) *error_type= regexp_PATTERN_RANGE; + return false; + } else { + if (*p == '\\') p++; // controllo degli escape + if (!*p++) { // controllo che l'escape non sia a fine pattern + if (error_type != NULL) *error_type= regexp_PATTERN_ESC; + return false; + } + } + } + } + break; + case '*': // tutti gli altri caratteri sono elementi validi del pattern + case '?': + default: + p++; // caratteri normali + break; + } + } + return true; +} + +static int matche_after_star(const char *p, const char *t) { + int match= 0; + while (*p == '?' || *p == '*') { // salto degli eventuali '*' e '?' + if (*p == '?') // salto di un carattere per ciascun '?' + if (!*t++) return regexp_MATCH_ABORT; // se la stringa termina qui non c'è coincidenza + p++; // posizionamento sul prossimo carattere del pattern + } + if (!*p) return regexp_MATCH_VALID; //se il pattern è concluso c'è coincidenza + int nextp= *p; // prelevamento del prossimo carattere, normale o '[' + if (nextp == '\\') { + nextp= p[1]; + if (!nextp) return regexp_MATCH_PATTERN; // se il pattern termina qui non è valido + } + do { // ciclo fino a conclusione di stringa o pattern + if (nextp == *t || nextp == '[') match= matche(p, t); // è necessario che il carattere corrente del testo coincida con il carattere corrente del pattern, oppure che il pattern abbia un inizio di costrutto [..] + if (!*t++) match= regexp_MATCH_ABORT; // se la stringa termina qui non c'è coincidenza + } while (match != regexp_MATCH_VALID && match != regexp_MATCH_ABORT && match != regexp_MATCH_PATTERN); + return match; // ritorno del risultato +} + +static int matche(const char *p, const char *t) { + for (; *p; p++, t++) { + if (!*t) // se si è alla fine della stringa, il confronto è concluso + return (*p == '*' && *++p == '\0') ? regexp_MATCH_VALID : regexp_MATCH_ABORT; + switch (*p) { // determina il tipo di wild card del pattern + case '?': // carattere singolo, qualunque carattere coincide + break; + case '*': // sottostringa, coincide qualunque sequenza di caratteri + return matche_after_star (p, t); + case '[': { // costrutto [..], controllo di coincidenza per inclusione o esclusione su un solo carattere + p++; // posizionamento all'inizio del range + bool invert= false; // controllo di inclusione o esclusione del costrutto + if (*p == '!' || *p == '^') { + invert= true; + p++; + } + if (*p == ']') // se si è su una chiusura di costrutto il pattern non è valido + return regexp_MATCH_PATTERN; + bool member_match= false; + bool loop= true; + while (loop) { + char range_start, range_end; // inizio e fine del range corrente + if (*p == ']') { // se si è alla fine del costrutto il ciclo si conclude + loop= false; + continue; + } + if (*p == '\\') // controllo di coincidenza su un metacarattere, dopo un escape + range_start= range_end= *++p; + else + range_start= range_end= *p; + if (!*p) return regexp_MATCH_PATTERN; // se il pattern termina non è valido + if (*++p == '-') { // controllo del segno di sottoinsieme + range_end= *++p; // impostazione della fine del range + if (range_end == '\0' || range_end == ']') return regexp_MATCH_PATTERN; // se il costrutto [..] o il pattern terminano qui allora il pattern non è valido + if (range_end == '\\') { // la fine del range è un metacarattere + range_end= *++p; + if (!range_end) return regexp_MATCH_PATTERN; // se il pattern termina non è valido + } + p++; // posizionamento oltre il range + } + if (range_start < range_end) { // confronto del carattere corrente con il costrutto, controllo della sequenzialità degli estremi del range + if (*t >= range_start && *t <= range_end) { + member_match= true; + loop= false; + } + } else { + if (*t >= range_end && *t <= range_start) { + member_match= true; + loop= false; + } + } + } + if ((invert && member_match) || !(invert || member_match)) // controllo del risultato dell'ultimo confronto nel costrutto [..] + return regexp_MATCH_RANGE; + if (member_match) { // salto del resto del costrutto se non è esclusivo + while (*p != ']') { + if (!*p) return regexp_MATCH_PATTERN; // se si è a fine pattern il costrutto non è valido + if (*p == '\\') { // salto di un confronto con un metacarattere + p++; + if (!*p) return regexp_MATCH_PATTERN; // se il pattern termina qui non è valido + } + p++; // posizionamento sul prossimo carattere del pattern + } + } + break; + } + case '\\': // confronto con un metacarattere + p++; // posizionamento sul carattere da confrontare + if (!*p) return regexp_MATCH_PATTERN; // se il pattern termina qui non è valido + default: // confronto con un carattere normale + if (*p != *t) return regexp_MATCH_LITERAL; + } + } + if (*t) return regexp_MATCH_END; // se la stringa non è conclusa non c'è coincidenza + else return regexp_MATCH_VALID; +} + +bool match(const char *pat, const char *str) +{ + const int err = matche(pat, str); + return (err == regexp_MATCH_VALID); // ritorna true se il pattern e la stringa coincidono +} diff --git a/xvaga/matche.h b/xvaga/matche.h new file mode 100755 index 000000000..2be5843eb --- /dev/null +++ b/xvaga/matche.h @@ -0,0 +1 @@ +bool match(const char *pat, const char *str); diff --git a/xvaga/xvaga.cpp b/xvaga/xvaga.cpp index dde849331..168974c3b 100755 --- a/xvaga/xvaga.cpp +++ b/xvaga/xvaga.cpp @@ -1,6 +1,7 @@ #include "wxinc.h" #include "wx/clipbrd.h" +#include "wx/calctrl.h" #include "wx/colordlg.h" #include "wx/confbase.h" #include "wx/fileconf.h" @@ -16,9 +17,8 @@ #include "xvintern.h" #include "agasys.h" -extern "C" { #include "fstrcmp.h" -} +#include "matche.h" #ifdef WIN32 #include "oswin32.h" @@ -323,7 +323,7 @@ void TDC::SetDirty(int d) static int PatternToStyle(PAT_STYLE pat) { - int style; + int style = wxSOLID; switch (pat) { case PAT_NONE: @@ -337,22 +337,21 @@ static int PatternToStyle(PAT_STYLE pat) case PAT_DIAGCROSS: style = wxCROSSDIAG_HATCH; break; case PAT_RUBBER: case PAT_SPECIAL: - default: style = wxSOLID; SORRY_BOX(); break; + default: SORRY_BOX(); break; } return style; } static int PenStyleToStyle(PEN_STYLE s, PAT_STYLE p) { - int style; + int style = wxSOLID; if (p != PAT_HOLLOW) { switch (s) { - case P_DOT: style = wxDOT; break; + case P_DOT : style = wxDOT; break; case P_DASH: style = wxSHORT_DASH; break; - case P_SOLID: - default: style = wxSOLID; break; + default: break; } } else @@ -1723,6 +1722,94 @@ COLOR xvt_dm_post_choose_color(WINDOW win, COLOR xc) return xc; } + +class TwxCalendarDlg : public wxDialog +{ + enum { ID_CAL = 1883 }; + wxDateTime& m_date; + wxCalendarCtrl* m_cal; + +protected: + virtual bool TransferDataFromWindow(); + void OnCalendar(wxCalendarEvent& event); + +public: + TwxCalendarDlg(wxWindow* parent, const wxPoint& pnt, wxDateTime& date); + + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(TwxCalendarDlg, wxDialog) + EVT_CALENDAR(wxID_ANY, TwxCalendarDlg::OnCalendar) +END_EVENT_TABLE() + +void TwxCalendarDlg::OnCalendar(wxCalendarEvent& event) +{ + wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK); + AddPendingEvent(evt); +} + +bool TwxCalendarDlg::TransferDataFromWindow() +{ + bool ok = wxDialog::TransferDataFromWindow(); + if (ok) + { + m_date = m_cal->GetDate(); + } + return ok; +} + +TwxCalendarDlg::TwxCalendarDlg(wxWindow* parent, const wxPoint& pnt, wxDateTime& date) + : wxDialog(parent, wxID_ANY, "Data", pnt, wxDefaultSize, wxRAISED_BORDER), m_date(date) +{ + + m_cal = new wxCalendarCtrl(this, ID_CAL, m_date, + pnt, wxDefaultSize, + wxCAL_MONDAY_FIRST | wxCAL_SHOW_HOLIDAYS | wxCAL_SHOW_SURROUNDING_WEEKS); + + wxButton* button = new wxButton(this, wxID_OK, "OK"); + + wxGridSizer* sizer = new wxFlexGridSizer(2, 1, 8, 8); + sizer->Add(m_cal, 0, wxALIGN_CENTER); + sizer->Add(button, 0, wxALIGN_CENTER); + SetSizer(sizer); + sizer->SetSizeHints(this); +} + +unsigned int xvt_dm_post_choose_date(WINDOW win, PNT pos, unsigned int ansidate) +{ + int d = ansidate%100; + int m = (ansidate/100)%100; + int y = ansidate / 10000; + + wxDateTime date; + if (d >= 1 && d <= 31 && m >= 1 && m <= 12 && y > 1900) + date.Set(d, wxDateTime::Month(m-1), y); + else + date = wxDateTime::Today(); + + CAST_WIN(win, w); + + wxPoint pnt(pos.h, pos.v); + if (pos.h < 0 || pos.v < 0) + pnt = wxDefaultPosition; + else + pnt = w.ClientToScreen(pnt); + + wxDialog* dlg = new TwxCalendarDlg(&w, pnt, date); + + if (dlg->ShowModal() == wxID_OK) + { + d = date.GetDay(); + m = date.GetMonth()+1; + y = date.GetYear(); + ansidate = y*10000 + m*100 + d; + } + dlg->Destroy(); + + return ansidate; +} + BOOLEAN xvt_dm_post_speech(const char* text, int priority, BOOLEAN async) { BOOLEAN ok = FALSE; @@ -2092,12 +2179,12 @@ wxFont& TFontId::Font(wxDC* dc, WINDOW win) const const int cpi10 = 10 * 120 / nSize; const wxString str('M', cpi10); - int nMin = 1, nMax = nSize*15; // Limiti arbitrari + int nMin = 1, nMax = nSize*16; // Limiti arbitrari int nBest = 0; while (nMin <= nMax) { const int nFontSize = (nMin+nMax)/2; - wxFont courier(-nFontSize, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE, DEFAULT_FONT_NAME); + wxFont courier(nFontSize, wxFIXED, wxNORMAL, wxNORMAL, FALSE, DEFAULT_FONT_NAME); dc->SetFont(courier); int tw; dc->GetTextExtent(str, &tw, NULL); if (tw <= nTarget10) @@ -2113,6 +2200,7 @@ wxFont& TFontId::Font(wxDC* dc, WINDOW win) const if (nBest == 0) nBest = nMax; +/* #ifdef WIN32 // Pezza per cercare di ovviare a dimensioni assurde calcolate dai sistemi NON XP int major, minor; @@ -2135,19 +2223,14 @@ wxFont& TFontId::Font(wxDC* dc, WINDOW win) const } } #endif - +*/ dPrintScale = double(nBest) / double(nSize); #ifdef LINUX - if (is_printer_dc(dc)) // test inutile - dPrintScale /= 10.0; // * wxPostScriptDC::GetResolution()) / 72.0); + dPrintScale /= 10.0; // * wxPostScriptDC::GetResolution()) / 72.0); #endif lastDC = dc; } nSize = (int)(nSize * dPrintScale + 0.5); -#ifdef WIN32 - // In Windows rendo negativa la dimensione perche' e' piu' preciso! - nSize = -nSize; -#endif } wxFont* font = wxTheFontList->FindOrCreateFont( @@ -3911,8 +3994,10 @@ char* xvt_str_duplicate(const char* str) return str ? strdup(str) : NULL; // bleah! } -BOOLEAN xvt_str_match(const char *mbs, const char *pat, BOOLEAN case_sensitive) +BOOLEAN xvt_str_match(const char* mbs, const char *pat, BOOLEAN case_sensitive) { +/* + // Attualmente la wxString::Matches funziona solo con * e ? :-( wxString text = mbs; wxString pattern = pat; if (!case_sensitive) @@ -3920,7 +4005,16 @@ BOOLEAN xvt_str_match(const char *mbs, const char *pat, BOOLEAN case_sensitive) text.MakeUpper(); pattern.MakeUpper(); } - return text.Matches(pattern); + return text.Matches(pattern); +*/ + + // Uso la vecchia funzione implementata anticamente in agalib + if (case_sensitive) + return match(pat, mbs); + + wxString text = mbs; text.MakeUpper(); + wxString pattern = pat; pattern.MakeUpper(); + return match(pattern, text); } void xvt_str_make_upper(char* str) @@ -4696,6 +4790,8 @@ WINDOW xvt_win_create(WIN_TYPE wtype, const RCT* rct_p, const char* title, int m default: SORRY_BOX(); break; } + if (parent == SCREEN_WIN) + parent = NULL; w = new TwxWindow((wxWindow*)parent, -1, caption, pos, size, style); w->_type = wtype; diff --git a/xvaga/xvapp.cpp b/xvaga/xvapp.cpp index c7fcb2c71..3feef7677 100755 --- a/xvaga/xvapp.cpp +++ b/xvaga/xvapp.cpp @@ -4,6 +4,8 @@ extern int xvt_main(int argc, char** argv); class TMainApp : public wxApp { + wxLocale m_Locale; + protected: virtual bool OnInit(); @@ -41,6 +43,8 @@ void TMainApp::OnIdle(wxIdleEvent& event) bool TMainApp::OnInit() { + m_Locale.Init(wxLocale::GetSystemLanguage()); // wxLANGUAGE_ITALIAN + #ifdef __WXDEBUG__ // wxLog::SetTraceMask(wxTraceMessages); #endif diff --git a/xvaga/xvt.h b/xvaga/xvt.h index dfcb146d1..83d2a94bd 100755 --- a/xvaga/xvt.h +++ b/xvaga/xvt.h @@ -61,11 +61,12 @@ XVTDLL void xvt_debug_printf(const char* fmt, ...); XVTDLL ASK_RESPONSE xvt_dm_post_ask(const char* Btn1, const char*Btn2, const char* Btn3, const char* xin_buffer); XVTDLL COLOR xvt_dm_post_choose_color(WINDOW win, COLOR c); // Added by guy +XVTDLL unsigned int xvt_dm_post_choose_date(WINDOW win, PNT pos, unsigned int ansidate); // Added by guy XVTDLL void xvt_dm_post_error(const char *fmt); XVTDLL void xvt_dm_post_fatal_exit(const char *fmt); XVTDLL FL_STATUS xvt_dm_post_file_open(FILE_SPEC *fsp, const char *msg); XVTDLL FL_STATUS xvt_dm_post_file_save(FILE_SPEC *fsp, const char *msg); -XVTDLL FL_STATUS xvt_dm_post_dir_sel(DIRECTORY *dir); +XVTDLL FL_STATUS xvt_dm_post_dir_sel(DIRECTORY *dir); // Added by Luca XVTDLL BOOLEAN xvt_dm_post_font_sel(WINDOW win, XVT_FNTID font_id, PRINT_RCD *precp, unsigned long reserved); XVTDLL void xvt_dm_post_message(const char *fmt); XVTDLL void xvt_dm_post_note(const char *fmt); @@ -236,8 +237,8 @@ XVTDLL SLIST xvt_print_list_devices(); XVTDLL BOOLEAN xvt_print_set_default_device(const char* name); XVTDLL BOOLEAN xvt_print_get_default_device(char* name, int namesize); -XVTDLL int xvt_rect_get_height(RCT *rctp); -XVTDLL int xvt_rect_get_width(RCT *rctp); +XVTDLL int xvt_rect_get_height(RCT *rctp); +XVTDLL int xvt_rect_get_width(RCT *rctp); XVTDLL BOOLEAN xvt_rect_has_point(RCT *rctp, PNT pnt); XVTDLL BOOLEAN xvt_rect_intersect(RCT *drctp, RCT *rctp1, RCT *rctp2); XVTDLL BOOLEAN xvt_rect_is_empty(const RCT *rctp); @@ -336,6 +337,12 @@ XVTDLL void xvt_win_set_cursor(WINDOW win, CURSOR Cursor); XVTDLL void xvt_win_set_handler(WINDOW win, EVENT_HANDLER eh); XVTDLL void xvt_win_trap_pointer(WINDOW win); +// Added by XVAGA +typedef int ODBC_CALLBACK(void*,int,char**, char**); +XVTDLL XVT_ODBC xvt_odbc_get_connection(const char* dsn, const char* usr, const char* pwd, const char* dir); +XVTDLL BOOLEAN xvt_odbc_free_connection(XVT_ODBC handle); +XVTDLL ULONG xvt_odbc_execute(XVT_ODBC handle, const char* sql, ODBC_CALLBACK cb, void* jolly); + #ifdef __cplusplus } #endif diff --git a/xvaga/xvt_type.h b/xvaga/xvt_type.h index 0ddde0228..44fe8f15c 100755 --- a/xvaga/xvt_type.h +++ b/xvaga/xvt_type.h @@ -18,6 +18,7 @@ typedef unsigned long WINDOW; typedef unsigned int UNIT_TYPE; typedef unsigned long ULONG; typedef unsigned long XVT_ERRMSG; +typedef unsigned long XVT_ODBC; typedef wchar_t XVT_WCHAR; typedef short MENU_TAG;