1 /**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 Printing.cpp
6
7 Dominic Mazzoni
8
9 *******************************************************************//*!
10
11 \class AudacityPrintout
12 \brief Derived from wxPrintout, this class helps with printing.
13
14 *//*******************************************************************/
15
16
17
18 #include "Printing.h"
19
20 #include <wx/defs.h>
21 #include <wx/dc.h>
22 #include <wx/intl.h>
23 #include <wx/print.h>
24 #include <wx/printdlg.h>
25
26 #include "AColor.h"
27 #include "ProjectWindows.h"
28 #include "TrackArtist.h"
29 #include "ViewInfo.h"
30 #include "Track.h"
31 #include "widgets/Ruler.h"
32 #include "widgets/AudacityMessageBox.h"
33
34 #include "TrackPanelDrawingContext.h"
35
36 #include "tracks/ui/TrackView.h"
37
38 // Globals, so that we remember settings from session to session
gPrintData()39 wxPrintData &gPrintData()
40 {
41 static wxPrintData theData;
42 return theData;
43 }
44
45 class AudacityPrintout final : public wxPrintout
46 {
47 public:
AudacityPrintout(wxString title,TrackList * tracks,TrackPanel & panel)48 AudacityPrintout(wxString title,
49 TrackList *tracks, TrackPanel &panel):
50 wxPrintout(title),
51 mTracks(tracks)
52 , mPanel(panel)
53 {
54 }
55 bool OnPrintPage(int page);
56 bool HasPage(int page);
57 bool OnBeginDocument(int startPage, int endPage);
58 void GetPageInfo(int *minPage, int *maxPage,
59 int *selPageFrom, int *selPageTo);
60
61 private:
62 TrackPanel &mPanel;
63 TrackList *mTracks;
64 };
65
OnPrintPage(int WXUNUSED (page))66 bool AudacityPrintout::OnPrintPage(int WXUNUSED(page))
67 {
68 wxDC *dc = GetDC();
69 if (!dc)
70 return false;
71
72 int width, height;
73 dc->GetSize(&width, &height);
74
75 int rulerScreenHeight = 40;
76 int screenTotalHeight =
77 TrackView::GetTotalHeight( *mTracks ) + rulerScreenHeight;
78
79 double scale = height / (double)screenTotalHeight;
80
81 int rulerPageHeight = (int)(rulerScreenHeight * scale);
82 Ruler ruler;
83 ruler.SetBounds(0, 0, width, rulerPageHeight);
84 ruler.SetOrientation(wxHORIZONTAL);
85 ruler.SetRange(0.0, mTracks->GetEndTime());
86 ruler.SetFormat(Ruler::TimeFormat);
87 ruler.SetLabelEdges(true);
88 ruler.Draw(*dc);
89
90 TrackArtist artist( &mPanel );
91 artist.SetBackgroundBrushes(*wxWHITE_BRUSH, *wxWHITE_BRUSH,
92 *wxWHITE_PEN, *wxWHITE_PEN);
93 const double screenDuration = mTracks->GetEndTime();
94 SelectedRegion region{};
95 artist.pSelectedRegion = ®ion;
96 ZoomInfo zoomInfo(0.0, width / screenDuration);
97 artist.pZoomInfo = &zoomInfo;
98 int y = rulerPageHeight;
99
100 for (auto n : mTracks->Any()) {
101 auto &view = TrackView::Get( *n );
102 wxRect r;
103 r.x = 0;
104 r.y = 0;
105 r.width = width;
106 // Note that the views as printed might not have the same proportional
107 // heights as displayed on the screen, because the fixed-sized separators
108 // are counted in those heights but not printed
109 auto trackHeight = (int)(view.GetHeight() * scale);
110 r.height = trackHeight;
111
112 const auto subViews = view.GetSubViews( r );
113 if (subViews.empty())
114 continue;
115
116 auto iter = subViews.begin(), end = subViews.end(), next = iter;
117 auto yy = iter->first;
118 for ( ; iter != end; iter = next ) {
119 ++next;
120 auto nextY = ( next == end )
121 ? trackHeight
122 : next->first;
123 r.y = y + yy;
124 r.SetHeight( nextY - yy );
125 yy = nextY;
126
127 TrackPanelDrawingContext context{
128 *dc, {}, {}, &artist
129 };
130 iter->second->Draw( context, r, TrackArtist::PassTracks );
131 }
132
133 dc->SetPen(*wxBLACK_PEN);
134 AColor::Line(*dc, 0, y, width, y);
135
136 y += trackHeight;
137 };
138
139 return true;
140 }
141
HasPage(int page)142 bool AudacityPrintout::HasPage(int page)
143 {
144 return (page==1);
145 }
146
OnBeginDocument(int startPage,int endPage)147 bool AudacityPrintout::OnBeginDocument(int startPage, int endPage)
148 {
149 return wxPrintout::OnBeginDocument(startPage, endPage);
150 }
151
GetPageInfo(int * minPage,int * maxPage,int * selPageFrom,int * selPageTo)152 void AudacityPrintout::GetPageInfo(int *minPage, int *maxPage,
153 int *selPageFrom, int *selPageTo)
154 {
155 *minPage = 1;
156 *maxPage = 1;
157 *selPageFrom = 1;
158 *selPageTo = 1;
159 }
160
HandlePageSetup(wxWindow * parent)161 void HandlePageSetup(wxWindow *parent)
162 {
163 wxPageSetupData pageSetupData;
164
165 wxPageSetupDialog pageSetupDialog(parent, &pageSetupData);
166 pageSetupDialog.ShowModal();
167
168 gPrintData() = pageSetupDialog.GetPageSetupData().GetPrintData();
169 }
170
HandlePrint(wxWindow * parent,const wxString & name,TrackList * tracks,TrackPanel & panel)171 void HandlePrint(
172 wxWindow *parent, const wxString &name, TrackList *tracks,
173 TrackPanel &panel)
174 {
175 wxPrintDialogData printDialogData(gPrintData());
176
177 wxPrinter printer(&printDialogData);
178 AudacityPrintout printout(name, tracks, panel);
179 if (!printer.Print(parent, &printout, true)) {
180 if (wxPrinter::GetLastError() == wxPRINTER_ERROR) {
181 AudacityMessageBox(
182 XO("There was a problem printing."),
183 XO("Print"),
184 wxOK);
185 }
186 else {
187 // Do nothing, the user cancelled...
188 }
189 }
190 else {
191 gPrintData() = printer.GetPrintDialogData().GetPrintData();
192 }
193 }
194