Dynamisches Drucken wxWidgets

  • Themenstarter Themenstarter Johannes
  • Beginndatum Beginndatum
J

Johannes

Hallo zusammen

Ausgangslage:
--------------------
Gnu/Linux, wxWidgets 2.8, wxSmith, C++

Ich möchte beispielsweise in einer Kundenverwaltung bei Klick auf einen Button
mit Drucker-Icon einen Printview machen, mit welchem man natürlich auch aus-
drucken könnte.

Zum Drucken (und Printviews) erstellen ist unter: examples/samples/printing
ein gutes Beispiel bei wxWidgets beigelegt. Das Sample ist aber auch schon
in die Jahre gekommen :)


Problem 1:
---------------
Mit dem Sample-Beispiel zu wxPrinting konnte ich schon vieles erreichen,
doch das Beispiel beinhaltet zwei statische Seiten (Page 1 und Page 2).

Wie kann ich aber z.B. bei einer Kundenliste, bei welcher man nicht weiss,
ob in der Datenbank 10 oder 1000 Kunden gespeichert sind, einen Seiten-
umbruch machen? (Bei 10 Kunden gibt es eine Seite, bei 1000 Kunden
n-Seiten).

Wie kann ich mit einer For-Schleife eine Seitenumbruch mach n-Zeilen
machen?


Problem 2:
---------------
Wenn ich beispielsweise in der Kundendatenbank ein langes Bemerkungs-
feld habe, dann schreibt es ja bekanntlich einfach über den Seitenrand hinaus.
Ich habe es damit versucht, dass ich die Zeichen des Feldinhaltes durchlaufe,
nach einer bestimmten Anzahl Zeichen diese Zeile in ein wxArrayString
schreibe und dann das Array zeilenweise schreibe. Doch so richtig hat es
nicht geklappt; es hat mir nachfolgende Zeilen vorher geschrieben, statt
in der richtigen Reihenfolge. Naja, vielleicht hatte ich auch einen Fehler
im Code.

Wie kann ich den Zeilenumbruch bei langen Textfeldern im Druck/Printview
machen?

...


Hat schon jemand von euch dynamische Sachen mit Drucken gemacht?
Für Anregungen oder ein wenig Code wäre ich sehr dankbar.
 
Hi Johannes,

beim Drucken von dynamischen Texten/Tabellen etc. spielt die Formatierung (Schriftgröße etc.) auch eine entscheidende Rolle. Beim Qt-Framework kann man in Erfahrung bringen wie groß das jeweilige Objekt gerendert sein wird. Anhand dieser Infos kann man dann entscheiden ob und wann man z. B. einen Zeilenumbruch machen will oder lieber das ganze Objekt auf die nächste Seite packen will.

Ich entwickel nicht mit wxWidgets aber vielleicht kann man auch mit diesem Framework (genau wie bei Qt) durch einige Klassen/Methoden ermitteln wie hoch/breit das jeweilige Objekt wird.

Hoffe das du mit diesem Denkansatz etwas anfangen kannst.

Gruß
RudolfG
 
Danke Rudolf.

Das mit der Schriftgrösse habe ich mit Hilfe des Sampels schon hin gekriegt:

void MyPrintout::DrawPageOne(wxDC *dc)
{
int ppiScreenX, ppiScreenY;
int ppiPrinterX, ppiPrinterY;

GetPPIScreen(&ppiScreenX, &ppiScreenY);
GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);

float scale = (float)((float)ppiPrinterX/(float)ppiScreenX);
int pageWidth, pageHeight;
int w, h;
dc->GetSize(&w, &h);
GetPageSizePixels(&pageWidth, &pageHeight);

float overallScale = scale * (float)(w/(float)pageWidth);
dc->SetUserScale(overallScale, overallScale);

// Draw 50 mm by 50 mm L shape
float logUnitsFactor = (float)(ppiPrinterX/(scale*25.4));
float logUnits = (float)(50*logUnitsFactor);

int pageWidthMM, pageHeightMM;
GetPageSizeMM(&pageWidthMM, &pageHeightMM);

float leftMarginLogical = (float)(logUnitsFactor*leftMargin);
float topMarginLogical = (float)(logUnitsFactor*topMargin);
float bottomMarginLogical = (float)(logUnitsFactor*(pageHeightMM - bottomMargin));
float rightMarginLogical = (float)(logUnitsFactor*(pageWidthMM - rightMargin));

// Code oben ist aus dem Printing-Sample

// Mit folgendem Code kann ich Text schreiben, Schriftgrösse wird berücksichtigt (ausser Fett frisst er noch nicht :)) //
wxFont fntTitle(16, wxSWISS, wxBOLD, wxNORMAL);
wxFont fntNormal(10, wxSWISS, wxNORMAL, wxNORMAL);
wxFont fntNormalSmall(8, wxSWISS, wxNORMAL, wxNORMAL);
wxFont fntNormalBold(10, wxSWISS, wxBOLD, wxNORMAL);


