1 /**************************************************************************
2 * Copyright (C) 2005-2020 by Oleksandr Shneyder *
3 * <o.shneyder@phoca-gmbh.de> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17
18 #include "x2goclientconfig.h"
19 #include "printprocess.h"
20 #include "x2gologdebug.h"
21 #include <QFile>
22 #include "x2gosettings.h"
23 #include <QDir>
24 #include "printdialog.h"
25 #if (!defined Q_OS_WIN) && (!defined Q_WS_HILDON)
26 #include "cupsprint.h"
27 #else
28 #include "printwidget.h"
29 #endif
30 #include <QProcess>
31 #include <QMessageBox>
32 #include <QFileDialog>
33 #include "x2gologdebug.h"
34 #ifdef Q_OS_WIN
35 #include "wapi.h"
36 #endif
37 #include <QTimer>
PrintProcess(QString pdf,QString title,QObject * parent)38 PrintProcess::PrintProcess ( QString pdf, QString title, QObject *parent ) :
39 QObject ( parent )
40 {
41 x2goDebug<<"Starting print process.";
42 pdfFile=pdf;
43 pdfTitle=title;
44 parentWidg= ( QWidget* ) parent;
45 if ( !loadSettings() )
46 {
47 QFile::remove ( pdfFile );
48 return;
49 }
50 if ( viewPdf )
51 {
52 x2goDebug<<"Opening PDF file: "<<pdfFile<<"; title: "<<pdfTitle;
53 QTimer::singleShot ( 100, this, SLOT ( openPdf() ) );
54 }
55 else
56 {
57 x2goDebug<<"Printing PDF file: "<<pdfFile<<"; title: "<<pdfTitle;
58 QTimer::singleShot ( 100, this, SLOT ( print() ) );
59 }
60 }
61
62
~PrintProcess()63 PrintProcess::~PrintProcess()
64 {
65 x2goDebug<<"Closing print process.";
66 }
67
68
slot_processFinished(int exitCode,QProcess::ExitStatus exitStatus)69 void PrintProcess::slot_processFinished ( int exitCode,
70 QProcess::ExitStatus exitStatus )
71 {
72 disconnect ( this,SIGNAL ( finished ( int , QProcess::ExitStatus ) ),
73 this,SLOT ( slot_processFinished (
74 int,QProcess::ExitStatus ) ) );
75 QFile::remove ( pdfFile );
76 if ( exitCode==0 && exitStatus==QProcess::NormalExit )
77 {
78 if ( !printStdIn )
79 {
80 if ( !QProcess::startDetached (
81 printCmd+" \""+psFile+"\"" ) )
82 slot_error ( QProcess::FailedToStart );
83 }
84 else
85 {
86 QProcess* proc=new QProcess;
87 proc->setStandardInputFile ( psFile );
88 connect ( proc,SIGNAL (
89 error ( QProcess::ProcessError ) ),
90 this,SLOT (
91 slot_error (
92 QProcess::ProcessError ) ) );
93 proc->start ( printCmd );
94 }
95 }
96 else
97 slot_pdf2psError ( QProcess::Crashed );
98 }
99
100
loadSettings()101 bool PrintProcess::loadSettings()
102 {
103 X2goSettings st ( "printing" );
104
105 if ( st.setting()->value ( "showdialog",true ).toBool() )
106 {
107 PrintDialog dlg;
108 if ( dlg.exec() ==QDialog::Rejected )
109 return false;
110 }
111
112 viewPdf=st.setting()->value ( "pdfview",false ).toBool();
113 customPrintCmd=st.setting()->value ( "print/startcmd",false ).toBool();
114 printCmd=st.setting()->value ( "print/command","lpr" ).toString();
115 printStdIn= st.setting()->value ( "print/stdin",false ).toBool();
116 printPs=st.setting()->value ( "print/ps",false ).toBool();
117
118 pdfOpen= st.setting()->value ( "view/open",true ).toBool();
119
120 #ifndef Q_OS_WIN
121 pdfOpenCmd=st.setting()->value ( "view/command","xpdf" ).toString();
122 #else
123 winX2goPrinter=
124 st.setting()->value ( "print/defaultprinter",
125 wapiGetDefaultPrinter() ).toString();
126 #endif
127 #ifdef Q_WS_HILDON
128 pdfOpenCmd="run-standalone.sh dbus-send --print-reply"
129 " --dest=com.nokia.osso_pdfviewer "
130 "/com/nokia/osso_pdfviewer "
131 "com.nokia.osso_pdfviewer.mime_open string:file://";
132 viewPdf=true;
133 #endif
134 return true;
135
136 }
137
138
openPdf()139 void PrintProcess::openPdf()
140 {
141 x2goDebug<<"Opening/saving PDF ...";
142 if ( pdfOpen )
143 {
144 #ifndef Q_OS_WIN
145 #ifndef Q_WS_HILDON
146 QString cmd=pdfOpenCmd+" \""+pdfFile+"\"";
147 #else
148 QString cmd=pdfOpenCmd+"\""+pdfFile+"\"";
149 #endif
150 x2goDebug<<"Using PDF viewer command: "<<cmd;
151 if ( ! QProcess::startDetached ( cmd ) )
152 slot_error ( QProcess::FailedToStart );
153
154 #else
155 wapiShellExecute ( "open",
156 wapiShortFileName ( pdfFile ),
157 QString::null,
158 wapiShortFileName ( QDir::homePath() ) );
159 #endif
160 }
161 else
162 {
163 QString homePath=QDir::homePath();
164 #ifndef Q_OS_WIN
165 homePath +="/"+pdfTitle+".pdf";
166 #else
167 homePath +="\\x2goprint.pdf";
168 #endif
169 QString fileName = QFileDialog::getSaveFileName ( 0,
170 tr ( "Save File" ),
171 homePath,
172 tr ( "PDF Document (*.pdf)" ) );
173 if ( fileName.length() >0 )
174 QFile::rename ( pdfFile,fileName );
175
176 }
177 }
178
print()179 void PrintProcess::print()
180 {
181 #ifndef Q_WS_HILDON
182 if ( !customPrintCmd )
183 {
184 #ifndef Q_OS_WIN
185 CUPSPrint prn;
186 prn.setCurrentPrinter ( prn.getDefaultUserPrinter() );
187 prn.print ( pdfFile, pdfTitle );
188 #else
189 x2goDebug<<"Printing to "<<winX2goPrinter;
190 wapiShellExecute ( "printto",
191 wapiShortFileName ( pdfFile ),
192 winX2goPrinter,
193 wapiShortFileName ( QDir::homePath() ) );
194 #endif
195 }
196 else
197 #endif //Q_WS_HILDON
198 {
199 if ( !printPs )
200 {
201 if ( !printStdIn )
202 {
203 if ( !QProcess::startDetached (
204 printCmd+
205 " \""+pdfFile+"\"" ) )
206 slot_error ( QProcess::FailedToStart );
207
208 }
209 else
210 {
211 QProcess* proc=new QProcess;
212 proc->setStandardInputFile ( pdfFile );
213 connect ( proc,SIGNAL (
214 error (
215 QProcess::ProcessError ) ),
216 this,SLOT (
217 slot_error (
218 QProcess::ProcessError ) ) );
219 proc->start ( printCmd );
220 }
221 }
222 else
223 {
224 QStringList args;
225 psFile=pdfFile;
226 psFile.replace ( "pdf","ps" );
227 args<<pdfFile<<psFile;
228 QProcess* proc=new QProcess;
229 connect ( proc,SIGNAL (
230 finished ( int ,
231 QProcess::ExitStatus ) ),
232 this,SLOT (
233 slot_processFinished (
234 int,
235 QProcess::ExitStatus ) ) );
236 connect ( proc,SIGNAL (
237 error ( QProcess::ProcessError ) ),
238 this,SLOT (
239 slot_pdf2psError (
240 QProcess::ProcessError ) ) );
241 #ifndef Q_OS_WIN
242 proc->start ( "pdf2ps",args );
243 #else
244 QString pdf2ps,ver;
245 PrintWidget::gsInfo ( ver,pdf2ps );
246 QString wdir=pdf2ps;
247 wdir.replace ( "pdf2ps.bat","" );
248 proc->setWorkingDirectory ( wdir );
249 QStringList env=QProcess::systemEnvironment();
250 env.replaceInStrings ( QRegExp ( "^PATH=(.*)",
251 Qt::CaseInsensitive ),
252 "PATH=\\1;"+wdir );
253 wdir.replace ( "\\lib\\","\\bin\\" );
254 env.replaceInStrings ( QRegExp ( "^PATH=(.*)",
255 Qt::CaseInsensitive ),
256 "PATH=\\1;"+wdir );
257 proc->setEnvironment ( env );
258 proc->start ( pdf2ps,args );
259 #endif
260 }
261 }
262 }
263
slot_error(QProcess::ProcessError)264 void PrintProcess::slot_error ( QProcess::ProcessError )
265 {
266 QString message=tr ( "Failed to execute command:\n" );
267 if ( viewPdf )
268 message+=" "+pdfOpenCmd+ " " +pdfFile;
269 else
270 {
271 message+=printCmd;
272 if ( !printStdIn )
273 {
274 message+=" ";
275 if ( printPs )
276 message+=psFile;
277 else
278 message+=pdfFile;
279 }
280 }
281 QMessageBox::critical ( 0l, tr ( "Printing error." ),
282 message );
283
284 }
285
slot_pdf2psError(QProcess::ProcessError)286 void PrintProcess::slot_pdf2psError ( QProcess::ProcessError )
287 {
288 QMessageBox::critical ( 0l, tr ( "Printing error." ),
289 tr ( "Failed to execute command:\n" ) +
290 "pdf2ps "+pdfFile+" "+psFile );
291 }
292