kprintpreview.cpp
00001 /* 00002 * This file is part of the KDE libraries 00003 * Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be> 00004 * 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Library General Public 00008 * License version 2 as published by the Free Software Foundation. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Library General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Library General Public License 00016 * along with this library; see the file COPYING.LIB. If not, write to 00017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 * Boston, MA 02110-1301, USA. 00019 **/ 00020 00021 #include "kprintpreview.h" 00022 #include "kmfactory.h" 00023 00024 #include <tqfile.h> 00025 #include <tqlayout.h> 00026 #include <tqvbox.h> 00027 00028 #include <kparts/part.h> 00029 #include <kaccel.h> 00030 #include <kaction.h> 00031 #include <klibloader.h> 00032 #include <ktrader.h> 00033 #include <kuserprofile.h> 00034 #include <krun.h> 00035 #include <kapplication.h> 00036 #include <kstandarddirs.h> 00037 #include <klocale.h> 00038 #include <kmessagebox.h> 00039 #include <kdebug.h> 00040 #include <kconfig.h> 00041 #include <ktoolbar.h> 00042 #include <kmimetype.h> 00043 00044 KPreviewProc::KPreviewProc() 00045 : KProcess() 00046 { 00047 m_bOk = false; 00048 connect(this, TQT_SIGNAL(processExited(KProcess*)), TQT_SLOT(slotProcessExited(KProcess*))); 00049 } 00050 00051 KPreviewProc::~KPreviewProc() 00052 { 00053 } 00054 00055 bool KPreviewProc::startPreview() 00056 { 00057 if (start()) 00058 { 00059 kapp->enter_loop(); 00060 return m_bOk; 00061 } 00062 else 00063 return false; 00064 } 00065 00066 void KPreviewProc::slotProcessExited(KProcess* proc) 00067 { 00068 kapp->exit_loop(); 00069 if ( proc->normalExit() && proc->exitStatus() == 0 ) 00070 m_bOk = true; 00071 else 00072 kdDebug(500) << "KPreviewProc::slotProcessExited: normalExit=" << proc->normalExit() 00073 << " exitStatus=" << proc->exitStatus() << endl; 00074 } 00075 00076 //******************************************************************************************* 00077 00078 class KPrintPreview::KPrintPreviewPrivate 00079 { 00080 public: 00081 KPrintPreviewPrivate(KPrintPreview *dlg) : gvpart_(0) 00082 { 00083 mainwidget_ = new TQWidget(dlg, "MainWidget"); 00084 toolbar_ = new KToolBar(mainwidget_, "PreviewToolBar", true); 00085 actions_ = new KActionCollection(dlg); 00086 accel_ = new KAccel(dlg); 00087 previewonly_ = false; 00088 } 00089 ~KPrintPreviewPrivate() 00090 { 00091 if (gvpart_) delete gvpart_; 00092 } 00093 void plugAction(KAction *act) 00094 { 00095 act->plug(toolbar_); 00096 act->plugAccel(accel_); 00097 } 00098 00099 KParts::ReadOnlyPart *gvpart_; 00100 KToolBar *toolbar_; 00101 KActionCollection *actions_; 00102 TQWidget *mainwidget_; 00103 KAccel *accel_; 00104 bool previewonly_; 00105 }; 00106 00107 static KLibFactory* componentFactory() 00108 { 00109 kdDebug(500) << "kdeprint: querying trader for 'application/postscript' service" << endl; 00110 KLibFactory *factory(0); 00111 factory = KLibLoader::self()->factory("libkghostviewpart"); 00112 if( factory ) 00113 return factory; 00114 KTrader::OfferList offers = KTrader::self()->query(TQString::fromLatin1("application/postscript"), TQString::fromLatin1("KParts/ReadOnlyPart"), TQString::null, TQString::null); 00115 for (KTrader::OfferList::ConstIterator it = offers.begin(); it != offers.end(); ++it) 00116 { 00117 KService::Ptr service = *it; 00118 factory = KLibLoader::self()->factory(TQFile::encodeName(service->library())); 00119 if (factory) 00120 break; 00121 } 00122 if (!factory) 00123 { 00124 // nothing has been found, try to load directly the KGhostview part 00125 factory = KLibLoader::self()->factory("libkghostviewpart"); 00126 } 00127 return factory; 00128 } 00129 00130 static bool continuePrint(const TQString& msg_, TQWidget *parent, bool previewOnly) 00131 { 00132 QString msg(msg_); 00133 if (previewOnly) 00134 { 00135 KMessageBox::error(parent, msg); 00136 return false; 00137 } 00138 else 00139 { 00140 msg.append(" ").append(i18n("Do you want to continue printing anyway?")); 00141 return (KMessageBox::warningContinueCancel(parent, msg, TQString::null, KGuiItem(i18n("Print"),"fileprint")) == KMessageBox::Continue); 00142 } 00143 } 00144 00145 //******************************************************************************************* 00146 00147 KPrintPreview::KPrintPreview(TQWidget *parent, bool previewOnly) 00148 : KDialogBase(parent, "PreviewDlg", true, i18n("Print Preview"), 0) 00149 { 00150 kdDebug(500) << "kdeprint: creating preview dialog" << endl; 00151 d = new KPrintPreviewPrivate(this); 00152 d->previewonly_ = previewOnly; 00153 00154 // create main view and actions 00155 setMainWidget(d->mainwidget_); 00156 if (previewOnly) 00157 KStdAction::close(TQT_TQOBJECT(this), TQT_SLOT(reject()), d->actions_, "close_print"); 00158 else 00159 { 00160 new KAction(i18n("Print"), "fileprint", Qt::Key_Return, TQT_TQOBJECT(this), TQT_SLOT(accept()), d->actions_, "continue_print"); 00161 new KAction(i18n("Cancel"), "stop", Qt::Key_Escape, TQT_TQOBJECT(this), TQT_SLOT(reject()), d->actions_, "stop_print"); 00162 } 00163 00164 } 00165 00166 KPrintPreview::~KPrintPreview() 00167 { 00168 delete d; 00169 } 00170 00171 void KPrintPreview::initView(KLibFactory *factory) 00172 { 00173 // load the component 00174 d->gvpart_ = (KParts::ReadOnlyPart*)factory->create(TQT_TQOBJECT(d->mainwidget_), "gvpart", "KParts::ReadOnlyPart"); 00175 00176 // populate the toolbar 00177 if (d->previewonly_) 00178 d->plugAction(d->actions_->action("close_print")); 00179 else 00180 { 00181 d->plugAction(d->actions_->action("continue_print")); 00182 d->plugAction(d->actions_->action("stop_print")); 00183 } 00184 if (d->gvpart_) 00185 { 00186 TQDomNodeList l = d->gvpart_->domDocument().elementsByTagName( "ToolBar" ); 00187 if ( l.length() > 0 ) 00188 { 00189 d->toolbar_->insertLineSeparator(); 00190 TQDomNodeList acts = l.item( 0 ).toElement().elementsByTagName( "Action" ); 00191 for ( uint i=0; i<acts.length(); i++ ) 00192 { 00193 TQDomElement a = acts.item( i ).toElement(); 00194 if ( a.attribute( "name" ) == "goToPage" ) 00195 continue; 00196 KAction *act = d->gvpart_->action( a ); 00197 if ( act != 0 ) 00198 d->plugAction( act ); 00199 } 00200 } 00201 /* 00202 KAction *act; 00203 d->toolbar_->insertLineSeparator(); 00204 if ((act = d->gvpart_->action("zoomIn")) != 0) 00205 d->plugAction(act); 00206 if ((act = d->gvpart_->action("zoomOut")) != 0) 00207 d->plugAction(act); 00208 d->toolbar_->insertSeparator(); 00209 if ((act = d->gvpart_->action("prevPage")) != 0) 00210 d->plugAction(act); 00211 if ((act = d->gvpart_->action("nextPage")) != 0) 00212 d->plugAction(act); 00213 */ 00214 } 00215 d->toolbar_->setIconText(KToolBar::IconTextRight); 00216 d->toolbar_->setBarPos(KToolBar::Top); 00217 d->toolbar_->setMovingEnabled(false); 00218 //d->adjustSize(); 00219 00220 // construct the layout 00221 TQVBoxLayout *l0 = new TQVBoxLayout(d->mainwidget_, 0, 0); 00222 l0->addWidget(d->toolbar_, AlignTop); 00223 if (d->gvpart_) 00224 l0->addWidget(d->gvpart_->widget()); 00225 00226 resize(855, 500); 00227 setCaption(i18n("Print Preview")); 00228 } 00229 00230 void KPrintPreview::openFile(const TQString& file) 00231 { 00232 d->gvpart_->openURL(KURL(file)); 00233 } 00234 00235 bool KPrintPreview::isValid() const 00236 { 00237 return (d->gvpart_ != 0); 00238 } 00239 00240 bool KPrintPreview::preview(const TQString& file, bool previewOnly, WId parentId) 00241 { 00242 KMimeType::Ptr mime = KMimeType::findByPath( file ); 00243 bool isPS = ( mime->name() == "application/postscript" ); 00244 if ( !isPS ) 00245 kdDebug( 500 ) << "Previewing a non PostScript file, built-in preview disabled" << endl; 00246 00247 KConfig *conf = KMFactory::self()->printConfig(); 00248 conf->setGroup("General"); 00249 KLibFactory *factory(0); 00250 bool externalPreview = conf->readBoolEntry("ExternalPreview", false); 00251 TQWidget *parentW = TQT_TQWIDGET(TQWidget::find(parentId)); 00252 TQString exe; 00253 if (!externalPreview && isPS && (factory = componentFactory()) != 0) 00254 { 00255 KPrintPreview dlg(parentW, previewOnly); 00256 dlg.initView(factory); 00257 00258 if (dlg.isValid()) 00259 { 00260 dlg.openFile(file); 00261 return dlg.exec(); 00262 } 00263 else 00264 { 00265 // do nothing at that point: try to use the other way around by 00266 // using an external PS viewer if possible 00267 } 00268 } 00269 00270 // Either the PS viewer component was not found, or an external 00271 // preview program has been specified 00272 KPreviewProc proc; 00273 if (externalPreview && isPS ) 00274 { 00275 exe = conf->readPathEntry("PreviewCommand", "gv"); 00276 if (KStandardDirs::findExe(exe).isEmpty()) 00277 { 00278 QString msg = i18n("The preview program %1 cannot be found. " 00279 "Check that the program is correctly installed and " 00280 "located in a directory included in your PATH " 00281 "environment variable.").arg(exe); 00282 return continuePrint(msg, parentW, previewOnly); 00283 } 00284 proc << exe << file; 00285 } 00286 else 00287 { 00288 KService::Ptr serv = KServiceTypeProfile::preferredService( mime->name(), TQString::null ); 00289 if ( serv ) 00290 { 00291 KURL url; 00292 url.setPath( file ); 00293 TQStringList args = KRun::processDesktopExec( *serv, url, false ); 00294 proc << args; 00295 exe = serv->name(); 00296 } 00297 else 00298 { 00299 // in that case, the PS viewer component could not be loaded and no service 00300 // could be found to view PS 00301 TQString msg; 00302 if ( isPS ) 00303 msg = i18n("Preview failed: neither the internal KDE PostScript " 00304 "viewer (KGhostView) nor any other external PostScript " 00305 "viewer could be found."); 00306 else 00307 msg = i18n( "Preview failed: KDE could not find any application " 00308 "to preview files of type %1." ).arg( mime->name() ); 00309 00310 return continuePrint(msg, parentW, previewOnly); 00311 } 00312 } 00313 00314 // start the preview process 00315 if (!proc.startPreview()) 00316 { 00317 QString msg = i18n("Preview failed: unable to start program %1.").arg(exe); 00318 return continuePrint(msg, parentW, previewOnly); 00319 } 00320 else if (!previewOnly) 00321 { 00322 return (KMessageBox::questionYesNo(parentW, i18n("Do you want to continue printing?"), TQString::null, KGuiItem(i18n("Print"),"fileprint"), KStdGuiItem::cancel(), "continuePrinting") == KMessageBox::Yes); 00323 } 00324 else 00325 return false; 00326 } 00327 00328 #include "kprintpreview.moc"