campo-sirio/xvaga/xvaga.cpp
alex 566d5f1852 Patch level : 10.0 no patch
Files correlati     : pd0398.exe
Ricompilazione Demo : [ ]
Commento

E' possibile ora copiare file da e verso ftp.


git-svn-id: svn://10.65.10.50/branches/R_10_00@20986 c028cbd2-c16b-5b4b-a496-9718f37d4682
2010-10-11 14:37:18 +00:00

4566 lines
105 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "wxinc.h"
#include "xvt.h"
#include "statbar.h"
#include "agasys.h"
#include "fstrcmp.h"
#include "matche.h"
#include "xvtart.h"
#include "xvtwin.h"
#include <wx/artprov.h>
#include <wx/aui/aui.h>
#include <wx/clipbrd.h>
#include <wx/dialup.h>
#include <wx/fileconf.h>
#include <wx/filename.h>
#include <wx/image.h>
#include <wx/protocol/ftp.h>
#include <wx/protocol/http.h>
#include <wx/snglinst.h>
#include <wx/sysopt.h>
#include <wx/thread.h>
#include <wx/tokenzr.h>
#include <wx/url.h>
#include <wx/wfstream.h>
#include <errno.h>
#if wxCHECK_VERSION(2,9,0)
#include <wx/propgrid.h>
#else
#include <wx/propgrid/propgrid.h>
#endif
#ifdef __WXMSW__
#include "oswin32.h"
#include "XFont.h"
#else
#include <errno.h>
#include <unistd.h>
#include "oslinux.h"
#include <wx/dcps.h>
#endif
#define XVT_ASSERT(test) _AssertBox((test), __FUNCTION__, __FILE__, __LINE__)
wxWindow* _mouse_trapper = NULL;
RCT _startup_rect = { 0,0,0,0 };
long _startup_style = 0;
wxString _startup_dir;
wxString _strDefaultStatbarText;
wxString _appl_name;
wxString _appl_version;
wxLocale* _locale = NULL;
static XVT_ERRMSG_HANDLER _error_handler = NULL;
const wxString& _GetAppTitle()
{ return _appl_name; }
void _AssertBox(bool test, const char* func, const char* file, int line)
{
if (!test)
{
bool display = (_error_handler == NULL) || (_error_handler(SEV_FATAL, NULL) == FALSE);
if (display)
{
wxString strMessage;
strMessage.Printf("Sorry, the application passed some invalid parameters to\n"
"function %s in file %s at line %d.", func, file, line);
xvt_dm_post_error(strMessage);
}
}
}
///////////////////////////////////////////////////////////
// XVT
///////////////////////////////////////////////////////////
void xvt_app_allow_quit(void)
{
wxTheApp->ExitMainLoop(); // Già lo fa la destroy
}
XVTDLL void xvt_app_pre_create(void)
{
DIRECTORY dir;
xvt_fsys_get_default_dir(&dir); // Init Startup Directory
wxString strResPath = dir.path; strResPath += "/res";
_locale = new wxLocale(wxLANGUAGE_DEFAULT); // wxLANGUAGE_ITALIAN
_locale->AddCatalogLookupPathPrefix(strResPath);
_locale->AddCatalog("wxstd", wxLanguage(_locale->GetLanguage()), NULL);
::wxInitAllImageHandlers();
xvtart_Init();
#ifdef __WXMSW__
if (::wxDisplayDepth() >= 32 && wxTheApp->GetComCtl32Version() >= 600)
wxSystemOptions::SetOption(wxT("msw.remap"), 2);
else
wxSystemOptions::SetOption(wxT("msw.remap"), 0);
#endif
#ifdef SPEECH_API
xvt_dm_enable_speech(0xFF);
#endif
}
void xvt_app_create(int WXUNUSED(argc), char** WXUNUSED(argv), unsigned long WXUNUSED(flags),
EVENT_HANDLER eh, XVT_CONFIG* config)
{
_task_win_handler = eh;
_appl_name = config->appl_name;
const wxString title = config->taskwin_title;
wxPoint pos = wxDefaultPosition;
wxSize size = wxDefaultSize;
long style = wxDEFAULT_FRAME_STYLE;
wxWindow* pParent = NULL;
#ifdef __WXMSW__
HWND hwndParent = (HWND)OsWin32_FindMenuContainer();
if (hwndParent != NULL)
{
pParent = new wxWindow;
pParent->AssociateHandle(hwndParent);
const wxSize szWin = pParent->GetSize();
const wxSize szCli = pParent->GetClientSize();
xvt_rect_set(&_startup_rect, 0, 0, szWin.x, szWin.y);
style = wxSYSTEM_MENU; // Lo stile si riduce al minimo: niente cornici
if ((szWin.y - szCli.y) > 2) // Sposto la finestra in modo da coprire il menu del padre
_startup_rect.top -= xvt_vobj_get_attr(NULL_WIN, ATTR_MENU_HEIGHT);
}
#endif
if (_startup_rect.right > _startup_rect.left)
{
pos.x = _startup_rect.left;
pos.y = _startup_rect.top;
size.x = _startup_rect.right - _startup_rect.left;
size.y = _startup_rect.bottom - _startup_rect.top;
}
else
{
#ifdef __WXMSW__
style |= wxMAXIMIZE;
#else
style &= ~wxMAXIMIZE;
const wxRect rect = wxGetClientDisplayRect();
pos = rect.GetPosition();
size = rect.GetSize();
#endif
}
if (_startup_style & WSF_NO_TASKBAR)
style |= wxFRAME_NO_TASKBAR;
_task_win = new TTaskWin(ICON_RSRC, title, pos, size, style);
_task_win->SetBackgroundStyle(wxBG_STYLE_CUSTOM); // Lo sfondo viene disegnato nella OnPaint
_nice_windows.Put((WINDOW)_task_win, _task_win);
if (pParent != NULL)
{
_task_win->Reparent(pParent);
pParent->DissociateHandle();
pParent = NULL;
}
wxMenu* Menus[3];
wxString Title[3];
Title[0] = "&File";
Menus[0] = new wxMenu;
Menus[0]->Append(M_FILE_PG_SETUP, "&Impostazione Stampante...");
Menus[0]->Append(M_FILE_PRINT, "&Stampa");
Menus[0]->Append(M_FILE_PREVIEW, "&Anteprima");
Menus[0]->AppendSeparator();
Menus[0]->Append(M_FILE_QUIT, "&Fine");
Title[1] = "&Modifica";
Menus[1] = new wxMenu;
Menus[1]->Append(M_EDIT_CUT, "&Taglia\tCtrl+X");
Menus[1]->Append(M_EDIT_COPY, "&Copia\tCtrl+C");
Menus[1]->Append(M_EDIT_PASTE, "&Incolla\tCtrl+V");
Menus[1]->Append(M_EDIT_CLEAR, "&Elimina\tCanc");
Title[2] = "&?";
Menus[2] = new wxMenu;
Menus[2]->Append(M_HELP_CONTENTS, "&Sommario");
Menus[2]->Append(M_HELP_ONCONTEXT, "&Aiuto contestuale");
Menus[2]->AppendSeparator();
Menus[2]->Append(M_FILE_ABOUT, "&Informazioni");
wxMenuBar* pMenubar = new wxMenuBar(3, Menus, Title);
_task_win->SetMenuBar(pMenubar);
if (style & wxMAXIMIZE)
_task_win->Maximize();
_task_win->Show();
_task_win->Raise();
wxApp* a = wxTheApp;
a->SetTopWindow(_task_win);
EVENT e; memset(&e, 0, sizeof(e));
e.type = E_CREATE;
long ret = _task_win_handler((WINDOW)_task_win, &e);
if (ret != 0)
{
// Simula main loop
xvt_app_process_pending_events();
}
a->ExitMainLoop(); // Non entrare nel main loop di wxWidgets
}
void xvt_app_destroy(void)
{
wxTheApp->ExitMainLoop();
if (_task_win != NULL)
_task_win->Destroy();
#ifdef SPEECH_API
xvt_dm_enable_speech(0x00);
#endif
xvt_sign_stop();
if (_locale != NULL)
{
delete _locale;
_locale = NULL;
}
}
DRAW_CTOOLS* xvt_app_get_default_ctools(DRAW_CTOOLS *ct)
{
XVT_ASSERT(ct != NULL);
TDC dc(NULL);
memcpy(ct, &dc._dct, sizeof(DRAW_CTOOLS));
return ct;
}
void xvt_app_process_pending_events(void)
{
wxApp* a = wxTheApp; // Memorizzo il risultato di wxGetInstance
if (a != NULL) // Puo' succedere!
{
while (a->Pending())
a->Dispatch();
a->ProcessIdle(); // Necessario per wxAUI
a->Yield(true); // Non so se serva veramente
}
}
///////////////////////////////////////////////////////////
// Clipboard functions
///////////////////////////////////////////////////////////
static DATA_PTR ptrClipboardData = NULL;
char* xvt_cb_alloc_data(long size)
{
xvt_cb_free_data();
if (size > 0)
ptrClipboardData = xvt_mem_zalloc(size+1);
return ptrClipboardData;
}
BOOLEAN xvt_cb_close(void)
{
wxTheClipboard->Close();
wxTheClipboard->Flush();
return TRUE;
}
void xvt_cb_free_data(void)
{
if (ptrClipboardData != NULL)
{
xvt_mem_free(ptrClipboardData);
ptrClipboardData = NULL;
}
}
char* xvt_cb_get_data(CB_FORMAT cbfmt, char *name, long *sizep)
{
if (xvt_cb_has_format(cbfmt, name))
{
wxTextDataObject data;
wxTheClipboard->GetData(data);
*sizep = data.GetDataSize();
if (*sizep > 0)
{
xvt_cb_alloc_data(*sizep);
memcpy(ptrClipboardData, data.GetText(), *sizep);
(*sizep)--; // Elimino lo '/0' finale che non piace a XI
return ptrClipboardData;
}
}
sizep = 0;
return NULL;
}
BOOLEAN xvt_cb_has_format(CB_FORMAT fmt, char* WXUNUSED(name))
{
return (fmt == CB_TEXT) && wxTheClipboard->IsSupported(wxDF_TEXT);
}
BOOLEAN xvt_cb_open(BOOLEAN WXUNUSED(writing))
{
return wxTheClipboard->Open();
}
BOOLEAN xvt_cb_put_data(CB_FORMAT cbfmt, char* WXUNUSED(name), long WXUNUSED(size), PICTURE WXUNUSED(pic))
{
BOOLEAN ok = cbfmt == CB_TEXT && ptrClipboardData != NULL;
if (ok)
wxTheClipboard->SetData(new wxTextDataObject(ptrClipboardData));
return ok;
}
///////////////////////////////////////////////////////////
// Debug functions
///////////////////////////////////////////////////////////
void xvt_debug_printf(const char* fmt, ...)
{
#ifndef NDEBUG
static FILE* f = NULL;
if (f == NULL)
f = fopen("trace.log", "w");
if (f != NULL)
{
char msg[256];
va_list argptr;
va_start(argptr,fmt);
vsprintf(msg,fmt,argptr);
va_end(argptr);
fprintf(f, "%s\n", msg);
fflush(f);
}
#endif
}
///////////////////////////////////////////////////////////
// Dongle functions
///////////////////////////////////////////////////////////
BOOLEAN xvt_dongle_hl_crypt(unsigned short* data) // Array di 4 words (8 bytes)
{
#ifdef __WXMSW__
return OsWin32_HL_Crypt(data);
#else
return OsLinux_HL_Crypt(data);
#endif
}
BOOLEAN xvt_dongle_hl_login(unsigned short address, const unsigned char* label, const unsigned char* password)
{
#ifdef __WXMSW__
return OsWin32_HL_Login(address, label, password);
#else
return OsLinux_HL_Login(address, label, password);
#endif
}
BOOLEAN xvt_dongle_hl_logout()
{
#ifdef __WXMSW__
return OsWin32_HL_Logout();
#else
return OsLinux_HL_Logout();
#endif
}
BOOLEAN xvt_dongle_hl_read(unsigned short reg, unsigned short* data)
{
#ifdef __WXMSW__
return OsWin32_HL_Read(reg, data);
#else
return OsLinux_HL_Read(reg, data);
#endif
}
BOOLEAN xvt_dongle_hl_read_block(unsigned char* data)
{
#ifdef __WXMSW__
return OsWin32_HL_ReadBlock(data);
#else
return OsLinux_HL_ReadBlock(data);
#endif
}
BOOLEAN xvt_dongle_hl_write(unsigned short reg, unsigned short data)
{
#ifdef __WXMSW__
return OsWin32_HL_Write(reg, data);
#else
return OsLinux_HL_Write(reg, data);
#endif
}
BOOLEAN xvt_dongle_sl_crypt(unsigned short* data)
{
#ifdef __WXMSW__
return OsWin32_SL_Crypt(data);
#else
return OsLinux_SL_Crypt(data);
#endif
}
BOOLEAN xvt_dongle_sl_login(const unsigned char* label, const unsigned char* password)
{
#ifdef __WXMSW__
return OsWin32_SL_Login(label, password);
#else
return OsLinux_SL_Login(label, password);
#endif
}
BOOLEAN xvt_dongle_sl_logout()
{
#ifdef __WXMSW__
return OsWin32_SL_Logout();
#else
return OsLinux_SL_Logout();
#endif
}
BOOLEAN xvt_dongle_sl_read_block(unsigned short reg, unsigned short size, unsigned short* data)
{
#ifdef __WXMSW__
return OsWin32_SL_ReadBlock(reg, size, data);
#else
return OsLinux_SL_ReadBlock(reg, size, data);
#endif
}
BOOLEAN xvt_dongle_sl_write_block(unsigned short reg, unsigned short size, const unsigned short* data)
{
#ifdef __WXMSW__
return OsWin32_SL_WriteBlock(reg, size, data);
#else
return OsLinux_SL_WriteBlock(reg, size, data);
#endif
}
///////////////////////////////////////////////////////////
// Font cache
///////////////////////////////////////////////////////////
//WX_DECLARE_HASH_MAP(wxString, wxFont*, wxStringHash, wxStringEqual, wxFontHashMap);
WX_DECLARE_STRING_HASH_MAP(wxFont*, wxFontHashMap);
class TFontCache
{
wxFontHashMap* m_map;
public:
wxFont& FindOrCreate(int pointSize, int family, int style, int weight,
bool underline, const wxString& face);
void Destroy();
TFontCache() : m_map(NULL) { }
~TFontCache() { Destroy(); }
} XVT_FONT_CACHE;
void TFontCache::Destroy()
{
if (m_map)
{
m_map->clear();
// delete m_map; // NON funziona ma non si capisce perche': PAZIENZA!
m_map = NULL;
}
}
wxFont& TFontCache::FindOrCreate(int pointSize, int family, int style, int weight,
bool underline, const wxString& face)
{
if (m_map == NULL)
m_map = new wxFontHashMap;
wxString key;
key.Printf("%s_%d_%d_%d_%d", face, pointSize, style, weight, underline);
wxFont* pFont = (*m_map)[key];
if (pFont == NULL)
{
pFont = new wxFont(pointSize, family, style, weight, underline, face);
pFont->SetPointSize(pointSize); // Colpo di classe indispensabile per i PDF :-)
(*m_map)[key] = pFont;
}
return *pFont;
}
///////////////////////////////////////////////////////////
// Image handling
///////////////////////////////////////////////////////////
class TXVT_IMAGE : public wxImage
{
DECLARE_DYNAMIC_CLASS(TXVT_IMAGE);
int m_nDepth;
bool m_bDirty;
#ifdef __WXMSW__
HBITMAP m_bitmap;
#else
wxBitmap* m_bitmap;
#endif
protected:
void Destroy();
public:
const wxImage& Image() const { return *this; }
wxImage& Image() { m_bDirty = true; return *this; }
#ifdef __WXMSW__
HBITMAP Bitmap(wxDC& dc);
#else
const wxBitmap& Bitmap(wxDC& dc);
#endif
COLOR GetPixel(int x, int y) const;
void SetPixel(int x, int y, COLOR color);
TXVT_IMAGE() : m_bitmap(NULL), m_nDepth(0), m_bDirty(false) { }
~TXVT_IMAGE();
};
IMPLEMENT_DYNAMIC_CLASS(TXVT_IMAGE, wxImage);
#define CAST_TIMAGE(xvtimg, img) TXVT_IMAGE* img = wxDynamicCast(xvtimg, TXVT_IMAGE);
#define CAST_IMAGE(xvtimg, img) const wxImage* img = wxDynamicCast(xvtimg, wxImage);
// Chissa' perche' non esiste la GetRGB
COLOR TXVT_IMAGE::GetPixel(int x, int y) const
{
if (IsTransparent(x, y))
return XVT_MAKE_COLOR(GetMaskRed(), GetMaskGreen(), GetMaskBlue());
const long pos = XYToIndex(x, y) * 3;
unsigned char* data = GetData() + pos;
return XVT_MAKE_COLOR(data[0], data[1], data[2]);
}
void TXVT_IMAGE::SetPixel(int x, int y, COLOR color)
{
SetRGB(x, y, XVT_COLOR_GET_RED(color), XVT_COLOR_GET_GREEN(color), XVT_COLOR_GET_BLUE(color));
m_bDirty = true;
}
#ifdef __WXMSW__
HBITMAP TXVT_IMAGE::Bitmap(wxDC& dc)
{
if (m_bDirty || m_bitmap == NULL || dc.GetDepth() != m_nDepth)
{
Destroy();
m_nDepth = dc.GetDepth();
m_bitmap = OsWin32_CreateBitmap(*this, dc);
m_bDirty = false;
}
return m_bitmap;
}
#else
const wxBitmap& TXVT_IMAGE::Bitmap(wxDC& dc)
{
if (m_bDirty || m_bitmap == NULL || dc.GetDepth() != m_nDepth)
{
Destroy();
m_nDepth = dc.GetDepth();
m_bitmap = new wxBitmap(*this, m_nDepth);
m_bDirty = false;
}
return *m_bitmap;
}
#endif
void TXVT_IMAGE::Destroy()
{
if (m_bitmap != NULL)
#ifdef __WXMSW__
::DeleteObject(m_bitmap);
#else
delete m_bitmap;
#endif
m_bitmap = NULL;
}
TXVT_IMAGE::~TXVT_IMAGE()
{
Destroy();
}
///////////////////////////////////////////////////////////
// Font Handling
///////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC_CLASS(TFontId, wxObject);
void TFontId::Copy(const TFontId& rFont)
{
m_strFace = rFont.m_strFace;
m_nSize = rFont.m_nSize;
m_wMask = rFont.m_wMask;
m_win = rFont.m_win;
}
bool TFontId::IsEqual(const TFontId& rFont) const
{
if (m_strFace != rFont.m_strFace)
return false;
if (m_nSize != rFont.m_nSize)
return false;
if (m_wMask != rFont.m_wMask)
return false;
return true;
}
const char* TFontId::FaceName() const
{
if (m_strFace.IsEmpty())
return XVT_FFN_COURIER;
return m_strFace;
}
int TFontId::Family() const
{
if (m_strFace.IsEmpty() || m_strFace == XVT_FFN_COURIER)
return wxMODERN;
if (m_strFace == XVT_FFN_HELVETICA)
return wxSWISS;
if (m_strFace == XVT_FFN_TIMES)
return wxROMAN;
if (m_strFace == XVT_FFN_FIXED)
return wxMODERN;
if (m_strFace == XVT_FFN_SYSTEM)
return wxDEFAULT;
return wxSWISS;
}
int TFontId::Style() const
{
return (m_wMask & XVT_FS_ITALIC) ? wxITALIC : wxNORMAL;
}
bool TFontId::Underline() const
{
return (m_wMask & XVT_FS_UNDERLINE) != 0;
}
int TFontId::Weight() const
{
return (m_wMask & XVT_FS_BOLD) ? wxBOLD : wxNORMAL;
}
const wxFont& TFontId::Font(wxDC* dc, WINDOW win) const
{
int nSize = PointSize();
if (win == PRINTER_WIN)
{
static wxDC* lastDC = NULL;
static wxSize lastPPI;
static double dPrintScale = 1.0;
const wxSize ppi = dc->GetPPI();
if (dc != lastDC || ppi != lastPPI)
{
#ifdef __WXMSW__
const char* const DEFAULT_FONT_NAME = "Courier New";
#else
const char* const DEFAULT_FONT_NAME = "Courier";
#endif
const int nTarget10 = 10 * ppi.x; // pixel in 10 pollici in larghezza
const int cpi10 = 10 * 120 / nSize; // caratteri stimati in 10 pollici
const wxString str('M', cpi10); // stringa campione per stimare la larghezza
int nMin = 1, nMax = nSize*16; // Limiti arbitrari
int nBest = 0;
while (nMin <= nMax)
{
const int nFontSize = (nMin+nMax)/2;
wxFont courier(nFontSize, wxFIXED, wxNORMAL, wxNORMAL, false, DEFAULT_FONT_NAME);
dc->SetFont(courier);
int tw; dc->GetTextExtent(str, &tw, NULL);
if (tw <= nTarget10)
{
nMin = nFontSize+1;
nBest = nFontSize;
if (tw == nTarget10)
break;
}
else
nMax = nFontSize-1;
}
if (nBest == 0)
nBest = nMax;
#ifdef __WXMSW__
// Pezza per cercare di ovviare a dimensioni assurde calcolate dai sistemi Win *
// Praticamente succede che il Courier 70 sia piu' piccolo del Curier 60
// Per cui una volta candidata una dimensione (nBest) tramite le righe precedenti
// cerco il primo font piu' piccolo che non sfondi
bool bPrevGood = true;
for (int i = 15; i > 0; i--)
{
const int nFontSize = nBest-i;
wxFont courier(nFontSize, wxFIXED, wxNORMAL, wxNORMAL, false, DEFAULT_FONT_NAME);
dc->SetFont(courier);
int tw, th; dc->GetTextExtent(str, &tw, &th);
if (tw > nTarget10 && bPrevGood)
{
nBest = nFontSize-1;
break;
}
bPrevGood = tw <= nTarget10;
}
#endif
dPrintScale = double(nBest) / double(nSize);
#ifdef LINUX
dPrintScale /= 10.0; // * wxPostScriptDC::GetResolution()) / 72.0);
#endif
lastDC = dc;
lastPPI = ppi;
}
nSize = (int)(nSize * dPrintScale + 0.5);
}
const wxFont& ff1 = XVT_FONT_CACHE.FindOrCreate(nSize, Family(), Style(), Weight(), Underline(), FaceName());
if (ff1.GetPointSize() > 0)
return ff1;
XVT_FONT_CACHE.Destroy();
const wxFont& ff2 = XVT_FONT_CACHE.FindOrCreate(nSize, Family(), Style(), Weight(), Underline(), FaceName());
return ff2;
}
void TFontId::Copy(const wxFont& rFont)
{
m_strFace = rFont.GetFaceName();
m_nSize = rFont.GetPointSize();
m_wMask = XVT_FS_NONE;
if (rFont.GetUnderlined())
m_wMask |= XVT_FS_UNDERLINE;
if (rFont.GetWeight() >= wxBOLD)
m_wMask |= XVT_FS_BOLD;
if (rFont.GetStyle() == wxITALIC)
m_wMask |= XVT_FS_ITALIC;
m_win = NULL_WIN;
}
///////////////////////////////////////////////////////////
// Drawable windows
///////////////////////////////////////////////////////////
void xvt_dwin_clear(WINDOW win, COLOR col)
{
if (win != NULL_WIN && win != PRINTER_WIN)
{
CAST_DC(win, dc);
CAST_COLOR(col, colour);
wxBrush* brush = wxTheBrushList->FindOrCreateBrush(colour, wxSOLID);
dc.SetBackground(*brush);
dc.Clear();
}
}
void xvt_dwin_draw_arc(WINDOW win, const RCT* r, int sx, int sy, int ex, int ey)
{
if (win != NULL_WIN && r != NULL)
{
CAST_DC(win, dc);
const wxRect rect = RCT2Rect(r);
const wxPoint c(rect.x+rect.width/2, rect.y+rect.height/2);
if (abs(rect.width - rect.height) < 2)
dc.DrawArc(sx, sy, ex, ey, c.x, c.y);
else
{
const double pi = acos(-1.0);
double sa = atan2(double(c.y-sy), double(sx-c.x)) * 180 / pi; if (sa < 0) sa += 360;
double ea = atan2(double(c.y-ey), double(ex-c.x)) * 180 / pi; while (ea < sa) ea += 360;
dc.DrawEllipticArc(rect.x, rect.y, rect.width, rect.height, sa, ea);
}
}
}
void xvt_dwin_draw_gradient_circular(WINDOW win, const RCT* r, COLOR col1, COLOR col2, const PNT* center)
{
if (win != NULL_WIN && r != NULL)
{
CAST_DC(win, dc);
const wxRect rect = RCT2Rect(r);
CAST_COLOR(col1, color1);
CAST_COLOR(col2, color2);
if (center != NULL)
dc.GradientFillConcentric(rect, color1, color2, wxPoint(center->h, center->v));
else
dc.GradientFillConcentric(rect, color1, color2);
}
}
void xvt_dwin_draw_gradient_linear(WINDOW win, const RCT* r, COLOR col1, COLOR col2, int angle)
{
if (win != NULL_WIN && r != NULL)
{
CAST_DC(win, dc);
const wxRect rect = RCT2Rect(r);
CAST_COLOR(col1, color1);
CAST_COLOR(col2, color2);
angle %= 360;
if (angle < 0)
angle += 360;
wxDirection dir = wxDOWN;
switch (angle / 90)
{
case 0: dir = wxRIGHT; break;
case 1: dir = wxUP; break;
case 2: dir = wxLEFT; break;
default: dir = wxDOWN; break;
}
dc.GradientFillLinear(rect, color1, color2, dir);
}
}
void xvt_dwin_draw_icon(WINDOW win, int x, int y, int rid)
{
const wxIcon ico = xvtart_GetIconResource(rid);
if (ico.IsOk())
{
CAST_DC(win, dc);
dc.DrawIcon(ico, x, y);
}
}
void xvt_dwin_draw_icon_rect(WINDOW win, RCT* rct, int rid)
{
const int w = xvt_rect_get_width(rct);
const int h = xvt_rect_get_height(rct);
const int s = min(w/16*16, h/16*16);
if (s > 0)
{
const wxIcon ico = xvtart_GetIconResource(rid, NULL, s);
if (ico.IsOk())
{
CAST_DC(win, dc);
dc.DrawIcon(ico, rct->left+(w-s)/2, rct->top+(h-s)/2);
}
}
}
static wxRect ComputeRect(const wxRect& rct, int h, int v, int k)
{
const int sx = rct.x + h * rct.width / k;
const int ex = rct.x + (h+1) * rct.width / k;
const int sy = rct.y + v * rct.height / k;
const int ey = rct.y + (v+1) * rct.height / k;
return wxRect(sx, sy, ex-sx, ey-sy);
}
static void DrawImageOnDC(wxDC& dc, TXVT_IMAGE* image, const wxRect& dst, const wxRect& src)
{
#ifdef __WXMSW__
if (!OsWin32_DrawBitmap(image->Bitmap(dc), dc, dst, src))
{
const int k = 4;
for (int h = 0; h < k; h++)
{
for (int v = 0; v < k; v++)
{
const wxRect destin = ComputeRect(dst, h, v, k);
wxRect source = ComputeRect(src, h, v, k);
wxImage img = image->Image().GetSubImage(source);
source.x = source.y = 0;
wxBitmap bmp(img);
OsWin32_DrawBitmap((HBITMAP)bmp.GetHBITMAP(), dc, destin, source);
}
}
}
#else
const wxBitmap& bmp = image->Bitmap(dc);
const bool printing = is_printer_dc(&dc);
if (src.GetPosition() == wxPoint(0,0) && src.GetSize() == dst.GetSize() && bmp.Ok())
dc.DrawBitmap(bmp, dst.GetX(), dst.GetY(), !printing);
else
{
wxImage img = image->Image().GetSubImage(src);
if (dst.GetHeight() < src.GetHeight() ||
dst.GetWidth() < src.GetWidth())
img.Rescale(dst.GetWidth() * 4, dst.GetHeight() * 4);
img.Rescale(dst.GetWidth(), dst.GetHeight());
wxBitmap bmp(img);
dc.DrawBitmap(bmp, dst.GetX(), dst.GetY(), !printing);
}
#endif
}
void xvt_dwin_draw_image(WINDOW win, XVT_IMAGE img, const RCT* dest, const RCT* source)
{
CAST_TIMAGE(img, image);
if (image != NULL)
{
CAST_DC(win, dc);
const wxRect src = RCT2Rect(source);
const wxRect dst = RCT2Rect(dest);
DrawImageOnDC(dc, image, dst, src);
}
}
void xvt_dwin_draw_oval(WINDOW win, const RCT* rctp)
{
CAST_DC(win, dc);
const wxRect rct = RCT2Rect(rctp);
dc.DrawEllipse(rct);
}
void xvt_dwin_draw_pie(WINDOW win, const RCT *rctp,
int WXUNUSED(start_x), int WXUNUSED(start_y), int WXUNUSED(stop_x), int WXUNUSED(stop_y))
{
SORRY_BOX();
xvt_dwin_draw_oval(win, rctp);
}
void xvt_dwin_draw_polygon(WINDOW win, const PNT *lpnts, int npnts)
{
if (lpnts != NULL && npnts > 1)
{
CAST_DC(win, dc);
wxPoint* pt = new wxPoint[npnts];
for (int i = 0; i < npnts; i++)
{
pt[i].x = lpnts[i].h;
pt[i].y = lpnts[i].v;
}
dc.DrawPolygon(npnts, pt);
delete pt;
}
}
void xvt_dwin_draw_polyline(WINDOW win, const PNT *lpnts, int npnts)
{
if (win != NULL_WIN && lpnts != NULL && npnts > 1) // Occorrono almeno 2 punti
{
xvt_dwin_draw_set_pos(win, lpnts[0]);
for (int i = 1; i < npnts; i++)
xvt_dwin_draw_line(win, lpnts[i]);
}
}
void xvt_dwin_draw_rect(WINDOW win, RCT *rctp)
{
CAST_DC(win, dc);
const wxRect rct = RCT2Rect(rctp);
dc.DrawRectangle(rct);
}
void xvt_dwin_draw_roundrect(WINDOW win, const RCT *rctp, int oval_width, int oval_height)
{
CAST_DC(win, dc);
const wxRect rct = RCT2Rect(rctp);
dc.DrawRoundedRectangle(rct, min(oval_width, oval_height));
}
void xvt_dwin_draw_dotted_rect(WINDOW win, RCT *rctp)
{
#ifdef __WXMSW__
CAST_DC(win, dc);
OsWin32_DrawDottedRect(dc.GetHDC(), rctp->left, rctp->top, rctp->right, rctp->bottom);
#else
DRAW_CTOOLS dct;
xvt_dwin_get_draw_ctools(win, &dct);
CPEN pen;
pen.width = 1;
pen.pat = PAT_SOLID;
pen.style = P_DOT;
pen.color = dct.fore_color;
xvt_dwin_set_cpen(win, &pen);
CBRUSH brush;
brush.color = dct.back_color;
brush.pat = PAT_HOLLOW;
xvt_dwin_set_cbrush(win, &brush);
xvt_dwin_draw_rect(win, rctp);
xvt_dwin_set_draw_ctools(win, &dct);
#endif
}
void xvt_dwin_draw_set_pos(WINDOW win, PNT pnt)
{
CAST_TDC(win, dc);
dc._pnt.x = pnt.h;
dc._pnt.y = pnt.v;
}
// x refers to to the left of the text
// y refers to the baseline of the text
// s is the text
// len is the klenght of the text (-1 stands for all the null terminated text)
void xvt_dwin_draw_text(WINDOW win, int x, int y, const char *s, int len)
{
if (s && *s && len != 0)
{
CAST_TDC(win, tdc);
RCT rct;
const bool noclip = !tdc.GetClippingBox(&rct);
if (noclip || x < rct.right)
{
wxString str(s);
if (len >= 0)
str.Truncate(len);
wxDC& dc = tdc.GetDC(); // Prima getto il DC ...
const int delta = tdc.GetFontDelta(); // ... poi faccio la GetFontDelta!
/*
#ifndef NDEBUG
// Disegna linee base del testo
int width = ::xvt_dwin_get_text_width(win, s, len);
int leading, ascent, descent; xvt_dwin_get_font_metrics(win, &leading, &ascent, &descent);
dc.SetPen(*wxMEDIUM_GREY_PEN);
dc.DrawLine(x, y, x+width, y);
dc.SetPen(*wxCYAN_PEN);
dc.DrawLine(x, y-ascent, x+width, y-ascent);
dc.SetPen(*wxGREEN_PEN);
dc.DrawLine(x, y+descent, x+width, y+descent);
if (leading > 0)
{
dc.SetPen(*wxRED_PEN);
dc.DrawLine(x, y+descent+leading, x+width, y+descent+leading);
}
#endif
*/
dc.DrawText(str, x, y-delta);
}
}
}
RCT* xvt_dwin_get_clip(WINDOW win, RCT* rct)
{
CAST_TDC(win, dc);
dc.GetClippingBox(rct);
return rct;
}
DRAW_CTOOLS* xvt_dwin_get_draw_ctools(WINDOW win, DRAW_CTOOLS* ctoolsp)
{
CAST_TDC(win, dc);
memcpy(ctoolsp, &dc._dct, sizeof(DRAW_CTOOLS));
return ctoolsp;
}
XVT_FNTID xvt_dwin_get_font(WINDOW win)
{
CAST_TDC(win, dc);
TFontId* pFont = new TFontId(dc._font);
return pFont;
}
void xvt_dwin_get_font_metrics(WINDOW win, int *leadingp, int *ascentp, int *descentp)
{
// Attenzione: non funziona la chiamate in cascata a xvt_font_get_metrics
CAST_DC(win, dc);
const wxString str = "Kpfx";
int height, desc, lead;
dc.GetTextExtent(str, NULL, &height, &desc, &lead);
if (leadingp)
*leadingp = lead;
if (ascentp)
*ascentp = height-desc;
if (descentp)
*descentp = desc;
}
long xvt_dwin_get_font_size_mapped(WINDOW win)
{
CAST_WIN(win, dc);
const wxFont& font = dc.GetFont();
int height = font.GetPointSize();
return height;
}
int xvt_dwin_get_text_width(WINDOW win, const char *s, int len)
{
int width = 0;
if (s && *s && len != 0)
{
CAST_DC(win, dc);
wxString str = s;
if (str.StartsWith("ABCDEFGH") || str.StartsWith("MMMMMMMM"))
{
const wxString emme('G', str.Length()); // Questa lettera cambia con le mode
str = emme;
}
if (len > 0)
str.Truncate(len);
int height = 0;
dc.GetTextExtent(str, &width, &height);
}
return width;
}
void xvt_dwin_invalidate_rect(WINDOW win, const RCT* rctp)
{
if (win != NULL_WIN)
{
CAST_WIN(win, w);
if (rctp != NULL)
{
const wxRect rct = RCT2Rect(rctp);
w.Refresh(false, &rct);
}
else
w.Refresh(false);
}
}
BOOLEAN xvt_dwin_is_update_needed(WINDOW win, const RCT* rctp)
{
if (win != NULL_WIN && rctp != NULL)
{
if (win == PRINTER_WIN || win == SCREEN_WIN)
return TRUE;
CAST_WIN(win, w); // child windows and TASK_WIN
const wxRect rect1 = RCT2Rect(rctp);
const wxRect rect2 = w.GetUpdateClientRect();
return rect1.Intersects(rect2);
}
return FALSE;
}
void xvt_dwin_scroll_rect(WINDOW win, RCT *rctp, int dh, int dv)
{
if (dh != 0 || dv != 0)
{
CAST_WIN(win, w);
if (rctp != NULL)
{
const wxRect rct = RCT2Rect(rctp);
if (!rct.IsEmpty())
// w.ScrollWindow(dh, dv, &rct); // Metodo ortodosso ma impreciso di un pixel
w.Refresh(false, &rct); // Pezza "TEMPORANEA" per evitare artefatti
}
else
w.ScrollWindow(dh, dv);
}
}
void xvt_dwin_set_back_color(WINDOW win, COLOR color)
{
CAST_TDC(win, dc);
dc._dct.back_color = color;
dc.SetDirty();
}
void xvt_dwin_set_cbrush(WINDOW win, CBRUSH* cbrush)
{
CAST_TDC(win, dc);
memcpy(&dc._dct.brush, cbrush, sizeof(CBRUSH));
dc.SetDirty();
}
void xvt_dwin_set_clip(WINDOW win, const RCT* rctp)
{
CAST_TDC(win, dc);
dc.SetClippingBox(rctp);
dc.SetDirty();
}
void xvt_dwin_set_cpen(WINDOW win, CPEN* cpen)
{
CAST_TDC(win, dc);
memcpy(&dc._dct.pen, cpen, sizeof(CPEN));
dc.SetDirty();
}
void xvt_dwin_set_draw_ctools(WINDOW win, DRAW_CTOOLS* xct)
{
CAST_TDC(win, dc);
memcpy(&dc._dct, xct, sizeof(DRAW_CTOOLS));
dc.SetDirty();
}
void xvt_dwin_set_draw_mode(WINDOW win, DRAW_MODE mode)
{
CAST_TDC(win, dc);
dc._dct.mode = mode;
dc.SetDirty();
}
void xvt_dwin_set_font(WINDOW win, XVT_FNTID font_id)
{
CAST_TDC(win, dc);
CAST_FONT(font_id, font);
if (dc._font != font)
{
dc._font = font;
dc.SetDirty();
}
}
void xvt_dwin_set_fore_color(WINDOW win, COLOR color)
{
CAST_TDC(win, dc);
dc._dct.fore_color = color;
dc.SetDirty();
}
void xvt_dwin_set_std_cbrush(WINDOW win, long flag)
{
CBRUSH brush;
brush.pat = PAT_SOLID;
switch (flag)
{
case TL_BRUSH_BLACK: brush.color = COLOR_BLACK; break;
case TL_BRUSH_WHITE: brush.color = COLOR_WHITE; break;
default: SORRY_BOX(); break;
}
xvt_dwin_set_cbrush(win, &brush);
}
void xvt_dwin_set_std_cpen(WINDOW win, long flag)
{
CPEN pen; memset(&pen, 0, sizeof(CPEN));
pen.style = P_SOLID;
pen.pat = PAT_SOLID;
switch(flag)
{
case TL_PEN_BLACK : pen.color = COLOR_BLACK; break;
case TL_PEN_DKGRAY: pen.color = COLOR_DKGRAY; break;
case TL_PEN_GRAY : pen.color = COLOR_GRAY; break;
case TL_PEN_LTGRAY: pen.color = COLOR_LTGRAY; break;
case TL_PEN_WHITE : pen.color = COLOR_WHITE; break;
case TL_PEN_HOLLOW: pen.pat = PAT_HOLLOW; break;
case TL_PEN_RUBBER: pen.pat = PAT_RUBBER; break;
default: SORRY_BOX(); break;
}
xvt_dwin_set_cpen(win, &pen);
}
void xvt_dwin_draw_line(WINDOW win, PNT pnt)
{
CAST_TDC(win, tdc);
const wxPoint to(pnt.h, pnt.v);
if (tdc._pnt != to)
{
wxDC& dc = tdc.GetDC();
dc.DrawLine(tdc._pnt, to);
// dc.DrawPoint(to); // Non scommentare o cancellare: Un giorno capiro' il perche' servisse
}
tdc._pnt = to;
}
void xvt_dwin_update(WINDOW win)
{
CAST_WIN(win, w);
w.Update();
}
///////////////////////////////////////////////////////////
// Debug functions
///////////////////////////////////////////////////////////
XVT_ERRSEV xvt_errmsg_get_sev_id(XVT_ERRMSG err)
{
return (XVT_ERRSEV)err;
}
///////////////////////////////////////////////////////////
// Fonts
///////////////////////////////////////////////////////////
void xvt_font_copy(XVT_FNTID dest_font_id, XVT_FNTID src_font_id, XVT_FONT_ATTR_MASK mask)
{
XVT_ASSERT(dest_font_id && src_font_id && mask == XVT_FA_ALL);
CAST_FONT(dest_font_id, dst);
CAST_FONT(src_font_id, src);
dst = src;
}
XVT_FNTID xvt_font_create(void)
{
TFontId* pFont = new TFontId;
return (XVT_FNTID)pFont;
}
void xvt_font_deserialize(XVT_FNTID font_id, const char* buf)
{
// 01\\Courier\\0\\10\\WIN01/-13/0/0/0/400/0/0/0/0/1/2/1/49/Courier
CAST_FONT(font_id, font)
const char* s = strchr(buf, '/');
if (s == NULL)
return;
const int nSize = atoi(s+1);
if (nSize > 0)
font.SetPointSize(nSize);
else
font.SetPointSize(-nSize * 10 / 13);
// Ignore 4 fields
int i;
for (i = 0; i < 4; i++)
{
s = strchr(s+1, '/');
if (s == NULL)
return;
}
s++;
const int nWeight = atoi(s);
if (nWeight >= 600)
font.SetMask(font.Mask() | XVT_FS_BOLD);
s = strchr(s, '/');
if (s == NULL)
return;
const int nItalic = atoi(s+1);
if (nItalic)
font.SetMask(font.Mask() | XVT_FS_ITALIC);
// Ignore 8 fields
for (i = 0; i < 8; i++)
{
s = strchr(s+1, '/');
if (s == NULL)
return;
}
font.SetFaceName(s+1);
font.SetWin(NULL_WIN);
}
void xvt_font_destroy(XVT_FNTID font_id)
{
TFontId* fp = wxDynamicCast(font_id, TFontId);
if (fp != NULL)
delete fp;
}
BOOLEAN xvt_font_get_family(XVT_FNTID font_id, char* buf, long max_buf)
{
BOOLEAN ok = font_id != NULL && buf != NULL && max_buf > 0;
if (ok)
{
CAST_FONT(font_id, font);
wxStrncpy(buf, font.FaceName(), max_buf);
buf[max_buf-1] = '\0';
}
return ok;
}
BOOLEAN xvt_font_get_family_mapped(XVT_FNTID font_id, char* buf, long max_buf)
{ return xvt_font_get_family(font_id, buf, max_buf); }
void xvt_font_get_metrics(XVT_FNTID font_id, int *leadingp, int *ascentp, int *descentp)
{
CAST_FONT(font_id, font);
WINDOW win = font.Win();
if (win != PRINTER_WIN)
win = TASK_WIN; // Non mi fido troppo della finestra su cui il font e' mappato
CAST_DC(win, dc);
const wxString str = "Kpfx";
int height = 0, desc = 0, lead = 0;
const wxFont& ff = font.Font(&dc, win);
dc.GetTextExtent(str, NULL, &height, &desc, &lead, (wxFont*)&ff);
if (height <= 0 || height > 64000) // Gestisce eventuali anomalie alla meno peggio
{
wxASSERT(false);
height = ff.GetPointSize();
desc = height / 5;
lead = 0;
}
if (leadingp)
*leadingp = lead;
if (ascentp)
*ascentp = height-desc; //*ascentp = height-desc-lead;
if (descentp)
*descentp = desc;
}
BOOLEAN xvt_font_get_native_desc(XVT_FNTID font_id, char *buf, long max_buf)
{
const long len = xvt_font_serialize(font_id, buf, max_buf);
return len > 0 && len < max_buf;
}
long xvt_font_get_size(XVT_FNTID font_id)
{
CAST_FONT(font_id, font);
return font.PointSize();
}
XVT_FONT_STYLE_MASK xvt_font_get_style(XVT_FNTID font_id)
{
CAST_FONT(font_id, font);
return font.Mask();
}
WINDOW xvt_font_get_win(XVT_FNTID font_id)
{
CAST_FONT(font_id, font);
return font.Win();
}
BOOLEAN xvt_font_is_mapped(XVT_FNTID font_id)
{
return xvt_font_get_win(font_id) != NULL_WIN;
}
void xvt_font_map(XVT_FNTID font_id, WINDOW win)
{
CAST_FONT(font_id, font);
font.SetWin(win);
}
void xvt_font_map_using_default(XVT_FNTID font_id)
{
xvt_font_map(font_id, TASK_WIN);
}
void xvt_font_set_family(XVT_FNTID font_id, const char* family)
{
CAST_FONT(font_id, font);
font.SetFaceName(family);
}
void xvt_font_set_size(XVT_FNTID font_id, long size)
{
CAST_FONT(font_id, font);
font.SetPointSize(size);
}
void xvt_font_set_style(XVT_FNTID font_id, XVT_FONT_STYLE_MASK mask)
{
CAST_FONT(font_id, font);
font.SetMask(mask);
}
long xvt_font_serialize(XVT_FNTID font_id, char *buf, long max_buf)
{
// 01\\Courier\\0\\10\\WIN01/-13/0/0/0/400/0/0/0/0/1/2/1/49/Courier
CAST_FONT(font_id, font);
const char* name = font.FaceName();
const int size = font.PointSize();
const int italic = (font.Mask() & XVT_FS_ITALIC) != 0;
const int weight = (font.Mask() & XVT_FS_BOLD) ? 700 : 400;
wxString str;
str.Printf("01\\%s\\0\\%d\\WIN01/%d/%d/0/0/%d/0/0/0/0/0/0/0/0/%s",
name, size, size, weight, italic, name);
if (buf != NULL && max_buf > 0)
{
wxStrncpy(buf, str, max_buf);
buf[max_buf-1] = '\0';
}
return str.Len();
}
void xvt_font_unmap(XVT_FNTID font_id)
{
CAST_FONT(font_id, font);
font.SetWin(NULL_WIN);
}
///////////////////////////////////////////////////////////
// File system
///////////////////////////////////////////////////////////
BOOLEAN xvt_fsys_build_pathname(char* mbs, const char* volname, const char* dirname, const char* leafroot, const char* leafext, const char* /* leafvers */)
{
#ifdef __WXMSW__
_makepath(mbs, volname, dirname, leafroot, leafext);
#else
*mbs = '\0';
if (dirname && *dirname)
strcpy(mbs, dirname);
if (leafroot && *leafroot)
{
if (!wxEndsWithPathSeparator(mbs) && !wxIsPathSeparator(*leafroot))
strcat(mbs, "/");
strcat(mbs, leafroot);
}
if (leafext && *leafext)
{
if (*leafext != '.')
strcat(mbs, ".");
strcat(mbs, leafext);
}
#endif
return TRUE;
}
BOOLEAN xvt_fsys_parse_pathname(const char* mbs, char* volname, char* dirname, char* leafroot, char* leafext, char* leafvers)
{
wxString volume, path, file, ext;
wxFileName::SplitPath(mbs, &volume, &path, &file, &ext);
if (volname)
{
if (mbs[0] == mbs[1] && wxIsPathSeparator(mbs[0]))
{
volume.insert(size_t(0), size_t(2), wxFILE_SEP_PATH); // Mette due slash all'inizio
if (!wxIsPathSeparator(path[0]))
volume << wxFILE_SEP_PATH; // Accoda uno slash
path.insert(0, volume);
*volname = '\0';
}
else
{
wxStrcpy(volname, volume);
#ifdef __WXMSW__
if (volname[0] != '\0' && volname[1] == '\0')
wxStrcat(volname, ":");
#endif
}
}
if (dirname) strcpy(dirname, path);
if (leafroot) strcpy(leafroot, file);
if (leafext) strcpy(leafext, ext);
if (leafvers) strcpy(leafvers, ""); // TBI put here last change date/time?
return true;
}
BOOLEAN xvt_fsys_convert_dir_to_str(DIRECTORY* dirp, char* path, int sz_path)
{
BOOLEAN ok = dirp != NULL && path != NULL && sz_path > 0;
if (ok)
{
wxStrncpy(path, dirp->path, sz_path-1);
path[sz_path-1] = '\0';
}
return ok;
}
BOOLEAN xvt_fsys_convert_str_to_dir(const char *path, DIRECTORY *dirp)
{
BOOLEAN ok = path != NULL && dirp != NULL;
if (ok)
{
const int sz = sizeof(dirp->path)-1;
wxStrncpy(dirp->path, path, sz);
dirp->path[sz] = '\0';
}
return ok;
}
BOOLEAN xvt_fsys_convert_fspec_to_str(const FILE_SPEC *fs, char *path, int sz_path)
{
BOOLEAN ok = FALSE;
if (fs != NULL && path != NULL && sz_path > 0)
{
char mbs[_MAX_PATH];
xvt_fsys_build_pathname(mbs, "", fs->dir.path, fs->name, fs->type, NULL);
wxStrncpy(path, mbs, sz_path);
ok = *path > ' ';
}
return ok;
}
BOOLEAN xvt_fsys_convert_str_to_fspec(const char *mbs, FILE_SPEC *fs)
{
BOOLEAN ok = FALSE;
if (fs != NULL)
{
memset(fs, 0, sizeof(FILE_SPEC));
wxStrcpy(fs->creator, "CAMPO");
if (mbs && *mbs)
{
char volume[_MAX_DRIVE], path[_MAX_PATH];
xvt_fsys_parse_pathname(mbs, volume, path, fs->name, fs->type, NULL);
wxStrcpy(fs->dir.path, volume);
wxStrcat(fs->dir.path, path);
ok = fs->name[0] != '\0';
}
}
return ok;
}
void xvt_fsys_get_default_dir(DIRECTORY *dirp)
{
if (_startup_dir.IsEmpty())
_startup_dir = ::wxGetCwd();
xvt_fsys_convert_str_to_dir(_startup_dir, dirp);
}
BOOLEAN xvt_fsys_get_dir(DIRECTORY *dirp)
{
return xvt_fsys_convert_str_to_dir(::wxGetCwd(), dirp);
}
static wxString get_disk_root(const char* path)
{
wxString str;
if (path && *path)
{
str = path;
if (!wxEndsWithPathSeparator(str))
str << wxFILE_SEP_PATH;
wxChar drive[_MAX_DRIVE], dir[_MAX_DIR];
xvt_fsys_parse_pathname(str,drive,dir,NULL,NULL,NULL);
if (*drive)
str = drive;
else
str = dir;
if (!wxEndsWithPathSeparator(str))
str << wxFILE_SEP_PATH;
}
return str;
}
// Il disco e' un floppy?
BOOLEAN xvt_fsys_is_floppy_drive(const char* path)
{
BOOLEAN yes = xvt_fsys_is_removable_drive(path);
if (yes)
{
const unsigned long mb = xvt_fsys_get_disk_size(path, 'M'); // Dimensioni in Mb
yes = mb < 4; // E' un vero floppy solo se e' piu' piccolo di 4 Mb
}
return yes;
}
// Il disco e' rimuovibile? (floppy / memory stick)
BOOLEAN xvt_fsys_is_removable_drive(const char* path)
{
BOOLEAN yes = FALSE;
if (path && *path)
{
#ifdef __WXMSW__
const wxString strRoot = get_disk_root(path);
yes = ::GetDriveType(strRoot) == DRIVE_REMOVABLE;
#else
char dev[_MAX_PATH];
OsLinux_GetFileSys(path, dev, NULL, NULL);
yes = strncmp(dev, "/dev/fd", 7) == 0;
#endif
}
return yes;
}
BOOLEAN xvt_fsys_is_network_drive(const char* path)
{
BOOLEAN yes = FALSE;
if (path && *path)
{
if (wxIsPathSeparator(path[0]) && wxIsPathSeparator(path[1]))
yes = TRUE;
else
{
#ifdef __WXMSW__
const wxString strRoot = get_disk_root(path);
yes = ::GetDriveType(strRoot) == DRIVE_REMOTE;
#else
yes = OsLinux_IsNetworkDrive(path);
#endif
}
}
return yes;
}
BOOLEAN xvt_fsys_is_fixed_drive(const char* path)
{
BOOLEAN yes = FALSE;
if (path && *path)
{
if (!wxIsPathSeparator(path[0]) || !wxIsPathSeparator(path[1]))
{
#ifdef __WXMSW__
const wxString strRoot = get_disk_root(path);
yes = ::GetDriveType(strRoot) == DRIVE_FIXED;
#else
yes = !(xvt_fsys_is_network_drive(path) || xvt_fsys_is_removable_drive(path));
#endif
}
}
return yes;
}
static unsigned long compute_disk_size(const char* path, bool tot, char unit)
{
long nVal = 0;
if (path && *path)
{
const wxString strRoot = get_disk_root(path);
wxLongLong total = 0, unused = 0;
wxGetDiskSpace(strRoot, &total, &unused);
__int64 nBytes = tot ? total.ToDouble() : unused.ToDouble();
if (nBytes > 0)
{
switch (unit)
{
case 'K': nBytes >>= 10; break; // Kilobytes
case 'M': nBytes >>= 20; break; // Megabytes
case 'G': nBytes >>= 30; break; // Gigabytes
case 'T': nBytes >>= 40; break; // Terabytes
default : break;
}
const unsigned long nMax = (unsigned long)(~0L);
nVal = nBytes > nMax ? nMax : (unsigned long)nBytes;
}
}
return nVal;
}
unsigned long xvt_fsys_get_disk_size(const char* path, char unit)
{
return compute_disk_size(path, true, unit);
}
unsigned long xvt_fsys_get_disk_free_space(const char* path, char unit)
{
return compute_disk_size(path, false, unit);
}
BOOLEAN xvt_fsys_test_disk_free_space(const char* path, unsigned long filesize)
{
// Arrotonda per eccesso al Kilobyte
unsigned long kb = filesize/1024+4;
return kb <= xvt_fsys_get_disk_free_space(path, 'K');
}
// Usr friendly implementation
long xvt_fsys_file_attr(const char* path, long attr)
{
long ret = 0;
if (path && *path && attr >= XVT_FILE_ATTR_MINIMUM && attr <= XVT_FILE_ATTR_MAXIMUM)
{
const wxString name(path);
switch (attr)
{
case XVT_FILE_ATTR_EXIST:
ret = xvt_fsys_access(path, 0) == 0;
break;
case XVT_FILE_ATTR_READ:
ret = xvt_fsys_access(path, 1) == 0;
break;
case XVT_FILE_ATTR_WRITE:
ret = xvt_fsys_access(path, 2) == 0;
break;
case XVT_FILE_ATTR_DIRECTORY:
ret = ::wxDirExists(name);
break;
case XVT_FILE_ATTR_SIZE:
{
wxURL url(path);
wxString scheme = url.GetScheme();
if (scheme == "ftp" || scheme == "http")
{
SLIST files = xvt_fsys_list_files("", path, false);
const int count = xvt_slist_count(files);
if (count > 0)
{
SLIST_ELT e = xvt_slist_get_first(files);
ret = e->data;
}
else
ret = -1L;
xvt_slist_destroy(files);
return ret;
}
const wxULongLong sz = wxFileName::GetSize(name);
ret = sz.GetHi() != 0 ? INT_MAX : sz.GetLo();
}
break;
case XVT_FILE_ATTR_MTIME:
ret = ::wxFileModificationTime(name);
break;
default: break;
}
}
return ret;
}
// Original XVT implementation
long xvt_fsys_get_file_attr(const FILE_SPEC* fs, long attr)
{
char mbs[_MAX_PATH]; xvt_fsys_convert_fspec_to_str(fs, mbs, sizeof(mbs));
return xvt_fsys_file_attr(mbs, attr);
}
///////////////////////////////////////////////////////////
// File system
///////////////////////////////////////////////////////////
SLIST xvt_fsys_list_files(const char *type, const char *pat, BOOLEAN dirs)
{
SLIST list = xvt_slist_create();
int flags = 0;
if (dirs)
{
if (strcmp(type, DIR_TYPE) == 0)
flags = wxDIR;
}
else
flags = wxFILE;
wxURL url(pat);
if (url.GetScheme() == "ftp")
{
const wxString strHost = url.GetServer();
const wxString strUser = url.GetUser();
const wxString strPwd = url.GetPassword();
const wxFileName fnPath = url.GetPath();
const wxString fnDir = fnPath.GetPath(wxPATH_GET_VOLUME, wxPATH_UNIX);
const wxString fnName = fnPath.GetFullName();
wxString RemotePath(pat);
const int mask = dirs ? (strcmp(type, DIR_TYPE) == 0 ? 2 : 3) : 1;
wxFTP ftp;
RemotePath = RemotePath.BeforeLast('/');
if (!strUser.IsEmpty())
{
ftp.SetUser(strUser);
ftp.SetPassword(strPwd);
}
if (ftp.Connect(strHost))
if (ftp.ChDir(fnDir))
{
wxArrayString files;
ftp.GetDirList(files, fnName);
for (size_t i = 0; i < files.GetCount(); i++)
{
int type = files[i][0] == 'd' ? 2 : 1;
if (type & mask)
{
wxString f(RemotePath);
f << '/' << files[i].AfterLast(' ');
wxString size = files[i].Mid(30);
xvt_slist_add_at_elt(list, NULL, f, type == 2 ? -1 : wxAtol(size));
}
}
}
}
else //normale list_files
{
wxString f = ::wxFindFirstFile(pat, flags);
while (!f.IsEmpty())
{
if (f.StartsWith(".\\") || f.StartsWith("./"))
f = f.Mid(2);
xvt_slist_add_at_elt(list, NULL, f, 0L);
f = ::wxFindNextFile();
}
}
return list;
}
static wxString _strSavedir;
void xvt_fsys_restore_dir()
{
wxASSERT(!_strSavedir.IsEmpty());
::wxSetWorkingDirectory(_strSavedir);
_strSavedir = wxEmptyString;
}
void xvt_fsys_save_dir()
{
wxASSERT(_strSavedir.IsEmpty());
_strSavedir = ::wxGetCwd();
}
BOOLEAN xvt_fsys_set_dir(const DIRECTORY *dirp)
{
return ::wxSetWorkingDirectory(dirp->path);
}
BOOLEAN xvt_fsys_fcopy(const char* orig, const char* dest)
{
wxURL orig_url(orig);
wxURL dest_url(dest);
wxInputStream * input = orig_url.GetInputStream();
wxOutputStream * output = NULL;
wxString scheme = dest_url.GetScheme();
if (input == NULL)
input = new wxFileInputStream(orig);
if (scheme == "ftp")
{
wxFTP ftp;
const wxString strHost = dest_url.GetServer();
const wxString strUser = dest_url.GetUser();
const wxString strPwd = dest_url.GetPassword();
const wxFileName fnPath = dest_url.GetPath();
const wxString fnDir = fnPath.GetPath(wxPATH_GET_VOLUME, wxPATH_UNIX);
const wxString fnName = fnPath.GetFullName();
if (!strUser.IsEmpty())
{
ftp.SetUser(strUser);
ftp.SetPassword(strPwd);
}
if (ftp.Connect(strHost))
if (ftp.SetBinary())
if (ftp.ChDir(fnDir))
output = ftp.GetOutputStream(fnName);
}
else
if (scheme == "http")
return false;
/* {
const wxString strHost = dest_url.GetServer();
const wxString strUser = dest_url.GetUser();
const wxString strPwd = dest_url.GetPassword();
const wxFileName fnPath = dest_url.GetPath();
wxHTTP http;
if (!strUser.IsEmpty())
{
http.SetUser(strUser);
http.SetPassword(strPwd);
}
http.SetHeader(_T("Content-type"), _T("application/x-www-form-urlencoded")); //remember to define “Content-type: application/x-www-form-urlencoded”, or remote server cant get your posted data.
wxString PostData("postdata=");
PostData << fnPath.GetFullPath();
http.SetPostBuffer(PostData); //its the data to be posted
bool httpok = false;
if (http.Connect(strHost))
{
wxInputStream *httpStream = http.GetInputStream(_T("/getfile.php"));
httpok = http.GetError() == wxPROTO_NOERR;
wxDELETE(httpStream);
}
return httpok;
} */
else
output = new wxFileOutputStream(dest);
bool ok = false;
if (input != NULL && output != NULL)
{
input->Read(*output);
wxStreamError err = output->GetLastError();
ok = (err == wxSTREAM_NO_ERROR);
}
if (input != NULL)
delete input;
if (output != NULL)
delete output;
return ok;
}
///////////////////////////////////////////////////////////
// Images
///////////////////////////////////////////////////////////
inline bool XVT_SAME_COLOR(COLOR col1, COLOR col2) { return (col1 & 0x00FFFFFF) == (col2 & 0x00FFFFFF); }
void xvt_image_blur(XVT_IMAGE img, short radius)
{
CAST_TIMAGE(img, image);
image->Blur(radius);
}
XVT_IMAGE xvt_image_capture(WINDOW win, const RCT* src)
{
wxRect r;
if (src == NULL)
{
RCT rct; xvt_vobj_get_client_rect(win, &rct);
r = RCT2Rect(&rct);
}
else
r = RCT2Rect(src);
wxBitmap bmp(r.GetWidth(), r.GetHeight());
CAST_DC(win, wdc);
wxMemoryDC mdc(bmp);
mdc.Blit(wxPoint(0,0), r.GetSize(), &wdc, r.GetPosition());
TXVT_IMAGE* i = new TXVT_IMAGE;
i->Image() = bmp.ConvertToImage();
return (XVT_IMAGE)i;
}
XVT_IMAGE xvt_image_create(XVT_IMAGE_FORMAT WXUNUSED(format), short width, short height, COLOR color)
{
TXVT_IMAGE* i = new TXVT_IMAGE;
i->Image().Create(width, height);
if (color != COLOR_INVALID)
{
CAST_COLOR(color, rgb);
#if wxCHECK_VERSION(2,9,0)
if (rgb.Red() == rgb.Green() && rgb.Green() == rgb.Blue())
i->Image().Clear(rgb.Red());
else
#endif
{
const wxRect rct(0, 0, width, height);
i->Image().SetRGB(rct, rgb.Red(), rgb.Green(), rgb.Blue());
}
}
return (XVT_IMAGE)i;
}
void xvt_image_destroy(XVT_IMAGE img)
{
CAST_TIMAGE(img, image);
if (image != NULL)
delete image;
}
int xvt_image_find_clut_index(XVT_IMAGE img, COLOR rgb)
{
CAST_IMAGE(img, image);
int i = -1;
if (image && image->Ok() && image->HasPalette())
{
const wxPalette& pal = image->GetPalette();
for (i = 255; i >= 0; i--)
{
unsigned char ri, gi, bi;
if (pal.GetRGB(i, &ri, &gi, &bi))
{
const COLOR rgbi = XVT_MAKE_COLOR(ri, gi, bi);
if ((rgbi & 0x00FFFFFF) == (rgb & 0x00FFFFFF))
break;
}
}
}
return i;
}
COLOR xvt_image_get_clut(XVT_IMAGE img, short index)
{
CAST_IMAGE(img, image);
if (image && image->Ok() && image->HasPalette())
{
const wxPalette& pal = image->GetPalette();
unsigned char r, g, b;
if (pal.GetRGB(index, &r, &g, &b))
return XVT_MAKE_COLOR(r, g, b);
}
return COLOR_INVALID;
}
void xvt_image_get_dimensions(XVT_IMAGE image, short* width, short* height)
{
*width = *height = 0;
CAST_IMAGE(image, img);
if (img != NULL && img->Ok())
{
*width = img->GetWidth();
*height = img->GetHeight();
}
}
XVT_IMAGE_FORMAT xvt_image_get_format(XVT_IMAGE image)
{
CAST_IMAGE(image, img);
if (img != NULL && img->Ok())
return img->HasPalette() ? XVT_IMAGE_CL8 : XVT_IMAGE_RGB;
return XVT_IMAGE_NONE;
}
short xvt_image_get_ncolors(XVT_IMAGE image)
{
int n = 0;
if (xvt_image_get_format(image) == XVT_IMAGE_CL8)
{
CAST_IMAGE(image, i);
const wxPalette& pal = i->GetPalette();
unsigned char r, g, b;
for (n = 16; n < 256; n++)
{
if (!pal.GetRGB(n, &r, &g, &b))
break;
}
}
return n;
}
COLOR xvt_image_get_pixel(XVT_IMAGE image, short x, short y)
{
CAST_TIMAGE(image, i);
if (i != NULL && i->Ok())
return i->GetPixel(x, y);
return COLOR_INVALID;
}
XVT_IMAGE xvt_image_read(const char* filenamep)
{
TXVT_IMAGE* i = NULL;
#ifdef __WXMSW__
const wxString name = filenamep;
#else
wxString name;
if (isalpha(filenamep[0u]))
{
name = _startup_dir;
name += "/";
}
name += filenamep;
#endif
if (::wxFileExists(name))
{
i = new TXVT_IMAGE;
i->LoadFile(name);
if (!i->Ok())
{
delete i;
i = NULL;
}
}
return (XVT_IMAGE)i;
}
XVT_IMAGE xvt_image_read_bmp(const char *filenamep)
{
return xvt_image_read(filenamep); // Very clever!
}
void xvt_image_set_clut(XVT_IMAGE image, short index, COLOR color)
{
CAST_TIMAGE(image, i);
if (i != NULL && i->Ok() && i->HasPalette())
{
CAST_COLOR(color, c);
wxImage& bmp = i->Image(); // Set dirty!
const COLOR old_trans = XVT_MAKE_COLOR(bmp.GetMaskRed(), bmp.GetMaskGreen(), bmp.GetMaskBlue());
const int idx = xvt_image_find_clut_index(image, old_trans);
if (idx == index)
bmp.SetMaskColour(c.Red(), c.Green(), c.Blue());
const wxPalette& pal = bmp.GetPalette();
unsigned char ri, gi, bi;
pal.GetRGB(index, &ri, &gi, &bi);
const COLOR old_color = XVT_MAKE_COLOR(ri, gi, bi);
const int w = bmp.GetWidth();
const int h = bmp.GetHeight();
for (int y = 0; y < h; y++) for (int x = 0; x < w; x++)
{
const COLOR rgb = i->GetPixel(x, y);
if (XVT_SAME_COLOR(rgb, old_color))
i->SetPixel(x, y, color);
}
}
}
void xvt_image_replace_color(XVT_IMAGE image, COLOR old_color, COLOR new_color)
{
CAST_TIMAGE(image, i);
if (i != NULL && i->Ok())
{
if (i->HasPalette())
{
int index = -1;
while (true)
{
const int idx = xvt_image_find_clut_index(image, old_color);
if (idx > index)
{
xvt_image_set_clut(image, idx, new_color);
index = idx;
}
else
break;
}
}
else
{
wxImage& bmp = i->Image(); // Set dirty!
const COLOR old_trans = XVT_MAKE_COLOR(bmp.GetMaskRed(), bmp.GetMaskGreen(), bmp.GetMaskBlue());
const int w = bmp.GetWidth();
const int h = bmp.GetHeight();
for (int y = 0; y < h; y++) for (int x = 0; x < w; x++)
{
const COLOR rgb = i->GetPixel(x, y);
if (XVT_SAME_COLOR(rgb, old_color))
i->SetPixel(x, y, new_color);
}
// Imposto la nuova trasparenza se cambiata
if (XVT_SAME_COLOR(old_trans, old_color))
bmp.SetMaskColour(XVT_COLOR_GET_RED(new_color), XVT_COLOR_GET_GREEN(new_color), XVT_COLOR_GET_BLUE(new_color));
}
}
}
void xvt_image_set_ncolors(XVT_IMAGE WXUNUSED(image), short WXUNUSED(ncolors))
{
// SORRY_BOX();
}
void xvt_image_set_pixel(XVT_IMAGE image, short x, short y, COLOR color)
{
CAST_TIMAGE(image, i);
if (i != NULL && i->Ok())
i->SetPixel(x, y, color);
}
void xvt_image_transfer(XVT_IMAGE dstimage, XVT_IMAGE srcimage, RCT *dstrctp, RCT *srcrctp)
{
CAST_TIMAGE(dstimage, dst);
CAST_TIMAGE(srcimage, src);
if (dst != NULL && src != NULL)
{
const wxRect rctDst = RCT2Rect(dstrctp);
const wxRect rctSrc = RCT2Rect(srcrctp);
wxMemoryDC dc;
wxBitmap bmp(*dst);
dc.SelectObject(bmp);
DrawImageOnDC(dc, src, rctDst, rctSrc);
dst->Image() = bmp.ConvertToImage();
dc.SelectObject(wxNullBitmap);
}
}
BOOLEAN xvt_image_filter(XVT_IMAGE image, IMAGE_FILTER filter, void* param)
{
CAST_TIMAGE(image, img);
BOOLEAN ok = img != NULL && img->Ok();
if (ok)
{
const short w = img->GetWidth();
const short h = img->GetHeight();
ok = w > 0 && h > 0;
if (ok)
{
const int nPixelSize = img->HasAlpha() ? 4 : 3;
for (short y = 0; y < h; y++)
{
unsigned char* rgb = img->Image().GetData() + nPixelSize*y;
for (short x = 0; x < w; x++, rgb += nPixelSize)
filter(x, y, rgb, param);
}
}
}
return ok;
}
///////////////////////////////////////////////////////////
// Memory management
///////////////////////////////////////////////////////////
DATA_PTR xvt_mem_alloc(size_t size)
{
DATA_PTR ptr = (DATA_PTR)malloc(size);
return ptr;
}
void xvt_mem_free(DATA_PTR p)
{ free(p); }
DATA_PTR xvt_mem_realloc(DATA_PTR p, size_t size)
{ return (DATA_PTR)realloc(p, size); }
DATA_PTR xvt_mem_rep(DATA_PTR dst, DATA_PTR src, unsigned int srclen, long reps)
{
XVT_ASSERT(dst != NULL || src != NULL);
if (srclen == 1)
memset(dst, *src, reps);
else
{
for (long i = 0; i < reps; i++)
memcpy(dst + i*srclen, src, srclen);
}
return dst;
}
DATA_PTR xvt_mem_zalloc(size_t size)
{
DATA_PTR ptr = xvt_mem_alloc(size);
memset(ptr, 0, size);
return ptr;
}
///////////////////////////////////////////////////////////
// Menu management
///////////////////////////////////////////////////////////
static int xvt_menu_count(const MENU_ITEM* m)
{
int n = 0;
if (m != NULL)
for (n = 0; m[n].tag != 0; n++);
return n;
}
// Funzione inventata
MENU_ITEM* xvt_menu_duplicate_tree(const MENU_ITEM* m)
{
MENU_ITEM* TheMenu = NULL;
if (m != NULL && m->tag != 0)
{
const int n = xvt_menu_count(m)+1;
TheMenu = (MENU_ITEM*)xvt_mem_zalloc(sizeof(MENU_ITEM)*n);
memcpy(TheMenu, m, n*sizeof(MENU_ITEM));
for (int i = 0; i < n; i++)
{
MENU_ITEM* mi = &TheMenu[i];
mi->text = xvt_str_duplicate(mi->text);
mi->child = xvt_menu_duplicate_tree(mi->child);
}
}
return TheMenu;
}
MENU_ITEM* xvt_menu_get_tree(WINDOW win)
{
MENU_ITEM* m = NULL;
if (win == TASK_WIN)
{
TTaskWin* w = wxStaticCast((wxObject*)win, TTaskWin);
m = xvt_menu_duplicate_tree(w->GetMenuTree());
}
else
{
CAST_TWIN(win, w);
m = xvt_menu_duplicate_tree(w.GetMenuTree());
}
return m;
}
BOOLEAN xvt_menu_popup(const MENU_ITEM *menu_p, WINDOW win, PNT pos,
XVT_POPUP_ALIGNMENT /* alignment */, MENU_TAG /* item */)
{
wxMenu menu;
for (const MENU_ITEM* mi = menu_p; mi != NULL && mi->tag != 0; mi++)
{
if (mi->separator || mi->text == NULL)
menu.AppendSeparator();
else
{
wxMenuItem* item = NULL;
if (mi->checkable)
{
item = menu.AppendCheckItem(mi->tag, mi->text);
item->Check(mi->checked);
}
else
item = menu.Append(mi->tag, mi->text);
// Operazioni fattibili solo dopo la menu.Append(), non prima!
item->Enable(mi->enabled);
}
}
wxPoint mp = wxDefaultPosition;
if (pos.h >= 0 && pos.v >= 0)
{
mp.x = pos.h;
mp.y = pos.v;
}
CAST_WIN(win, w);
return w.PopupMenu(&menu, mp);
}
static void TranslateMenu(wxMenu* pMenu, TRANSLATE_CALLBACK tc)
{
wxMenuItemList& list = pMenu->GetMenuItems();
for (unsigned i = 0; i < list.GetCount(); i++)
{
wxMenuItem* mi = list[i];
if (!mi->IsSeparator())
{
const char* ita = mi->GetText();
const char* eng = tc(ita);
mi->SetText(eng);
wxMenu* pMenu = mi->GetSubMenu();
if (pMenu != NULL)
TranslateMenu(pMenu, tc);
}
}
}
void xvt_menu_translate_tree(WINDOW win, TRANSLATE_CALLBACK tc)
{
if (win == TASK_WIN)
{
wxMenuBar* pMenuBar = _task_win->GetMenuBar();
if (pMenuBar != NULL)
{
for (int m = pMenuBar->GetMenuCount()-1; m >= 0; m--)
{
const wxString ita = pMenuBar->GetLabelTop(m);
const char* eng = tc(ita);
pMenuBar->SetLabelTop(m, eng);
wxMenu* pMenu = pMenuBar->GetMenu(m);
TranslateMenu(pMenu, tc);
}
}
}
}
void xvt_menu_set_font_sel(WINDOW win, XVT_FNTID WXUNUSED(font_id))
{
XVT_ASSERT(win == TASK_WIN);
}
static wxMenuItem* GetXvtMenuItem(WINDOW win, MENU_TAG tag)
{
wxMenuItem* item = NULL;
wxFrame* pFrame = wxDynamicCast((wxObject*)win, wxFrame);
if (pFrame != NULL)
{
wxMenuBar* bar = pFrame->GetMenuBar();
if (bar != NULL)
item = bar->FindItem(tag);
}
return item;
}
void xvt_menu_set_item_checked(WINDOW win, MENU_TAG tag, BOOLEAN check)
{
wxMenuItem* item = GetXvtMenuItem(win, tag);
if (item)
item->Check(check != 0);
}
void xvt_menu_set_item_enabled(WINDOW win, MENU_TAG tag, BOOLEAN enable)
{
wxMenuItem* item = GetXvtMenuItem(win, tag);
if (item)
item->Enable(enable != 0);
}
void xvt_menu_set_item_title(WINDOW win, MENU_TAG tag, const char* text)
{
wxMenuItem* item = GetXvtMenuItem(win, tag);
if (item)
item->SetText(text);
}
void xvt_menu_set_tree(WINDOW win, MENU_ITEM* tree)
{
if (win == TASK_WIN)
{
TTaskWin* w = wxStaticCast((wxObject*)win, TTaskWin); //occhio
w->SetMenuTree(tree);
}
else
{
CAST_TWIN(win, w);
w.SetMenuTree(tree);
}
}
void xvt_menu_update(WINDOW /*win*/)
{
wxMenuBar* bar = _task_win != NULL ? _task_win->GetMenuBar() : NULL;
if (bar)
bar->Refresh();
}
///////////////////////////////////////////////////////////
// Palette management
///////////////////////////////////////////////////////////
short xvt_palet_add_colors(XVT_PALETTE WXUNUSED(palet), COLOR* WXUNUSED(colorsp), short numcolors) { return numcolors; }
short xvt_palet_add_colors_from_image(XVT_PALETTE WXUNUSED(palet), XVT_IMAGE image) { return xvt_image_get_ncolors(image); }
XVT_PALETTE xvt_palet_create(XVT_PALETTE_TYPE WXUNUSED(type), XVT_PALETTE_ATTR WXUNUSED(reserved)) { return NULL; }
void xvt_palet_destroy(XVT_PALETTE WXUNUSED(palet)) { SORRY_BOX(); }
short xvt_palet_get_colors(XVT_PALETTE WXUNUSED(palet), COLOR* WXUNUSED(colorsp), short WXUNUSED(maxcolors)) { return 0; }
short xvt_palet_get_ncolors(XVT_PALETTE WXUNUSED(palet)) { return 0; }
int xvt_palet_get_tolerance(XVT_PALETTE WXUNUSED(p)) { return 0; }
void xvt_palet_set_tolerance(XVT_PALETTE WXUNUSED(p), int WXUNUSED(t)) { SORRY_BOX(); }
///////////////////////////////////////////////////////////
// Rectangles
///////////////////////////////////////////////////////////
int xvt_rect_get_height(const RCT *rctp)
{
return rctp ? abs(rctp->bottom - rctp->top) : 0;
// 3.1 return rctp ? rctp->bottom - rctp->top : 0;
}
int xvt_rect_get_width(const RCT *rctp)
{
return rctp ? abs(rctp->right - rctp->left) : 0;
// 3.1 return rctp ? rctp->right - rctp->left : 0;
}
BOOLEAN xvt_rect_has_point(const RCT *rctp, PNT pnt)
{
const wxRect rct = RCT2Rect(rctp);
return rct.Contains(pnt.h, pnt.v);
}
BOOLEAN xvt_rect_intersect(RCT *drctp, const RCT *rctp1, const RCT *rctp2)
{
const wxRect rect1 = RCT2Rect(rctp1);
const wxRect rect2 = RCT2Rect(rctp2);
const BOOLEAN yes = rect1.Intersects(rect2);
if (drctp)
{
if (yes)
{
/*
drctp->left = max(rect1.x, rect2.x);
drctp->top = max(rect1.y, rect2.y);
drctp->right = min(rect1.GetRight(), rect2.GetRight())+1;
drctp->bottom = min(rect1.GetBottom(), rect2.GetBottom())+1;
*/
const wxRect rect0 = rect1.Intersect(rect2);
Rect2RCT(rect0, drctp);
}
else
{
// drctp->left = drctp->right = rect1.x;
// drctp->top = drctp->bottom = rect1.y;
xvt_rect_set_null(drctp);
}
}
return yes;
}
BOOLEAN xvt_rect_is_empty(const RCT* rct)
{
return rct == NULL || (rct->left==rct->right && rct->top==rct->bottom);
}
void xvt_rect_offset(RCT *rctp, short dh, short dv)
{
XVT_ASSERT(rctp != NULL);
rctp->left += dh;
rctp->top += dv;
rctp->right += dh;
rctp->bottom += dv;
}
void xvt_rect_set(RCT *rctp, short left, short top, short right, short bottom)
{
XVT_ASSERT(rctp != NULL);
rctp->left = left;
rctp->top = top;
rctp->right = right;
rctp->bottom = bottom;
}
void xvt_rect_set_empty(RCT *rctp)
{
XVT_ASSERT(rctp != NULL);
rctp->right = rctp->left;
rctp->bottom = rctp->top;
}
void xvt_rect_set_null(RCT* rctp)
{
XVT_ASSERT(rctp != NULL);
memset(rctp, 0, sizeof(RCT));
}
BOOLEAN xvt_rect_set_pos(RCT *rctp, PNT pos)
{
BOOLEAN ok = rctp != NULL;
if (ok)
{
const short w = rctp->right-rctp->left;
const short h = rctp->bottom-rctp->top;
xvt_rect_set(rctp, pos.h, pos.v, pos.h + w, pos.v + h);
}
return ok;
}
void xvt_rect_deflate(RCT *rctp, short ix, short iy)
{
if (rctp != NULL)
{
rctp->left += ix; rctp->right -= ix;
rctp->top += iy; rctp->bottom -= iy;
}
}
void xvt_rect_inflate(RCT *rctp, short ix, short iy)
{
if (rctp != NULL)
{
rctp->left -= ix; rctp->right += ix;
rctp->top -= iy; rctp->bottom += iy;
}
}
///////////////////////////////////////////////////////////
// Resource management
///////////////////////////////////////////////////////////
void xvt_res_free_menu_tree(MENU_ITEM* tree)
{
XVT_ASSERT(tree != NULL);
if (tree != NULL)
{
for (MENU_ITEM* item = tree; item->tag != 0; item++)
{
if (item->text)
xvt_mem_free(item->text);
if (item->child != NULL)
xvt_res_free_menu_tree(item->child);
}
xvt_mem_free((DATA_PTR)tree);
}
}
XVT_FNTID xvt_res_get_font(int rid)
{
XVT_FNTID f = xvt_font_create();
if (rid <= 0)
{
CAST_FONT(f, font);
font.Copy(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
}
return f;
}
XVT_IMAGE xvt_res_get_icon(int rid)
{
XVT_IMAGE img = NULL;
const wxIcon icon = xvtart_GetIconResource(rid);
if (icon.IsOk())
{
int w = icon.GetWidth(); if (w <= 0) w = 32;
int h = icon.GetHeight(); if (h <= 0) h = 32;
wxBitmap bmp(w, h, icon.GetDepth());
{
wxMemoryDC dc(bmp);
dc.DrawIcon(icon, 0, 0);
}
XVT_IMAGE_FORMAT xif = bmp.GetDepth()>8 ? XVT_IMAGE_RGB : XVT_IMAGE_CL8;
img = xvt_image_create(xif, w, h, 0);
((TXVT_IMAGE*)img)->Image() = bmp.ConvertToImage();
}
return img;
}
XVT_IMAGE xvt_res_get_image(int rid)
{
const wxString strFileName = xvtart_GetResourceName("Image", rid);
const bool ok = !strFileName.IsEmpty();
XVT_ASSERT(ok);
return ok ? xvt_image_read(strFileName) : NULL;
}
static int SplitString(const wxString& str, wxArrayString& a)
{
const char* s = str;
char* comma = "";
a.Clear();
while (comma)
{
comma = (char*)strchr(s, ',');
if (comma)
{
*comma = '\0';
a.Add(s);
*comma = ',';
s = comma+1;
}
else
a.Add(s);
}
return a.GetCount();
}
static void FillMenuItem(const wxString& strValue, MENU_ITEM* mi)
{
wxArrayString a;
const int n = SplitString(strValue, a);
mi->tag = n > 0 ? atoi(a[0]) : 0;
if (mi->tag > 0)
{
const wxString& str = a[1];
const int accelera = str.Find('&');
if (accelera >= 0)
mi->mkey = str[accelera+1];
mi->text = xvt_str_duplicate(str);
mi->enabled = n < 3 || (a[2].Find('D')<0);
mi->checkable = n >= 3 && (a[2].Find('C')>=0);
mi->checked = n >= 3 && (a[2].Find('c')>=0);
}
else
{
mi->tag = -1;
mi->separator = TRUE;
}
}
MENU_ITEM* xvt_res_get_menu(int rid)
{
wxFileConfig ini("", "", xvtart_GetResourceIni());
const int MAX_MENU = 16;
MENU_ITEM* TheMenu = (MENU_ITEM*)xvt_mem_zalloc(sizeof(MENU_ITEM)*MAX_MENU);
wxString strName;
if (rid >= 10000 && rid < 10100)
{
wxFileName::SplitPath(wxTheApp->argv[0], NULL, &strName, NULL);
strName.MakeUpper();
strName.Printf("/Menu_%s-%X", (const char*)strName.Left(3), (rid-1)%16);
}
else
strName.Printf("/Menu_%d", rid);
ini.SetPath(strName);
wxString strItem;
for (int i = 0; i < MAX_MENU; i++)
{
MENU_ITEM* mi = &TheMenu[i];
strItem.Printf("Item_%02d", i);
if (ini.Read(strItem, &strName))
{
FillMenuItem(strName, mi);
mi = mi->child = (MENU_ITEM*)xvt_mem_zalloc(sizeof(MENU_ITEM)*MAX_MENU);
for (int j = 0; j < MAX_MENU; j++, mi++)
{
strItem.Printf("Item_%02d_%02d", i, j);
if (ini.Read(strItem, &strName))
FillMenuItem(strName, mi);
else
break;
}
}
else
break;
}
if (TheMenu->tag == 0)
{
XVT_ASSERT(false); // Menu not found
xvt_res_free_menu_tree(TheMenu);
TheMenu = NULL;
}
return TheMenu;
}
char* xvt_res_get_str(int rid, char *s, int sz_s)
{
XVT_ASSERT(s != NULL && sz_s > 0);
const wxString str = xvtart_GetResourceName("String", rid);
wxStrncpy(s, str, sz_s);
s[sz_s-1] = '\0';
return s;
}
///////////////////////////////////////////////////////////
// Scroll bars
///////////////////////////////////////////////////////////
#define CAST_GAUGE(win, pb) wxGauge& pb = *wxStaticCast((wxObject*)win, wxGauge);
#define CAST_SLIDER(win, sc) wxSlider& sc = *wxStaticCast((wxObject*)win, wxSlider);
#define CAST_SCROLL(win, sb) wxScrollBar& sb = *wxStaticCast((wxObject*)win, wxScrollBar);
#define CAST_SCROLL_TYPE(t, dir) const int dir = t == HSCROLL ? wxHORIZONTAL : wxVERTICAL;
int xvt_sbar_get_pos(WINDOW win, SCROLL_TYPE t)
{
int pos = 0;
switch (t)
{
case HSCROLL:
case VSCROLL:
{
CAST_WIN(win, w);
CAST_SCROLL_TYPE(t, dir);
pos = w.GetScrollPos(dir);
}
break;
case HVGAUGE:
{
CAST_GAUGE(win, g);
pos = g.GetValue();
}
break;
case HVSLIDER:
{
CAST_SLIDER(win, g);
pos = g.GetValue();
}
break;
default:
{
CAST_SCROLL(win, sb);
pos = sb.GetThumbPosition();
}
break;
}
return pos;
}
int xvt_sbar_get_proportion(WINDOW win, SCROLL_TYPE t)
{
int p = 1;
switch (t)
{
case HSCROLL:
case VSCROLL:
{
CAST_WIN(win, w);
CAST_SCROLL_TYPE(t, dir);
p = w.GetScrollThumb(dir);
}
break;
case HVSLIDER:
{
CAST_SLIDER(win, sc);
p = sc.GetPageSize();
}
break;
default:
{
CAST_SCROLL(win, sb);
p = sb.GetThumbSize();
}
break;
}
return p;
}
void xvt_sbar_get_range(WINDOW win, SCROLL_TYPE t, int *minp, int *maxp)
{
wxASSERT(minp && maxp);
*minp = 0;
switch (t)
{
case HSCROLL:
case VSCROLL:
{
CAST_WIN(win, w);
CAST_SCROLL_TYPE(t, dir);
*maxp = w.GetScrollRange(dir);
}
break;
case HVGAUGE:
{
CAST_GAUGE(win, g);
*maxp = g.GetRange();
}
break;
default:
{
CAST_SCROLL(win, sb);
*maxp = sb.GetRange();
}
break;
}
}
void xvt_sbar_set_pos(WINDOW win, SCROLL_TYPE t, int pos)
{
switch(t)
{
case HSCROLL:
case VSCROLL:
{
CAST_WIN(win, w);
CAST_SCROLL_TYPE(t, dir);
w.SetScrollPos(dir, pos);
}
break;
case HVGAUGE:
{
CAST_GAUGE(win, g);
if (g.GetRange() <= 1)
g.Pulse();
else
g.SetValue(pos);
}
break;
case HVSLIDER:
{
CAST_SLIDER(win, g);
g.SetValue(pos);
}
break;
default:
{
CAST_SCROLL(win, sb);
const int range = sb.GetRange();
const int size = sb.GetThumbSize();
sb.SetScrollbar(pos, size, range, size);
}
break;
}
}
void xvt_sbar_set_proportion(WINDOW win, SCROLL_TYPE t, int proportion)
{
switch (t)
{
case HSCROLL:
case VSCROLL:
{
CAST_WIN(win, w);
CAST_SCROLL_TYPE(t, dir);
const int pos = w.GetScrollPos(dir);
const int range = w.GetScrollRange(dir);
w.SetScrollbar(dir, pos, proportion, range);
}
break;
case HVSLIDER:
{
CAST_SLIDER(win, sc);
sc.SetPageSize(proportion);
sc.SetTickFreq(sc.GetMax()/proportion, 0);
}
break;
default:
{
CAST_SCROLL(win, sb);
const int pos = sb.GetThumbPosition();
const int range = sb.GetRange();
sb.SetScrollbar(pos, proportion, range, proportion);
}
break;
}
}
void xvt_sbar_set_range(WINDOW win, SCROLL_TYPE t, int min, int max)
{
XVT_ASSERT(min == 0 && max >= min);
switch (t)
{
case HSCROLL:
case VSCROLL:
{
CAST_WIN(win, w);
CAST_SCROLL_TYPE(t, dir);
const int pos = w.GetScrollPos(dir);
const int size = w.GetScrollThumb(dir);
w.SetScrollbar(dir, pos, size, max);
}
break;
case HVGAUGE:
{
CAST_GAUGE(win, g);
g.SetRange(max);
}
break;
case HVSLIDER:
{
CAST_SLIDER(win, g);
g.SetRange(min, max);
}
break;
default:
{
CAST_SCROLL(win, sb);
const int pos = sb.GetThumbPosition();
const int size = sb.GetThumbSize();
sb.SetScrollbar(pos, size, max, size);
}
break;
}
}
///////////////////////////////////////////////////////////
// Window manager
///////////////////////////////////////////////////////////
void xvt_scr_beep(void)
{
xvt_sys_beep(0);
}
WINDOW xvt_scr_get_focus_topwin(void)
{
wxWindow* w = _task_win->FindFocus();
while (w != NULL && w->IsKindOf(CLASSINFO(wxControl)))
w = w->GetParent();
return (WINDOW)w;
}
WINDOW xvt_scr_get_focus_vobj(void)
{
return (WINDOW)_task_win->FindFocus();
}
SLIST xvt_scr_list_wins()
{
SLIST list = xvt_slist_create();
_nice_windows.BeginFind();
for (wxHashTable::Node* node = _nice_windows.Next(); node; node = _nice_windows.Next())
{
wxWindow* pWin = wxDynamicCast(node->GetData(), wxWindow);
if (pWin != NULL)
{
const char* title = pWin->GetLabel();
xvt_slist_add_at_elt(list, NULL, title, (long)pWin);
}
}
return list;
}
void xvt_scr_set_busy_cursor()
{
xvt_win_set_cursor(TASK_WIN, CURSOR_WAIT);
}
void xvt_scr_set_focus_vobj(WINDOW win)
{
CAST_WIN(win, w);
w.SetFocus();
}
///////////////////////////////////////////////////////////
// String lists
///////////////////////////////////////////////////////////
BOOLEAN xvt_slist_add_at_elt(SLIST list, SLIST_ELT e, const char *sx, long data)
{
const BOOLEAN ok = list != NULL;
if (ok)
{
SLIST_ELT item = new SLIST_ITEM;
item->str = xvt_str_duplicate(sx);
item->data = data;
item->next = NULL;
SLIST_ELT last = NULL;
// if (e != NULL) // Add at head by default (else at tail)
// {
for (SLIST_ELT i = list->head; i; i = (SLIST_ELT)i->next)
{
last = i;
if (i == e)
break;
}
// }
if (last == NULL)
{
item->next = list->head;
list->head = item;
}
else
{
item->next = last->next;
last->next = item;
}
list->count++;
}
return ok;
}
int xvt_slist_count(SLIST list)
{
return list != NULL ? list->count : 0;
}
SLIST xvt_slist_create()
{
SLIST list = new xvtList;
list->head = NULL;
list->count = 0;
return list;
}
void xvt_slist_destroy(SLIST list)
{
if (list != NULL)
{
SLIST_ELT obj = list->head;
while (obj != NULL)
{
SLIST_ELT tokill = obj;
xvt_mem_free(tokill->str);
obj = (SLIST_ELT)tokill->next;
delete tokill;
}
delete list;
}
}
char* xvt_slist_get(SLIST list, SLIST_ELT e, long* datap)
{
if (list != NULL && e != NULL)
{
if (datap != NULL)
*datap = e->data;
return e->str;
}
return NULL;
}
long* xvt_slist_get_data(SLIST_ELT elt)
{
return elt != NULL ? &elt->data : NULL;
}
SLIST_ELT xvt_slist_get_first(SLIST list)
{
return list != NULL ? list->head : NULL;
}
SLIST_ELT xvt_slist_get_next(SLIST list, SLIST_ELT item)
{
return (SLIST_ELT)(list != NULL && item != NULL ? item->next : NULL);
}
///////////////////////////////////////////////////////////
// XVT Strings???
///////////////////////////////////////////////////////////
int xvt_str_compare_ignoring_case (const char* s1, const char* s2)
{
return wxStricmp(s1, s2);
}
char* xvt_str_duplicate(const char* str)
{
return str ? wxStrdup(str) : NULL; // bleah!
}
char* xvt_str_number_format(char* str, int size)
{
#ifdef __WXMSW__
OsWin32_NumberFormat(str, size);
#else
wxString txt;
for (const char* s = str; *s; s++)
{
if (isdigit(*s))
txt << *s;
else
{
if (*s == '.')
txt << ',';
}
}
wxStrncpy(str, txt, size);
#endif
return str;
}
static const char* const ENCRYPTION_KEY = "QSECOFR-";
int xvt_str_encode(const char* text, char* cipher, int mode)
{
int i = 0;
switch (mode)
{
case 1: // BASE64
break;
default: // AGA
for (i = 0; text[i]; i++)
cipher[i] = text[i] + (i < 8 ? ENCRYPTION_KEY[i] : text[i - 8]);
cipher[i] = '\0';
break;
}
return i;
}
int xvt_str_decode(const char* cipher, char* text, int mode)
{
int i = 0;
switch (mode)
{
case 1: // BASE64
break;
default: // AGA
for (i = 0; cipher[i]; i++)
text[i] = cipher[i] - (i < 8 ? ENCRYPTION_KEY[i] : text[i - 8]);
text[i] = '\0';
break;
}
return i;
}
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)
{
text.MakeUpper();
pattern.MakeUpper();
}
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)
{
wxString s(str);
s.MakeUpper();
wxStrcpy(str, s);
}
void xvt_str_make_lower(char* str)
{
wxString s(str);
s.MakeLower();
wxStrcpy(str, s);
}
double xvt_str_fuzzy_compare (const char* s1, const char* s2)
{
return fstrcmp(s1, s2);
}
double xvt_str_fuzzy_compare_ignoring_case (const char* s1, const char* s2)
{
wxString str1(s1); str1.MakeUpper();
wxString str2(s2); str2.MakeUpper();
return fstrcmp(str1, str2);
}
BOOLEAN xvt_chr_is_digit(int c)
{
return (c <= 255) && wxIsdigit(c);
}
BOOLEAN xvt_chr_is_alpha(int c)
{
return (c <= 255) && wxIsalpha(c);
}
BOOLEAN xvt_chr_is_alnum(int c)
{
return (c <= 255) && wxIsalnum(c);
}
int xvt_net_get_status()
{
int nStatus = 0;
//stoppa il log di wxWidgets per non avere segnalazioni di errori incomprensibili!
const bool bLogEnabled = wxLog::EnableLogging(false);
wxDialUpManager* dum = wxDialUpManager::Create();
if (dum != NULL)
{
if (dum->IsOk() && dum->IsOnline())
{
nStatus = 0x1; // 1 = Online
if (dum->IsAlwaysOnline())
{
nStatus |= 0x2; // 2 = Always Online
wxIPV4address addr;
if (addr.Hostname("www.google.com"))
nStatus |= 0x4; // 4 = Connected to web
}
}
delete dum;
}
wxLog::EnableLogging(bLogEnabled);
return nStatus;
}
///////////////////////////////////////////////////////////
// XVT system calls (added by Guy)
///////////////////////////////////////////////////////////
void xvt_sys_beep(int severity)
{
#ifdef __WXMSW__
OsWin32_Beep(severity);
#else
wxBell();
#endif
}
BOOLEAN xvt_sys_get_host_name(char* name, int maxlen)
{
wxString str = wxGetHostName();
wxStrncpy(name, str, maxlen);
name[maxlen-1] = '\0';
return *name > '\0';
}
BOOLEAN xvt_sys_get_user_name(char* name, int maxlen)
{
wxString str = wxGetUserId();
wxStrncpy(name, str, maxlen);
name[maxlen-1] = '\0';
return *name > '\0';
}
///////////////////////////////////////////////////////////
// TIconizeTaskThread
///////////////////////////////////////////////////////////
static bool __bChildRunning = false;
class TIconizeTaskThread : public wxThread
{
protected:
virtual ExitCode Entry();
public:
TIconizeTaskThread();
};
wxThread::ExitCode TIconizeTaskThread::Entry()
{
::wxMilliSleep(500);
if (__bChildRunning) // Il programma e' ancora attivo
_task_win->Iconize();
return 0;
}
TIconizeTaskThread::TIconizeTaskThread()
{
Create();
SetPriority(WXTHREAD_MIN_PRIORITY);
Run();
}
///////////////////////////////////////////////////////////
// Process processing
///////////////////////////////////////////////////////////
long xvt_sys_execute(const char* cmdline, BOOLEAN sync, BOOLEAN iconizetask)
{
long exitcode = 0;
wxString cmd(cmdline);
#ifdef LINUX
if (isalpha(cmd[0u]))
cmd = "./" + cmd;
#endif
if (sync)
{
if (iconizetask)
{
wxEnableTopLevelWindows(FALSE);
TIconizeTaskThread* it = new TIconizeTaskThread(); // No need to delete
if (it != NULL)
{
__bChildRunning = true;
exitcode = wxExecute(cmd, wxEXEC_SYNC);
__bChildRunning = false;
if (_task_win->IsIconized())
_task_win->Restore();
wxEnableTopLevelWindows(TRUE);
}
}
else
exitcode = wxExecute(cmd, wxEXEC_SYNC); // Valutare wxEXEC_NODISABLE
_task_win->Raise();
}
else
{
if (_task_win != NULL && _task_win_handler != NULL)
{
wxProcess* p = new wxProcess(_task_win->GetEventHandler(), wxID_ANY);
exitcode = wxExecute(cmd, wxEXEC_ASYNC, p);
if (exitcode > 0)
{
XVT_EVENT e(E_PROCESS);
e.v.process.msg_id = E_CREATE;
e.v.process.pid = exitcode;
_task_win_handler((WINDOW)_task_win, &e);
}
else
delete p;
}
else
exitcode = wxExecute(cmd, wxEXEC_ASYNC);
}
return exitcode;
}
BOOLEAN xvt_sys_kill(long pid)
{
BOOLEAN bKilled = wxProcess::Kill(pid, wxSIGTERM, wxKILL_CHILDREN) == wxKILL_OK;
if (!bKilled)
bKilled = wxProcess::Kill(pid, wxSIGKILL, wxKILL_CHILDREN) == wxKILL_OK;
if (bKilled && _task_win != NULL && _task_win_handler != NULL)
{
XVT_EVENT e(E_PROCESS);
e.v.process.msg_id = E_DESTROY;
e.v.process.pid = pid;
_task_win_handler((WINDOW)_task_win, &e);
}
return bKilled;
}
long xvt_sys_execute_in_window(const char* cmdline, WINDOW win)
{
const long inst = xvt_sys_execute(cmdline, FALSE, FALSE);
if (inst > 0 && win != NULL_WIN)
{
CAST_WIN(win, w);
#ifdef __WXMSW__
OsWin32_PlaceProcessInWindow(inst, "", (unsigned int)w.GetHandle());
#else
OsLinux_PlaceProcessInWindow(inst, "", w.GetHandle());
#endif
}
return inst;
}
long xvt_sys_close_children(WINDOW win)
{
long c = 0;
#ifdef __WXMSW__
CAST_WIN(win, w);
c = OsWin32_CloseChildren((unsigned int)w.GetHandle());
#endif
return c;
}
BOOLEAN xvt_sys_goto_url(const char* url, const char* action)
{
#ifdef __WXMSW__
if (action && *action && xvt_str_compare_ignoring_case(action, "open") != 0)
return OsWin32_GotoUrl(url, action);
#endif
return wxLaunchDefaultBrowser(url);
}
BOOLEAN xvt_sys_dongle_server_is_running()
{
wxSingleInstanceChecker sic("Authorization");
return sic.IsAnotherRunning();
}
#define OEM_INI wxString(_startup_dir+wxT("/setup/oem.ini"))
long xvt_sys_get_oem_int(const char* name, long defval)
{
static long _oem = -1;
if (_oem < 0)
_oem = xvt_sys_get_profile_int(OEM_INI, "MAIN", "OEM", -1);
if (_oem >= 0)
{
if (wxStricmp(name, wxT("OEM")) != 0)
{
wxString strPara; strPara.Printf(wxT("OEM_%d"), _oem);
defval = xvt_sys_get_profile_int(OEM_INI, strPara, name, defval);
}
else
defval = _oem;
}
return defval;
}
int xvt_sys_get_oem_string(const char* name, const char* defval, char* value, int maxsize)
{
const int oem = xvt_sys_get_oem_int("OEM", -1);
if (oem >= 0)
{
if (wxStricmp(name, wxT("OEM")) != 0)
{
wxString strPara; strPara.Printf(wxT("OEM_%d"), oem);
return xvt_sys_get_profile_string(OEM_INI, strPara, name, defval, value, maxsize);
}
else
{
wxString str; str.Printf("%d", oem);
wxStrncpy(value, str, maxsize);
return 1;
}
}
return 0;
}
int xvt_sys_get_profile_string(const char* file, const char* paragraph, const char* name,
const char* defval, char* value, int maxsize)
{
if (file == NULL || *file == '\0')
file = xvt_fsys_get_campo_ini();
if (paragraph == NULL || *paragraph == '\0')
paragraph = "Main";
#ifdef __WXMSW__
int len = ::GetPrivateProfileString(paragraph, name, defval, value, maxsize, file);
#else
wxFileConfig ini("", "", file, "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
wxString path;
path << "/" << paragraph;
ini.SetPath(path);
int len = 0;
wxString val;
if (!ini.Read(name, &val))
val = defval;
len = val.Length();
if (value)
{
wxStrncpy(value, val, maxsize);
value[maxsize-1] = '\0';
}
#endif
return len;
}
long xvt_sys_get_profile_int(const char* file, const char* paragraph, const char* name, long defval)
{
char defstr[16] = "", str[16] = "";
long value = defval;
if (defval != 0)
wxSprintf(defstr, "%ld", defval);
if (xvt_sys_get_profile_string(file, paragraph, name, defstr, str, sizeof(str)))
value = atol(str);
return value;
}
BOOLEAN xvt_sys_set_profile_string(const char* file, const char* paragraph, const char* name,
const char* value)
{
if (file == NULL || *file == '\0')
file = xvt_fsys_get_campo_ini();
if (paragraph == NULL || *paragraph == '\0')
paragraph = "Main";
#ifdef __WXMSW__
return ::WritePrivateProfileString(paragraph, name, value, file);
#else
wxFileConfig ini("", "", file, "", wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
ini.SetUmask(0x0);
wxString path;
path << "/" << paragraph;
ini.SetPath(path);
return ini.Write(name, value);
#endif
}
BOOLEAN xvt_sys_find_editor(const char* file, char* editor)
{
BOOLEAN ok = FALSE;
#ifdef __WXMSW__
const wxString e = OsWin32_File2App(file);
#else
const wxString e = OsLinux_File2App(file);
#endif
ok = !e.IsEmpty();
if (ok && editor != NULL)
wxStrncpy(editor, e, _MAX_PATH);
return ok;
}
int xvt_sys_get_session_id()
{
#ifdef __WXMSW__
return OsWin32_GetSessionId();
#else
return OsLinux_GetSessionId();
#endif
}
unsigned long xvt_sys_get_free_memory()
{
const wxMemorySize sz = ::wxGetFreeMemory();
return sz.GetHi() ? -1 : sz.GetLo();
}
unsigned long xvt_sys_get_free_memory_kb()
{
const wxMemorySize sz = ::wxGetFreeMemory() / 1024; // Arrotondo per difetto
return sz.GetHi() ? -1 : sz.GetLo();
}
int xvt_sys_get_os_version()
{
int os = 0;
#ifdef __WXMSW__
int nVersion = 0;
::GetWinVer(NULL, 0, &nVersion);
switch (nVersion)
{
case 1:
case 2:
case 3: os = XVT_WS_WIN_95; break;
case 4:
case 5:
case 6: os = XVT_WS_WIN_98; break;
case 7: os = XVT_WS_WIN_ME; break;
case 101:
case 102: os = XVT_WS_WIN_NT; break;
case 103: os = XVT_WS_WIN_2000; break;
case 104: os = XVT_WS_WIN_XP; break;
case 105: os = XVT_WS_WIN_2003; break;
case 106: os = XVT_WS_WIN_VISTA; break;
case 107: os = XVT_WS_WIN_2008; break;
case 108: os = XVT_WS_WIN_2008R2; break;
case 109:
default : os = XVT_WS_WIN_7; break;
}
#else
os = XVT_WS_LINUX;
#endif
return os;
}
BOOLEAN xvt_sys_is_pda()
{
wxSize sz;
if (_task_win == NULL)
{
sz.x = wxSystemSettings::GetMetric(wxSYS_SCREEN_X);
sz.y = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y);
}
else
sz = _task_win->GetSize();
return max(sz.x,sz.y) <= 640;
}
int xvt_sys_get_version(char* os_version, char* ptk_version, int maxsize)
{
const int version = xvt_sys_get_os_version();
if (os_version && maxsize >= 8)
{
#ifdef __WXMSW__
if (version >= XVT_WS_WIN_VISTA) // wxWidgets non sa descrivere i moderni sistemi Microsoft
::GetWinVer(os_version, maxsize, NULL);
else
#endif
wxStrncpy(os_version, wxGetOsDescription(), maxsize);
}
if (ptk_version && maxsize >= 8)
wxStrncpy(ptk_version, wxVERSION_STRING, maxsize);
return version;
}
void xvt_sys_sleep(unsigned long msec)
{
::wxMilliSleep(msec);
}
///////////////////////////////////////////////////////////
// XVT system calls
///////////////////////////////////////////////////////////
XVTDLL BOOLEAN xvt_sys_get_env(const char* varname, char* value, int max_size)
{
const wxString strName(varname);
wxString strValue;
const bool ok = wxGetEnv(strName, &strValue);
if (ok)
wxStrncpy(value, strValue, max_size);
return ok;
}
void xvt_sys_searchenv(const char * filename, const char * varname, char * pathname)
{
DEPRECATED_BOX("xvt_sys_search_env");
xvt_sys_search_env(filename, varname, pathname);
}
void xvt_sys_search_env(const char * filename, const char * varname, char * pathname)
{
#ifdef __WXMSW__
_searchenv(filename, varname, pathname);
#else
const char * value = wxGetEnv(varname);
if (value)
{
char path_list[4096];
strcpy(path_list, value);
for (const char* s = path_list; *s; )
{
char* s1 = strchr(s, ';');
if (s1 != NULL)
*s1 = '\0';
xvt_fsys_build_pathname(pathname, NULL, s, filename, NULL, NULL);
if (xvt_fsys_file_exists(pathname))
break;
if (s1 != NULL)
s = s1 + 1;
else
break;
}
}
else
*pathname = '\0';
#endif
}
BOOLEAN xvt_sys_set_env(const char* varname, const char* value)
{
const wxString strName(varname);
return value != NULL ? wxSetEnv(strName, value) : wxUnsetEnv(strName);
}
// BOOLEAN o int? Adso!
int xvt_fsys_access(const char *pathname, int mode)
{
wxURL url(pathname);
wxString scheme = url.GetScheme();
if (scheme == "ftp" || scheme == "http")
{
if (mode & 4)
return ENOEXEC;
if (mode & 2 && scheme == "http")
return EACCES;
SLIST files = xvt_fsys_list_files("", pathname, true);
const int count = xvt_slist_count(files);
xvt_slist_destroy(files);
return count > 0 ? 0 : ENOENT;
}
return wxAccess(pathname, mode) == -1 ? errno : 0;
}
BOOLEAN xvt_fsys_file_exists(const char *pathname)
{
return xvt_fsys_access(pathname, 0) == 0;
}
BOOLEAN xvt_fsys_mkdir(const char *pathname)
{
// Crea l'intero albero di cartelle senza dare erroire se esistono gia'
return wxFileName::Mkdir(pathname, 0777, wxPATH_MKDIR_FULL);
}
BOOLEAN xvt_fsys_rmdir(const char *pathname)
{
if (!wxDirExists(pathname))
return TRUE;
return wxRmdir(pathname);
}
BOOLEAN xvt_fsys_remove_file(const char *pathname)
{
wxURL url(pathname);
wxString scheme = url.GetScheme();
if (scheme == "ftp")
{
wxFTP ftp;
const wxString strHost = url.GetServer();
const wxString strUser = url.GetUser();
const wxString strPwd = url.GetPassword();
const wxFileName fnPath = url.GetPath();
const wxString fnDir = fnPath.GetPath(wxPATH_GET_VOLUME, wxPATH_UNIX);
const wxString fnName = fnPath.GetFullName();
if (!strUser.IsEmpty())
{
ftp.SetUser(strUser);
ftp.SetPassword(strPwd);
}
if (ftp.Connect(strHost))
if (ftp.ChDir(fnDir))
return ftp.RmFile(fnName);
return false;
}
else
if (scheme == "http")
return false;
return wxRemoveFile(pathname);
}
BOOLEAN xvt_fsys_removefile(const char *pathname)
{
DEPRECATED_BOX("xvt_fsys_remove_file");
return xvt_fsys_remove_file(pathname);
}
BOOLEAN xvt_fsys_rename_file(const char *src_pathname, const char *dst_pathname)
{
return wxRenameFile(src_pathname, dst_pathname);
}
///////////////////////////////////////////////////////////
// Timers
///////////////////////////////////////////////////////////
struct tm* xvt_time_now()
{ return wxDateTime::GetTmNow(); }
long xvt_timer_create(WINDOW win, long interval)
{
CAST_TWIN(win, w);
if (w._timer == NULL)
w._timer = new wxTimer(&w, TIMER_ID);
w._timer->Start(interval);
return win;
}
void xvt_timer_destroy(long id)
{
if (id > 0L)
{
CAST_TWIN(id, w);
wxTimer*& t = w._timer;
if (t != NULL)
{
t->Stop();
delete t;
t = NULL;
}
}
}
///////////////////////////////////////////////////////////
// Visual objects
///////////////////////////////////////////////////////////
static wxWindow* SafeCastWin(WINDOW win)
{
wxWindow* w = wxDynamicCast(_nice_windows.Get(win), wxWindow);
if (w != NULL)
{
wxASSERT(win == (WINDOW)w);
const TwxWindow* tw = wxDynamicCast(w, TwxWindow);
if (tw != NULL && tw->InDestroy())
w = NULL;
}
return w;
}
void xvt_vobj_destroy(WINDOW win)
{
wxWindow* w = SafeCastWin(win);
if (w != NULL)
{
xvt_win_set_caret_visible(win, FALSE);
w->Destroy(); // same as delete w
_nice_windows.Delete(win); // Elimina "di nuovo" dalla lista delle finestre attive
}
}
static long xvt_vobj_get_metric(WINDOW win, wxSystemMetric data)
{
wxWindow* w = wxDynamicCast((wxObject*)win, wxWindow);
if (w == NULL) w = _task_win;
long ret = wxSystemSettings::GetMetric(data, w);
return ret;
}
long xvt_vobj_get_attr(WINDOW win, long data)
{
long ret = 0L;
switch(data)
{
case ATTR_APP_CTL_COLORS:
{
XVT_COLOR_COMPONENT* xcc = (XVT_COLOR_COMPONENT*)xvt_mem_zalloc(sizeof(XVT_COLOR_COMPONENT)*16);
if (win != NULL_WIN && win != SCREEN_WIN)
{
TTaskWin* tw = wxDynamicCast(_task_win, TTaskWin);
if (tw != NULL)
{
const XVT_COLOR_COMPONENT* tcc = tw->GetCtlColors();
int c = 0;
for (c = 0; c < 15 && tcc[c].type != XVT_COLOR_NULL; c++);
memcpy(xcc, tcc, (c+1)*sizeof(XVT_COLOR_COMPONENT));
return long(xcc);
}
}
// XVT components
xcc[0].type = XVT_COLOR_FOREGROUND;
xcc[0].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT));
xcc[1].type = XVT_COLOR_BACKGROUND;
xcc[1].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
xcc[2].type = XVT_COLOR_BLEND;
xcc[2].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT));
xcc[3].type = XVT_COLOR_BORDER;
xcc[3].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW));
xcc[4].type = XVT_COLOR_SELECT;
xcc[4].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
xcc[5].type = XVT_COLOR_HIGHLIGHT;
xcc[5].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
xcc[6].type = XVT_COLOR_TROUGH;
xcc[6].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
// AGA components
xcc[7].type = XVT_COLOR_CAPTIONLT;
xcc[7].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION));
xcc[8].type = XVT_COLOR_CAPTIONDK;
xcc[8].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_INACTIVECAPTION));
xcc[9].type = XVT_COLOR_CAPTIONTEXT;
xcc[9].color = MAKE_XVT_COLOR(wxSystemSettings::GetColour(wxSYS_COLOUR_CAPTIONTEXT));
// Ensure last (NULL) component
xcc[15].type = XVT_COLOR_NULL;
xcc[15].color = 0;
ret = (long)xcc;
}
break;
case ATTR_APPL_VERSION_STRING:
ret = (long)(const char*)_appl_version;
break;
case ATTR_DOCFRAME_WIDTH:
case ATTR_FRAME_WIDTH:
ret = xvt_vobj_get_metric(win, wxSYS_FRAMESIZE_X);
break;
case ATTR_DOCFRAME_HEIGHT:
case ATTR_FRAME_HEIGHT:
ret = xvt_vobj_get_metric(win, wxSYS_FRAMESIZE_Y);
break;
case ATTR_MENU_HEIGHT:
ret = xvt_vobj_get_metric(win, wxSYS_MENU_Y);
break;
case ATTR_TITLE_HEIGHT:
ret = xvt_vobj_get_metric(win, wxSYS_CAPTION_Y);
break;
case ATTR_CTL_VERT_SBAR_WIDTH:
ret = wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
break;
case ATTR_CTL_HORZ_SBAR_HEIGHT:
ret = wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y);
break;
case ATTR_DISPLAY_TYPE:
switch (::wxDisplayDepth()) // Test ormai ridicolo?
{
case 1: ret = XVT_DISPLAY_MONO; break; // Ridicolissimo :-)
case 4: ret = XVT_DISPLAY_COLOR_16; break;
case 8: ret = XVT_DISPLAY_COLOR_256; break;
default: ret = XVT_DISPLAY_DIRECT_COLOR; break;
}
break;
case ATTR_ERRMSG_HANDLER:
ret = (long)_error_handler;
break;
case ATTR_NATIVE_GRAPHIC_CONTEXT:
SORRY_BOX(); // Obsoleto e non piu' usato
break;
case ATTR_NATIVE_WINDOW:
{
const wxWindow* w = SafeCastWin(win);
if (w != NULL)
ret = (long)w->GetHandle();
}
break;
case ATTR_PRINTER_HEIGHT:
xvt_app_escape(XVT_ESC_GET_PRINTER_INFO, NULL, &ret, NULL, NULL, NULL);
break;
case ATTR_PRINTER_HRES:
xvt_app_escape(XVT_ESC_GET_PRINTER_INFO, NULL, NULL, NULL, NULL, &ret);
break;
case ATTR_PRINTER_VRES:
xvt_app_escape(XVT_ESC_GET_PRINTER_INFO, NULL, NULL, NULL, &ret, NULL);
break;
case ATTR_PRINTER_WIDTH:
xvt_app_escape(XVT_ESC_GET_PRINTER_INFO, NULL, NULL, &ret, NULL, NULL);
break;
case ATTR_SCREEN_HEIGHT:
ret = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y);
break;
case ATTR_SCREEN_WIDTH:
ret = wxSystemSettings::GetMetric(wxSYS_SCREEN_X);
break;
case ATTR_SCREEN_WINDOW:
ret = 882L; // Scelta arbitraria ma accettabile
break;
case ATTR_SPEECH_MODE:
ret = xvt_dm_speech_enabled();
break;
case ATTR_TASK_WINDOW:
ret = long(_task_win);
break;
case ATTR_PRINTER_WINDOW:
ret = 883L; // Scelta arbitraria ma accettabile
break;
case ATTR_WIN_INSTANCE:
ret = 0;
break;
case ATTR_WIN_OPENFILENAME_HOOK:
ret = 0;
break;
case ATTR_WIN_PM_DRAWABLE_TWIN:
ret = TRUE;
break;
case ATTR_WIN_PM_TWIN_STARTUP_STYLE:
ret = _startup_style;
break;
case ATTR_ICON_WIDTH:
ret = xvt_vobj_get_metric(win, wxSYS_ICON_X);
break;
case ATTR_ICON_HEIGHT:
ret = xvt_vobj_get_metric(win, wxSYS_ICON_Y);
break;
default:
SORRY_BOX();
break;
}
return ret;
}
RCT* xvt_vobj_get_client_rect(WINDOW win, RCT *rctp)
{
XVT_ASSERT(rctp != NULL);
int l, h;
if (win != NULL_WIN)
{
if (win == PRINTER_WIN)
{
l = h = 6000; // circa A4 height
} else
if (win == SCREEN_WIN)
{
l = wxSystemSettings::GetMetric(wxSYS_SCREEN_X);
h = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) - 32; // Puerile tentativo di escludere la task bar
} else
{
CAST_WIN(win, w);
w.GetClientSize(&l, &h);
}
}
else // NULL_WIN = schermo intero
{
l = wxSystemSettings::GetMetric(wxSYS_SCREEN_X);
h = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y);
}
rctp->left = rctp->top = 0;
rctp->right = l; rctp->bottom = h;
return rctp;
}
long xvt_vobj_get_data(WINDOW win)
{
const TwxWindow* w = wxDynamicCast(SafeCastWin(win), TwxWindow);
return w != NULL ? w->_app_data : 0L;
}
RCT* xvt_vobj_get_outer_rect(WINDOW win, RCT *rctp)
{
if (win != NULL_WIN)
{
if (win == SCREEN_WIN)
{
const short sx = wxSystemSettings::GetMetric(wxSYS_SCREEN_X);
const short sy = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y);
xvt_rect_set(rctp, 0, 0, sx, sy);
}
else
{
CAST_WIN(win, w);
const wxRect rct = w.GetRect();
Rect2RCT(rct, rctp);
}
}
else
xvt_rect_set_null(rctp);
return rctp;
}
XVT_PALETTE xvt_vobj_get_palet(WINDOW WXUNUSED(win))
{ return NULL; }
WINDOW xvt_vobj_get_parent(WINDOW win)
{
if (win == NULL_WIN || win == TASK_WIN)
return NULL_WIN;
CAST_WIN(win, w);
return (WINDOW)w.GetParent();
}
char* xvt_vobj_get_title(WINDOW win, char *title, int sz_title)
{
CAST_WIN(win, w);
wxStrncpy(title, w.GetLabel(), sz_title);
title[sz_title-1] = '\0';
return title;
}
WIN_TYPE xvt_vobj_get_type(WINDOW win)
{
if (win == NULL_WIN)
return W_NONE;
if (win == TASK_WIN)
return W_TASK;
if (win == SCREEN_WIN)
return W_SCREEN;
if (win == PRINTER_WIN)
return W_PRINT;
TwxWindow* w = wxDynamicCast((wxObject*)win, TwxWindow);
if (w != NULL)
return w->_type;
return WO_TE; // Unknown custom control
}
BOOLEAN xvt_vobj_is_focusable(WINDOW win)
{
BOOLEAN ok = win != NULL_WIN && win != PRINTER_WIN && xvt_vobj_is_valid(win);
if (ok)
{
CAST_WIN(win, w);
ok = w.IsEnabled() && w.IsShownOnScreen();
}
return ok;
}
BOOLEAN xvt_vobj_is_valid(WINDOW win)
{
return win != NULL_WIN && SafeCastWin(win) != NULL;
}
void xvt_vobj_maximize(WINDOW win)
{
XVT_ASSERT(win != NULL_WIN && _task_win != NULL);
if (win == TASK_WIN)
_task_win->Maximize();
else
{
CAST_WIN(win, w);
wxWindow* parent = w.GetParent();
if (parent == NULL)
parent = _task_win;
int width, height;
parent->GetClientSize(&width, &height);
w.SetSize(0, 0, width, height);
}
}
void xvt_vobj_minimize(WINDOW win)
{
wxFrame* pMain = wxDynamicCast((wxObject*)win, wxFrame);
if (pMain != NULL)
pMain->Iconize();
else
SORRY_BOX();
}
void xvt_vobj_move(WINDOW win, const RCT* rctp)
{
CAST_WIN(win, w);
const wxRect rct = RCT2Rect(rctp);
w.Move(rct.x, rct.y);
w.SetClientSize(rct.width, rct.height);
}
void xvt_vobj_raise(WINDOW win)
{
CAST_WIN(win, w);
w.Raise();
}
static void SetArtistColor(WINDOW win, int id, long rgb)
{
CAST_WIN(win, w);
const wxAuiManager* pMgr = wxAuiManager::GetManager(&w);
wxAuiDockArt* pArt = (pMgr != NULL) ? pMgr->GetArtProvider() : NULL;
if (pArt != NULL)
{
CAST_COLOR(rgb, col);
pArt->SetColour(id, col);
if (id == wxAUI_DOCKART_BACKGROUND_COLOUR)
{
}
}
}
void xvt_vobj_set_attr(WINDOW win, long data, long value)
{
switch (data)
{
case ATTR_APP_CTL_COLORS:
if (win == TASK_WIN)
{
TTaskWin* tw = wxDynamicCast(_task_win, TTaskWin);
if (tw != NULL)
tw->SetCtlColors((XVT_COLOR_COMPONENT*)value);
}
break;
case ATTR_APPL_VERSION_STRING: _appl_version = (const char*)value; break;
case ATTR_BACK_COLOR: SetArtistColor(win, wxAUI_DOCKART_BACKGROUND_COLOUR, value); break;
case ATTR_ERRMSG_HANDLER: _error_handler = (XVT_ERRMSG_HANDLER)value; break;
case ATTR_EVENT_HOOK: SORRY_BOX(); break; // TBI?: Native events hook!
case ATTR_WIN_PM_DRAWABLE_TWIN: break; // Ignored: Always TRUE
case ATTR_WIN_PM_TWIN_STARTUP_RCT: _startup_rect = *(RCT*)value; break;
case ATTR_WIN_PM_TWIN_STARTUP_STYLE: _startup_style = value; break;
case ATTR_SPEECH_MODE: xvt_dm_speech_enable(value); break;
default: SORRY_BOX(); break;
}
}
void xvt_vobj_set_data(WINDOW win, long app_data)
{
CAST_TWIN(win, w);
w._app_data = app_data;
}
void xvt_vobj_set_enabled(WINDOW win, BOOLEAN enabled)
{
CAST_WIN(win, w);
w.Enable(enabled != 0);
}
void xvt_vobj_set_palet(WINDOW WXUNUSED(win), XVT_PALETTE WXUNUSED(palet))
{
// Do not implement!
}
void xvt_vobj_set_title(WINDOW win, const char* title)
{
CAST_WIN(win, w);
w.SetLabel(title);
}
void xvt_vobj_set_visible(WINDOW win, BOOLEAN show)
{
CAST_WIN(win, w);
w.Show(show != 0);
}
void xvt_vobj_translate_points(WINDOW from_win, WINDOW to_win, PNT *pntp, int npnts)
{
XVT_ASSERT(from_win != NULL_WIN && to_win != NULL_WIN);
XVT_ASSERT(pntp != NULL && npnts > 0);
CAST_WIN(from_win, w1);
CAST_WIN(to_win, w2);
for (int i = 0; i < npnts; i++)
{
int x = pntp[i].h;
int y = pntp[i].v;
w1.ClientToScreen(&x, &y);
w2.ScreenToClient(&x, &y);
pntp[i].h = x;
pntp[i].v = y;
}
}
///////////////////////////////////////////////////////////
// Real windows
///////////////////////////////////////////////////////////
WINDOW xvt_win_create(WIN_TYPE wtype, const RCT* rct_p, const char* title, int menu_rid, WINDOW parent, long win_flags,
EVENT_MASK WXUNUSED(mask), EVENT_HANDLER eh, long app_data)
{
const wxRect rct = RCT2Rect(rct_p);
const wxString caption = title;
long style = wxCLIP_SIBLINGS | wxCLIP_CHILDREN | wxWANTS_CHARS;
if (win_flags & WSF_VSCROLL)
style |= wxVSCROLL;
if (win_flags & WSF_HSCROLL)
style |= wxHSCROLL;
TwxWindow* w = NULL;
switch (wtype)
{
case W_DOC:
style |= wxSYSTEM_MENU; // Questo flag in realta' viene interpretato come wxCAPTION
if (win_flags & WSF_CLOSE)
style |= wxCLOSE_BOX;
break;
case W_PLAIN:
// style |= wxBORDER; // Non attivare MAI il bordo!
if (win_flags & WSF_TRANSPARENT)
style |= wxTRANSPARENT_WINDOW;
break;
default:
SORRY_BOX(); break;
}
if (parent == SCREEN_WIN)
parent = NULL;
w = new TwxWindow((wxWindow*)parent, -1, caption, rct.GetPosition(), rct.GetSize(), style);
w->_type = wtype;
w->_app_data = app_data;
w->SetBackgroundStyle(wxBG_STYLE_CUSTOM); // Lo sfondo viene disegnato nella OnPaint
#ifdef __WXMSW__
OsWin32_SetCaptionStyle(w->GetHWND(), style);
#else
OsLinux_SetCaptionStyle(w, style);
#endif
if (menu_rid > 0 && menu_rid != 8000) // 8000 = NULL_MENU_RID
{
MENU_ITEM* mi = xvt_res_get_menu(menu_rid);
if (mi)
{
w->SetMenuTree(mi);
xvt_res_free_menu_tree(mi);
}
}
if (style & wxHSCROLL)
w->SetScrollbar(wxHORIZONTAL, 0, 1, 100);
if (style & wxVSCROLL)
w->SetScrollbar(wxVERTICAL, 0, 1, 100);
if (win_flags & WSF_DISABLED)
w->Disable();
else
w->Enable();
if (win_flags & WSF_INVISIBLE)
w->Hide();
else
w->Show(); // Non dovrebbe mai succedere nel nostro caso
// Accetta messaggi solo da ora!
w->_eh = eh;
EVENT e; memset(&e, 0, sizeof(e));
e.type = E_CREATE; // Serve a poco, ma fa' lo stesso
eh((WINDOW)w, &e);
xvt_vobj_move((WINDOW)w, rct_p); // Forza la giusta dimensione della client area
return (WINDOW)w;
}
long xvt_win_dispatch_event(WINDOW win, EVENT* event_p)
{
XVT_ASSERT(win != NULL_WIN && event_p != NULL);
if (win == (WINDOW)_task_win)
return _task_win_handler(win, event_p);
CAST_TWIN(win, w);
return w._eh(win, event_p);
}
BOOLEAN xvt_win_enum_wins(WINDOW parent_win, XVT_ENUM_CHILDREN func, long data, unsigned long /*reserved*/)
{
CAST_WIN(parent_win, w)
wxWindowList& list = w.GetChildren();
const BOOLEAN ok = list.GetCount() > 0;
if (ok && func != NULL)
{
for (wxWindowList::iterator i = list.begin(); i != list.end(); ++i)
{
wxWindow* tw = wxDynamicCast(*i, wxWindow);
if (tw != NULL)
{
if (!func((WINDOW)tw, data))
break;
}
}
}
return ok;
}
long xvt_win_get_children_count(WINDOW parent_win)
{
long nCount = 0;
if (parent_win != NULL_WIN)
{
CAST_WIN(parent_win, w)
#ifdef __WXMSW__
nCount = OsWin32_GetChildrenCount((unsigned int)w.GetHandle());
#else
nCount = w.GetChildren().GetCount();
#endif
}
return nCount;
}
void xvt_win_post_event(WINDOW win, EVENT* event_p)
{
// Per ora e' garantito che funzioni solo con la task window
CAST_WIN(win, w);
switch (event_p->type)
{
case E_COMMAND:
{
wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, event_p->v.cmd.tag);
e.SetEventObject(&w);
wxPostEvent(&w, e);
}
break;
default:
SORRY_BOX();
break;
}
}
void xvt_win_release_pointer(void)
{
if (_mouse_trapper != NULL)
{
// cap SHOULD be equal to _mouse_trapper :-)
wxWindow* cap = wxWindow::GetCapture();
if (cap != NULL)
cap->ReleaseMouse();
_mouse_trapper = NULL;
}
}
void xvt_win_set_cursor(WINDOW win, CURSOR cursor)
{
CAST_WIN(win, w);
wxCursor cur;
switch (cursor)
{
case CURSOR_ARROW: cur = *wxSTANDARD_CURSOR; break;
case CURSOR_CROCE: cur = *wxCROSS_CURSOR; break;
case CURSOR_WAIT : cur = *wxHOURGLASS_CURSOR; break;
default: cur = xvtart_GetCursorResource(cursor); break; // Always succeeds
}
w.SetCursor(cur);
}
void xvt_win_set_handler(WINDOW win, EVENT_HANDLER eh)
{
if (win == (WINDOW)_task_win)
{
_task_win_handler = eh;
}
else
{
CAST_TWIN(win, w);
w._eh = eh;
}
}
void xvt_win_trap_pointer(WINDOW win)
{
CAST_WIN(win, w);
xvt_win_release_pointer();
w.CaptureMouse();
_mouse_trapper = &w;
}
///////////////////////////////////////////////////////////
// Status bar
///////////////////////////////////////////////////////////
static wxStatusBar* WIN2StatBar(WINDOW win)
{
wxStatusBar* pStatusBar = NULL;
if (win == NULL_WIN || win == TASK_WIN)
pStatusBar = _task_win->GetStatusBar();
else
pStatusBar = wxDynamicCast((wxObject*)win, wxStatusBar);
return pStatusBar;
}
const char* statbar_set_title(WINDOW win, const char* text)
{
wxStatusBar* pStatusBar = WIN2StatBar(win);
if (pStatusBar != NULL)
{
if (text == NULL)
text = _strDefaultStatbarText;
wxStringTokenizer tok(text, "\t", wxTOKEN_RET_EMPTY);
for (int t = 0; tok.HasMoreTokens(); t++)
{
const wxString strMsg = tok.GetNextToken();
pStatusBar->SetStatusText(strMsg, t);
if (t == 0)
pStatusBar->SetToolTip(strMsg);
}
}
return text;
}
const char* statbar_set_default_title(WINDOW win, const char *text)
{
_strDefaultStatbarText = text;
return statbar_set_title(win, text);
}
XVT_FNTID statbar_set_fontid(WINDOW win, XVT_FNTID font_id)
{
wxStatusBar* pStatBar = WIN2StatBar(win);
if (pStatBar != NULL && font_id != NULL)
{
CAST_FONT(font_id, font);
pStatBar->SetFont(font.Font(NULL, win));
}
return font_id;
}
XVT_FNTID statbar_get_fontid(WINDOW win, XVT_FNTID font_id)
{
wxStatusBar* pStatBar = WIN2StatBar(win);
if (pStatBar != NULL && font_id != NULL)
{
CAST_FONT(font_id, font);
font.Copy(pStatBar->GetFont());
}
return font_id;
}
WINDOW statbar_create(int cid, int WXUNUSED(left), int WXUNUSED(top), int WXUNUSED(right), int WXUNUSED(bottom),
int WXUNUSED(prop_count), char** WXUNUSED(prop_list), WINDOW parent_win,
int WXUNUSED(parent_rid), long WXUNUSED(parent_flags), char* WXUNUSED(parent_class))
{
wxStatusBar* pStatusBar = NULL;
wxFrame* w = wxDynamicCast(SafeCastWin(parent_win), wxFrame);
if (w != NULL)
{
const int nStyle = 0; // not wxST_SIZEGRIP
pStatusBar = w->CreateStatusBar(3, nStyle, cid);
if (pStatusBar != NULL)
{
const int widths[4] = { -4, -2, -2, 0 };
pStatusBar->SetStatusWidths(3, widths);
}
}
return (WINDOW)pStatusBar;
}
BOOLEAN statbar_destroy(WINDOW win)
{
wxStatusBar* pStatusBar = WIN2StatBar(win);
if (pStatusBar != NULL)
{
if (_task_win->GetStatusBar() == pStatusBar)
_task_win->SetStatusBar(NULL);
pStatusBar->Destroy();
}
return pStatusBar != NULL;
}