unsigned int x = 20;
unsigned int y = 40;
dc->SetFont(fntTitle);
dc->DrawText(wxT("KUNDENLISTE"), leftMarginLogical, y);

// ... weiterer Code
}

........................

Das Ganze Printing-Zeugs nennt sich in wxWidgets ebenfalls "Printing Framework"
Classes: wxPrintout, wxPrinter, wxPrintPreview, wxPrinterDC, wxPostScriptDC, wxPrintDialog,
wxPrintData, wxPrintDialogData, wxPageSetupDialog, wxPageSetupDialogData


Aber leider kann ich bei keiner Klasse so etwas wie Methode "PageBreak()" finden, auch mit Suchen
in der Hilfe nicht. Oder sowas wie "newPage()" wäre auch nicht schlecht.

Weiss jemand Rat?

........................

Ich habe unter http://wxcode.sourceforge.net/components/wxpdfdoc/
wxPdfDocument gefunden. Das wäre natürlich auch ideal, einfach das pdf
zu drucken. Ein wenig überflüssig zwar, da man unter Linux auch vom
PrintDialog aus PDFs drucken kann.
Doch leider hat der Download von wxPdfDocument nur MS-VC-Code
dabei.

Weiss jemand, ob es wxPdfDocument auch für Linux gibt. Z.B.
eine .so- oder .a-Library?

Danke und Gruss Johannes
 
Ach, ja, mit folgendem Code kann man - mit Einbindung des Codes oben - Text zentrieren:

// Code s. oben plus

long xExtent, yExtent;
dc->GetTextExtent(wxT("Seite 1/1"), &xExtent, &yExtent);
float xPos = (float)(((((pageWidthMM - leftMargin - rightMargin)/2.0)+leftMargin)*logUnitsFactor) - (xExtent/2.0));

dc->SetFont(fntNormalSmall);
dc->DrawText(wxT("Seite 1/1"), (long)xPos, (long)bottomMarginLogical);
 
Ich konnte das Problem lösen:

In Methode GetPageInfo berechne ich wie viele Seiten es geben wird:

void CustomerListPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
{
Customer cust; // Instanz der Klasse Kunden
int number = cust.getNumberOfCustomersBySearchString(strGetSearchString); // Methode gibt Anzahl gefundene Datensätze in der DB zurück

if(number == 0) { *maxPage = 0; } // TODO: wenn 0 Seiten, Preview gar nicht öffnen
else {
if(number % 30 == 0) { *maxPage = (int) ((number / 30)); } // Anzahl Seiten bei 30 Zeilen pro Seite
else { *maxPage = (int) ((number / 30) + 1); } // Anzahl Seiten bei 30 Zeilen pro Seite + 1 Seite weil Rest
}
}

So long mates
 
Hallo Johannes,

> Ich habe unter http://wxcode.sourceforge.net/components/wxpdfdoc/
> wxPdfDocument gefunden. [...] Doch leider hat der Download von
> wxPdfDocument nur MS-VC-Code dabei.

Das ist schlicht falsch. Jede wxPdfDocument-Version wird jeweils in 2 Release-Varianten zur Verfügung gestellt:

a) als ZIP-Archiv für Windows
b) als tar.gz-Archiv für Linux

> Weiss jemand, ob es wxPdfDocument auch für Linux gibt.

Sicher. wxPdfDocument funktioniert unter Windows, Linux und Mac OS X. Vermutlich auch unter den übrigen von wxWidgets unterstützten Plattformen.

> Z.B. eine .so- oder .a-Library?

Der Release erfolgt als Quellcode. Sofern wxWidgets und GCC installiert sind, kann man per configure ganz nach Wunsch eine shared oder static library erzeugen.

Gruß,

Ulrich
 
Hallo Ulrich,

Danke für deine Antwort.

Selbstverständlich ich habe bei http://wxcode.sourceforge.net/components/wxpdfdoc/ das »wxpdfdoc-0.8.5.2.tar.gz«
heruntergeladen, .h-Dateien gefunden, aber keine »pdfdocument.cpp«-Datei mit der Klasse. Leider habe ich von Auge
gesucht und habe im Verzeichnis »/build« eben nur das Windoofs-VC-Zeugs wie z.B. »wxpdfdoc_vc6.dsw« u.A. gefunden.

Doch Dank deiner Hilfe habe ich es mit der Nautilus-Suche gefunden :) (im /src) Danke :) :) :) Dann brauche ich momentan
auch keine .a- oder .so-lib.
 
Wenn sich jetzt dein Problem erledigt hat, währe es sehr schön wenn du diesen Thread auch auf Erledigt setzten würdest. (falls das auch Gästen möglich ist!)

Gruß
RudolfG
 
Zurück