diff options
Diffstat (limited to 'kdeprint/kdeprintfax/faxctrl.cpp')
-rw-r--r-- | kdeprint/kdeprintfax/faxctrl.cpp | 669 |
1 files changed, 0 insertions, 669 deletions
diff --git a/kdeprint/kdeprintfax/faxctrl.cpp b/kdeprint/kdeprintfax/faxctrl.cpp deleted file mode 100644 index c1b1b1a0d..000000000 --- a/kdeprint/kdeprintfax/faxctrl.cpp +++ /dev/null @@ -1,669 +0,0 @@ -/* - * tdeprintfax - a small fax utility - * Copyright (C) 2001 Michael Goffioul - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "faxctrl.h" -#include "tdeprintfax.h" -#include "defcmds.h" - -#include <ktextedit.h> -#include <tqfile.h> -#include <tqtextstream.h> -#include <kpushbutton.h> -#include <tqlayout.h> -#include <tqregexp.h> -#include <kprinter.h> -#include <tqsimplerichtext.h> -#include <tqpainter.h> -#include <tqpaintdevicemetrics.h> -#include <tqvaluestack.h> -#include <tqstylesheet.h> - -#include <kprocess.h> -#include <kglobal.h> -#include <kconfig.h> -#include <klocale.h> -#include <kdialogbase.h> -#include <kmimetype.h> -#include <kstandarddirs.h> -#include <kapplication.h> -#include <kwin.h> -#include <kemailsettings.h> -#include <kdebug.h> -#include <kstdguiitem.h> -#include <kfiledialog.h> -#include <kmessagebox.h> - -#include <stdlib.h> -#include <stdarg.h> - -#define quote(x) KProcess::quote(x) - -/** \brief Return a string for the page size. - * - * @param size the page size, which is actually of type @c TQPrinter::PageSize - * @return a pointer to a static string for the name of the page size. - */ -char const* pageSizeText(int size) -{ - switch(size) - { - case TQPrinter::A4: return "a4"; - case TQPrinter::Legal: return "legal"; - case TQPrinter::Letter: return "letter"; - default: return "letter"; - } -} - -/** \brief Return the default page size. - */ -static TQString pageSize() -{ - KConfig *conf = KGlobal::config(); - conf->setGroup("Fax"); - return conf->readEntry("Page", pageSizeText(KGlobal::locale()->pageSize())); -} - -static TQString stripNumber( const TQString& s ) -{ - KConfig *conf = KGlobal::config(); - conf->setGroup( "Personal" ); - - // removes any non-numeric character, except ('+','*','#') (hope it's supported by faxing tools) - TQString strip_s = s; - strip_s.replace( TQRegExp( "[^\\d+*#]" ), "" ); - if ( strip_s.find( '+' ) != -1 && conf->readBoolEntry( "ReplaceIntChar", false ) ) - strip_s.replace( "+", conf->readEntry( "ReplaceIntCharVal" ) ); - return strip_s; -} - -static TQString tagList( int n, ... ) -{ - TQString t; - - va_list ap; - va_start( ap, n ); - for ( int i=0; i<n; i++ ) - { - TQString tag = va_arg( ap, const char* ); - tag.append( "(_(\\w|\\{[^\\}]*\\}))?" ); - if ( t.isEmpty() ) - t = tag; - else - t.append( "|" ).append( tag ); - } - - return t; -} - -/** Process a @c %variable that has a boolean value. - * The format is <tt>%name_{iftrue??iffalse}</tt>. Either - * @em iftrue or @em iffalse can be empty (or both, but that would - * be silly). For example, if the fax software uses the - * option @c -l for low resolution, you might use <tt>%res_{??-l}</tt>, - * and if it uses high resolution, use <tt>%res_{-h??}</tt>. As an - * abbreviation, omit the trailing <tt>?</tt>, e.g., <tt>%res_{-h}</tt>. - * - * By the way, when using multiple, adjacent question marks, - * always be careful about inadvertently using trigraphs. - * Always escape the second and subsequent question marks, to be safe. - * I suppose question marks are not the best string to use, - * but I think they work well for the end-user. - * - * @param match the string to process - * @param value the Boolean value to control the processing - * @return the new value of the tag - */ -static TQString processTag( const TQString& match, bool value) -{ - TQString v; - int p = match.find( '_' ); - if ( p != -1 && match[ p+1 ] == '{' ) - { - // Find the ?? that separates the iftrue from the iffalse parts. - int q = match.find( "?\?", p+2 ); - if ( q == -1 ) - { - // No iffalse part - if (value) - v = match.mid( p+2 ); - // else value is false, so leave v empty. - } - else if ( value ) - // Extract only the iftrue part - v = match.mid( p+2, q-p-2 ); - else - // Extract only the iffalse part - v = match.mid( q+2, match.length()-q-3 ); - } - // Else the string is malformed: no _ or no { after the _ - // In either case, there isn't much the program can do, - // so just leave the result string empty. - - return v; -} - -static TQString processTag( const TQString& match, const TQString& value ) -{ - TQString v; - int p = match.find( '_' ); - if ( p != -1 ) - { - if ( value.isEmpty() ) - v = ""; - else - { - if ( match[ p+1 ] == '{' ) - { - v = match.mid( p+2, match.length()-p-3 ); - v.replace( "@@", quote( value ) ); - } - else - v = ( "-" + match.mid( p+1 ) + " " + quote( value ) ); - } - } - else - v = quote( value ); - return v; -} - -static bool isTag( const TQString& m, const TQString& t ) -{ - return ( m == t || m.startsWith( t+"_" ) ); -} - -static TQString replaceTags( const TQString& s, const TQString& tags, KdeprintFax *fax = NULL, const KdeprintFax::FaxItem& item = KdeprintFax::FaxItem() ) -{ - // unquote variables (they will be replaced with quoted values later) - - TQValueStack<bool> stack; - KConfig *conf = KGlobal::config(); - - TQString cmd = s; - - bool issinglequote=false; - bool isdoublequote=false; - TQRegExp re_noquote("(\\$\\(|\\)|\\(|\"|'|\\\\|`|"+tags+")"); - TQRegExp re_singlequote("('|"+tags+")"); - TQRegExp re_doublequote("(\\$\\(|\"|\\\\|`|"+tags+")"); - for ( int i = re_noquote.search(cmd); - i != -1; - i = (issinglequote?re_singlequote.search(cmd,i) - :isdoublequote?re_doublequote.search(cmd,i) - :re_noquote.search(cmd,i)) - ) - { - if (cmd[i]=='(') // (...) - { - // assert(isdoublequote == false) - stack.push(isdoublequote); - i++; - } - else if (cmd[i]=='$') // $(...) - { - stack.push(isdoublequote); - isdoublequote = false; - i+=2; - } - else if (cmd[i]==')') // $(...) or (...) - { - if (!stack.isEmpty()) - isdoublequote = stack.pop(); - else - qWarning("Parse error."); - i++; - } - else if (cmd[i]=='\'') - { - issinglequote=!issinglequote; - i++; - } - else if (cmd[i]=='"') - { - isdoublequote=!isdoublequote; - i++; - } - else if (cmd[i]=='\\') - i+=2; - else if (cmd[i]=='`') - { - // Replace all `...` with safer $(...) - cmd.replace (i, 1, "$("); - TQRegExp re_backticks("(`|\\\\`|\\\\\\\\|\\\\\\$)"); - for ( int i2=re_backticks.search(cmd,i+2); - i2!=-1; - i2=re_backticks.search(cmd,i2) - ) - { - if (cmd[i2] == '`') - { - cmd.replace (i2, 1, ")"); - i2=cmd.length(); // leave loop - } - else - { // remove backslash and ignore following character - cmd.remove (i2, 1); - i2++; - } - } - // Leave i unchanged! We need to process "$(" - } - else - { - TQString match, v; - - // get match - if (issinglequote) - match=re_singlequote.cap(); - else if (isdoublequote) - match=re_doublequote.cap(); - else - match=re_noquote.cap(); - - // substitute %variables - // settings - if ( isTag( match, "%dev" ) ) - { - conf->setGroup("Fax"); - v = processTag( match, conf->readEntry("Device", "modem") ); - - } - else if (isTag( match, "%server" )) - { - conf->setGroup( "Fax" ); - v = conf->readEntry("Server"); - if (v.isEmpty()) - v = getenv("FAXSERVER"); - if (v.isEmpty()) - v = TQString::tqfromLatin1("localhost"); - v = processTag( match, v ); - } - else if (isTag( match, "%page" )) - { - conf->setGroup( "Fax" ); - v = processTag( match, pageSize() ); - } - else if (isTag( match, "%res" )) - { - conf->setGroup( "Fax" ); - v = processTag(match, conf->readEntry("Resolution", "High") == "High"); - } - else if (isTag( match, "%user" )) - { - conf->setGroup("Personal"); - v = processTag(match, conf->readEntry("Name", getenv("USER"))); - } - else if (isTag( match, "%from" )) - { - conf->setGroup( "Personal" ); - v = processTag(match, conf->readEntry("Number")); - } - else if (isTag( match, "%email" )) - { - KEMailSettings e; - v = processTag(match, e.getSetting(KEMailSettings::EmailAddress)); - } - // arguments - else if (isTag( match, "%number" )) - v = processTag( match, stripNumber( item.number) ); - else if (isTag( match, "%rawnumber" )) - v = processTag( match, item.number ); - else if (isTag( match, "%name" )) - v = processTag(match, item.name); - else if (isTag( match, "%comment" )) - v = processTag(match, fax->comment()); - else if (isTag( match, "%enterprise" )) - v = processTag(match, item.enterprise); - else if ( isTag( match, "%time" ) ) - v = processTag( match, fax->time() ); - else if ( isTag( match, "%subject" ) ) - v = processTag( match, fax->subject() ); - else if (isTag( match, "%cover" )) - v = processTag(match, fax->cover()); - - // %variable inside of a quote? - if (isdoublequote) - v='"'+v+'"'; - else if (issinglequote) - v="'"+v+"'"; - - cmd.replace (i, match.length(), v); - i+=v.length(); - } - } - - return cmd; -} - -FaxCtrl::FaxCtrl(TQWidget *parent, const char *name) -: TQObject(parent, name) -{ - m_process = new KProcess(); - m_process->setUseShell(true); - connect(m_process, TQT_SIGNAL(receivedStdout(KProcess*,char*,int)), TQT_SLOT(slotReceivedStdout(KProcess*,char*,int))); - connect(m_process, TQT_SIGNAL(receivedStderr(KProcess*,char*,int)), TQT_SLOT(slotReceivedStdout(KProcess*,char*,int))); - connect(m_process, TQT_SIGNAL(processExited(KProcess*)), TQT_SLOT(slotProcessExited(KProcess*))); - connect(this, TQT_SIGNAL(faxSent(bool)), TQT_SLOT(cleanTempFiles())); - m_logview = 0; -} - -FaxCtrl::~FaxCtrl() -{ - slotCloseLog(); - delete m_process; -} - -bool FaxCtrl::send(KdeprintFax *f) -{ - m_command = faxCommand(); - if (m_command.isEmpty()) - return false; - - // replace tags common to all fax "operations" - m_command = replaceTags( m_command, tagList( 11, "%dev", "%server", "%page", "%res", "%user", "%from", "%email", "%comment", "%time", "%subject", "%cover" ), f ); - - m_log = TQString::null; - m_filteredfiles.clear(); - cleanTempFiles(); - m_files = f->files(); - m_faxlist = f->faxList(); - - addLogTitle( i18n( "Converting input files to PostScript" ) ); - filter(); - - return true; -} - -void FaxCtrl::slotReceivedStdout(KProcess*, char *buffer, int len) -{ - TQCString str(buffer, len); - kdDebug() << "Received stdout: " << str << endl; - addLog(TQString(str)); -} - -void FaxCtrl::slotProcessExited(KProcess*) -{ - // we exited a process: if there's still entries in m_files, this was a filter - // process, else this was the fax process - bool ok = (m_process->normalExit() && ((m_process->exitStatus() & (m_files.count() > 0 ? 0x1 : 0xFFFFFFFF)) == 0)); - if ( ok ) - { - if ( m_files.count() > 0 ) - { - // remove first element - m_files.remove(m_files.begin()); - if (m_files.count() > 0) - filter(); - else - sendFax(); - } - else if ( !m_faxlist.isEmpty() ) - sendFax(); - else - faxSent( true ); - } - else - { - emit faxSent(false); - } -} - -TQString FaxCtrl::faxCommand() -{ - KConfig *conf = KGlobal::config(); - conf->setGroup("System"); - TQString sys = conf->readPathEntry("System", "efax"); - TQString cmd; - if (sys == "hylafax") - cmd = conf->readPathEntry("HylaFax", hylafax_default_cmd); - else if (sys == "mgetty") - cmd = conf->readPathEntry("Mgetty", mgetty_default_cmd); - else if ( sys == "other" ) - cmd = conf->readPathEntry( "Other", TQString::null ); - else - cmd = conf->readPathEntry("EFax", efax_default_cmd); - if (cmd.startsWith("%exe_")) - cmd = defaultCommand(cmd); - return cmd; -} - -void FaxCtrl::sendFax() -{ - if ( m_command.find( "%files" ) != -1 ) - { - // replace %files tag - TQString filestr; - for (TQStringList::ConstIterator it=m_filteredfiles.begin(); it!=m_filteredfiles.end(); ++it) - filestr += (quote(*it)+" "); - m_command.replace("%files", filestr); - } - - if ( !m_faxlist.isEmpty() ) - { - KdeprintFax::FaxItem item = m_faxlist.first(); - m_faxlist.remove(m_faxlist.begin()); - - addLogTitle( i18n( "Sending fax to %1 (%2)" ).arg( item.number ).arg( item.name ) ); - - TQString cmd = replaceTags( m_command, tagList( 4, "%number", "%name", "%enterprise", "%rawnumber" ), NULL, item ); - m_process->clearArguments(); - *m_process << cmd; - addLog(i18n("Sending to fax using: %1").arg(cmd)); - if (!m_process->start(KProcess::NotifyOnExit, KProcess::AllOutput)) - emit faxSent(false); - else - emit message(i18n("Sending fax to %1...").arg( item.number )); - } -} - -void FaxCtrl::filter() -{ - if (m_files.count() > 0) - { - TQString mimeType = KMimeType::findByURL(KURL(m_files[0]), 0, true)->name(); - if (mimeType == "application/postscript" || mimeType == "image/tiff") - { - emit message(i18n("Skipping %1...").arg(m_files[0])); - m_filteredfiles.prepend(m_files[0]); - m_files.remove(m_files.begin()); - filter(); - } - else - { - TQString tmp = locateLocal("tmp","tdeprintfax_") + kapp->randomString(8); - m_filteredfiles.prepend(tmp); - m_tempfiles.append(tmp); - m_process->clearArguments(); - *m_process << locate("data","tdeprintfax/anytops") << "-m" << KProcess::quote(locate("data","tdeprintfax/faxfilters")) - << TQString::tqfromLatin1("--mime=%1").arg(mimeType) - << "-p" << pageSize() - << KProcess::quote(m_files[0]) << KProcess::quote(tmp); - if (!m_process->start(KProcess::NotifyOnExit, KProcess::AllOutput)) - emit faxSent(false); - else - emit message(i18n("Filtering %1...").arg(m_files[0])); - } - } - else - { - sendFax(); - } -} - -bool FaxCtrl::abort() -{ - if (m_process->isRunning()) - return m_process->kill(); - else - return false; -} - -void FaxCtrl::viewLog(TQWidget *) -{ - if (!m_logview) - { - TQWidget *topView = new TQWidget(0, "LogView", (WFlags)(WType_TopLevel|WStyle_DialogBorder|WDestructiveClose)); - m_logview = new KTextEdit(topView); - m_logview->setTextFormat( TQt::LogText ); - m_logview->setWordWrap( TQTextEdit::WidgetWidth ); - m_logview->setPaper( Qt::white ); - //m_logview->setReadOnly(true); - //m_logview->setWordWrap(TQTextEdit::NoWrap); - TQPushButton *m_clear = new KPushButton(KStdGuiItem::clear(), topView); - TQPushButton *m_close = new KPushButton(KStdGuiItem::close(), topView); - TQPushButton *m_print = new KPushButton( KStdGuiItem::print(), topView ); - TQPushButton *m_save = new KPushButton( KStdGuiItem::saveAs(), topView ); - m_close->setDefault(true); - connect(m_clear, TQT_SIGNAL(clicked()), TQT_SLOT(slotClearLog())); - connect(m_close, TQT_SIGNAL(clicked()), TQT_SLOT(slotCloseLog())); - connect(m_logview, TQT_SIGNAL(destroyed()), TQT_SLOT(slotCloseLog())); - connect( m_print, TQT_SIGNAL( clicked() ), TQT_SLOT( slotPrintLog() ) ); - connect( m_save, TQT_SIGNAL( clicked() ), TQT_SLOT( slotSaveLog() ) ); - - TQVBoxLayout *l0 = new TQVBoxLayout(topView, 10, 10); - l0->addWidget(m_logview); - TQHBoxLayout *l1 = new TQHBoxLayout(0, 0, 10); - l0->addLayout(l1); - l1->addStretch(1); - l1->addWidget( m_save ); - l1->addWidget( m_print ); - l1->addWidget(m_clear); - l1->addWidget(m_close); - - m_logview->setText(m_log); - - topView->resize(450, 350); - topView->show(); - } - else - { - KWin::activateWindow(m_logview->parentWidget()->winId()); - } -} - -void FaxCtrl::addLogTitle( const TQString& s ) -{ - TQString t( s ); - t.prepend( '\n' ).append( '\n' ); - addLog( t, true ); -} - -void FaxCtrl::addLog(const TQString& s, bool isTitle) -{ - TQString t = TQStyleSheet::escape(s); - if ( isTitle ) - t.prepend( "<font color=red><b>" ).append( "</b></font>" ); - m_log.append( t + '\n' ); - if (m_logview) - m_logview->append(t); -} - -TQString FaxCtrl::faxSystem() -{ - KConfig *conf = KGlobal::config(); - conf->setGroup("System"); - TQString s = conf->readEntry("System", "efax"); - s[0] = s[0].upper(); - return s; -} - -void FaxCtrl::cleanTempFiles() -{ - for (TQStringList::ConstIterator it=m_tempfiles.begin(); it!=m_tempfiles.end(); ++it) - TQFile::remove(*it); - m_tempfiles.clear(); -} - -void FaxCtrl::slotClearLog() -{ - m_log = TQString::null; - if (m_logview) - m_logview->clear(); -} - -void FaxCtrl::slotCloseLog() -{ - const TQObject *obj = TQT_TQOBJECT_CONST(sender()); - if (m_logview) - { - TQTextEdit *view = m_logview; - m_logview = 0; - if (obj && obj->inherits(TQPUSHBUTTON_OBJECT_NAME_STRING)) - delete view->parentWidget(); -kdDebug() << "slotClose()" << endl; - } -} - -void FaxCtrl::slotPrintLog() -{ - if ( m_logview ) - { - KPrinter printer; - printer.setDocName( i18n( "Fax log" ) ); - printer.setDocFileName( "faxlog" ); - if ( printer.setup( m_logview->tqtopLevelWidget(), i18n( "Fax Log" ) ) ) - { - TQPainter painter( &printer ); - TQPaintDeviceMetrics metric( &printer ); - TQRect body( 0, 0, metric.width(), metric.height() ), view( body ); - //TQString txt = m_logview->text(); - TQString txt = m_log; - - txt.replace( '\n', "<br>" ); - txt.prepend( "<h2>" + i18n( "KDEPrint Fax Tool Log" ) + "</h2>" ); - - kdDebug() << "Log: " << txt << endl; - TQSimpleRichText richText( txt, m_logview->font() ); - - richText.setWidth( &painter, body.width() ); - do - { - richText.draw( &painter, body.left(), body.top(), view, m_logview->tqcolorGroup() ); - view.moveBy( 0, body.height() ); - painter.translate( 0, -body.height() ); - if ( view.top() >= richText.height() ) - break; - printer.newPage(); - } while ( true ); - } - } -} - -void FaxCtrl::slotSaveLog() -{ - if ( m_logview ) - { - TQString filename = KFileDialog::getSaveFileName( TQString::null, TQString::null, m_logview ); - if ( !filename.isEmpty() ) - { - TQFile f( filename ); - if ( f.open( IO_WriteOnly ) ) - { - TQTextStream t( &f ); - t << i18n( "KDEPrint Fax Tool Log" ) << endl; - t << m_logview->text() << endl; - f.close(); - } - else - KMessageBox::error( m_logview, i18n( "Cannot open file for writing." ) ); - } - } -} - -#include "faxctrl.moc" |