campo-sirio/xvaga/xvtextra.cpp
guy 3821c153e9 Patch level : 2.0 nopatch by now
Files correlati     : xvaga.dll
Ricompilazione Demo : [ ]
Commento            :

Riveduta e corretta gestione moduli di stampa personalizzati


git-svn-id: svn://10.65.10.50/trunk@11758 c028cbd2-c16b-5b4b-a496-9718f37d4682
2004-02-13 14:52:01 +00:00

814 lines
17 KiB
C++
Executable File

#include "wxinc.h"
#include "wx/print.h"
#include "wx/printdlg.h"
#include "xvt.h"
#ifdef WIN32
#include "oswin32.h"
#else
#include "oslinux.h"
#include <fstream.h>
#endif
#include "xvintern.h"
#pragma pack(4)
struct TPRINT_RCD : public PRINT_RCD
{
unsigned char m_data[16*1024];
unsigned int m_size; // Dimensione della struct DEVMODE
void SetData(void* data, unsigned int nSize);
TPRINT_RCD();
~TPRINT_RCD();
};
#pragma pack()
void TPRINT_RCD::SetData(void* data, unsigned int nSize)
{
if (nSize <= sizeof(m_data))
{
memcpy(m_data, data, nSize);
m_size = nSize;
}
else
xvt_dm_post_error("Printer info exceeds 16K");
}
TPRINT_RCD::TPRINT_RCD() : m_size(0)
{
pr = NULL;
memset(m_data, 0, sizeof(m_data));
}
TPRINT_RCD::~TPRINT_RCD()
{
memset(m_data, 0, sizeof(m_data));
m_size = 0;
}
///////////////////////////////////////////////////////////
// TwxPrintOut
///////////////////////////////////////////////////////////
class TwxPrintOut : public wxPrintout
{
protected:
TPRINT_RCD* m_prcd;
bool m_bBadDriver;
virtual bool HasPage(int pageNum);
virtual bool OnPrintPage(int pageNum);
void ResetDC();
public:
void SetBadDriver(bool bd) { m_bBadDriver = bd; }
bool HasBadDriver() const { return m_bBadDriver; }
void InitDC(TPRINT_RCD* prcd);
TwxPrintOut(TPRINT_RCD* prcd = NULL);
virtual ~TwxPrintOut();
};
static TwxPrintOut* m_po = NULL;
bool TwxPrintOut::HasPage(int pageNum)
{ return true; }
bool TwxPrintOut::OnPrintPage(int pageNum)
{ return false; }
void TwxPrintOut::ResetDC()
{
wxDC* dc = GetDC();
if (dc != NULL)
delete dc;
}
void TwxPrintOut::InitDC(TPRINT_RCD* prcd)
{
ResetDC();
wxDC* dc = NULL;
m_prcd = prcd;
if (m_prcd == NULL)
{
wxPrinter printer;
#ifdef WIN32
dc = new wxPrinterDC(printer.GetPrintDialogData().GetPrintData());
#else
dc = new wxPostScriptDC(printer.GetPrintDialogData().GetPrintData());
#endif
}
else
{
wxPrintData data;
#ifdef WIN32
data.SetNativeData(OsWin32_ConvertToNativePrinterInfo(prcd->m_data, prcd->m_size));
data.ConvertFromNative();
dc = new wxPrinterDC(data);
#else
dc = new wxPostScriptDC(prcd->m_data);
#endif
}
wxSize s = dc->GetPPI();
SetPPIPrinter(s.x, s.y);
s = dc->GetSize();
SetPageSizePixels(s.x, s.y);
SetDC(dc);
}
TwxPrintOut::TwxPrintOut(TPRINT_RCD* prcd)
: wxPrintout(_GetAppTitle()), m_bBadDriver(false)
{
InitDC(prcd);
}
TwxPrintOut::~TwxPrintOut()
{
ResetDC();
}
///////////////////////////////////////////////////////////
// TwxPrintOutCache
///////////////////////////////////////////////////////////
class TwxPrintOutCache
{
unsigned long m_signature;
TwxPrintOut* m_po;
protected:
unsigned long Signature(TPRINT_RCD* prcd) const;
public:
TwxPrintOut* Get(TPRINT_RCD* prcd);
void Reset();
TwxPrintOutCache() : m_signature(0), m_po(NULL) { }
~TwxPrintOutCache() { Reset(); }
} m_PrintoutCache;
unsigned long TwxPrintOutCache::Signature(TPRINT_RCD* prcd) const
{
const unsigned char* data = (const unsigned char*)prcd;
unsigned long h = 0;
for (size_t c = 0; c < prcd->m_size; c++)
{
h = (h << 2) + data[c];
const unsigned long i = h & 0xC0000000;
if (i) h = (h ^ (i >> 12)) & 0x3FFFFFFF;
}
return h;
}
void TwxPrintOutCache::Reset()
{
if (m_po != NULL)
{
delete m_po;
m_po = NULL;
}
}
TwxPrintOut* TwxPrintOutCache::Get(TPRINT_RCD* prcd)
{
unsigned long signature = Signature(prcd);
if (m_po != NULL && m_signature == signature)
return m_po;
Reset();
m_po = new TwxPrintOut(prcd);
m_signature = signature;
return m_po;
}
///////////////////////////////////////////////////////////
// TPrintDC
///////////////////////////////////////////////////////////
wxDC& TPrintDC::GetDC(bool)
{
_dc = m_po->GetDC(); // Forza display context corrente
if (_dirty)
_dirty = -1;
return TDC::GetDC(false);
}
TPrintDC::TPrintDC(wxWindow* owner) : TDC(owner)
{ }
TPrintDC::~TPrintDC()
{
_dc = NULL; // Evita distruzione!
}
///////////////////////////////////////////////////////////
// Printing management :-(((((
///////////////////////////////////////////////////////////
BOOLEAN xvt_app_escape(int esc_code, PRINT_RCD* rcd, long* ph, long* pw, long* pvr, long* phr)
{
*ph = *pw = *pvr = *phr = 0;
switch (esc_code)
{
case XVT_ESC_GET_PRINTER_INFO:
if (rcd == NULL || xvt_print_is_valid(rcd))
{
int w, h;
if (m_po == NULL)
{
TwxPrintOut* po = m_PrintoutCache.Get((TPRINT_RCD*)rcd);
po->GetPPIPrinter(&w, &h);
*phr = w; *pvr = h;
po->GetPageSizePixels(&w, &h);
*pw = w; *ph = h;
}
else
{
m_po->GetPPIPrinter(&w, &h);
*phr = w; *pvr = h;
m_po->GetPageSizePixels(&w, &h);
*pw = w; *ph = h;
}
return TRUE;
}
break;
default:
break;
}
return FALSE;
}
BOOLEAN xvt_dm_post_page_setup(PRINT_RCD* precp)
{
wxPageSetupDialog dlg((wxWindow*)TASK_WIN);
TPRINT_RCD* rcd = (TPRINT_RCD*)precp;
wxPageSetupData& pdd = dlg.GetPageSetupData();
wxPrintData& data = pdd.GetPrintData();
#ifdef WIN32
void* pHandle = OsWin32_ConvertToNativePrinterInfo(rcd->m_data, rcd->m_size);
data.SetNativeData(pHandle);
data.ConvertFromNative();
#endif
pdd.EnableMargins(false);
const BOOLEAN ok = dlg.ShowModal() == wxID_OK;
if (ok)
{
#ifdef WIN32
pHandle = data.GetNativeData();
unsigned int nSize = 0;
void* ptr = OsWin32_ConvertFromNativePrinterInfo(pHandle, nSize);
rcd->SetData(ptr, nSize);
delete ptr;
#else
rcd->SetData((void *) &data, (unsigned int) sizeof(data));
#endif
m_PrintoutCache.Reset();
}
return ok;
}
long xvt_fmap_get_family_sizes(PRINT_RCD *precp, char *family, long *size_array, BOOLEAN *scalable, long max_sizes)
{
long size = 0;
*scalable = FALSE;
if (precp != NULL)
{
#ifdef WIN32
TwxPrintOut* po = m_PrintoutCache.Get((TPRINT_RCD*)precp);
if (!po->HasBadDriver())
size = OsWin32_EnumerateSizes(po->GetDC()->GetHDC(), family, size_array, scalable, max_sizes);
#else
size = OsLinux_EnumerateSizes(family, size_array, scalable, max_sizes);
#endif
}
return size;
}
long xvt_fmap_get_families(PRINT_RCD *precp, char **family_array, long max_families)
{
long size = 0;
family_array[0] = NULL;
if (precp != NULL)
{
#ifdef WIN32
TwxPrintOut* po = m_PrintoutCache.Get((TPRINT_RCD*)precp);
size = OsWin32_EnumerateFamilies(po->GetDC()->GetHDC(), family_array, max_families);
if (size == 0)
po->SetBadDriver(true);
#else
size = OsLinux_EnumerateFamilies(family_array, max_families);
#endif
}
return size;
}
void xvt_print_close(void)
{
// Nothing to do ?
}
BOOLEAN xvt_print_close_page(PRINT_RCD* /*precp*/)
{
BOOLEAN ok = m_po != NULL;
if (ok)
m_po->GetDC()->EndPage();
return ok;
}
PRINT_RCD* xvt_print_create(int *sizep)
{
TPRINT_RCD* pr = NULL;
*sizep = 0;
#ifdef WIN32
void* data = OsWin32_GetPrinterInfo(*sizep, NULL);
if (data != NULL)
{
pr = new TPRINT_RCD;
pr->SetData(data, *sizep);
*sizep += 4; // Spazio per puntatore iniziale
delete data;
}
#else
wxPrinter printer;
wxPrintData &data = printer.GetPrintDialogData().GetPrintData();
data.SetPrinterName(""); //verificare
pr = new TPRINT_RCD;
pr->SetData((void *) &data, (unsigned int) sizeof(data));
#endif
return pr;
}
// Nuova funzione inventata da Aga
PRINT_RCD* xvt_print_create_by_name(int* sizep, const char* name)
{
TPRINT_RCD* pr = NULL;
*sizep = 0;
#ifdef WIN32
void* data = OsWin32_GetPrinterInfo(*sizep, name);
if (data != NULL)
{
pr = new TPRINT_RCD;
pr->SetData(data, *sizep);
*sizep += 4; // Spazio per puntatore iniziale
delete data;
}
#else
wxPrinter printer;
wxPrintData &data = printer.GetPrintDialogData().GetPrintData();
wxString PrinterName(name);
data.SetPrinterName(PrinterName); //verificare
pr = new TPRINT_RCD;
pr->SetData((void *) &data, (unsigned int) sizeof(data));
#endif
return pr;
}
WINDOW xvt_print_create_win(PRINT_RCD* precp, char* /* title */)
{
WINDOW win = NULL_WIN;
if (m_po != NULL)
{
m_po->InitDC((TPRINT_RCD*)precp);
m_po->OnBeginPrinting();
m_po->OnBeginDocument(1, 32000);
win = _print_win;
}
return win;
}
void xvt_print_destroy(PRINT_RCD* precp)
{
delete precp;
}
RCT* xvt_print_get_next_band(void)
{
static bool yes = false;
static RCT rct;
yes = !yes;
if (m_po == NULL || !yes)
return NULL;
int w, h;
m_po->GetPageSizePixels(&w, &h);
rct.left = rct.top = 0;
rct.right = w;
rct.bottom = h;
return &rct;
}
BOOLEAN xvt_print_is_valid(PRINT_RCD* precp)
{
BOOLEAN ok = precp != NULL && precp->pr == NULL;
if (ok)
{
#ifdef WIN32
TPRINT_RCD* rcd = (TPRINT_RCD*)precp;
ok = OsWin32_CheckPrinterInfo(rcd->m_data, rcd->m_size);
#else
// verificare (c'e' da fare qualcosa ?)
#endif
}
return ok;
}
int xvt_print_get_name(PRINT_RCD* precp, char* name, int sz_s)
{
#ifdef WIN32
wxString n = ((const char*)precp) + 4;
if (n.Length() > 30)
{
SLIST plist = xvt_print_list_devices();
for (SLIST_ELT pitem = xvt_slist_get_first(plist);
pitem != NULL; pitem = xvt_slist_get_next(plist, pitem))
{
const wxString pname = xvt_slist_get(plist, pitem, NULL);
if (pname.StartsWith(n))
{
n = pname;
break;
}
}
xvt_slist_destroy(plist);
}
if (name != NULL && sz_s > 0)
{
strncpy(name, n, sz_s);
name[sz_s-1] = '\0';
}
return n.Length();
#else
return 0; // TBI
#endif
}
BOOLEAN xvt_print_open(void)
{
return m_po == NULL;
}
///////////////////////////////////////////////////////////
void CreateAbortWindow()
{
wxFrame* parent = (wxFrame*)TASK_WIN;
wxPrintAbortDialog* win = new wxPrintAbortDialog(parent, "Stampa" , wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE);
wxBoxSizer *button_sizer = new wxBoxSizer( wxVERTICAL );
button_sizer->Add( new wxStaticText( win, -1, "Stampa in corso..."), 0, wxALL, 10 );
button_sizer->Add( new wxButton( win, wxID_CANCEL, wxT("Annulla") ), 0, wxALL | wxALIGN_CENTER, 10 );
win->SetAutoLayout( TRUE );
win->SetSizer( button_sizer );
button_sizer->Fit(win);
button_sizer->SetSizeHints (win) ;
win->Show();
win->Update();
wxPrinterBase::sm_abortWindow = win;
}
void DestroyAbortWindow()
{
if (wxPrinterBase::sm_abortWindow != NULL)
{
wxPrinterBase::sm_abortWindow->Hide();
delete wxPrinterBase::sm_abortWindow;
wxPrinterBase::sm_abortWindow = NULL;
}
}
///////////////////////////////////////////////////////////
BOOLEAN xvt_print_start_thread(BOOLEAN(*print_fcn)(long), long data)
{
wxBeginBusyCursor();
m_po = new TwxPrintOut;
wxEndBusyCursor();
CreateAbortWindow();
print_fcn(data);
DestroyAbortWindow();
#ifdef WIN32
// Stampa un line feed aggiuntivo nella stampa su generica solo testo in Win 98
int w, h;
m_po->GetPPIPrinter(&w, &h);
if (h == 6) // Solo Win 98 torna 6 pixel per pollice = 1 pixel per riga
{
wxDC* dc = m_po->GetDC();
dc->StartPage();
OsWin32_SpoolRow("\n\n", 1, dc->GetHDC()); // Probabilmente basta "\n" (visto che poi specifichiamo 1) ma non ci fidiamo
dc->EndPage();
}
#endif
m_po->OnEndDocument();
m_po->OnEndPrinting();
delete m_po; m_po = NULL;
return TRUE;
}
BOOLEAN xvt_print_open_page(PRINT_RCD* precp)
{
BOOLEAN ok = m_po != NULL;
if (ok)
{
if (wxPrinterBase::sm_abortIt)
ok = FALSE;
else
m_po->GetDC()->StartPage();
}
return ok;
}
///////////////////////////////////////////////////////////
// Added by XVAGA
///////////////////////////////////////////////////////////
#ifdef LINUX
static bool is_cups()
{
static int printer_system = -1;
if (printer_system < 0)
printer_system = xvt_fsys_file_exists("/etc/cups/printer.conf") ? 1 : 2;
return (printer_system == 1);
}
#endif
SLIST xvt_print_list_devices()
{
SLIST list = xvt_slist_create();
#ifdef WIN32
char buf[4096]; memset(buf, 0, sizeof(buf));
GetProfileString("devices", NULL, "", buf, sizeof(buf));
int start = 0;
for (int i = 0; i < sizeof(buf); i++) if (buf[i] == '\0')
{
const char* pname = buf+start;
if (*pname == '\0')
break;
xvt_slist_add_at_elt(list, NULL, pname, NULL);
start = i+1;
}
#else
if (is_cups())
{
ifstream p("/etc/cups/printer.conf"); // vedere
char line[4096];
while (p.getline(line, sizeof(line)))
{
if (line[0] == '<')
{
char * s = strstr(line, "Printer") ;
if (s != NULL)
{
s += 7;
while (isspace(*s))
s++;
if (*s)
{
char * l = s + strlen(s) - 1;
while (isspace(*l))
l--;
*(l + 1) = '\0';
xvt_slist_add_at_elt(list, NULL, s, 0L);
}
}
}
}
}
else
{
ifstream p("/etc/printcap"); // vedere
char line[4096];
while (p.getline(line, sizeof(line)))
{
if (line[0] != '#')
{
const int len = strlen(line);
int i;
for (i = 0; i < len; i++)
{
const char c = line[i];
if (!(isalpha(c) || isdigit(c) || isblank(c)))
break;
}
line[i] = '\0';
xvt_slist_add_at_elt(list, NULL, line, 0L);
}
}
}
#endif
return list;
}
BOOLEAN xvt_print_set_default_device(const char* name)
{
BOOLEAN ok = name && *name > ' ';
#ifdef WIN32
if (ok)
{
wxString pdev(name);
if (pdev.Find(',') < 0)
{
char szDevice[256];
::GetProfileString ("devices", pdev, "", szDevice, sizeof(szDevice));
pdev << ',' << szDevice;
}
ok = ::WriteProfileString("windows", "device", pdev) != 0;
}
#else
SORRY_BOX(); //verificare
#endif
return ok;
}
BOOLEAN xvt_print_get_default_device(char* name, int namesize)
{
bool ok = FALSE;
#ifdef WIN32
ok = ::GetProfileString ("windows", "device", ",,,", name, namesize) != 0;
#else
*name = '\0';
if (is_cups())
{
ifstream p("/etc/cups/printer.conf"); // vedere
char line[4096];
while (p.getline(line, sizeof(line)))
{
if (line[0] == '<')
{
char * s = strstr(line, "ltPrinter") ;
if (s != NULL)
{
s += 9;
while (isspace(*s))
s++;
if (*s)
{
char * l = s + strlen(s) - 1;
while (isspace(*l))
l--;
*(l + 1) = '\0';
strcpy(name, s);
}
ok = TRUE;
}
}
}
}
#endif
return ok;
}
///////////////////////////////////////////////////////////
// Gestione files di configurazione
///////////////////////////////////////////////////////////
int xvt_fsys_get_campo_stp_value(const char* name, char* value, int valsize)
{
BOOLEAN bFound = FALSE;
#ifdef WIN32
const char* stpfile = "c:/campo.stp";
int p;
DIRECTORY dir;
char exedir[_MAX_PATH], path[_MAX_PATH];
xvt_fsys_get_default_dir(&dir);
xvt_fsys_convert_dir_to_str(&dir, exedir, sizeof(exedir));
for (p = 1; ; p++)
{
int len = 0;
char para[4]; sprintf(para, "%d", p);
len = xvt_sys_get_profile_string(stpfile, para, "Program", "", path, sizeof(path));
if (len <= 0)
break;
if (path[len-1] == '\\' || path[len-1] == '/')
{
len--;
path[len] = '\0';
}
if (xvt_str_compare_ignoring_case(path, exedir) == 0)
{
xvt_sys_get_profile_string(stpfile, para, name, "", value, valsize);
bFound = *value > ' ';
break;
}
}
#endif
return bFound;
}
/*
@($) CGetCampoIni FILES
@(ID)
Restituisce il nome del file che contiene il prefisso corrente.
@(FD)
@(ISV)
s,s1 = stringhe di lavoro.
Versione WIN32 e LINUX.
@(FSV)
*/
const char* xvt_fsys_get_campo_ini()
{
static char* prawin = NULL;
if (prawin == NULL)
{
BOOLEAN bFound = FALSE;
#ifdef WIN32
// Nelle installazioni sfigate con programmi in rete cerca di stabilire il percorso locale di Campo.ini
DIRECTORY dir;
char exedir[_MAX_PATH], path[_MAX_PATH];
xvt_fsys_get_default_dir(&dir);
xvt_fsys_convert_dir_to_str(&dir, exedir, sizeof(exedir));
if (xvt_fsys_is_network_drive(exedir))
{
bFound = xvt_fsys_get_campo_stp_value("CampoIni", path, sizeof(path));
if (!bFound)
{
const char* pp = getenv("PREFPATH");
if (pp != NULL)
{
char dri[_MAX_DRIVE], dir[_MAX_PATH];
xvt_fsys_parse_pathname(pp, dri, dir, NULL, NULL, NULL);
xvt_fsys_build_pathname(path, dri, dir, "campo", "ini", NULL);
bFound = TRUE;
}
}
}
#endif
if (!bFound)
{
#ifdef LINUX
char ininame[32];
sprintf(ininame, "campo%u", getuid());
xvt_fsys_build_pathname(path, NULL, exedir, ininame, "ini", NULL);
#else
xvt_fsys_build_pathname(path, NULL, exedir, "campo", "ini", NULL);
#endif
if (!xvt_fsys_file_exists(path))
{
char msg[256];
sprintf(msg, "Impossibile aprire '%s'", (const char *)path);
xvt_dm_post_fatal_exit(msg);
}
}
prawin = xvt_str_duplicate(path);
}
return prawin;
}