Files correlati : xvaga.dll Ricompilazione Demo : [ ] Commento : 0001220: Esportazione in PDF Se imposto il foglio in orizzontale, l'esportazione in pdf sembra rigirare il foglio in verticale troncando la stampa. Impostando la stampante come pdf creator la stampa viene corretta. git-svn-id: svn://10.65.10.50/trunk@18609 c028cbd2-c16b-5b4b-a496-9718f37d4682
4790 lines
109 KiB
C++
Executable File
4790 lines
109 KiB
C++
Executable File
#include "wxinc.h"
|
||
|
||
#include <wx/clipbrd.h>
|
||
#include <wx/calctrl.h>
|
||
#include <wx/colordlg.h>
|
||
#include <wx/dialup.h>
|
||
#include <wx/fileconf.h>
|
||
#include <wx/filename.h>
|
||
#include <wx/fontdlg.h>
|
||
#include <wx/image.h>
|
||
#include <wx/filefn.h>
|
||
#include <wx/snglinst.h>
|
||
#include <wx/statline.h>
|
||
#include <wx/sysopt.h>
|
||
#include <wx/thread.h>
|
||
#include <wx/tokenzr.h>
|
||
#include <wx/aui/aui.h>
|
||
|
||
#include "xvt.h"
|
||
#include "statbar.h"
|
||
|
||
#include "agasys.h"
|
||
#include "fstrcmp.h"
|
||
#include "matche.h"
|
||
#include "xvtwin.h"
|
||
|
||
#ifdef WIN32
|
||
#include "oswin32.h"
|
||
#include "XFont.h"
|
||
#else
|
||
#include <errno.h>
|
||
#include <unistd.h>
|
||
#include "oslinux.h"
|
||
#include <wx/dcps.h>
|
||
#include <wx/hash.h>
|
||
#endif
|
||
|
||
#define XVT_ASSERT(test) _AssertBox((test), __FUNCTION__, __FILE__, __LINE__)
|
||
#define CAST_WIN(win,w) wxWindow& w = *wxStaticCast((wxObject*)win, wxWindow);
|
||
#define CAST_TWIN(win,w) TwxWindow& w = *wxStaticCast((wxObject*)win, TwxWindow);
|
||
#define CAST_TDC(win,dc) TDC& dc = GetTDCMapper().GetTDC(win);
|
||
#define CAST_DC(win,dc) wxDC& dc = GetTDCMapper().GetDC(win);
|
||
#define CAST_FONT(font_id, font) TFontId& font = *wxStaticCast(font_id, TFontId);
|
||
|
||
wxWindow* _mouse_trapper = NULL;
|
||
RCT _startup_rect = { 0,0,0,0 };
|
||
long _startup_style = 0;
|
||
wxString _startup_dir;
|
||
wxString _strDefaultStatbarText;
|
||
wxString _appl_name;
|
||
wxLocale* _locale = NULL;
|
||
|
||
static wxHashTable _nice_icons;
|
||
static XVT_ERRMSG_HANDLER _error_handler = NULL;
|
||
|
||
const wxString& _GetAppTitle()
|
||
{ return _appl_name; }
|
||
|
||
class TMessageBox : public wxDialog
|
||
{
|
||
protected:
|
||
void OnButton(wxCommandEvent& evt);
|
||
void AddButton(wxSizer* sz, int id, int ico);
|
||
DECLARE_EVENT_TABLE()
|
||
|
||
public:
|
||
TMessageBox(const wxString& msg, int nStyle);
|
||
};
|
||
|
||
BEGIN_EVENT_TABLE(TMessageBox, wxDialog)
|
||
EVT_BUTTON(wxID_ANY, TMessageBox::OnButton)
|
||
END_EVENT_TABLE()
|
||
|
||
void TMessageBox::OnButton(wxCommandEvent& evt)
|
||
{
|
||
int ec = wxCANCEL;
|
||
switch (evt.GetId())
|
||
{
|
||
case wxID_YES: ec = wxYES; break;
|
||
case wxID_OK : ec = wxOK; break;
|
||
case wxID_NO : ec = wxNO; break;
|
||
default : ec = wxCANCEL; break;
|
||
}
|
||
EndModal(ec);
|
||
}
|
||
|
||
void TMessageBox::AddButton(wxSizer* sz, int id, int WXUNUSED(ico))
|
||
{
|
||
sz->Add(new wxButton(this, id, wxEmptyString, wxDefaultPosition,
|
||
wxSize(80, 32)), 0, wxALL, 4);
|
||
}
|
||
|
||
TMessageBox::TMessageBox(const wxString& msg, int nStyle)
|
||
: wxDialog(NULL, wxID_ANY, _GetAppTitle(), wxDefaultPosition, wxDefaultSize,
|
||
wxCAPTION | wxRAISED_BORDER)
|
||
{
|
||
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||
SetSizer(sizer);
|
||
|
||
wxBoxSizer* sz1 = new wxBoxSizer(wxHORIZONTAL);
|
||
sizer->Add(sz1);
|
||
int nIco = 162;
|
||
if (nStyle & wxICON_ERROR) nIco = 201;
|
||
if (nStyle & wxICON_QUESTION) nIco = 202;
|
||
if (nStyle & wxICON_EXCLAMATION) nIco = 203;
|
||
const int nBorder = 8;
|
||
sz1->Add(new wxStaticBitmap(this, nIco, _GetToolResource(nIco, 64)), 0, wxALL, nBorder);
|
||
wxStaticText* ss = new wxStaticText(this, wxID_ANY, wxEmptyString);
|
||
ss->Wrap(160);
|
||
ss->SetLabel(msg);
|
||
sz1->Add(ss, 0, wxALL | wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL, nBorder);
|
||
|
||
sizer->Add(new wxStaticLine(this), 0, wxALL | wxEXPAND, nBorder);
|
||
|
||
wxBoxSizer* sz2 = new wxBoxSizer(wxHORIZONTAL);
|
||
sizer->Add(sz2, 0, wxALIGN_CENTER);
|
||
if (nStyle & wxYES_NO)
|
||
{
|
||
SetAffirmativeId(wxID_YES);
|
||
if (nStyle & wxNO_DEFAULT)
|
||
{
|
||
AddButton(sz2, wxID_NO, 102);
|
||
AddButton(sz2, wxID_YES, 101);
|
||
}
|
||
else
|
||
{
|
||
AddButton(sz2, wxID_YES, 101);
|
||
AddButton(sz2, wxID_NO, 102);
|
||
}
|
||
}
|
||
if (nStyle & wxOK)
|
||
{
|
||
SetAffirmativeId(wxID_OK);
|
||
AddButton(sz2, wxID_OK, 101);
|
||
}
|
||
if (nStyle & wxCANCEL)
|
||
{
|
||
SetEscapeId(wxID_CANCEL);
|
||
AddButton(sz2, wxID_CANCEL, 102);
|
||
}
|
||
|
||
sizer->SetSizeHints(this);
|
||
|
||
if (nStyle & wxCENTRE)
|
||
Centre();
|
||
}
|
||
|
||
int _MessageBox(const wxString& msg, int nStyle)
|
||
{
|
||
xvt_dm_post_speech(msg, 1, TRUE);
|
||
|
||
//int ret = ::wxMessageBox(msg, _GetAppTitle(), nStyle);
|
||
TMessageBox dlg(msg, nStyle);
|
||
const int ret = dlg.ShowModal();
|
||
|
||
switch(ret)
|
||
{
|
||
case wxOK : xvt_dm_post_speech("ok", 7, TRUE); break;
|
||
case wxYES: xvt_dm_post_speech("si", 7, TRUE); break;
|
||
case wxNO : xvt_dm_post_speech("no", 7, TRUE); break;
|
||
default : xvt_dm_post_speech("annulla", 7, TRUE); break;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
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\nfunction %s in file %s at line %d .",
|
||
func, file, line);
|
||
_MessageBox(strMessage, wxOK|wxICON_ERROR);
|
||
}
|
||
}
|
||
}
|
||
|
||
void xvt_sys_sorry_box(const char* func, const char* file, int line)
|
||
{
|
||
static wxHashTable sorry(wxKEY_STRING);
|
||
if (sorry.Get(func) == NULL)
|
||
{
|
||
sorry.Put(func, &sorry); // Dummy
|
||
wxString strMessage;
|
||
strMessage.Printf("Function %s in file %s at line %d\nis not implemented yet: be patient...",
|
||
func, file, line);
|
||
_MessageBox(strMessage, wxOK | wxICON_WARNING);
|
||
}
|
||
}
|
||
|
||
void xvt_sys_deprecated_box(const char* func, const char* file, int line)
|
||
{
|
||
static wxHashTable deprecated;
|
||
if (deprecated.Get(func) == NULL)
|
||
{
|
||
deprecated.Put(func, &deprecated); // Dummy
|
||
wxString strMessage;
|
||
strMessage.Printf("Function %s in file %s at line %d is deprecated:\nYou can blame Guy for this, if you're bold enough!",
|
||
func, file, line);
|
||
_MessageBox(strMessage, wxOK | wxICON_WARNING);
|
||
}
|
||
}
|
||
|
||
static bool RectIntersect(const wxRect &rect1, const wxRect &rect2)
|
||
{
|
||
if (rect1.GetRight() < rect2.GetLeft())
|
||
return false;
|
||
if (rect2.GetRight() < rect1.GetLeft())
|
||
return false;
|
||
if (rect1.GetBottom() < rect2.GetTop())
|
||
return false;
|
||
if (rect2.GetBottom() < rect1.GetTop())
|
||
return false;
|
||
return true;
|
||
}
|
||
|
||
wxString GetResourceIni()
|
||
{ return _startup_dir + "/res/resource.ini"; }
|
||
|
||
wxString _GetResourceName(const char* type, int rid)
|
||
{
|
||
wxString strName(type); strName << "s";
|
||
wxString strKey; strKey.Printf("%d", rid);
|
||
|
||
if ((rid == ICON_RSRC || rid == 0) && strName == "Icons")
|
||
{
|
||
wxString strFileName = _startup_dir + "/setup/oem.ini";
|
||
const int oem = xvt_sys_get_profile_int(strFileName, "MAIN", "OEM", -1);
|
||
if (oem >= 0)
|
||
{
|
||
wxString strPara; strPara << "OEM_" << oem;
|
||
char name[MAX_PATH];
|
||
xvt_sys_get_profile_string(strFileName, strPara, "Icon", "", name, sizeof(name));
|
||
if (*name)
|
||
{
|
||
strFileName = _startup_dir + "/setup/" + name;
|
||
if (wxFileExists(strFileName))
|
||
return strFileName;
|
||
}
|
||
}
|
||
}
|
||
|
||
wxString val;
|
||
char* buff = val.GetWriteBuf(MAX_PATH);
|
||
xvt_sys_get_profile_string(GetResourceIni(), strName, strKey, "", buff, MAX_PATH);
|
||
val.UngetWriteBuf();
|
||
|
||
if (!val.IsEmpty())
|
||
{
|
||
strName = _startup_dir;
|
||
strName += "/custom/";
|
||
strName += val;
|
||
if (!wxFileExists(strName))
|
||
{
|
||
strName = _startup_dir;
|
||
strName += "/res/";
|
||
strName += val;
|
||
}
|
||
}
|
||
else
|
||
strName.Empty();
|
||
return strName;
|
||
}
|
||
|
||
static wxIcon* _GetDefaultIcon()
|
||
{
|
||
wxIcon* icon = NULL;
|
||
|
||
wxString strName = _GetResourceName("Icon", ICON_RSRC);
|
||
if (::wxFileExists(strName))
|
||
icon = new wxIcon(strName, wxBITMAP_TYPE_ICO);
|
||
else
|
||
{
|
||
strName.Printf("%d", ICON_RSRC);
|
||
icon = new wxIcon(strName, wxBITMAP_TYPE_ICO_RESOURCE);
|
||
}
|
||
return icon;
|
||
}
|
||
|
||
const wxIcon& _GetIconResource(int rid)
|
||
{
|
||
wxIcon* icon = wxDynamicCast(_nice_icons.Get(rid), wxIcon);
|
||
if (icon == NULL)
|
||
{
|
||
if (rid > 0 && rid != ICON_RSRC)
|
||
{
|
||
const wxString strName = _GetResourceName("Icon", rid);
|
||
if (::wxFileExists(strName))
|
||
icon = new wxIcon(strName, wxBITMAP_TYPE_ICO);
|
||
}
|
||
if (icon == NULL)
|
||
icon = _GetDefaultIcon(); // Icona di salvezza
|
||
|
||
_nice_icons.Put(rid, icon);
|
||
}
|
||
return *icon;
|
||
}
|
||
|
||
const wxCursor* GetCursorResource(int rid)
|
||
{
|
||
static wxHashTable _nice_cursors;
|
||
const wxCursor* cursor = wxDynamicCast(_nice_cursors.Get(rid), wxCursor);
|
||
if (cursor == NULL)
|
||
{
|
||
switch (rid)
|
||
{
|
||
case CURSOR_CROCE: cursor = new wxCursor(wxCURSOR_CROSS); break;
|
||
case CURSOR_IBEAM: cursor = new wxCursor(wxCURSOR_IBEAM); break;
|
||
default:
|
||
{
|
||
const wxString strName = _GetResourceName("Cursor", rid);
|
||
if (::wxFileExists(strName))
|
||
{
|
||
if (strName.Find(".ico") > 0)
|
||
cursor = new wxCursor(strName, wxBITMAP_TYPE_ICO);
|
||
else
|
||
cursor = new wxCursor(strName, wxBITMAP_TYPE_CUR);
|
||
|
||
if (!cursor->Ok())
|
||
{
|
||
delete cursor;
|
||
cursor = NULL;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
if (cursor == NULL)
|
||
{
|
||
XVT_ASSERT(false);
|
||
cursor = wxSTANDARD_CURSOR;
|
||
}
|
||
_nice_cursors.Put(rid, (wxCursor*)cursor);
|
||
}
|
||
return cursor;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Font cache
|
||
///////////////////////////////////////////////////////////
|
||
|
||
WX_DECLARE_HASH_MAP(wxString, wxFont*, wxStringHash, wxStringEqual, 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;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Speech support
|
||
///////////////////////////////////////////////////////////
|
||
|
||
// 0 Errors
|
||
// 1 Warnings
|
||
// 2 Messages
|
||
// 3 Requests
|
||
// 7 Buttons
|
||
static int m_nSpeechMode = 0;
|
||
|
||
void xvt_dm_enable_speech(int mode)
|
||
{
|
||
#ifdef SPEECH_API
|
||
m_nSpeechMode = mode;
|
||
#ifdef WIN32
|
||
if (m_nSpeechMode != 0)
|
||
{
|
||
if (!OsWin32_InitializeSpeech())
|
||
m_nSpeechMode = 0;
|
||
}
|
||
else
|
||
{
|
||
OsWin32_DeinitializeSpeech();
|
||
}
|
||
#endif
|
||
#endif
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// XVT
|
||
///////////////////////////////////////////////////////////
|
||
|
||
void xvt_app_allow_quit(void)
|
||
{
|
||
wxTheApp->ExitMainLoop(); // Gi<47> 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();
|
||
|
||
#ifdef WIN32
|
||
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 argc, char **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;
|
||
bool bHasMenu = true, bCanChangeFirm = true;
|
||
|
||
#ifdef WIN32
|
||
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
|
||
|
||
bHasMenu = (szWin.y - szCli.y) < 2;
|
||
bCanChangeFirm = false;
|
||
}
|
||
#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 WIN32
|
||
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;
|
||
}
|
||
|
||
if (bHasMenu)
|
||
{
|
||
wxMenu* Menus[3];
|
||
wxString Title[3];
|
||
Title[0] = "&File";
|
||
Menus[0] = new wxMenu;
|
||
|
||
if (bCanChangeFirm)
|
||
{
|
||
Menus[0]->Append(M_FILE_NEW, "Scelta &Ditta...");
|
||
Menus[0]->AppendSeparator();
|
||
}
|
||
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");
|
||
|
||
#ifdef WIN32
|
||
wxMenuBar* pMenubar = new wxMenuBar(3, Menus, Title);
|
||
#else
|
||
wxMenuBar* pMenubar = new wxMenuBar();
|
||
for (int i= 0; i < 3; i++)
|
||
pMenubar->Append(Menus[i], Title[i]);
|
||
#endif
|
||
_task_win->SetMenuBar(pMenubar);
|
||
}
|
||
|
||
if (style & wxMAXIMIZE)
|
||
_task_win->Maximize();
|
||
_task_win->Show();
|
||
|
||
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 wxWindows
|
||
}
|
||
|
||
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
|
||
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 WIN32
|
||
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 WIN32
|
||
return OsWin32_HL_Login(address, label, password);
|
||
#else
|
||
return OsLinux_HL_Login(address, label, password);
|
||
#endif
|
||
}
|
||
|
||
BOOLEAN xvt_dongle_hl_logout()
|
||
{
|
||
#ifdef WIN32
|
||
return OsWin32_HL_Logout();
|
||
#else
|
||
return OsLinux_HL_Logout();
|
||
#endif
|
||
}
|
||
|
||
BOOLEAN xvt_dongle_hl_read(unsigned short reg, unsigned short* data)
|
||
{
|
||
#ifdef WIN32
|
||
return OsWin32_HL_Read(reg, data);
|
||
#else
|
||
return OsLinux_HL_Read(reg, data);
|
||
#endif
|
||
}
|
||
|
||
BOOLEAN xvt_dongle_hl_read_block(unsigned char* data)
|
||
{
|
||
#ifdef WIN32
|
||
return OsWin32_HL_ReadBlock(data);
|
||
#else
|
||
return OsLinux_HL_ReadBlock(data);
|
||
#endif
|
||
}
|
||
|
||
BOOLEAN xvt_dongle_hl_write(unsigned short reg, unsigned short data)
|
||
{
|
||
#ifdef WIN32
|
||
return OsWin32_HL_Write(reg, data);
|
||
#else
|
||
return OsLinux_HL_Write(reg, data);
|
||
#endif
|
||
}
|
||
|
||
BOOLEAN xvt_dongle_sl_crypt(unsigned short* data)
|
||
{
|
||
#ifdef WIN32
|
||
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 WIN32
|
||
return OsWin32_SL_Login(label, password);
|
||
#else
|
||
return OsLinux_SL_Login(label, password);
|
||
#endif
|
||
}
|
||
|
||
BOOLEAN xvt_dongle_sl_logout()
|
||
{
|
||
#ifdef WIN32
|
||
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 WIN32
|
||
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 WIN32
|
||
return OsWin32_SL_WriteBlock(reg, size, data);
|
||
#else
|
||
return OsLinux_SL_WriteBlock(reg, size, data);
|
||
#endif
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Common dialogs
|
||
///////////////////////////////////////////////////////////
|
||
|
||
COLOR xvt_dm_post_choose_color(WINDOW win, COLOR xc)
|
||
{
|
||
CAST_COLOR(xc, wc);
|
||
|
||
wxColourData cd;
|
||
cd.SetChooseFull(true);
|
||
cd.SetColour(wc);
|
||
for (int i = 0; i < 16; i++)
|
||
{
|
||
const unsigned char val = (i & 0x8) ? 255 : 127;
|
||
const unsigned char red = (i & 0x1) ? val : 0;
|
||
const unsigned char green = (i & 0x2) ? val : 0;
|
||
const unsigned char blue = (i & 0x4) ? val : 0;
|
||
wxColour col(red, green, blue);
|
||
cd.SetCustomColour(i, col);
|
||
}
|
||
|
||
CAST_WIN(win, w);
|
||
wxColourDialog dialog(&w, &cd);
|
||
if (dialog.ShowModal() == wxID_OK)
|
||
{
|
||
xc = MAKE_XVT_COLOR(dialog.GetColourData().GetColour());
|
||
if (xc == 0) xc = COLOR_BLACK; // 0x000000 confonde XI, mentre con 0x07000000 e' a suo agio
|
||
}
|
||
|
||
return xc;
|
||
}
|
||
|
||
class TwxCalendarDlg : public wxDialog
|
||
{
|
||
enum { ID_CAL = 1883 };
|
||
wxDateTime& m_date;
|
||
wxCalendarCtrl* m_cal;
|
||
|
||
protected:
|
||
virtual bool TransferDataFromWindow();
|
||
void OnCalendar(wxCalendarEvent& e);
|
||
|
||
public:
|
||
TwxCalendarDlg(wxWindow* parent, wxDateTime& date);
|
||
|
||
DECLARE_EVENT_TABLE()
|
||
};
|
||
|
||
BEGIN_EVENT_TABLE(TwxCalendarDlg, wxDialog)
|
||
EVT_CALENDAR(wxID_ANY, TwxCalendarDlg::OnCalendar)
|
||
END_EVENT_TABLE()
|
||
|
||
void TwxCalendarDlg::OnCalendar(wxCalendarEvent& WXUNUSED(e))
|
||
{
|
||
wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK);
|
||
AddPendingEvent(evt);
|
||
}
|
||
|
||
bool TwxCalendarDlg::TransferDataFromWindow()
|
||
{
|
||
bool ok = wxDialog::TransferDataFromWindow();
|
||
if (ok)
|
||
m_date = m_cal->GetDate();
|
||
return ok;
|
||
}
|
||
|
||
TwxCalendarDlg::TwxCalendarDlg(wxWindow* parent, wxDateTime& date)
|
||
: wxDialog(parent, wxID_ANY, "Data", wxDefaultPosition, wxDefaultSize, wxRAISED_BORDER), m_date(date)
|
||
{
|
||
|
||
m_cal = new wxCalendarCtrl(this, ID_CAL, m_date, wxDefaultPosition, wxDefaultSize,
|
||
wxCAL_MONDAY_FIRST | wxCAL_SHOW_HOLIDAYS | wxCAL_SHOW_SURROUNDING_WEEKS);
|
||
|
||
wxButton* button = new wxButton(this, wxID_OK, "OK");
|
||
|
||
wxGridSizer* sizer = new wxFlexGridSizer(2, 1, 8, 8);
|
||
sizer->Add(m_cal, 0, wxALIGN_CENTER);
|
||
sizer->Add(button, 0, wxALIGN_CENTER);
|
||
SetSizer(sizer);
|
||
sizer->SetSizeHints(this);
|
||
}
|
||
|
||
unsigned int xvt_dm_post_choose_date(WINDOW win, const RCT* rct, unsigned int ansidate)
|
||
{
|
||
int d = ansidate%100;
|
||
int m = (ansidate/100)%100;
|
||
int y = ansidate / 10000;
|
||
|
||
wxDateTime date;
|
||
if (d >= 1 && d <= 31 && m >= 1 && m <= 12 && y > 1900)
|
||
date.Set(d, wxDateTime::Month(m-1), y);
|
||
else
|
||
date = wxDateTime::Today();
|
||
|
||
CAST_WIN(win, w);
|
||
wxDialog* dlg = new TwxCalendarDlg(&w, date);
|
||
|
||
if (rct != NULL)
|
||
{
|
||
const wxRect client = w.GetClientRect();
|
||
const wxRect rect = dlg->GetRect();
|
||
wxPoint pos(rct->right - rect.width, rct->bottom);
|
||
if (pos.x < 0)
|
||
pos.x = rct->left;
|
||
if (rct->bottom + rect.height > client.GetBottom())
|
||
pos.y = rct->top - rect.height;
|
||
dlg->Move(w.ClientToScreen(pos));
|
||
}
|
||
|
||
if (dlg->ShowModal() == wxID_OK)
|
||
{
|
||
d = date.GetDay();
|
||
m = date.GetMonth()+1;
|
||
y = date.GetYear();
|
||
ansidate = y*10000 + m*100 + d;
|
||
}
|
||
dlg->Destroy();
|
||
|
||
return ansidate;
|
||
}
|
||
|
||
BOOLEAN xvt_dm_post_speech(const char* text, int priority, BOOLEAN async)
|
||
{
|
||
BOOLEAN ok = FALSE;
|
||
#ifdef SPEECH_API
|
||
if ((m_nSpeechMode & (1 << priority)) != 0)
|
||
{
|
||
#ifdef WIN32
|
||
ok = OsWin32_Speak(text, async != 0);
|
||
#endif
|
||
}
|
||
#endif
|
||
return ok;
|
||
}
|
||
|
||
ASK_RESPONSE xvt_dm_post_ask(const char* Btn1, const char* Btn2, const char* Btn3, const char* fmt)
|
||
{
|
||
int nFlags = wxCENTRE | wxICON_QUESTION | wxYES_NO;
|
||
if (Btn3 == NULL)
|
||
{
|
||
if (wxStricmp(Btn1, "no") == 0)
|
||
nFlags |= wxNO_DEFAULT;
|
||
}
|
||
else
|
||
nFlags |= wxCANCEL;
|
||
|
||
const int answer = _MessageBox(fmt, nFlags);
|
||
return answer == wxYES ? RESP_DEFAULT : (answer == wxNO ? RESP_2 : RESP_3);
|
||
}
|
||
|
||
void xvt_dm_post_error(const char *fmt)
|
||
{
|
||
_MessageBox(fmt, wxOK | wxCENTRE | wxICON_HAND);
|
||
}
|
||
|
||
void xvt_dm_post_fatal_exit(const char *fmt)
|
||
{
|
||
xvt_dm_post_speech(fmt, 1, TRUE);
|
||
wxLogFatalError(fmt);
|
||
xvt_dm_post_speech("OK", 7, TRUE);
|
||
}
|
||
|
||
static wxString MakeFileName(const wxChar* name, const wxChar* ext)
|
||
{
|
||
wxString f = name;
|
||
if (ext && *ext)
|
||
{
|
||
if (*ext != '.')
|
||
f += '.';
|
||
f += ext;
|
||
}
|
||
return f;
|
||
}
|
||
|
||
static FL_STATUS xvt_dm_post_file_ask(FILE_SPEC *fsp, const char *msg, int flags)
|
||
{
|
||
DIRECTORY savedir; xvt_fsys_get_dir(&savedir); // Salvo cartella corrente
|
||
|
||
wxString path = fsp->dir.path;
|
||
wxString name = MakeFileName(fsp->name, fsp->type);
|
||
wxString extension = fsp->type;
|
||
wxString mask = MakeFileName("*", fsp->type);
|
||
|
||
wxString selectedname = wxFileSelector(msg, path, name, extension , mask, flags);
|
||
if (selectedname.IsEmpty())
|
||
return FL_CANCEL;
|
||
xvt_fsys_convert_str_to_fspec(selectedname, fsp);
|
||
|
||
xvt_fsys_set_dir(&savedir); // Ripristino cartella corrente
|
||
|
||
return FL_OK;
|
||
}
|
||
|
||
FL_STATUS xvt_dm_post_file_open(FILE_SPEC *fsp, const char *msg)
|
||
{
|
||
const int flags = wxOPEN | wxFILE_MUST_EXIST;
|
||
return xvt_dm_post_file_ask(fsp, msg, flags);
|
||
}
|
||
|
||
FL_STATUS xvt_dm_post_file_save(FILE_SPEC *fsp, const char *msg)
|
||
{
|
||
const int flags = wxSAVE | wxOVERWRITE_PROMPT;
|
||
return xvt_dm_post_file_ask(fsp, msg, flags);
|
||
}
|
||
|
||
FL_STATUS xvt_dm_post_dir_sel(DIRECTORY *dir)
|
||
{
|
||
wxDirDialog dlg(_task_win);
|
||
dlg.SetPath(dir->path);
|
||
if (dlg.ShowModal() == wxID_OK)
|
||
{
|
||
xvt_fsys_convert_str_to_dir(dlg.GetPath(), dir);
|
||
return FL_OK;
|
||
}
|
||
return FL_CANCEL;
|
||
}
|
||
|
||
BOOLEAN xvt_dm_post_font_sel(WINDOW win, XVT_FNTID font_id, PRINT_RCD* WXUNUSED(precp), unsigned long reserved)
|
||
{
|
||
CAST_FONT(font_id, font);
|
||
wxFontData data;
|
||
data.SetInitialFont(font.Font(NULL, win));
|
||
data.EnableEffects(reserved != 0);
|
||
wxFontDialog dlg(_task_win, data);
|
||
BOOLEAN ok = dlg.ShowModal() == wxID_OK;
|
||
if (ok)
|
||
{
|
||
font.Copy(dlg.GetFontData().GetChosenFont());
|
||
if (win == (WINDOW)_task_win)
|
||
{
|
||
EVENT e; memset(&e, 0, sizeof(EVENT));
|
||
e.type = E_FONT;
|
||
e.v.font.font_id = font_id;
|
||
_task_win_handler(win, &e);
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
void xvt_dm_post_message(const char *fmt)
|
||
{
|
||
_MessageBox(fmt, wxOK | wxCENTRE | wxICON_INFORMATION);
|
||
}
|
||
|
||
void xvt_dm_post_note(const char *fmt)
|
||
{
|
||
_MessageBox(fmt, wxOK | wxCENTRE | wxICON_EXCLAMATION);
|
||
}
|
||
|
||
char* xvt_dm_post_string_prompt(const char* message, char* response, int response_len)
|
||
{
|
||
XVT_ASSERT(message && response && response_len > 0);
|
||
wxTextEntryDialog dlg(NULL, message, _GetAppTitle(), response);
|
||
if (dlg.ShowModal() == wxID_OK)
|
||
{
|
||
wxStrncpy(response, dlg.GetValue(), response_len);
|
||
response[response_len-1] = '\0';
|
||
}
|
||
else
|
||
*response = '\0';
|
||
return response;
|
||
}
|
||
|
||
void xvt_dm_post_warning(const char *fmt)
|
||
{
|
||
_MessageBox(fmt, wxOK | wxCENTRE | wxICON_EXCLAMATION);
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Help system
|
||
///////////////////////////////////////////////////////////
|
||
|
||
struct XVAGA_HELP_INFO
|
||
{
|
||
wxString m_strFilename;
|
||
bool m_hlp;
|
||
} help_info;
|
||
|
||
XVT_HELP_INFO xvt_help_open_helpfile(FILE_SPEC* WXUNUSED(fs), unsigned long WXUNUSED(flags))
|
||
{
|
||
return (XVT_HELP_INFO)&help_info;
|
||
}
|
||
|
||
void xvt_help_close_helpfile(XVT_HELP_INFO hi)
|
||
{
|
||
if (hi == NULL_HELP_INFO)
|
||
hi = (XVT_HELP_INFO)&help_info;
|
||
}
|
||
|
||
BOOLEAN xvt_help_process_event(XVT_HELP_INFO hi, WINDOW win, EVENT *ev)
|
||
{
|
||
BOOLEAN bProcessed = FALSE;
|
||
|
||
#ifdef WIN32
|
||
WXHWND hwnd = (WXHWND)xvt_vobj_get_attr(win, ATTR_NATIVE_WINDOW);
|
||
switch (ev->type)
|
||
{
|
||
case E_COMMAND:
|
||
bProcessed = OsWin32_Help(hwnd, "", ev->v.cmd.tag, NULL);
|
||
break;
|
||
case E_HELP:
|
||
bProcessed = OsWin32_Help(hwnd, "", M_HELP_ONCONTEXT, (const char*)ev->v.help.tid);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
#endif // WIN32
|
||
|
||
return bProcessed;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Image handling
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TXVT_IMAGE : public wxImage
|
||
{
|
||
DECLARE_DYNAMIC_CLASS(TXVT_IMAGE);
|
||
|
||
int m_nDepth;
|
||
bool m_bDirty;
|
||
|
||
#ifdef WIN32
|
||
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 WIN32
|
||
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 WIN32
|
||
|
||
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 WIN32
|
||
::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 WIN32
|
||
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 WIN32
|
||
// 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 = NormalizeRCT(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 = NormalizeRCT(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 = NormalizeRCT(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 = _GetIconResource(rid);
|
||
if (ico.IsOk())
|
||
{
|
||
CAST_DC(win, dc);
|
||
dc.DrawIcon(ico, x, y);
|
||
}
|
||
}
|
||
|
||
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 WIN32
|
||
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)
|
||
{
|
||
if (xvt_dwin_is_update_needed(win, dest))
|
||
{
|
||
CAST_DC(win, dc);
|
||
const wxRect src = NormalizeRCT(source);
|
||
const wxRect dst = NormalizeRCT(dest);
|
||
DrawImageOnDC(dc, image, dst, src);
|
||
}
|
||
}
|
||
}
|
||
|
||
void xvt_dwin_draw_oval(WINDOW win, const RCT* rctp)
|
||
{
|
||
CAST_DC(win, dc);
|
||
const wxRect rct = NormalizeRCT(rctp);
|
||
dc.DrawEllipse(rct);
|
||
}
|
||
|
||
void xvt_dwin_draw_pie(WINDOW win, const RCT *rctp, int start_x, int start_y, int stop_x, int stop_y)
|
||
{ SORRY_BOX(); }
|
||
|
||
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 = NormalizeRCT(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 = NormalizeRCT(rctp);
|
||
dc.DrawRoundedRectangle(rct, min(oval_width, oval_height));
|
||
}
|
||
|
||
void xvt_dwin_draw_dotted_rect(WINDOW win, RCT *rctp)
|
||
{
|
||
#ifdef WIN32
|
||
static int can_draw_dots = -1;
|
||
if (can_draw_dots < 0)
|
||
can_draw_dots = xvt_sys_get_os_version() >= XVT_WS_WIN_NT;
|
||
if (can_draw_dots)
|
||
{
|
||
CAST_DC(win, dc);
|
||
OsWin32_DrawDottedRect(dc.GetHDC(), rctp->left, rctp->top, rctp->right, rctp->bottom);
|
||
return;
|
||
}
|
||
#endif
|
||
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);
|
||
}
|
||
|
||
void xvt_dwin_draw_set_pos(WINDOW win, PNT pnt)
|
||
{
|
||
CAST_TDC(win, dc);
|
||
dc._pnt.x = pnt.h;
|
||
dc._pnt.y = pnt.v;
|
||
}
|
||
|
||
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!
|
||
#ifdef LINUX
|
||
if (tdc._dct.opaque_text)
|
||
{
|
||
RCT back;
|
||
back.left = x;
|
||
back.right = x + xvt_dwin_get_text_width(win, str, -1);
|
||
back.top = y - delta;
|
||
back.bottom = y;
|
||
CAST_COLOR(tdc._dct.back_color, brush_color);
|
||
|
||
wxBrush* brush = wxTheBrushList->FindOrCreateBrush(brush_color, wxSOLID);
|
||
const wxBrush & old_brush = dc.GetBrush();
|
||
const wxPen & old_pen = dc.GetPen();
|
||
const wxRect rct = NormalizeRCT(&back);
|
||
|
||
dc.SetBrush(*brush);
|
||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||
dc.DrawRectangle(rct);
|
||
dc.SetBrush(old_brush);
|
||
dc.SetPen(old_pen);
|
||
}
|
||
#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 = "Mg";
|
||
int height, desc, lead;
|
||
dc.GetTextExtent(str, NULL, &height, &desc, &lead);
|
||
if (leadingp)
|
||
*leadingp = lead;
|
||
if (ascentp)
|
||
*ascentp = height-lead-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 = NormalizeRCT(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 = NormalizeRCT(rctp);
|
||
const wxRect rect2 = w.GetUpdateClientRect();
|
||
return RectIntersect(rect1, 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 = NormalizeRCT(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);
|
||
wxDC& dc = tdc.GetDC();
|
||
if (tdc._pnt != to)
|
||
dc.DrawLine(tdc._pnt, to);
|
||
// dc.DrawPoint(to); // 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)
|
||
{
|
||
if (font_id != NULL)
|
||
{
|
||
TFontId* fp = wxStaticCast(font_id, TFontId);
|
||
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 = "Mq";
|
||
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-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 WIN32
|
||
_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 WIN32
|
||
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 (mbs && *mbs && fs != NULL)
|
||
{
|
||
memset(fs, 0, sizeof(FILE_SPEC));
|
||
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);
|
||
wxStrcpy(fs->creator, "CAMPO");
|
||
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 WIN32
|
||
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 WIN32
|
||
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 WIN32
|
||
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 = ::wxFileExists(name);
|
||
break;
|
||
case XVT_FILE_ATTR_READ:
|
||
ret = ::wxAccess(name, 0x1) != 0;
|
||
break;
|
||
case XVT_FILE_ATTR_WRITE:
|
||
ret = ::wxAccess(name, 0x2) != 0;
|
||
break;
|
||
case XVT_FILE_ATTR_DIRECTORY:
|
||
ret = ::wxDirExists(name);
|
||
break;
|
||
case XVT_FILE_ATTR_SIZE:
|
||
{
|
||
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;
|
||
|
||
wxString f = ::wxFindFirstFile(pat, flags);
|
||
while (!f.IsEmpty())
|
||
{
|
||
#ifdef WIN32
|
||
if (f.StartsWith(".\\"))
|
||
#else
|
||
if (f.StartsWith("./"))
|
||
#endif
|
||
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);
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Images
|
||
///////////////////////////////////////////////////////////
|
||
|
||
inline bool XVT_SAME_COLOR(COLOR col1, COLOR col2) { return (col1 & 0x00FFFFFF) == (col2 & 0x00FFFFFF); }
|
||
|
||
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 = NormalizeRCT(&rct);
|
||
}
|
||
else
|
||
r = NormalizeRCT(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 format, short width, short height, long reserved)
|
||
{
|
||
TXVT_IMAGE* i = new TXVT_IMAGE;
|
||
i->Image().Create(width, height);
|
||
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;
|
||
CAST_IMAGE(image, i);
|
||
if (i != NULL && i->Ok() && i->HasPalette())
|
||
{
|
||
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 WIN32
|
||
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 image, short 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 = NormalizeRCT(dstrctp);
|
||
const wxRect rctSrc = NormalizeRCT(srcrctp);
|
||
wxMemoryDC dc;
|
||
wxBitmap bmp(*dst);
|
||
dc.SelectObject(bmp);
|
||
DrawImageOnDC(dc, src, rctDst, rctSrc);
|
||
dst->Image() = bmp.ConvertToImage();
|
||
dc.SelectObject(wxNullBitmap);
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// 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 = *(TTaskWin*)win;
|
||
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 font_id)
|
||
{ /* Ignored */ }
|
||
|
||
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 palet, COLOR *colorsp, short numcolors) { return 0; }
|
||
short xvt_palet_add_colors_from_image(XVT_PALETTE palet, XVT_IMAGE image) { return 0; }
|
||
XVT_PALETTE xvt_palet_create(XVT_PALETTE_TYPE type, XVT_PALETTE_ATTR reserved) { return NULL; }
|
||
void xvt_palet_destroy(XVT_PALETTE palet) { SORRY_BOX(); }
|
||
short xvt_palet_get_colors(XVT_PALETTE palet, COLOR *colorsp, short maxcolors) { return 0; }
|
||
short xvt_palet_get_ncolors(XVT_PALETTE palet) { return 0; }
|
||
int xvt_palet_get_tolerance(XVT_PALETTE p) { return 0; }
|
||
void xvt_palet_set_tolerance(XVT_PALETTE p, int 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 = NormalizeRCT(rctp);
|
||
return rct.Contains(pnt.h, pnt.v);
|
||
}
|
||
|
||
BOOLEAN xvt_rect_intersect(RCT *drctp, const RCT *rctp1, const RCT *rctp2)
|
||
{
|
||
const wxRect rect1 = NormalizeRCT(rctp1);
|
||
const wxRect rect2 = NormalizeRCT(rctp2);
|
||
const BOOLEAN yes = RectIntersect(rect1, 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;
|
||
}
|
||
else
|
||
{
|
||
drctp->left = drctp->right = rect1.x;
|
||
drctp->top = drctp->bottom = rect1.y;
|
||
}
|
||
}
|
||
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;
|
||
}
|
||
|
||
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_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)
|
||
{
|
||
const wxIcon& icon = _GetIconResource(rid);
|
||
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;
|
||
XVT_IMAGE 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 = _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("", "", 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 = _GetResourceName("String", rid);
|
||
wxStrncpy(s, str, sz_s);
|
||
s[sz_s-1] = '\0';
|
||
return s;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Scroll bars
|
||
///////////////////////////////////////////////////////////
|
||
|
||
#define CAST_SCROLL(win, sb) XVT_ASSERT(win != NULL_WIN); wxScrollBar& sb = *(wxScrollBar*)win;
|
||
#define CAST_SCROLL_TYPE(t, dir) const int dir = t == HSCROLL ? wxHORIZONTAL : wxVERTICAL;
|
||
#define CAST_GAUGE(win, pb) XVT_ASSERT(win != NULL_WIN); wxGauge& pb = *(wxGauge*)win;
|
||
#define CAST_SLIDER(win, sc) XVT_ASSERT(win != NULL_WIN); wxSlider& sc = *(wxSlider*)win;
|
||
|
||
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)
|
||
{
|
||
*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 WIN32
|
||
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;
|
||
}
|
||
|
||
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); str1.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;
|
||
wxDialUpManager* dum = wxDialUpManager::Create();
|
||
if (dum != NULL)
|
||
{
|
||
if (dum->IsOk() && dum->IsOnline())
|
||
{
|
||
nStatus = 0x1; // 1 = Online
|
||
|
||
if (dum->IsAlwaysOnline())
|
||
nStatus |= 0x2; // 2 = Always Online
|
||
|
||
wxArrayString isp;
|
||
if (dum->GetISPNames(isp) > 0)
|
||
nStatus |= 0x4; // 4 = Internet enabled
|
||
}
|
||
delete dum;
|
||
}
|
||
return nStatus;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// XVT system calls (added by Guy)
|
||
///////////////////////////////////////////////////////////
|
||
|
||
void xvt_sys_beep(int severity)
|
||
{
|
||
#ifdef WIN32
|
||
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';
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Process processing
|
||
///////////////////////////////////////////////////////////
|
||
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();
|
||
}
|
||
|
||
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
|
||
__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
|
||
exitcode = wxExecute(cmd, wxEXEC_ASYNC);
|
||
|
||
return exitcode;
|
||
}
|
||
|
||
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 WIN32
|
||
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 WIN32
|
||
CAST_WIN(win, w);
|
||
c = OsWin32_CloseChildren((unsigned int)w.GetHandle());
|
||
#endif
|
||
return c;
|
||
}
|
||
|
||
long xvt_sys_close_siblings(WINDOW win)
|
||
{
|
||
long c = 0; // Non sto a perder tempo a contarli :-)
|
||
#ifdef WIN32
|
||
CAST_WIN(win, w);
|
||
OsWin32_CloseSiblings((unsigned int)w.GetHandle());
|
||
#endif
|
||
return c;
|
||
}
|
||
|
||
BOOLEAN xvt_sys_goto_url(const char* url, const char* action)
|
||
{
|
||
#ifdef WIN32
|
||
if (action != NULL && 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");
|
||
BOOLEAN ok = sic.IsAnotherRunning();
|
||
|
||
#ifdef WIN32
|
||
if (!ok) // Testo anche il buon vecchio Frontend!
|
||
ok = ::GlobalFindAtom("DONGLE_SERVER_ATOM") != 0;
|
||
#endif
|
||
|
||
return ok;
|
||
}
|
||
|
||
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 WIN32
|
||
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)
|
||
sprintf(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 WIN32
|
||
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 WIN32
|
||
const wxString e = OsWin32_File2App(file);
|
||
#else
|
||
const wxString e = OsLinux_File2App(file);
|
||
#endif
|
||
ok = !e.IsEmpty();
|
||
if (ok && editor != NULL)
|
||
wxStrcpy(editor, e);
|
||
|
||
return ok;
|
||
}
|
||
|
||
unsigned int xvt_sys_load_icon(const char* file)
|
||
{
|
||
unsigned int id = 0;
|
||
wxIcon* icon = NULL;
|
||
|
||
wxString str = file;
|
||
str.MakeLower();
|
||
if (str.EndsWith(".ico"))
|
||
icon = new wxIcon(file, wxBITMAP_TYPE_ICO);
|
||
else
|
||
{
|
||
#ifdef WIN32
|
||
icon = OsWin32_LoadIcon(file);
|
||
#else
|
||
icon = new wxIcon;
|
||
#endif
|
||
}
|
||
|
||
if (icon != NULL)
|
||
{
|
||
for (id = 60001; ; id++)
|
||
{
|
||
wxIcon* ico = wxDynamicCast(_nice_icons.Get(id), wxIcon);
|
||
if (ico == NULL)
|
||
{
|
||
_nice_icons.Put(id, icon);
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
#ifdef WIN32
|
||
if (ico->GetHICON() == icon->GetHICON()) // C'e' gia'
|
||
#else
|
||
if (ico == icon) // C'e' gia'
|
||
#endif
|
||
{
|
||
delete icon;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return id;
|
||
}
|
||
|
||
int xvt_sys_get_session_id()
|
||
{
|
||
#ifdef WIN32
|
||
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 WIN32
|
||
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_7; break;
|
||
default : os = XVT_WS_WIN_XP; break;
|
||
}
|
||
#else
|
||
os = XVT_WS_LINUX;
|
||
#endif
|
||
return os;
|
||
}
|
||
|
||
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 WIN32
|
||
if (version > XVT_WS_WIN_XP) // 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(filename, varname, pathname);
|
||
}
|
||
|
||
void xvt_sys_search_env(const char * filename, const char * varname, char * pathname)
|
||
{
|
||
#ifdef WIN32
|
||
_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)
|
||
{
|
||
return wxAccess(pathname, mode) == -1 ? errno : 0;
|
||
}
|
||
|
||
BOOLEAN xvt_fsys_file_exists(const char *pathname)
|
||
{
|
||
return xvt_fsys_file_attr(pathname, XVT_FILE_ATTR_EXIST);
|
||
}
|
||
|
||
BOOLEAN xvt_fsys_mkdir(const char *pathname)
|
||
{
|
||
if (wxDirExists(pathname))
|
||
return TRUE;
|
||
return wxMkdir(pathname);
|
||
}
|
||
|
||
BOOLEAN xvt_fsys_rmdir(const char *pathname)
|
||
{
|
||
if (!wxDirExists(pathname))
|
||
return TRUE;
|
||
return wxRmdir(pathname);
|
||
}
|
||
|
||
BOOLEAN xvt_fsys_remove_file(const char *pathname)
|
||
{
|
||
return wxRemoveFile(pathname);
|
||
}
|
||
|
||
BOOLEAN xvt_fsys_removefile(const char *pathname)
|
||
{
|
||
DEPRECATED_BOX();
|
||
return xvt_fsys_remove_file(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
|
||
}
|
||
}
|
||
|
||
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);
|
||
|
||
// 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));
|
||
|
||
// Last (NULL) component
|
||
xcc[10].type = XVT_COLOR_NULL;
|
||
xcc[10].color = 0;
|
||
|
||
ret = (long)xcc;
|
||
}
|
||
break;
|
||
case ATTR_FRAME_WIDTH:
|
||
#ifdef LINUX
|
||
ret = 8; //verificare not impl
|
||
#else
|
||
ret = wxSystemSettings::GetMetric(wxSYS_FRAMESIZE_X);
|
||
#endif
|
||
break;
|
||
case ATTR_FRAME_HEIGHT:
|
||
#ifdef LINUX
|
||
ret = 8; //verificare not impl
|
||
#else
|
||
ret = wxSystemSettings::GetMetric(wxSYS_FRAMESIZE_Y);
|
||
#endif
|
||
break;
|
||
case ATTR_MENU_HEIGHT:
|
||
ret = wxSystemSettings::GetMetric(wxSYS_MENU_Y);
|
||
break;
|
||
case ATTR_TITLE_HEIGHT:
|
||
#ifdef LINUX
|
||
ret = 32; //verificare not impl
|
||
#else
|
||
ret = wxSystemSettings::GetMetric(wxSYS_CAPTION_Y);
|
||
#endif
|
||
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_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 = m_nSpeechMode;
|
||
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 = wxSystemSettings::GetMetric(wxSYS_ICON_X);
|
||
break;
|
||
case ATTR_ICON_HEIGHT:
|
||
ret = wxSystemSettings::GetMetric(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)
|
||
{
|
||
CAST_WIN(win, w);
|
||
const wxRect rct = w.GetRect();
|
||
xvt_rect_set(rctp, rct.x, rct.y, rct.GetRight(), rct.GetBottom());
|
||
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 = NormalizeRCT(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_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_enable_speech(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 win, XVT_PALETTE 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 mask, EVENT_HANDLER eh, long app_data)
|
||
{
|
||
const wxRect rct = NormalizeRCT(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 WIN32
|
||
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 WIN32
|
||
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);
|
||
const wxCursor* cur = wxSTANDARD_CURSOR; // Dummy initilization
|
||
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 = 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 left, int top, int right, int bottom,
|
||
int prop_count, char **prop_list, WINDOW parent_win,
|
||
int parent_rid, long parent_flags, char *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);
|
||
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;
|
||
}
|
||
|
||
|