Files correlati : xvaga.dll Ricompilazione Demo : [ ] Commento : 0000934: impostazione nuova stampante Se selezione file ed imposta stampante, se scelgo la stampante mi da l'errore che allego, se la stessa operazione si fa dal pc di Salomoni campo si chiude senza dare errori. git-svn-id: svn://10.65.10.50/trunk@17536 c028cbd2-c16b-5b4b-a496-9718f37d4682
1179 lines
25 KiB
C++
Executable File
1179 lines
25 KiB
C++
Executable File
#include "wxinc.h"
|
|
#include "wx/print.h"
|
|
|
|
#include "xvt.h"
|
|
|
|
#ifdef WIN32
|
|
#include "wx/dcps.h"
|
|
#include "wx/msw/printdlg.h"
|
|
#include "oswin32.h"
|
|
#else
|
|
#include "wx/setup.h"
|
|
#include "wx/dcps.h"
|
|
#include "oslinux.h"
|
|
#include "incstr.h"
|
|
#endif
|
|
|
|
#include "xvtpdf.h"
|
|
#include "xvtwin.h"
|
|
|
|
#pragma pack(4)
|
|
|
|
struct TPRINT_RCD : public PRINT_RCD
|
|
{
|
|
#ifdef WIN32
|
|
unsigned char m_data[16*1024];
|
|
unsigned int m_size; // Dimensione della struct DEVMODE
|
|
|
|
void SetData(void * data, unsigned int nSize);
|
|
#else
|
|
wxPrintNativeDataBase * m_data;
|
|
unsigned int m_size; // Dimensione di wxPostScriptPrintNativeData
|
|
|
|
void GetData(wxPrintNativeDataBase * data) const;
|
|
void SetData(void * data);
|
|
|
|
|
|
#endif
|
|
|
|
unsigned int GetSize() const { return m_size; }
|
|
|
|
TPRINT_RCD();
|
|
~TPRINT_RCD();
|
|
};
|
|
|
|
#pragma pack()
|
|
|
|
#ifdef WIN32
|
|
void TPRINT_RCD::SetData(void* data, unsigned int nSize)
|
|
{
|
|
if (nSize <= sizeof(m_data))
|
|
{
|
|
memset(m_data, 0, sizeof(m_data)); // Azzero per bene anche tutto quanto segue nSize
|
|
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;
|
|
|
|
}
|
|
#else
|
|
void TPRINT_RCD::GetData(wxPrintNativeDataBase * data) const
|
|
{
|
|
memcpy(data, m_data, GetSize());
|
|
}
|
|
|
|
void TPRINT_RCD::SetData(void* data)
|
|
{
|
|
memcpy(m_data, data, GetSize());
|
|
}
|
|
|
|
wxNativePrintFactory __factory;
|
|
|
|
TPRINT_RCD::TPRINT_RCD()
|
|
{
|
|
m_data = __factory.CreatePrintNativeData();
|
|
m_size = sizeof(*m_data);
|
|
}
|
|
|
|
TPRINT_RCD::~TPRINT_RCD()
|
|
{
|
|
delete m_data;
|
|
}
|
|
#endif
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TwxPrintOut
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TwxPrintOut : public wxPrintout
|
|
{
|
|
protected:
|
|
const TPRINT_RCD* m_prcd;
|
|
bool m_bBadDriver;
|
|
|
|
virtual bool HasPage(int pageNum);
|
|
virtual bool OnPrintPage(int pageNum);
|
|
void ResetDC();
|
|
|
|
wxDC* CreateDC(const TPRINT_RCD* prcd, const char* title);
|
|
|
|
|
|
public:
|
|
void SetBadDriver(bool bd) { m_bBadDriver = bd; }
|
|
bool HasBadDriver() const { return m_bBadDriver; }
|
|
|
|
wxString PrinterName() const;
|
|
bool IsPDF() const { return !HasBadDriver() && xvt_print_is_pdf(m_prcd) != 0; }
|
|
|
|
void InitDC(const TPRINT_RCD* prcd, const char* title);
|
|
TwxPrintOut(const TPRINT_RCD* prcd = NULL);
|
|
|
|
virtual ~TwxPrintOut() {}
|
|
};
|
|
|
|
wxString TwxPrintOut::PrinterName() const
|
|
{
|
|
char strName[MAX_PATH] = "";
|
|
xvt_print_get_name(m_prcd, strName, sizeof(strName));
|
|
return strName;
|
|
}
|
|
|
|
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;
|
|
SetDC(NULL);
|
|
}
|
|
}
|
|
|
|
|
|
static void RCD2data(const TPRINT_RCD* prcd, wxPrintData& data)
|
|
{
|
|
#ifdef WIN32
|
|
wxWindowsPrintNativeData ndb;
|
|
ndb.SetDevMode(OsWin32_ConvertToNativePrinterInfo((void*)prcd->m_data, prcd->m_size));
|
|
ndb.TransferTo(data);
|
|
|
|
// in assenza di PDEVNAMES aggiorno il nome in questo modo
|
|
char strName[MAX_PATH] = "";
|
|
xvt_print_get_name(prcd, strName, sizeof(strName));
|
|
data.SetPrinterName(strName);
|
|
#else
|
|
prcd->GetData(data.GetNativeData());
|
|
data.ConvertFromNative();
|
|
#endif
|
|
}
|
|
|
|
static void data2RCD(const wxPrintData& data, TPRINT_RCD* prcd)
|
|
{
|
|
#ifdef WIN32
|
|
wxWindowsPrintNativeData* pNative = (wxWindowsPrintNativeData*)data.GetNativeData();
|
|
unsigned int nSize = 0;
|
|
void* ptr = OsWin32_ConvertFromNativePrinterInfo(pNative->GetDevMode(), nSize);
|
|
prcd->SetData(ptr, nSize);
|
|
delete ptr;
|
|
#else
|
|
((wxPrintData&)data).ConvertToNative();
|
|
prcd->SetData(data.GetNativeData());
|
|
#endif
|
|
}
|
|
|
|
wxDC* TwxPrintOut::CreateDC(const TPRINT_RCD* prcd, const char* title)
|
|
{
|
|
m_prcd = prcd;
|
|
wxDC* dc = NULL;
|
|
|
|
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;
|
|
RCD2data(prcd, data);
|
|
|
|
const bool ispdf = IsPDF();
|
|
if (ispdf)
|
|
dc = new TwxPDFDC(data, title);
|
|
else
|
|
#ifdef WIN32
|
|
dc = new wxPrinterDC(data);
|
|
#else
|
|
dc = new wxPostScriptDC(data);
|
|
#endif
|
|
}
|
|
|
|
if (dc->IsOk())
|
|
{
|
|
wxSize s = dc->GetPPI();
|
|
SetPPIPrinter(s.x, s.y);
|
|
|
|
s = dc->GetSize();
|
|
SetPageSizePixels(s.x, s.y);
|
|
|
|
SetDC(dc);
|
|
|
|
wxWindow* pAbort = wxPrinterBase::sm_abortWindow;
|
|
if (pAbort != NULL)
|
|
{
|
|
wxWindow* pStatic = pAbort->FindWindow(wxID_STATIC);
|
|
if (pStatic != NULL)
|
|
{
|
|
wxString strPrompt = wxT("Stampa su ");
|
|
if (IsPDF())
|
|
strPrompt += wxT("PDF");
|
|
else
|
|
strPrompt += PrinterName();
|
|
pStatic->SetLabel(strPrompt);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// delete dc;
|
|
dc = NULL;
|
|
}
|
|
return dc;
|
|
}
|
|
|
|
void TwxPrintOut::InitDC(const TPRINT_RCD* prcd, const char* title)
|
|
{
|
|
ResetDC();
|
|
wxDC* dc = CreateDC(prcd, title);
|
|
if (dc != NULL)
|
|
{
|
|
wxSize s = dc->GetPPI();
|
|
if (s.x > 0)
|
|
SetPPIPrinter(s.x, s.y);
|
|
|
|
s = dc->GetSize();
|
|
if (s.x > 0)
|
|
SetPageSizePixels(s.x, s.y);
|
|
SetDC(dc);
|
|
}
|
|
m_bBadDriver = dc == NULL;
|
|
}
|
|
|
|
TwxPrintOut::TwxPrintOut(const TPRINT_RCD* prcd)
|
|
: wxPrintout(_GetAppTitle()), m_bBadDriver(false)
|
|
{
|
|
InitDC(prcd, _GetAppTitle());
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TwxPrintOutCache
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TwxPrintOutCache
|
|
{
|
|
unsigned long m_signature;
|
|
TwxPrintOut* m_po;
|
|
bool m_bLocked;
|
|
|
|
protected:
|
|
unsigned long Signature(const TPRINT_RCD* prcd) const;
|
|
|
|
public:
|
|
TwxPrintOut& Get(const TPRINT_RCD* prcd);
|
|
void Reset();
|
|
|
|
void Lock() { m_bLocked = true; }
|
|
void Unlock() { m_bLocked = false; }
|
|
|
|
bool Ok() const { return m_po != NULL; }
|
|
bool Locked() const { return m_bLocked; }
|
|
bool Printing() const { return Ok() && Locked(); }
|
|
|
|
TwxPrintOutCache();
|
|
~TwxPrintOutCache();
|
|
} m_PrintoutCache;
|
|
|
|
unsigned long TwxPrintOutCache::Signature(const TPRINT_RCD* prcd) const
|
|
{
|
|
unsigned long h = 0;
|
|
if (prcd != NULL)
|
|
{
|
|
const unsigned char* data = (const unsigned char*)prcd;
|
|
const size_t sz = prcd->GetSize();
|
|
for (size_t c = 0; c < sz; c++)
|
|
{
|
|
h = (h << 2) + data[c];
|
|
const unsigned long i = h & 0xC0000000;
|
|
if (i) h = (h ^ (i >> 12)) & 0x3FFFFFFF;
|
|
}
|
|
}
|
|
return h;
|
|
}
|
|
|
|
void TwxPrintOutCache::Reset()
|
|
{
|
|
wxASSERT(!Locked());
|
|
if (m_po != NULL)
|
|
{
|
|
delete m_po;
|
|
m_po = NULL;
|
|
}
|
|
}
|
|
|
|
TwxPrintOut& TwxPrintOutCache::Get(const TPRINT_RCD* prcd)
|
|
{
|
|
if (!Locked())
|
|
{
|
|
if (prcd == NULL)
|
|
{
|
|
if (m_po == NULL)
|
|
m_po = new TwxPrintOut;
|
|
}
|
|
else
|
|
{
|
|
unsigned long signature = Signature(prcd);
|
|
if (m_po != NULL && m_signature == signature)
|
|
return *m_po;
|
|
Reset();
|
|
m_po = new TwxPrintOut(prcd);
|
|
m_signature = signature;
|
|
}
|
|
}
|
|
wxASSERT(m_po != NULL);
|
|
return *m_po;
|
|
}
|
|
|
|
TwxPrintOutCache::TwxPrintOutCache() : m_signature(0), m_po(NULL)
|
|
{ }
|
|
|
|
TwxPrintOutCache::~TwxPrintOutCache()
|
|
{
|
|
// Reset(); // Essendo un oggetto statico la delete m_po non funziona!
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPrintDC
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Flag di reset ad inizio pagina
|
|
bool TPrintDC::_page_start = false;
|
|
|
|
void TPrintDC::SetPageStart()
|
|
{ _page_start = true; }
|
|
|
|
wxDC& TPrintDC::GetDC(bool)
|
|
{
|
|
_dc = m_PrintoutCache.Get(NULL).GetDC(); // Forza display context corrente
|
|
if (_page_start)
|
|
{
|
|
_dirty = -1;
|
|
_page_start = false;
|
|
}
|
|
return TDC::GetDC(false);
|
|
}
|
|
|
|
void TPrintDC::KillDC()
|
|
{
|
|
_dc = NULL; // _dc is owned by wxPrintout
|
|
}
|
|
|
|
TPrintDC::TPrintDC(wxWindow* owner) : TDC(owner)
|
|
{
|
|
_page_start = false;
|
|
}
|
|
|
|
TPrintDC::~TPrintDC()
|
|
{
|
|
KillDC();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Printing management :-(((((
|
|
///////////////////////////////////////////////////////////
|
|
|
|
BOOLEAN xvt_app_escape(int esc_code, PRINT_RCD* rcd, long* ph, long* pw, long* pvr, long* phr)
|
|
{
|
|
switch (esc_code)
|
|
{
|
|
case XVT_ESC_GET_PRINTER_INFO:
|
|
if (ph) *ph = *pw = 0;
|
|
if (pvr) *pvr = *phr = 0;
|
|
if (rcd == NULL || xvt_print_is_valid(rcd))
|
|
{
|
|
const TwxPrintOut& po = m_PrintoutCache.Get((TPRINT_RCD*)rcd);
|
|
int w, h;
|
|
if (ph)
|
|
{
|
|
po.GetPageSizePixels(&w, &h);
|
|
*pw = w; *ph = h;
|
|
}
|
|
if (pvr)
|
|
{
|
|
po.GetPPIPrinter(&w, &h);
|
|
*phr = w; *pvr = h;
|
|
}
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case XVT_ESC_SET_PRINTER_INFO:
|
|
if (xvt_print_is_valid(rcd) && ph != NULL && pw != NULL)
|
|
{
|
|
TPRINT_RCD* prcd = (TPRINT_RCD*)rcd;
|
|
wxPrintData data;
|
|
|
|
RCD2data(prcd, data);
|
|
data.SetOrientation(*ph > *pw ? 1 : 2);
|
|
data.ConvertToNative();
|
|
data2RCD(data, prcd);
|
|
|
|
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();
|
|
|
|
RCD2data(rcd, data);
|
|
|
|
pdd.EnableMargins(false);
|
|
|
|
const BOOLEAN ok = dlg.ShowModal() == wxID_OK;
|
|
if (ok)
|
|
{
|
|
data2RCD(data, rcd);
|
|
m_PrintoutCache.Reset();
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
void xvt_dwin_draw_image_on_pdf(WINDOW win, const char* name, RCT* dest)
|
|
{
|
|
wxASSERT(win == PRINTER_WIN);
|
|
const wxRect dst = NormalizeRCT(dest);
|
|
TwxPDFDC& dc = *wxStaticCast(&GetTDCMapper().GetDC(win), TwxPDFDC);
|
|
dc.DrawImage(name, dst);
|
|
}
|
|
|
|
long xvt_fmap_get_family_sizes(PRINT_RCD *precp, char *family, long *size_array, BOOLEAN *scalable, long max_sizes)
|
|
{
|
|
long size = 0;
|
|
*scalable = FALSE;
|
|
|
|
#ifdef WIN32
|
|
if (xvt_print_is_valid(precp))
|
|
{
|
|
const 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 = OsWin32_EnumerateSizes(NULL, 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;
|
|
|
|
#ifdef WIN32
|
|
if (xvt_print_is_valid(precp))
|
|
{
|
|
TwxPrintOut& po = m_PrintoutCache.Get((TPRINT_RCD*)precp);
|
|
if (!po.HasBadDriver())
|
|
{
|
|
size = OsWin32_EnumerateFamilies(po.GetDC()->GetHDC(), family_array, max_families);
|
|
if (size == 0)
|
|
po.SetBadDriver(true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wxFrame* tw = (wxFrame*)TASK_WIN;
|
|
wxClientDC dc(tw);
|
|
size = OsWin32_EnumerateFamilies(dc.GetHDC(), family_array, max_families);
|
|
}
|
|
#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_PrintoutCache.Printing();
|
|
if (ok)
|
|
{
|
|
const TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
wxDC* dc = po.GetDC();
|
|
dc->EndPage();
|
|
#ifdef WIN32
|
|
TPRINT_RCD* prcd = (TPRINT_RCD*)precp;
|
|
if (OsWin32_IsGenericTextOnly(prcd->m_data))
|
|
OsWin32_SpoolNewLine((unsigned int)dc->GetHDC());
|
|
#endif
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
PRINT_RCD* xvt_print_create(int *sizep)
|
|
{
|
|
return xvt_print_create_by_name(sizep, NULL);
|
|
}
|
|
|
|
// Impone il nome ad un PRINT_RCD.
|
|
// Utilizzato per la definiz. della stamp. virtuale PDF predefinita
|
|
int xvt_print_set_name(PRINT_RCD* precp, const char* name)
|
|
{
|
|
if (precp == NULL)
|
|
return 0;
|
|
|
|
if (!name || !*name)
|
|
return 0;
|
|
|
|
wxString n = name;
|
|
|
|
#ifdef WIN32
|
|
wxStrncpy(((char*)precp) + 4, name, 32);
|
|
#else
|
|
TPRINT_RCD* rcd = (TPRINT_RCD*)precp;
|
|
wxPrintData data;
|
|
|
|
rcd->GetData(data);
|
|
data.SetPrinterName(n);
|
|
rcd->SetData(data);
|
|
#endif
|
|
|
|
return n.Length();
|
|
}
|
|
|
|
// Nuova funzione inventata da Aga
|
|
PRINT_RCD* xvt_print_create_by_name(int* sizep, const char* name)
|
|
{
|
|
TPRINT_RCD* pr = NULL;
|
|
*sizep = 0;
|
|
|
|
const bool ispdf = name != NULL && xvt_str_compare_ignoring_case(name, XVT_PDF_PRINTER_NAME) == 0;
|
|
if (ispdf)
|
|
name = NULL;
|
|
|
|
#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
|
|
wxPrintData data;
|
|
|
|
data.SetPrinterName(name == NULL ? "" : name);
|
|
pr = new TPRINT_RCD;
|
|
data2RCD(data, pr);
|
|
*sizep = pr->GetSize();
|
|
#endif
|
|
|
|
if (ispdf)
|
|
xvt_print_set_name(pr, XVT_PDF_PRINTER_NAME);
|
|
|
|
return pr;
|
|
}
|
|
|
|
WINDOW xvt_print_create_win(PRINT_RCD* precp, const char* title)
|
|
{
|
|
TPRINT_RCD* rcd = (TPRINT_RCD*)precp;
|
|
|
|
if (m_PrintoutCache.Printing())
|
|
{
|
|
TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
po.InitDC(rcd, title);
|
|
po.OnBeginPrinting();
|
|
po.OnBeginDocument(1, 32000);
|
|
}
|
|
else
|
|
{
|
|
TwxPrintOut& po = m_PrintoutCache.Get(rcd);
|
|
po.InitDC(rcd, title);
|
|
}
|
|
return PRINTER_WIN;
|
|
}
|
|
|
|
void xvt_print_destroy(PRINT_RCD* precp)
|
|
{
|
|
if (precp != NULL)
|
|
delete precp;
|
|
}
|
|
|
|
RCT* xvt_print_get_next_band(void)
|
|
{
|
|
static bool yes = false;
|
|
static RCT rct;
|
|
yes = !yes;
|
|
|
|
if (!yes)
|
|
return NULL;
|
|
|
|
const TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
int w, h;
|
|
po.GetPageSizePixels(&w, &h);
|
|
rct.left = rct.top = 0;
|
|
rct.right = w;
|
|
rct.bottom = h;
|
|
|
|
return &rct;
|
|
}
|
|
|
|
BOOLEAN xvt_print_is_pdf(const PRINT_RCD* precp)
|
|
{
|
|
char strName[MAX_PATH];
|
|
xvt_print_get_name(precp, strName, sizeof(strName));
|
|
return xvt_str_compare_ignoring_case(strName, XVT_PDF_PRINTER_NAME) == 0;
|
|
}
|
|
|
|
BOOLEAN xvt_print_pdf_version(char* version, int size)
|
|
{
|
|
const BOOLEAN ok = version && size > 12;
|
|
if (ok)
|
|
{
|
|
wxString str = "PDFlib ";
|
|
str += PDFLIB_VERSIONSTRING;
|
|
wxStrncpy(version, str, size);
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
BOOLEAN xvt_print_is_valid(const PRINT_RCD* precp)
|
|
{
|
|
BOOLEAN ok = precp != NULL && precp->pr == NULL;
|
|
if (ok)
|
|
{
|
|
const TPRINT_RCD* rcd = (const TPRINT_RCD*)precp;
|
|
|
|
#ifdef WIN32
|
|
ok = OsWin32_CheckPrinterInfo(rcd->m_data, rcd->m_size);
|
|
#else
|
|
wxPrintData data;
|
|
RCD2data(rcd, data);
|
|
ok = data.Ok();
|
|
#endif
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
int xvt_print_get_name(const PRINT_RCD* precp, char* name, int sz_s)
|
|
{
|
|
if (!xvt_print_is_valid(precp))
|
|
return 0;
|
|
|
|
#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);
|
|
}
|
|
#else
|
|
TPRINT_RCD* rcd = (TPRINT_RCD*)precp;
|
|
wxPrintData data;
|
|
|
|
RCD2data(rcd, data);
|
|
wxString n = data.GetPrinterName();
|
|
#endif
|
|
if (name != NULL && sz_s > 0)
|
|
{
|
|
strncpy(name, n, sz_s);
|
|
name[sz_s-1] = '\0';
|
|
}
|
|
return n.Length();
|
|
}
|
|
|
|
BOOLEAN xvt_print_open(void)
|
|
{
|
|
return m_PrintoutCache.Ok();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TwxPrintAbortDialog : public wxPrintAbortDialog
|
|
{
|
|
public:
|
|
void Pulse();
|
|
TwxPrintAbortDialog();
|
|
};
|
|
|
|
void TwxPrintAbortDialog::Pulse()
|
|
{
|
|
wxGauge* pGauge = wxStaticCast(FindWindow(wxID_FORWARD), wxGauge);
|
|
pGauge->Pulse();
|
|
}
|
|
|
|
TwxPrintAbortDialog::TwxPrintAbortDialog()
|
|
: wxPrintAbortDialog(NULL, wxT("Stampa"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
|
|
{
|
|
wxBoxSizer *button_sizer = new wxBoxSizer( wxVERTICAL );
|
|
|
|
button_sizer->Add(new wxStaticText(this, wxID_STATIC, wxT("Stampa in corso..."), wxDefaultPosition, wxSize(320,-1)), 0, wxALL, 10 );
|
|
button_sizer->Add(new wxGauge(this, wxID_FORWARD, 1, wxDefaultPosition, wxSize(320,-1)), 0, wxALL, 10 );
|
|
button_sizer->Add(new wxButton(this, wxID_CANCEL, wxT("Annulla") ), 0, wxALL | wxALIGN_CENTER, 10 );
|
|
|
|
SetAutoLayout(true);
|
|
SetSizer(button_sizer);
|
|
|
|
button_sizer->Fit(this);
|
|
button_sizer->SetSizeHints(this);
|
|
|
|
Show();
|
|
Update();
|
|
}
|
|
|
|
void CreateAbortWindow()
|
|
{
|
|
wxPrinterBase::sm_abortWindow = new TwxPrintAbortDialog;
|
|
}
|
|
|
|
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)
|
|
{
|
|
const wxString strDir = ::wxGetCwd(); // Memorizzo la directory corrente (Acrobat la cambia)
|
|
|
|
wxBeginBusyCursor();
|
|
m_PrintoutCache.Reset(); // Forza nuovo contesto di stampa
|
|
TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
m_PrintoutCache.Lock();
|
|
wxEndBusyCursor();
|
|
|
|
CreateAbortWindow();
|
|
const BOOLEAN aborted = print_fcn(data);
|
|
DestroyAbortWindow();
|
|
|
|
po.OnEndDocument();
|
|
po.OnEndPrinting();
|
|
|
|
m_PrintoutCache.Unlock();
|
|
m_PrintoutCache.Reset();
|
|
|
|
::wxSetWorkingDirectory(strDir); // Ripristino la directory corrente (Acrobat l'ha cambiata)
|
|
|
|
return aborted;
|
|
}
|
|
|
|
BOOLEAN xvt_print_suspend_thread()
|
|
{
|
|
BOOLEAN ok = m_PrintoutCache.Printing();
|
|
if (ok)
|
|
{
|
|
TwxPrintOut& po = m_PrintoutCache.Get(NULL); // Sembra generare una pagina vuota indesiderata
|
|
po.OnEndDocument(); // Sembra generare una pagina vuota indesiderata
|
|
po.OnEndPrinting();
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
BOOLEAN xvt_print_restart_thread()
|
|
{
|
|
TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
po.OnBeginPrinting();
|
|
po.OnBeginDocument(1, 32000);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOLEAN xvt_print_open_page(PRINT_RCD* precp)
|
|
{
|
|
BOOLEAN ok = m_PrintoutCache.Printing();
|
|
if (ok)
|
|
{
|
|
if (wxPrinterBase::sm_abortIt)
|
|
ok = FALSE;
|
|
else
|
|
{
|
|
TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
po.GetDC()->StartPage();
|
|
TPrintDC::SetPageStart(); // Flag per azzeramento dati DC
|
|
|
|
// Aggiorna barra di attesa
|
|
TwxPrintAbortDialog* pad = wxDynamicCast(wxPrinterBase::sm_abortWindow, TwxPrintAbortDialog);
|
|
if (pad != NULL)
|
|
pad->Pulse();
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Added by XVAGA
|
|
///////////////////////////////////////////////////////////
|
|
|
|
#ifdef LINUX
|
|
static const char * cups_file = "/etc/cups/printers.conf";
|
|
static const char * cups_local_file = "./printers.conf";
|
|
static const char * prcap_local_file = "./printcap";
|
|
|
|
static bool is_cups()
|
|
{
|
|
static int printer_system = -1;
|
|
|
|
if (printer_system < 0)
|
|
printer_system = xvt_fsys_file_exists(cups_file) ? 1 : 2;
|
|
|
|
return printer_system == 1;
|
|
}
|
|
#endif
|
|
|
|
SLIST xvt_print_list_devices()
|
|
{
|
|
SLIST list = xvt_slist_create();
|
|
#ifdef WIN32
|
|
const DWORD dwFlags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS;
|
|
const int level = xvt_sys_get_os_version() >= XVT_WS_WIN_NT ? 4 : 5;
|
|
DWORD dwSize = 0, dwPrinters = 0;
|
|
::EnumPrinters (dwFlags, NULL, level, NULL, 0, &dwSize, &dwPrinters);
|
|
if (dwSize > 0)
|
|
{
|
|
BYTE* pBuffer = new BYTE[dwSize];
|
|
::EnumPrinters (dwFlags, NULL, level, pBuffer, dwSize, &dwSize, &dwPrinters);
|
|
if (level == 4)
|
|
{
|
|
const PRINTER_INFO_4* pPrnInfo = (const PRINTER_INFO_4*)pBuffer;
|
|
for (UINT i=0; i < dwPrinters; i++)
|
|
{
|
|
xvt_slist_add_at_elt(list, NULL, pPrnInfo->pPrinterName, NULL);
|
|
pPrnInfo++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const PRINTER_INFO_5* pPrnInfo = (const PRINTER_INFO_5*)pBuffer;
|
|
for (UINT i=0; i < dwPrinters; i++)
|
|
{
|
|
xvt_slist_add_at_elt(list, NULL, pPrnInfo->pPrinterName, NULL);
|
|
pPrnInfo++;
|
|
}
|
|
}
|
|
delete[] pBuffer;
|
|
}
|
|
#else
|
|
if (is_cups())
|
|
{
|
|
ifstream p(cups_local_file);
|
|
char line[4096];
|
|
const char * str_to_find = "Printer";
|
|
|
|
while (p.getline(line, sizeof(line)))
|
|
{
|
|
char * s;
|
|
|
|
if (line[0] == '<' && line[1] != '/' &&
|
|
(s = strstr(line, str_to_find)) != NULL)
|
|
{
|
|
s += strlen(str_to_find);
|
|
|
|
while (isspace(*s))
|
|
s++;
|
|
|
|
if (*s)
|
|
{
|
|
char * l = s + strlen(s) - 1;
|
|
|
|
while (*l == '>' || isspace(*l))
|
|
l--;
|
|
*(l + 1) = '\0';
|
|
xvt_slist_add_at_elt(list, NULL, s, 0L);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ifstream p(prcap_local_file); // 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 != NULL && *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;
|
|
}
|
|
#endif
|
|
return ok;
|
|
}
|
|
|
|
BOOLEAN xvt_print_get_default_device(char* name, int namesize)
|
|
{
|
|
/*
|
|
wxString strName, strPort;
|
|
const BOOLEAN ok = wxGetDefaultDeviceName(strName, strPort);
|
|
if (ok)
|
|
wxStrncpy(name, strName, namesize);
|
|
else
|
|
*name = '\0';
|
|
*/
|
|
bool ok = FALSE;
|
|
|
|
#ifdef WIN32
|
|
ok = ::GetProfileString ("windows", "device", ",,,", name, namesize) != 0;
|
|
#else
|
|
*name = '\0';
|
|
if (is_cups())
|
|
{
|
|
ifstream p(cups_local_file);
|
|
char line[4096];
|
|
const char * str_to_find = "<DefaultPrinter";
|
|
|
|
while (p.getline(line, sizeof(line)))
|
|
{
|
|
char * s = strstr(line, str_to_find) ;
|
|
|
|
if (s != NULL)
|
|
{
|
|
s += strlen(str_to_find);
|
|
|
|
while (isspace(*s))
|
|
s++;
|
|
|
|
if (*s)
|
|
{
|
|
char * l = s + strlen(s) - 1;
|
|
|
|
while (*l == '>' || 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* const 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++)
|
|
{
|
|
char para[4]; sprintf(para, "%d", p);
|
|
int 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;
|
|
char exedir[_MAX_PATH], path[_MAX_PATH];
|
|
// Nelle installazioni sfigate con programmi in rete cerca di stabilire il percorso locale di Campo.ini
|
|
DIRECTORY dir;
|
|
|
|
xvt_fsys_get_default_dir(&dir);
|
|
xvt_fsys_convert_dir_to_str(&dir, exedir, sizeof(exedir));
|
|
#ifdef WIN32
|
|
if (xvt_fsys_is_network_drive(exedir))
|
|
bFound = xvt_fsys_get_campo_stp_value("CampoIni", path, sizeof(path));
|
|
|
|
if (!bFound)
|
|
{
|
|
if (OsWin32_IsWindowsServer())
|
|
{
|
|
xvt_fsys_build_pathname(path, NULL, wxGetHomeDir(), "campo", "ini", NULL);
|
|
bFound = xvt_fsys_file_exists(path);
|
|
if (!bFound)
|
|
{
|
|
char pathstd[_MAX_PATH];
|
|
xvt_fsys_build_pathname(pathstd, NULL, exedir, "campo", "ini", NULL);
|
|
if (xvt_fsys_file_exists(pathstd))
|
|
wxCopyFile(pathstd, path);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bFound)
|
|
xvt_fsys_build_pathname(path, NULL, exedir, "campo", "ini", NULL);
|
|
#else
|
|
if (!bFound)
|
|
{
|
|
char username[32];
|
|
char ininame[_MAX_FNAME];
|
|
|
|
xvt_sys_get_user_name(username, sizeof(username));
|
|
if (xvt_str_compare_ignoring_case(username, "root") == 0)
|
|
*username = '\0';
|
|
|
|
sprintf(ininame, "campo%s", username);
|
|
xvt_fsys_build_pathname(path, NULL, exedir, ininame, "ini", NULL);
|
|
if (!xvt_fsys_file_exists(path) && *username > ' ')
|
|
{
|
|
char pathstd[_MAX_PATH];
|
|
xvt_fsys_build_pathname(pathstd, NULL, exedir, "campo", "ini", NULL);
|
|
if (xvt_fsys_file_exists(pathstd))
|
|
wxCopyFile(pathstd, path);
|
|
}
|
|
}
|
|
#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;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Gestione MD5
|
|
///////////////////////////////////////////////////////////
|
|
|
|
#include "MD5Checksum.h"
|
|
|
|
BOOLEAN xvt_str_md5(const char* instr, char* outstr)
|
|
{
|
|
wxASSERT(outstr != NULL);
|
|
BOOLEAN ok = instr && *instr && outstr;
|
|
if (ok)
|
|
{
|
|
wxStrcpy(outstr, wxMD5Checksum::GetMD5((unsigned char*)instr, strlen(instr)));
|
|
ok = *outstr != '\0';
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
BOOLEAN xvt_fsys_file_md5(const char* path, char* outstr)
|
|
{
|
|
wxASSERT(outstr != NULL);
|
|
BOOLEAN ok = path && *path && outstr;
|
|
if (ok)
|
|
{
|
|
wxStrcpy(outstr, wxMD5Checksum::GetMD5(wxString(path)));
|
|
ok = *outstr != '\0';
|
|
}
|
|
return ok;
|
|
}
|
|
|