/***************************************************************************
                          kgpginterface.cpp  -  description
                             -------------------
    begin                : Mon Jul 8 2002
    copyright          : (C) 2002 by Jean-Baptiste Mardelle
    email                : bj@altern.org

    updated to handle gpg21 : Sun Jul 30 10:18:29 CEST 2017
    copyright          : (C) 2017 by Emanoil Kotsev
    email              : deloptes@yahoo.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <stdio.h>

#include <tqdialog.h>
#include <tqclipboard.h>
#include <tqlayout.h>
#include <tqregexp.h>
#include <tqstring.h>
#include <tqlabel.h>
#include <tqapplication.h>
#include <tdeio/netaccess.h>
#include <tqcheckbox.h>

#include <tdemessagebox.h>
#include <tdelocale.h>
#include <kpassdlg.h>
#include <kmdcodec.h>
#include <klineedit.h>
#include <kcharsets.h>
#include <kpassivepopup.h>
#include <kiconloader.h>
#include <tdeaction.h>
#include <tqtextcodec.h>
#include <tdeprocess.h>
#include <tdeprocio.h>
#include <tdeconfig.h>
#include <tqfile.h>
#include <kled.h>
#include <kdebug.h>
#include <tdetempfile.h>
#include <tqcursor.h>

#include "kgpginterface.h"
#include "listkeys.h"
#include "detailedconsole.h"

KgpgInterface::KgpgInterface()
{}


int KgpgInterface::getGpgVersion()
{
FILE *fp;
        TQString readResult,gpgString;
        char buffer[200];
	bool readLine=true;

        TQString gpgcmd="gpg --version";

        fp = popen(TQFile::encodeName(gpgcmd), "r");
        while ( fgets( buffer, sizeof(buffer), fp)) {
                readResult=buffer;
                if (readLine) {
		gpgString=readResult.stripWhiteSpace().section(' ',-1);
		readLine=false;
		}
        }
        pclose(fp);
	return (100*gpgString.section('.',0,0).toInt()+10*gpgString.section('.',1,1).toInt()+gpgString.section('.',2,2).toInt());
}

void KgpgInterface::updateIDs(TQString txtString)
{
//	kdDebug(2100) << k_funcinfo << endl;
 int cut=txtString.find(' ',22,false);
          txtString.remove(0,cut);
          if (txtString.find("(",0,false)!=-1)
            txtString=txtString.section('(',0,0)+txtString.section(')',-1);
	    txtString.replace(TQRegExp("<"),"&lt;");
          if (userIDs.find(txtString)==-1)
            {
              if (!userIDs.isEmpty())
                userIDs+=i18n(" or ");
              userIDs+=txtString;
            }
}

void KgpgInterface::KgpgEncryptFile(TQStringList encryptKeys,KURL srcUrl,KURL destUrl, TQStringList Options, bool symetrical)
{
//	kdDebug(2100) << k_funcinfo << endl;
        sourceFile=srcUrl;
        message=TQString();

        TDEProcIO *proc=new TDEProcIO(TQTextCodec::codecForLocale());
	*proc<<"gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings";
	for ( TQStringList::Iterator it = Options.begin(); it != Options.end(); ++it )
       		if (!TQFile::encodeName(*it).isEmpty()) *proc<< TQString(TQFile::encodeName(*it));

                *proc<<"--output"<<TQString(TQFile::encodeName(destUrl.path()));

		if (!symetrical) {
		*proc<<"-e";
		for ( TQStringList::Iterator it = encryptKeys.begin(); it != encryptKeys.end(); ++it )
       		*proc<<"--recipient"<< *it;
        	} else  ////////////   symetrical encryption, prompt for password
                *proc<<"-c";

		*proc<<TQString(TQFile::encodeName(srcUrl.path()));

        /////////  when process ends, update dialog infos
        TQObject::connect(proc, TQ_SIGNAL(processExited(TDEProcess *)),this,TQ_SLOT(encryptfin(TDEProcess *)));
        TQObject::connect(proc,TQ_SIGNAL(readReady(TDEProcIO *)),this,TQ_SLOT(readencprocess(TDEProcIO *)));
        proc->start(TDEProcess::NotifyOnExit,true);
}


KgpgInterface::~KgpgInterface()
{}


void KgpgInterface::encryptfin(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
        if (message.find("END_ENCRYPTION")!=-1)
                emit encryptionfinished(sourceFile);
        else {
                emit errormessage(message);
        }
}

void KgpgInterface::readencprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required;
        while (p->readln(required,true)!=-1) {
                if (required.find("BEGIN_ENCRYPTION",0,false)!=-1)
                        emit processstarted(sourceFile.path());
                if (required.find("GET_")!=-1) {
                        if (required.find("openfile.overwrite.okay")!=-1)
                                p->writeStdin(TQString("Yes"));
                        else if ((required.find("passphrase.enter")!=-1)) {
                                TQString passphrase;
                                int code=KPasswordDialog::getNewPassword(passphrase,i18n("Enter passphrase for your file (symmetrical encryption):"));
                                if (code!=TQDialog::Accepted) {
                                        p->deleteLater();
                                        emit processaborted(true);
                                        return;
                                }
                                p->writeStdin(passphrase,true);
                        } else {
                                p->writeStdin(TQString("quit"));
                                p->closeWhenDone();
                        }
                }
                message+=required+"\n";
        }
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////   File decryption

void KgpgInterface::KgpgDecryptFile(KURL srcUrl,KURL destUrl,TQStringList Options)
{
//	kdDebug(2100) << k_funcinfo << endl;
        message=TQString();
        step=3;
	decryptUrl=srcUrl.path();
        userIDs=TQString();
        anonymous=false;

        TDEProcIO *proc=new TDEProcIO(TQTextCodec::codecForLocale());

                *proc<<"gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings";

		for ( TQStringList::Iterator it = Options.begin(); it != Options.end(); ++it )
       		if (!TQFile::encodeName(*it).isEmpty()) *proc<< TQString(TQFile::encodeName(*it));

		if (!destUrl.fileName().isEmpty()) // a filename was entered
				*proc<<"-o"<<TQString(TQFile::encodeName(destUrl.path()));

                *proc<<"-d"<<TQString(TQFile::encodeName(srcUrl.path()));

        TQObject::connect(proc, TQ_SIGNAL(processExited(TDEProcess *)),this,TQ_SLOT(decryptfin(TDEProcess *)));
        TQObject::connect(proc,TQ_SIGNAL(readReady(TDEProcIO *)),this,TQ_SLOT(readdecprocess(TDEProcIO *)));
        proc->start(TDEProcess::NotifyOnExit,true);
}

void KgpgInterface::decryptfin(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
        if ((message.find("DECRYPTION_OKAY")!=-1) && (message.find("END_DECRYPTION")!=-1)) //&& (message.find("GOODMDC")!=-1)
                emit decryptionfinished();
        else
	emit errormessage(message);
}


void KgpgInterface::readdecprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required;
        while (p->readln(required,true)!=-1) {
                if (required.find("BEGIN_DECRYPTION",0,false)!=-1)
                        emit processstarted(decryptUrl);
                if (required.find("USERID_HINT",0,false)!=-1)
			updateIDs(required);

                if (required.find("ENC_TO")!=-1) {
                        if (required.find("0000000000000000")!=-1)
                                anonymous=true;
                }
                if (required.find("GET_")!=-1) {
                        if (required.find("openfile.overwrite.okay")!=-1)
                                p->writeStdin(TQString("Yes"));
                        else if ((required.find("passphrase.enter")!=-1)) {
                                if (userIDs.isEmpty())
                                        userIDs=i18n("[No user id found]");
                                userIDs.replace(TQRegExp("<"),"&lt;");
                                TQString passphrase;
                                TQString passdlgmessage;
                                if (anonymous)
                                        passdlgmessage=i18n("<b>No user id found</b>. Trying all secret keys.<br>");
                                if ((step<3) && (!anonymous))
                                        passdlgmessage=i18n("<b>Bad passphrase</b>. You have %1 tries left.<br>").arg(step);

                                passdlgmessage+=i18n("Enter passphrase for <b>%1</b>").arg(userIDs);
                                int code=KPasswordDialog::getPassword(passphrase,passdlgmessage);
                                if (code!=TQDialog::Accepted) {
                                        p->deleteLater();
                                        emit processaborted(true);
                                        return;
                                }
                                p->writeStdin(passphrase,true);
                                userIDs=TQString();
                                if (step>1) step--;
				else step=3;
                        } else {
                                p->writeStdin(TQString("quit"));
                                p->closeWhenDone();
                        }
                }
                message+=required+"\n";
        }
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////    Text encryption


void KgpgInterface::KgpgEncryptText(TQString text,TQStringList userIDs, TQStringList Options)
{
//	kdDebug(2100) << k_funcinfo << endl;
        message=TQString();
	//TQTextCodec *codec = TDEGlobal::charsets()->codecForName(TDEGlobal::locale()->encoding());
	TQTextCodec *codec =TQTextCodec::codecForLocale ();
	if (codec->canEncode(text)) txtToEncrypt=text;
	else txtToEncrypt=text.utf8();

        TDEProcIO *proc=new TDEProcIO(TQTextCodec::codecForLocale());
        *proc<<"gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--command-fd=0"<<"--status-fd=1"<<"--utf8-strings";

	for ( TQStringList::Iterator it = Options.begin(); it != Options.end(); ++it )
       		if (!TQFile::encodeName(*it).isEmpty()) *proc<< TQString(TQFile::encodeName(*it));

	if (!userIDs.isEmpty())
	{
        *proc<<"-e";
	for ( TQStringList::Iterator it = userIDs.begin(); it != userIDs.end(); ++it )
       		*proc<<"--recipient"<< *it;
	}
	else
	  *proc<<"-c";

        /////////  when process ends, update dialog infos

        TQObject::connect(proc, TQ_SIGNAL(processExited(TDEProcess *)),this,TQ_SLOT(txtencryptfin(TDEProcess *)));
        TQObject::connect(proc,TQ_SIGNAL(readReady(TDEProcIO *)),this,TQ_SLOT(txtreadencprocess(TDEProcIO *)));
        proc->start(TDEProcess::NotifyOnExit,false);
	emit txtencryptionstarted();
}


void KgpgInterface::txtencryptfin(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
        if (!message.isEmpty())
                emit txtencryptionfinished(message);
        else
                emit txtencryptionfinished(TQString());
}

void KgpgInterface::txtreadencprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required;
        while (p->readln(required,true)!=-1) {
	  if (required.find("BEGIN_ENCRYPTION",0,false)!=-1)
	  {
	    p->writeStdin(txtToEncrypt,false);
	    txtToEncrypt=TQString();
	    p->closeWhenDone();
	  }
	  else
	if ((required.find("passphrase.enter")!=-1))
            {
              TQString passphrase;
              TQString passdlgmessage=i18n("Enter passphrase (symmetrical encryption)");
              int code=KPasswordDialog::getNewPassword(passphrase,passdlgmessage);
	      if (code!=TQDialog::Accepted)
                {
                  p->deleteLater();
                  return;
                }
              p->writeStdin(passphrase,true);
            }
	    else
		if (!required.startsWith("[GNUPG:]")) message+=required+"\n";
        }
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////     Text decryption

void KgpgInterface::KgpgDecryptText(TQString text,TQStringList Options)
{
//	kdDebug(2100) << k_funcinfo << endl;
  gpgOutput=TQString();
  log=TQString();

  message=TQString();
  userIDs=TQString();
  step=3;
  anonymous=false;
  decfinished=false;
  decok=false;
  badmdc=false;
  TDEProcess *proc=new TDEProcess();
  *proc<<"gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--command-fd=0"<<"--status-fd=2"<<"--no-batch"<<"--utf8-strings";
  for ( TQStringList::Iterator it = Options.begin(); it != Options.end(); ++it )
	  if (!TQFile::encodeName(*it).isEmpty()) *proc<< TQString(TQFile::encodeName(*it));
  *proc<<"-d";

  /////////  when process ends, update dialog infos

  TQObject::connect(proc, TQ_SIGNAL(processExited(TDEProcess *)),this,TQ_SLOT(txtdecryptfin(TDEProcess *)));
  connect(proc, TQ_SIGNAL(receivedStdout(TDEProcess *, char *, int)),this, TQ_SLOT(getOutput(TDEProcess *, char *, int)));
  connect(proc, TQ_SIGNAL(receivedStderr(TDEProcess *, char *, int)),this, TQ_SLOT(getCmdOutput(TDEProcess *, char *, int)));
  proc->start(TDEProcess::NotifyOnExit,TDEProcess::All);
  proc->writeStdin(text.utf8(), text.length());
}

void KgpgInterface::txtdecryptfin(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
if ((decok) && (!badmdc))
emit txtdecryptionfinished(message);

else if (badmdc)
{
KMessageBox::sorry(0,i18n("Bad MDC detected. The encrypted text has been manipulated."));
emit txtdecryptionfailed(log);
}
else
emit txtdecryptionfailed(log);
}


void KgpgInterface::getOutput(TDEProcess *, char *data, int )
{
//	kdDebug(2100) << k_funcinfo << endl;
	message.append(TQString::fromUtf8(data));
}


void KgpgInterface::getCmdOutput(TDEProcess *p, char *data, int )
{
//	kdDebug(2100) << k_funcinfo << endl;
  gpgOutput.append(TQString::fromUtf8(data));
  log.append(data);

  int pos;
  while ((pos=gpgOutput.find("\n"))!=-1)
  {
	TQString required=gpgOutput.left(pos);
	gpgOutput.remove(0,pos+2);

	if (required.find("USERID_HINT",0,false)!=-1)
		updateIDs(required);

	if (required.find("ENC_TO")!=-1)
	{
		if (required.find("0000000000000000")!=-1)
			anonymous=true;
	}

	if (required.find("GET_")!=-1)
	{
		if ((required.find("passphrase.enter")!=-1))
		{
			if (userIDs.isEmpty())
			userIDs=i18n("[No user id found]");
			TQString passphrase;
			TQString passdlgmessage;
			if (anonymous)
				passdlgmessage=i18n("<b>No user id found</b>. Trying all secret keys.<br>");
			if ((step<3) && (!anonymous))
				passdlgmessage=i18n("<b>Bad passphrase</b>. You have %1 tries left.<br>").arg(step);
			passdlgmessage+=i18n("Enter passphrase for <b>%1</b>").arg(userIDs);
			int code=KPasswordDialog::getPassword(passphrase,passdlgmessage);
			if (code!=TQDialog::Accepted)
			{
				p->deleteLater();
				emit processaborted(true);
				return;
			}
			passphrase.append("\n");
			TQCString passphrase_local = passphrase.local8Bit();
			p->writeStdin(passphrase_local, passphrase_local.length());
			userIDs=TQString();
			if (step>1) step--;
			else step=3;
		}
		else
		{
			p->writeStdin("quit",4);
			p->closeStdin();
		}
	}

	if (required.find("BEGIN_DECRYPTION")!=-1)
	{
		p->closeStdin();
		required=TQString();
	}

	if (required.find("END_DECRYPTION")!=-1) decfinished=true;
	if (required.find("DECRYPTION_OKAY")!=-1) decok=true;
	if (required.find("DECRYPTION_FAILED")!=-1) decok=false;
	if (required.find("BADMDC")!=-1) badmdc=true;
	}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////    Text signing


void KgpgInterface::KgpgSignText(TQString text,TQString userIDs, TQStringList Options)
{
//	kdDebug(2100) << k_funcinfo << endl;
        message=TQString();
	step=4;
	TQString txtprocess;
	TQTextCodec *codec =TQTextCodec::codecForLocale ();
	if (codec->canEncode(text)) txtprocess=text;
	else txtprocess=text.utf8();

        TDEProcIO *proc=new TDEProcIO(TQTextCodec::codecForLocale());
        *proc<<"gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--command-fd=0"<<"--status-fd=1"<<"--utf8-strings";

	for ( TQStringList::Iterator it = Options.begin(); it != Options.end(); ++it )
		if (!TQFile::encodeName(*it).isEmpty()) *proc<< TQString(TQFile::encodeName(*it));
        *proc<<"--clearsign"<<"-u"<<userIDs;

        /////////  when process ends, update dialog infos

        TQObject::connect(proc, TQ_SIGNAL(processExited(TDEProcess *)),this,TQ_SLOT(txtsignfin(TDEProcess *)));
        TQObject::connect(proc,TQ_SIGNAL(readReady(TDEProcIO *)),this,TQ_SLOT(txtsignprocess(TDEProcIO *)));

	//emit txtsigningstarted();

	proc->start(TDEProcess::NotifyOnExit,false);
	/*if (useAgent)
	{
//	kdDebug(2100)<<"Using Agent+++++++++++++"<<endl;
	//KMessageBox::sorry(0,"using agent");
	proc->writeStdin(txtprocess,true);
	proc->closeWhenDone();
	}
	else*/
	message=txtprocess;
}


void KgpgInterface::txtsignfin(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << "MSG: " << message<<endl;
        if (!message.isEmpty())
                emit txtSignOver(message);
        else
                emit txtSignOver(TQString());
}

void KgpgInterface::txtsignprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required;

        while (p->readln(required,true)!=-1) {
//	kdDebug(2100)<<"SIGNING: "<<required<<endl;

	if (required.find("USERID_HINT",0,false)!=-1)
        updateIDs(required);

	if (required.find("GOOD_PASSPHRASE")!=-1)
	{
	p->writeStdin(message,true);
	message=TQString();
	p->closeWhenDone();
	}

		if (required.find("BEGIN_SIGNING")!=-1) {
			p->writeStdin(message,true);
			message=TQString();
			p->closeWhenDone();
		}
	
	if ((required.find("passphrase.enter")!=-1))
            {
	      if (step>1) step--;
	      else step=3;
              if (userIDs.isEmpty())
                userIDs=i18n("[No user id found]");
              TQString passphrase;
              TQString passdlgmessage;
              if (step<3)
              passdlgmessage=i18n("<b>Bad passphrase</b>. You have %1 tries left.<br>").arg(step);
              passdlgmessage+=i18n("Enter passphrase for <b>%1</b>").arg(userIDs);
              int code=KPasswordDialog::getPassword(passphrase,passdlgmessage);
	      if (code!=TQDialog::Accepted)
                {
                  p->deleteLater();
                  return;
                }
              p->writeStdin(passphrase,true);
            }
	    else
		if (!required.startsWith("[GNUPG:]")) message+=required+"\n";
//		kdDebug(2100)<<"SIGNING: "<<message<<endl;
        }
}


////////////////////////////////////////////////   decrypt file to text

void KgpgInterface::KgpgDecryptFileToText(KURL srcUrl,TQStringList Options)
{
//	kdDebug(2100) << k_funcinfo << endl;

  message=TQString();
  userIDs=TQString();
  step=3;
  anonymous=false;
  decfinished=false;
  decok=false;
  badmdc=false;

  TDEProcess *proc=new TDEProcess();
  *proc<<"gpg"<<"--no-tty"<<"--utf8-strings"<<"--no-secmem-warning"<<"--command-fd=0"<<"--status-fd=2"<<"--no-batch"<<"-o"<<"-";
      	for ( TQStringList::Iterator it = Options.begin(); it != Options.end(); ++it ) {
       		if (!TQFile::encodeName(*it).isEmpty()) *proc<< TQString(TQFile::encodeName(*it));
    		}
      *proc<<"-d"<<TQString(TQFile::encodeName(srcUrl.path()));

  /////////  when process ends, update dialog infos

  connect(proc, TQ_SIGNAL(processExited(TDEProcess *)),this,TQ_SLOT(txtdecryptfin(TDEProcess *)));
  connect(proc, TQ_SIGNAL(receivedStdout(TDEProcess *, char *, int)),this, TQ_SLOT(getOutput(TDEProcess *, char *, int)));
  connect(proc, TQ_SIGNAL(receivedStderr(TDEProcess *, char *, int)),this, TQ_SLOT(getCmdOutput(TDEProcess *, char *, int)));
  proc->start(TDEProcess::NotifyOnExit,TDEProcess::All);
}


///////////////////////////////////////////////////////          verify text


void KgpgInterface::KgpgVerifyText(TQString text)
{
//	kdDebug(2100) << k_funcinfo << endl;

		TQTextCodec *codec =TQTextCodec::codecForLocale ();
		if (!codec->canEncode(text)) text=text.utf8();
		signmiss=false;
		signID=TQString();
		message=TQString();
		 TDEProcIO *verifyproc=new TDEProcIO(TQTextCodec::codecForLocale());
         *verifyproc<<"gpg"<<"--no-secmem-warning"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings"<<"--verify";
        	connect(verifyproc, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(slotverifyresult(TDEProcess *)));
        	connect(verifyproc, TQ_SIGNAL(readReady(TDEProcIO *)),this, TQ_SLOT(slotverifyread(TDEProcIO *)));
        	verifyproc->start(TDEProcess::NotifyOnExit,true);
		verifyproc->writeStdin (text);
		verifyproc->closeWhenDone();
}


void KgpgInterface::slotverifyresult(TDEProcess*)
{
//	kdDebug(2100) << k_funcinfo << endl;
if (signmiss) emit missingSignature(signID);
    else {
	if (signID.isEmpty()) signID=i18n("No signature found.");
	emit verifyOver(signID,message);
	}
//kdDebug(2100) << "GPG VERIFY OVER________"<<endl;
}

void KgpgInterface::slotverifyread(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
TQString required;
  while (p->readln(required,true)!=-1)
    {
    message+=required+"\n";
    required=required.section("]",1,-1).stripWhiteSpace();
     if (required.startsWith("GOODSIG"))
     {
	     TQString userName=required.section(" ",2,-1).replace(TQRegExp("<"),"&lt;");
	     userName=checkForUtf8(userName);
     signID=i18n("<qt>Good signature from:<br><b>%1</b><br>Key ID: %2</qt>").arg(userName).arg("0x"+required.section(" ",1,1).right(8));
     }
     if (required.startsWith("BADSIG"))
     {
     signID=i18n("<qt><b>Bad signature</b> from:<br>%1<br>Key ID: %2<br><br><b>Text is corrupted.</b></qt>").arg(required.section(" ",2,-1).replace(TQRegExp("<"),"&lt;")).arg("0x"+required.section(" ",1,1).right(8));
     }
     if (required.startsWith("NO_PUBKEY"))
     {
     signID="0x"+required.section(" ",1,1).right(8);
     signmiss=true;
     }
     if (required.startsWith("UNEXPECTED") || required.startsWith("NODATA"))
	signID=i18n("No signature found.");
     if (required.startsWith("TRUST_UNDEFINED"))
     signID+=i18n("The signature is valid, but the key is untrusted");
     if (required.startsWith("TRUST_ULTIMATE"))
     signID+=i18n("The signature is valid, and the key is ultimately trusted");
     }
}


///////////////////////////////////////////////////////////////////////////////////////////////////   MD5

Md5Widget::Md5Widget(TQWidget *parent, const char *name,KURL url):KDialogBase( parent, name, true,i18n("MD5 Checksum"),Apply | Close)
{
//	kdDebug(2100) << k_funcinfo << endl;
        setButtonApply(i18n("Compare MD5 with Clipboard"));
        mdSum=TQString();
        TQFile f(url.path());
        f.open( IO_ReadOnly);
        KMD5 checkfile;
        checkfile.reset();
        checkfile.update(f);
        mdSum=checkfile.hexDigest().data();
        f.close();
        TQWidget *page = new TQWidget(this);

        resize( 360, 150 );
        TQGridLayout *MyDialogLayout = new TQGridLayout( page, 1, 1, 5, 6, "MyDialogLayout");

        TQLabel *TextLabel1 = new TQLabel( page, "TextLabel1" );
        TextLabel1->setText(i18n("MD5 sum for <b>%1</b> is:").arg(url.fileName()));
        MyDialogLayout->addWidget( TextLabel1, 0, 0 );

        KLineEdit *KRestrictedLine1 = new KLineEdit(mdSum,page);
        KRestrictedLine1->setReadOnly(true);
        KRestrictedLine1->setPaletteBackgroundColor(TQColor(255,255,255));
        MyDialogLayout->addWidget( KRestrictedLine1, 1, 0 );


        TQHBoxLayout *Layout4 = new TQHBoxLayout( 0, 0, 6, "Layout4");

        KLed1=new KLed(TQColor(80,80,80),KLed::Off,KLed::Sunken,KLed::Circular,page,"KLed1");
        KLed1->off();
        KLed1->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)0, (TQSizePolicy::SizeType)0, 0, 0, KLed1->sizePolicy().hasHeightForWidth() ) );
        Layout4->addWidget( KLed1 );

        TextLabel1_2 = new TQLabel( page, "TextLabel1_2" );
        TextLabel1_2->setText(i18n( "<b>Unknown status</b>" ) );
        Layout4->addWidget( TextLabel1_2 );

        MyDialogLayout->addLayout( Layout4, 2, 0 );
        TQSpacerItem* spacer = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding );
        MyDialogLayout->addItem( spacer, 3, 0 );

        page->show();
        page->resize(page->minimumSize());
        setMainWidget(page);


}

Md5Widget::~Md5Widget()
{}

void Md5Widget::slotApply()
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQClipboard *cb = TQApplication::clipboard();
        TQString text;
        // Copy text from the clipboard (paste)
        text = cb->text(TQClipboard::Clipboard);
        if ( !text.isEmpty() ) {
                text=text.stripWhiteSpace();
                while (text.find(' ')!=-1)
                        text.remove(text.find(' '),1);
                if (text==mdSum) {
                        TextLabel1_2->setText(i18n("<b>Correct checksum</b>, file is ok."));
                        KLed1->setColor(TQColor(0,255,0));
                        KLed1->on();
                }//KMessageBox::sorry(0,"OK");
                else if (text.length()!=mdSum.length())
                        KMessageBox::sorry(0,i18n("Clipboard content is not a MD5 sum."));
                else {
                        TextLabel1_2->setText(i18n("<b>Wrong checksum, FILE CORRUPTED</b>"));
                        KLed1->setColor(TQColor(255,0,0));
                        KLed1->on();
                }
        }
}

/////////////////////////////////////////////////////////////////////////////////////////////   signatures


void KgpgInterface::KgpgSignFile(TQString keyID,KURL srcUrl,TQStringList Options)
{
//	kdDebug(2100) << k_funcinfo << endl;
        //////////////////////////////////////   create a detached signature for a chosen file
        message=TQString();
        step=3;
        /////////////       create gpg command
        TDEProcIO *proc=new TDEProcIO(TQTextCodec::codecForLocale());
        keyID=keyID.stripWhiteSpace();
        *proc<<"gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--utf8-strings"<<"--status-fd=2"<<"--command-fd=0"<<"-u"<<keyID.local8Bit();
		for ( TQStringList::Iterator it = Options.begin(); it != Options.end(); ++it )
       		if (!TQFile::encodeName(*it).isEmpty()) *proc<< TQString(TQFile::encodeName(*it));

	*proc<<"--output"<<TQString(TQFile::encodeName(srcUrl.path()+".sig"));
        *proc<<"--detach-sig"<<TQString(TQFile::encodeName(srcUrl.path()));

        TQObject::connect(proc, TQ_SIGNAL(processExited(TDEProcess *)),this,TQ_SLOT(signfin(TDEProcess *)));
        TQObject::connect(proc,TQ_SIGNAL(readReady(TDEProcIO *)),this,TQ_SLOT(readsignprocess(TDEProcIO *)));
        proc->start(TDEProcess::NotifyOnExit,true);
}



void KgpgInterface::signfin(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
        if (message.find("SIG_CREATED")!=-1)
                KMessageBox::information(0,i18n("The signature file %1 was successfully created.").arg(file.fileName()));
        else if (message.find("BAD_PASSPHRASE")!=-1)
                KMessageBox::sorry(0,i18n("Bad passphrase, signature was not created."));
        else
                KMessageBox::sorry(0,message);
        emit signfinished();
}


void KgpgInterface::readsignprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required;
        while (p->readln(required,true)!=-1) {
                if (required.find("USERID_HINT",0,false)!=-1)
		updateIDs(required);

                if (required.find("GET_")!=-1) {
                        if (required.find("openfile.overwrite.okay")!=-1)
                                p->writeStdin(TQString("Yes"));
                        else if ((required.find("passphrase.enter")!=-1)) {
                                if (userIDs.isEmpty())
                                        userIDs=i18n("[No user id found]");
                                TQString passphrase;
                                TQString passdlgmessage;
                                if (step<3)
                                        passdlgmessage=i18n("<b>Bad passphrase</b>. you have %1 tries left.<br>").arg(step);
                                passdlgmessage+=i18n("Enter passphrase for <b>%1</b>").arg(userIDs);
                                int code=KPasswordDialog::getPassword(passphrase,passdlgmessage);
                                if (code!=TQDialog::Accepted) {
                                        p->deleteLater();
                                        emit signfinished();
                                        return;
                                }
                                p->writeStdin(passphrase,true);
                                userIDs=TQString();
				if (step>1) step--;
				else step=3;
                        } else {
                                p->writeStdin(TQString("quit"));
                                p->closeWhenDone();
                        }
                }
                message+=required+"\n";
        }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


void KgpgInterface::KgpgVerifyFile(KURL sigUrl,KURL srcUrl)
{
//	kdDebug(2100) << k_funcinfo << endl;
        //////////////////////////////////////   verify signature for a chosen file
        message=TQString();
	signID=TQString();
	signmiss=false;
        /////////////       create gpg command
        TDEProcIO *proc=new TDEProcIO(TQTextCodec::codecForLocale());
        file=sigUrl;
        *proc<<"gpg"<<"--no-tty"<<"--utf8-strings"<<"--no-secmem-warning"<<"--status-fd=2"<<"--verify";
        if (!srcUrl.isEmpty())
                *proc<<TQString(TQFile::encodeName(srcUrl.path()));
        *proc<<TQString(TQFile::encodeName(sigUrl.path()));

        TQObject::connect(proc, TQ_SIGNAL(processExited(TDEProcess *)),this,TQ_SLOT(verifyfin(TDEProcess *)));
        TQObject::connect(proc,TQ_SIGNAL(readReady(TDEProcIO *)),this,TQ_SLOT(readprocess(TDEProcIO *)));
        proc->start(TDEProcess::NotifyOnExit,true);
}


void KgpgInterface::readprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
	TQString required;
  while (p->readln(required,true)!=-1)
    {
    message+=required+"\n";
	if (required.find("GET_")!=-1) {
        p->writeStdin(TQString("quit"));
        p->closeWhenDone();
        }
    required=required.section("]",1,-1).stripWhiteSpace();
    if (required.startsWith("UNEXPECTED") || required.startsWith("NODATA"))
	signID=i18n("No signature found.");
    if (required.startsWith("GOODSIG"))
    {
    signID=i18n("<qt>Good signature from:<br><b>%1</b><br>Key ID: %2</qt>").arg(required.section(" ",2,-1).replace(TQRegExp("<"),"&lt;")).arg("0x"+required.section(" ",1,1).right(8));
    }
    if (required.startsWith("BADSIG"))
    {
    signID=i18n("<qt><b>BAD signature</b> from:<br> %1<br>Key id: %2<br><br>"
                             "<b>The file is corrupted!</b></qt>").arg(required.section(" ",2,-1).replace(TQRegExp("<"),"&lt;")).arg("0x"+required.section(" ",1,1).right(8));
    }
    if (required.startsWith("NO_PUBKEY"))
    {
    signmiss=true;
    signID="0x"+required.section(" ",1,1).right(8);
    }
    if (required.startsWith("TRUST_UNDEFINED"))
    	signID+=i18n("The signature is valid, but the key is untrusted");
    if (required.startsWith("TRUST_ULTIMATE"))
	signID+=i18n("The signature is valid, and the key is ultimately trusted");
    }
}


void KgpgInterface::verifyfin(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
    if (!signmiss) {
        if (signID.isEmpty()) signID=i18n("No signature found.");
        (void) new KDetailedInfo(0,"verify_result",signID,message);
    }
    else {
    	if (KMessageBox::questionYesNo(0,i18n("<qt><b>Missing signature:</b><br>Key id: %1<br><br>"
                                                      "Do you want to import this key from a keyserver?</qt>").arg(signID),file.fileName(),TQString(), i18n("Import"), i18n("Do Not Import"))==KMessageBox::Yes)
    	emit verifyquerykey(signID);
    }
    emit verifyfinished();
}



////////////////////////////////////////////////////////////   sign a key

void KgpgInterface::KgpgSignKey(TQString keyID,TQString signKeyID,TQString signKeyMail,bool local,int checking)
{
//	kdDebug(2100) << k_funcinfo << endl;
        signKeyMail.replace(TQRegExp("<"),"&lt;");
        konsChecked=checking;
        konsLocal=local;
        konsSignKey=signKeyID;
        konsKeyID=keyID;
        errMessage=TQString();
        if (checkuid(keyID)>0)
	{
                openSignConsole();
		return;
	}

        signSuccess=0;
        step=1;
        output=TQString();
        TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
        *conprocess<<"gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--utf8-strings"<<"--command-fd=0"<<"--status-fd=2"<<"-u"<<signKeyID;
        *conprocess<<"--edit-key"<<keyID;
	if (local) *conprocess<<"lsign";
	else *conprocess<<"sign";
        TQObject::connect(conprocess,TQ_SIGNAL(readReady(TDEProcIO *)),this,TQ_SLOT(sigprocess(TDEProcIO *)));
        TQObject::connect(conprocess, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(signover(TDEProcess *)));
	TQApplication::setOverrideCursor(TQCursor(TQt::BusyCursor));
        conprocess->start(TDEProcess::NotifyOnExit,true);
}

void KgpgInterface::sigprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required=TQString();

	while (p->readln(required,true)!=-1) {
		output+=required+"\n";

		if ( KgpgInterface::getGpgVersion() >= 210 ) {
		//	kdDebug(2100) << k_funcinfo << " line " << required << endl;
			if (required.find("USERID_HINT",0,false)!=-1) {
				updateIDs(required);
			}

			if (signSuccess==4 && required.find("GET_")!=-1) {
			//	kdDebug(2100) << k_funcinfo << " success quit" << endl;
				p->writeStdin(TQString("quit"));
				p->closeWhenDone();
				return;
			}

			if ((required.find("GOOD_PASSPHRASE")!=-1)) {
			//	kdDebug(2100) << k_funcinfo << " GOOD_PASSPHRASE" << endl;
				signSuccess=3;
				step=2;
			}

			if (required.find("sign_uid.expire")!=-1) {
			//	kdDebug(2100) << k_funcinfo << " sign_uid.expire" << endl;
				p->writeStdin(TQString("Never"));
				required=TQString();
			}
			if (required.find("sign_uid.class")!=-1) {
			//	kdDebug(2100) << k_funcinfo << " sign_uid.class" << endl;
				p->writeStdin(TQString::number(konsChecked));
				required=TQString();
			}
			if (required.find("sign_all.okay")!=-1 || required.find("sign_uid.okay")!=-1 ) {
			//	kdDebug(2100) << k_funcinfo << " sign_uid.okay" << endl;
				step=2;
				p->writeStdin(TQString("Y"));
				required=TQString();
			}
			if (required.find("PINENTRY_LAUNCHED")!=-1) {
			//	kdDebug(2100) << k_funcinfo << "PINENTRY_LAUNCHED" << endl;
			//	p->writeStdin(TQString::number(konsChecked));
				required=TQString();
			}

			if (required.find("passphrase.enter")!=-1) {
				TQString signpass;
			//	kdDebug(2100) << k_funcinfo << "passphrase.enter" << endl;
				TQApplication::restoreOverrideCursor();
				int code=KPasswordDialog::getPassword(signpass,i18n("<qt>%1 Enter passphrase for <b>%2</b>:</qt>")
								.arg(errMessage).arg(userIDs));
				TQApplication::setOverrideCursor(TQCursor(TQt::BusyCursor));
				if (code!=TQDialog::Accepted) {
					signSuccess=4;  /////  aborted by user mode
					required=TQString();
					p->writeStdin(TQString("quit"));
					p->closeWhenDone();
					return;
				}
				p->writeStdin(signpass,true);
				required=TQString();
				// step=2;
			}
			if ((step==2) && (required.find("keyedit.prompt")!=-1) ) {
			//	kdDebug(2100) << k_funcinfo << "key sign" << endl;
				p->writeStdin(TQString("save"));
				p->closeWhenDone();
				signSuccess=4;  
				required=TQString();
			}
			if (required.find("BAD_PASSPHRASE")!=-1) {
			//	kdDebug(2100) << k_funcinfo << "BAD_PASSPHRASE" << endl;
				errMessage=i18n("<b>Bad passphrase</b>. Try again.</br>");
				required=TQString();
				signSuccess=2;  /////  bad passphrase
			}
//			if (required.find("GET_")!=-1) { /////// gpg asks for something unusal, turn to konsole mode
//			//	kdDebug(2100) << k_funcinfo << "GET_ " << required << endl;
//				if (signSuccess!=2) {
//					signSuccess=1;  /////  switching to console mode
//				}
//			}
		}

		else { // (KgpgInterface::getGpgVersion() < 210)
		//	kdDebug(2100) << k_funcinfo << " line " << required << endl;
			if (required.find("USERID_HINT",0,false)!=-1) {
				updateIDs(required);
			}

			if (signSuccess==4) {
			//	kdDebug(2100) << k_funcinfo << " success quit" << endl;
				if (required.find("GET_")!=-1) {
					p->writeStdin(TQString("quit"));
				}
				p->closeWhenDone();
				return;
			}

			if ((required.find("GOOD_PASSPHRASE")!=-1)) {
			//	kdDebug(2100) << k_funcinfo << " GOOD_PASSPHRASE" << endl;
				signSuccess=3;
				step=2;
			}

			if (required.find("sign_uid.expire")!=-1) {
			//	kdDebug(2100) << k_funcinfo << " sign_uid.expire" << endl;
				p->writeStdin(TQString("Never"));
				required=TQString();
			}
			if (required.find("sign_uid.class")!=-1) {
			//	kdDebug(2100) << k_funcinfo << " sign_uid.class" << endl;
				p->writeStdin(TQString::number(konsChecked));
				required=TQString();
			}
			if (required.find("sign_all.okay")!=-1 || required.find("sign_uid.okay")!=-1 ) {
			//	kdDebug(2100) << k_funcinfo << " sign_uid.okay" << endl;
				p->writeStdin(TQString("Y"));
				required=TQString();
			}
			if (required.find("PINENTRY_LAUNCHED")!=-1) {
			//	kdDebug(2100) << k_funcinfo << "PINENTRY_LAUNCHED" << endl;
			//	p->writeStdin(TQString::number(konsChecked));
				required=TQString();
			}

			if (required.find("passphrase.enter")!=-1) {
				TQApplication::restoreOverrideCursor();
				TQString signpass;
			//	kdDebug(2100) << k_funcinfo << "passphrase.enter" << endl;
				int code=KPasswordDialog::getPassword(signpass,i18n("<qt>%1 Enter passphrase for <b>%2</b>:</qt>")
								.arg(errMessage).arg(userIDs));
				TQApplication::setOverrideCursor(TQCursor(TQt::BusyCursor));
				if (code!=TQDialog::Accepted) {
					signSuccess=4;  /////  aborted by user mode
					required=TQString();
					p->writeStdin(TQString("quit"));
					p->closeWhenDone();
					return;
				}
				p->writeStdin(signpass,true);
				required=TQString();
				// step=2;
			}
			if ((step==2) && (required.find("keyedit.prompt")!=-1) ) {
			//	kdDebug(2100) << k_funcinfo << "key save" << endl;
				p->writeStdin(TQString("save"));
				required=TQString();
			}
			if (required.find("BAD_PASSPHRASE")!=-1) {
			//	kdDebug(2100) << k_funcinfo << "BAD_PASSPHRASE" << endl;
				errMessage=i18n("<b>Bad passphrase</b>. Try again.</br>");
				required=TQString();
				signSuccess=2;  /////  bad passphrase
			}
			if (required.find("GET_")!=-1) { /////// gpg asks for something unusal, turn to konsole mode
			//	kdDebug(2100) << k_funcinfo << "GET_ " << required << endl;
				if (signSuccess!=2) {
					signSuccess=1;  /////  switching to console mode
				}
				p->writeStdin(TQString("quit"));
				p->closeWhenDone();
			}
		}
	}
}


void KgpgInterface::signover(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
	TQApplication::restoreOverrideCursor();
        if (signSuccess>1)
                emit signatureFinished(signSuccess);  ////   signature successful or bad passphrase
        else {
                KDetailedConsole *q=new KDetailedConsole(0,"sign_error",i18n("<qt>Signing key <b>%1</b> with key <b>%2</b> failed.<br>"
                                    "Do you want to try signing the key in console mode?</qt>").arg(konsKeyID).arg(konsSignKey),output);
                if (q->exec()==TQDialog::Accepted)
                        openSignConsole();
                else
                        emit signatureFinished(0);
        }
}

void KgpgInterface::openSignConsole()
{
//	kdDebug(2100) << k_funcinfo << endl;
        TDEProcess conprocess;
	TDEConfig *config = TDEGlobal::config();
	config->setGroup("General");
	conprocess<< config->readPathEntry("TerminalApplication","konsole");
        conprocess<<"-e"<<"gpg";
        conprocess<<"--no-secmem-warning"<<"--expert"<<"-u"<<konsSignKey;
        if (!konsLocal)
                conprocess<<"--sign-key"<<konsKeyID;
        else
                conprocess<<"--lsign-key"<<konsKeyID;
        conprocess.start(TDEProcess::Block);
	emit signatureFinished(3);

}

////////////////////////////////////////////////////////////////////////////     delete signature


void KgpgInterface::KgpgDelSignature(TQString keyID,TQString signKeyID)
{
//	kdDebug(2100) << k_funcinfo << endl;
        if (checkuid(keyID)>0) {
                KMessageBox::sorry(0,i18n("This key has more than one user ID.\nEdit the key manually to delete signature."));
                return;
        }

        message=signKeyID.remove(0,2);
        deleteSuccess=false;
        step=0;

        FILE *fp;
        TQString encResult;
        char buffer[200];
        signb=0;
        sigsearch=0;

        TQString gpgcmd="gpg --no-tty --no-secmem-warning --with-colon --list-sigs "+keyID;
        fp = popen(TQFile::encodeName(gpgcmd), "r");
        while ( fgets( buffer, sizeof(buffer), fp)) {
                encResult=buffer;
                if (encResult.startsWith("sig")) {
                        if (encResult.find(message)!=-1)
                                break;
                        signb++;
                } else if (encResult.startsWith("rev"))
                        signb++;
        }
        pclose(fp);
        TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
        *conprocess<<"gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--utf8-strings"<<"--command-fd=0"<<"--status-fd=2";
        *conprocess<<"--edit-key"<<keyID<<"uid 1"<<"delsig";
        TQObject::connect(conprocess,TQ_SIGNAL(readReady(TDEProcIO *)),this,TQ_SLOT(delsigprocess(TDEProcIO *)));
        TQObject::connect(conprocess, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(delsignover(TDEProcess *)));
	TQApplication::setOverrideCursor(TQCursor(TQt::BusyCursor));
        conprocess->start(TDEProcess::NotifyOnExit,true);
}


void KgpgInterface::delsigprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;

        TQString required=TQString();
        while (p->readln(required,true)!=-1)
        {
                if (required.find("keyedit.delsig")!=-1){

                        if ((sigsearch==signb) && (step==0)) {
                                p->writeStdin(TQString("Y"));
                                step=1;
                        } else
                                p->writeStdin(TQString("n"));
                        sigsearch++;
                        required=TQString();
                }
                if ((step==1) && (required.find("keyedit.prompt")!=-1)) {
                        p->writeStdin(TQString("save"));
                        required=TQString();
                        deleteSuccess=true;
                }
                if (required.find("GET_LINE")!=-1) {
                        p->writeStdin(TQString("quit"));
                        p->closeWhenDone();
                        deleteSuccess=false;
                }
        }
}

void KgpgInterface::delsignover(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
	TQApplication::restoreOverrideCursor();
        emit delsigfinished(deleteSuccess);
}

/////////////////////////////////////////////////// check if a key has more than one id

int KgpgInterface::checkuid(TQString KeyID)
{
//	kdDebug(2100) << k_funcinfo << "KeyID: " << KeyID<< endl;
        FILE *fp;
        TQString encResult;
        char buffer[200];
        int  uidcnt=0;
	if (KgpgInterface::getGpgVersion() > 210 ) {
		uidcnt=-1; // there is always one uid in the new version
	}

        TQString gpgcmd="gpg --no-tty --no-secmem-warning --with-colon --list-sigs "+KeyID;
        //////////   encode with untrusted keys or armor if checked by user
        fp = popen(TQFile::encodeName(gpgcmd), "r");
        while (fgets(buffer, sizeof(buffer), fp)) {
                encResult=buffer;
                if (encResult.startsWith("uid"))
                        uidcnt++;
        }
//	kdDebug(2100) << k_funcinfo << "uid count: " << uidcnt<< endl;
        pclose(fp);
        return uidcnt;
}


///////////////////////////////////////////////////////////////    change key expiration


void KgpgInterface::KgpgKeyExpire(TQString keyID,TQDate date,bool unlimited)
{
//	kdDebug(2100) << k_funcinfo << endl;

//	kdDebug(2100) << "KgpgKeyExpire date: " << date;

        expSuccess=0;
        step=0;
        if (unlimited)
                expirationDelay=0;
        else
                expirationDelay=TQDate::currentDate().daysTo(date);
//	kdDebug(2100) << "KgpgKeyExpire date: " << TQDate::currentDate().daysTo(date) <<endl;
        output=TQString();
        TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
        *conprocess<<"gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--command-fd=0"<<"--status-fd=2"<<"--utf8-strings";
        *conprocess<<"--edit-key"<<keyID<<"expire";
        TQObject::connect(conprocess,TQ_SIGNAL(readReady(TDEProcIO *)),this,TQ_SLOT(expprocess(TDEProcIO *)));
        TQObject::connect(conprocess, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(expover(TDEProcess *)));
        conprocess->start(TDEProcess::NotifyOnExit,TDEProcess::AllOutput);

}

void KgpgInterface::expprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required=TQString();

        while (p->readln(required,true)!=-1) {
                output+=required+"\n";

                if (required.find("USERID_HINT",0,false)!=-1)
		updateIDs(required);

                if ((required.find("GOOD_PASSPHRASE")!=-1)) {
                        expSuccess=3;
                        step=2;
                }

                if (required.find("keygen.valid")!=-1) {
                        p->writeStdin(TQString::number(expirationDelay));
                        required=TQString();
                }

                if (required.find("passphrase.enter")!=-1) {
                        TQString signpass;
                        int code=KPasswordDialog::getPassword(signpass,i18n("<qt>Enter passphrase for <b>%1</b>:</qt>").arg(userIDs));
                        if (code!=TQDialog::Accepted) {
                                expSuccess=3;  /////  aborted by user mode
                                p->writeStdin(TQString("quit"));
                                p->closeWhenDone();
                                return;
                        }
                        p->writeStdin(signpass,true);
                        required=TQString();
                        //              step=2;
                }
                if ((step==2) && (required.find("keyedit.prompt")!=-1)) {
                        p->writeStdin(TQString("save"));
			p->closeWhenDone();
                        required=TQString();
                }
		if ((step==2) && (required.find("keyedit.save.okay")!=-1)) {
                        p->writeStdin(TQString("YES"));
			p->closeWhenDone();
                        required=TQString();
                }
                if (required.find("BAD_PASSPHRASE")!=-1) {
                        p->writeStdin(TQString("quit"));
                        p->closeWhenDone();
                        expSuccess=2;  /////  bad passphrase
                }
                if ((required.find("GET_")!=-1) && (expSuccess!=2)) /////// gpg asks for something unusal, turn to konsole mode
                {
                        expSuccess=1;  /////  switching to console mode
                        p->writeStdin(TQString("quit"));
                        p->closeWhenDone();

                }
        }
}



void KgpgInterface::expover(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
        if ((expSuccess==3) || (expSuccess==2))
                emit expirationFinished(expSuccess);  ////   signature successful or bad passphrase
        else {
                KDetailedConsole *q=new KDetailedConsole(0,"sign_error",i18n("<qt><b>Changing expiration failed.</b><br>"
                                    "Do you want to try changing the key expiration in console mode?</qt>"),output);
                if (q->exec()==TQDialog::Accepted)
                        KMessageBox::sorry(0,"work in progress...");
                //openSignConsole();
                else
                        emit expirationFinished(0);
        }
}


///////////////////////////////////////////////////////////////    change key trust


void KgpgInterface::KgpgTrustExpire(TQString keyID,int keyTrust)
{
//	kdDebug(2100) << k_funcinfo << endl;
	trustValue=keyTrust+1;
/*	Don't know=1; Do NOT trust=2; Marginally=3; Fully=4; Ultimately=5;   */

        output=TQString();
        TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
        *conprocess<<"gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--command-fd=0"<<"--status-fd=2"<<"--utf8-strings";
        *conprocess<<"--edit-key"<<keyID<<"trust";
        TQObject::connect(conprocess,TQ_SIGNAL(readReady(TDEProcIO *)),this,TQ_SLOT(trustprocess(TDEProcIO *)));
        TQObject::connect(conprocess, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(trustover(TDEProcess *)));
        conprocess->start(TDEProcess::NotifyOnExit,true);

}

void KgpgInterface::trustprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required=TQString();
        while (p->readln(required,true)!=-1) {
                output+=required+"\n";
                if (required.find("edit_ownertrust.set_ultimate.okay")!=-1) {
                        p->writeStdin(TQString("YES"));
                        required=TQString();
                }

                if (required.find("edit_ownertrust.value")!=-1) {
                        p->writeStdin(TQString::number(trustValue));
                        required=TQString();
                }

                if (required.find("keyedit.prompt")!=-1) {
                        p->writeStdin(TQString("save"));
			p->closeWhenDone();
                        required=TQString();
                }

                if (required.find("GET_")!=-1) /////// gpg asks for something unusal, turn to konsole mode
                {
                        expSuccess=1;  /////  switching to console mode
                        p->writeStdin(TQString("quit"));
                        p->closeWhenDone();

                }
        }
}



void KgpgInterface::trustover(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
        emit trustfinished();
}


///////////////////////////////////////////////////////////////    change passphrase


void KgpgInterface::KgpgChangePass(TQString keyID)
{
//	kdDebug(2100) << k_funcinfo << endl;
        step=1;
        output=TQString();
        message=TQString();
        TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
        *conprocess<<"gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--no-use-agent"<<"--command-fd=0"<<"--status-fd=2"<<"--utf8-strings";
        *conprocess<<"--edit-key"<<keyID<<"passwd";
        TQObject::connect(conprocess,TQ_SIGNAL(readReady(TDEProcIO *)),this,TQ_SLOT(passprocess(TDEProcIO *)));
        TQObject::connect(conprocess, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(passover(TDEProcess *)));
        conprocess->start(TDEProcess::NotifyOnExit,TDEProcess::AllOutput);

}

void KgpgInterface::passprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required=TQString();

        while (p->readln(required,true)!=-1) {
                output+=required+"\n";

                if (required.find("USERID_HINT",0,false)!=-1)
		updateIDs(required);

                if ((step>2) && (required.find("keyedit.prompt")!=-1)) {
			if (step==3)
			{
			emit passwordChanged();
                        p->writeStdin(TQString("save"));
			}
			else p->writeStdin(TQString("quit"));
                        required=TQString();
                }

                if ((required.find("GOOD_PASSPHRASE")!=-1) && (step==2))
                        step=3;

                if ((required.find("BAD_PASSPHRASE")!=-1) && (step==2)) {
                        step=1;
                        message=i18n("<b>Bad passphrase</b>. Try again<br>");
                }

                if ((required.find("passphrase.enter")!=-1)) {
                        if (userIDs.isEmpty())
                                userIDs=i18n("[No user id found]");
                        userIDs.replace(TQRegExp("<"),"&lt;");

                        if (step==1) {
                                TQString passphrase;
                                int code=KPasswordDialog::getPassword(passphrase,i18n("<qt>%1 Enter passphrase for <b>%2</b></qt>")
                                                                      .arg(message).arg(userIDs));
                                if (code!=TQDialog::Accepted) {
                                        p->writeStdin(TQString("quit"));
                                        //				 p->closeWhenDone();
                                        emit processaborted(true);
                                        p->deleteLater();
                                        return;
                                }
                                p->writeStdin(passphrase,true);
                                step=2;
                        }

                        if (step==3) {
                                TQString passphrase;
                                int code=KPasswordDialog::getNewPassword(passphrase,i18n("<qt>Enter new passphrase for <b>%1</b><br>If you forget this passphrase, all your encrypted files and messages will be lost !<br></qt>").arg(userIDs));
                                if (code!=TQDialog::Accepted) {
					step=4;
                                        p->writeStdin(TQString("quit"));
                                        p->writeStdin(TQString("quit"));
                                        p->closeWhenDone();
                                        emit processaborted(true);
                                        return;
                                }
                                p->writeStdin(passphrase,true);
                                userIDs=TQString();
                        }

                        required=TQString();
                }


                if (required.find("GET_")!=-1) /////// gpg asks for something unusal, turn to konsole mode
                {
                        p->writeStdin(TQString("quit"));
                        p->closeWhenDone();

                }
        }
}



void KgpgInterface::passover(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
        //emit trustfinished();
}



//////////////////////////////////////////////////////////////    key export

TQString KgpgInterface::getKey(TQStringList IDs, bool attributes)
{
//	kdDebug(2100) << k_funcinfo << endl;
        keyString=TQString();
        TDEProcIO *proc=new TDEProcIO(TQTextCodec::codecForLocale());
        *proc<< "gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--utf8-strings";
        *proc<<"--export"<<"--armor";
        if (!attributes)
                *proc<<"--export-options"<<"no-include-attributes";

        for ( TQStringList::Iterator it = IDs.begin(); it != IDs.end(); ++it )
                *proc << *it;
        TQObject::connect(proc, TQ_SIGNAL(readReady(TDEProcIO *)),this, TQ_SLOT(slotReadKey(TDEProcIO *)));
        proc->start(TDEProcess::Block,false);
        return keyString;
}


void KgpgInterface::slotReadKey(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString outp;
        while (p->readln(outp)!=-1)
                if (!outp.startsWith("gpg:")) keyString+=outp+"\n";
}


//////////////////////////////////////////////////////////////    key import

void KgpgInterface::importKeyURL(KURL url)
{
        /////////////      import a key

//	kdDebug(2100) << k_funcinfo << endl;
        if( TDEIO::NetAccess::download( url, tempKeyFile,0) ) {
                message=TQString();
                TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
                *conprocess<< "gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--status-fd=2"<<"--utf8-strings"<<"--import";
                *conprocess<<"--allow-secret-key-import";
                *conprocess<<tempKeyFile;
                TQObject::connect(conprocess, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(importURLover(TDEProcess *)));
                TQObject::connect(conprocess, TQ_SIGNAL(readReady(TDEProcIO *)),this, TQ_SLOT(importprocess(TDEProcIO *)));
                conprocess->start(TDEProcess::NotifyOnExit,true);
        }
}

void KgpgInterface::importKey(TQString keystr)
{
        /////////////      import a key
        message=TQString();
        TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
        *conprocess<< "gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--status-fd=2"<<"--import";
        *conprocess<<"--allow-secret-key-import";
        TQObject::connect(conprocess, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(importover(TDEProcess *)));
        TQObject::connect(conprocess, TQ_SIGNAL(readReady(TDEProcIO *)),this, TQ_SLOT(importprocess(TDEProcIO *)));
        conprocess->start(TDEProcess::NotifyOnExit,true);
        conprocess->writeStdin(keystr, true);
        conprocess->closeWhenDone();
}

void KgpgInterface::importover(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
TQStringList importedKeysIds;
TQStringList messageList;
TQString resultMessage;
bool secretImport=false;
kdDebug(2100)<<"Importing is over"<<endl;
        TQString parsedOutput=message;
        TQStringList importedKeys;

        while (parsedOutput.find("IMPORTED")!=-1) {
                parsedOutput.remove(0,parsedOutput.find("IMPORTED")+8);
		importedKeys<<parsedOutput.section("\n",0,0).stripWhiteSpace();
		importedKeysIds<<parsedOutput.stripWhiteSpace().section(' ',0,0);
        }


        if (message.find("IMPORT_RES")!=-1) {
                parsedOutput=message.section("IMPORT_RES",-1,-1).stripWhiteSpace();
		messageList=TQStringList::split(" ",parsedOutput,true);

                resultMessage=i18n("<qt>%n key processed.<br></qt>","<qt>%n keys processed.<br></qt>",messageList[0].toULong());
                if (messageList[4]!="0")
                        resultMessage+=i18n("<qt>One key unchanged.<br></qt>","<qt>%n keys unchanged.<br></qt>",messageList[4].toULong());
                if (messageList[7]!="0")
                        resultMessage+=i18n("<qt>One signature imported.<br></qt>","<qt>%n signatures imported.<br></qt>",messageList[7].toULong());
                if (messageList[1]!="0")
                        resultMessage+=i18n("<qt>One key without ID.<br></qt>","<qt>%n keys without ID.<br></qt>",messageList[1].toULong());
                if (messageList[3]!="0")
                        resultMessage+=i18n("<qt>One RSA key imported.<br></qt>","<qt>%n RSA keys imported.<br></qt>",messageList[3].toULong());
                if (messageList[5]!="0")
                        resultMessage+=i18n("<qt>One user ID imported.<br></qt>","<qt>%n user IDs imported.<br></qt>",messageList[5].toULong());
                if (messageList[6]!="0")
                        resultMessage+=i18n("<qt>One subkey imported.<br></qt>","<qt>%n subkeys imported.<br></qt>",messageList[6].toULong());
                if (messageList[8]!="0")
                        resultMessage+=i18n("<qt>One revocation certificate imported.<br></qt>","<qt>%n revocation certificates imported.<br></qt>",messageList[8].toULong());
                if (messageList[9]!="0")
			{
                        resultMessage+=i18n("<qt>One secret key processed.<br></qt>","<qt>%n secret keys processed.<br></qt>",messageList[9].toULong());
			secretImport=true;
			}
                if (messageList[10]!="0")
                        resultMessage+=i18n("<qt><b>One secret key imported.</b><br></qt>","<qt><b>%n secret keys imported.</b><br></qt>",messageList[10].toULong());
                if (messageList[11]!="0")
                        resultMessage+=i18n("<qt>One secret key unchanged.<br></qt>","<qt>%n secret keys unchanged.<br></qt>",messageList[11].toULong());
                if (messageList[12]!="0")
                        resultMessage+=i18n("<qt>One secret key not imported.<br></qt>","<qt>%n secret keys not imported.<br></qt>",messageList[12].toULong());
                if (messageList[2]!="0")
                        resultMessage+=i18n("<qt><b>One key imported:</b><br></qt>","<qt><b>%n keys imported:</b><br></qt>",messageList[2].toULong());

		if (secretImport) resultMessage+=i18n("<qt><br><b>You have imported a secret key.</b> <br>"
									"Please note that imported secret keys are not trusted by default.<br>"
									"To fully use this secret key for signing and encryption, you must edit the key (double click on it) and set its trust to Full or Ultimate.</qt>");
        } else
                resultMessage=i18n("No key imported... \nCheck detailed log for more infos");

	if (messageList[8]!="0") importedKeysIds="ALL";
	if ((messageList[9]!="0") && (importedKeysIds.isEmpty())) // orphaned secret key imported
	emit refreshOrphaned();
        emit importfinished(importedKeysIds);

	(void) new KDetailedInfo(0,"import_result",resultMessage,message,importedKeys);
}

void KgpgInterface::importURLover(TDEProcess *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TDEIO::NetAccess::removeTempFile(tempKeyFile);
        importover(p);
        //KMessageBox::information(0,message);
        //emit importfinished();
}

void KgpgInterface::importprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString outp;
        while (p->readln(outp)!=-1) {
                if (outp.find("http-proxy")==-1)
                        message+=outp+"\n";
        }
}


///////////////////////////////////////////////////////////////////////////////////////   User ID's


void KgpgInterface::KgpgAddUid(TQString keyID,TQString name,TQString email,TQString comment)
{
//	kdDebug(2100) << k_funcinfo << endl;
uidName=name;
uidComment=comment;
uidEmail=email;
output=TQString();
addSuccess=true;

        TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
        *conprocess<< "gpg"<<"--no-tty"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings";
        *conprocess<<"--edit-key"<<keyID<<"adduid";
        TQObject::connect(conprocess, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(adduidover(TDEProcess *)));
        TQObject::connect(conprocess, TQ_SIGNAL(readReady(TDEProcIO *)),this, TQ_SLOT(adduidprocess(TDEProcIO *)));
        conprocess->start(TDEProcess::NotifyOnExit,true);
}

void KgpgInterface::adduidover(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
if (addSuccess) emit addUidFinished();
else emit addUidError(output);
}

void KgpgInterface::adduidprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required=TQString();
        while (p->readln(required,true)!=-1) {
                output+=required+"\n";
                if (required.find("USERID_HINT",0,false)!=-1)
		updateIDs(required);

                if (required.find("keygen.name")!=-1)  {
                        p->writeStdin(uidName);
                        required=TQString();
                }

		if (required.find("keygen.email")!=-1)  {
                        p->writeStdin(uidEmail);
                        required=TQString();
                }

		if (required.find("keygen.comment")!=-1)  {
                        p->writeStdin(uidComment);
                        required=TQString();
                }

                if (required.find("passphrase.enter")!=-1) {
                        TQString delpass;
                        int code=KPasswordDialog::getPassword(delpass,i18n("<qt>Enter passphrase for <b>%1</b>:</qt>")
                                                              .arg(userIDs));
                        if (code!=TQDialog::Accepted) {
                                //addSuccess=false;
                                p->writeStdin(TQString("quit"));
                                p->closeWhenDone();
                                return;
                        }
                        p->writeStdin(delpass,true);
                        required=TQString();

                }

		if (required.find("keyedit.prompt")!=-1) {
		       p->writeStdin(TQString("save"));
                        required=TQString();
		}

		if ((required.find("GET_")!=-1)) /////// gpg asks for something unusal, turn to konsole mode
                {
                        kdDebug(2100)<<"unknown request"<<endl;
                        addSuccess=false;  /////  switching to console mode
                        p->writeStdin(TQString("quit"));
                        p->closeWhenDone();
                }
        }
}









/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  photo id's

void KgpgInterface::KgpgGetPhotoList(TQString keyID)
{
//	kdDebug(2100) << k_funcinfo << endl;
photoList.clear();
output=TQString();
photoCount=1;
userIDs=keyID;

        TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
        *conprocess<< "gpg"<<"--no-tty"<<"--status-fd=2"<<"--command-fd=0";
        *conprocess<<"--with-colon"<<"--list-keys"<<keyID;
        TQObject::connect(conprocess, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(photoreadover(TDEProcess *)));
        TQObject::connect(conprocess, TQ_SIGNAL(readReady(TDEProcIO *)),this, TQ_SLOT(photoreadprocess(TDEProcIO *)));
        conprocess->start(TDEProcess::NotifyOnExit,true);
}

void KgpgInterface::photoreadprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required=TQString();
        while (p->readln(required,true)!=-1) {
                output+=required+"\n";
                if (required.startsWith("uat") || required.startsWith("uid")) photoCount++;
}
}


void KgpgInterface::photoreadover(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
for (int i=1;i<photoCount+1;i++)
if (isPhotoId(i)) photoList+=TQString::number(i);

emit signalPhotoList(photoList);
}

bool KgpgInterface::isPhotoId(int uid)
{
//	kdDebug(2100) << k_funcinfo << endl;
KTempFile *kgpginfotmp=new KTempFile();
                kgpginfotmp->setAutoDelete(true);
                TQString pgpgOutput="cp %i "+kgpginfotmp->name();

TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
        *conprocess<< "gpg"<<"--no-tty"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings";
        *conprocess<<"--photo-viewer"<<TQString(TQFile::encodeName(pgpgOutput))<<"--edit-key"<<userIDs<<"uid"<<TQString::number(uid)<<"showphoto";
        conprocess->start(TDEProcess::Block);
	if (kgpginfotmp->file()->size()>0)
	{
	kgpginfotmp->unlink();
	return true;
	}
	kgpginfotmp->unlink();
	return false;
}

void KgpgInterface::KgpgDeletePhoto(TQString keyID,TQString uid)
{
//	kdDebug(2100) << k_funcinfo << endl;
	delSuccess=true;
	output=TQString();
        TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
        *conprocess<< "gpg"<<"--no-tty"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings";
        *conprocess<<"--edit-key"<<keyID<<"uid"<<uid<<"deluid";
        TQObject::connect(conprocess, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(delphotoover(TDEProcess *)));
        TQObject::connect(conprocess, TQ_SIGNAL(readReady(TDEProcIO *)),this, TQ_SLOT(delphotoprocess(TDEProcIO *)));
        conprocess->start(TDEProcess::NotifyOnExit,true);
}

void KgpgInterface::delphotoover(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
if (delSuccess) emit delPhotoFinished();
else emit delPhotoError(output);
}

void KgpgInterface::delphotoprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required=TQString();
        while (p->readln(required,true)!=-1) {
                output+=required+"\n";
                if (required.find("USERID_HINT",0,false)!=-1)
                                updateIDs(required);

                if (required.find("keyedit.remove.uid.okay")!=-1)  {
                        p->writeStdin(TQString("YES"));
                        required=TQString();
                }

                if (required.find("passphrase.enter")!=-1) {
                        TQString delpass;
                        int code=KPasswordDialog::getPassword(delpass,i18n("<qt>Enter passphrase for <b>%1</b>:</qt>").arg(userIDs));
                        if (code!=TQDialog::Accepted) {
                                //deleteSuccess=false;
                                p->writeStdin(TQString("quit"));
                                p->closeWhenDone();
                                return;
                        }
                        p->writeStdin(delpass,true);
                        required=TQString();

                }

		if (required.find("keyedit.prompt")!=-1) {
		       p->writeStdin(TQString("save"));
                        required=TQString();
		}

		if ((required.find("GET_")!=-1)) /////// gpg asks for something unusal, turn to konsole mode
                {
                        kdDebug(2100)<<"unknown request"<<endl;
                        delSuccess=false;
                        p->writeStdin(TQString("quit"));
                        p->closeWhenDone();

                }
        }
}


void KgpgInterface::KgpgAddPhoto(TQString keyID,TQString imagePath)
{
//	kdDebug(2100) << k_funcinfo << endl;
photoUrl=imagePath;
output=TQString();
addSuccess=true;
        TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
        *conprocess<< "gpg"<<"--no-tty"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings";
        *conprocess<<"--edit-key"<<keyID<<"addphoto";
        TQObject::connect(conprocess, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(addphotoover(TDEProcess *)));
        TQObject::connect(conprocess, TQ_SIGNAL(readReady(TDEProcIO *)),this, TQ_SLOT(addphotoprocess(TDEProcIO *)));
        conprocess->start(TDEProcess::NotifyOnExit,true);
}

void KgpgInterface::addphotoover(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
if (addSuccess) emit addPhotoFinished();
else emit addPhotoError(output);
}

void KgpgInterface::addphotoprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required=TQString();
        while (p->readln(required,true)!=-1) {
                output+=required+"\n";
                if (required.find("USERID_HINT",0,false)!=-1)
		updateIDs(required);

                if (required.find("photoid.jpeg.add")!=-1)  {
                        p->writeStdin(photoUrl);
                        required=TQString();
                }

		if (required.find("photoid.jpeg.size")!=-1)  {
			if (KMessageBox::questionYesNo(0,i18n("This image is very large. Use it anyway?"), TQString(), i18n("Use Anyway"), i18n("Do Not Use"))==KMessageBox::Yes)
                        p->writeStdin(TQString("Yes"));
			else
			{
			p->writeStdin(TQString("No"));
			p->writeStdin(TQString(""));
			p->writeStdin(TQString("quit"));
			}
                        required=TQString();
                }

                if (required.find("passphrase.enter")!=-1) {
                        TQString delpass;
                        int code=KPasswordDialog::getPassword(delpass,i18n("<qt>Enter passphrase for <b>%1</b>:</qt>").arg(userIDs));
                        if (code!=TQDialog::Accepted) {
                                //deleteSuccess=false;
                                p->writeStdin(TQString("quit"));
                                p->closeWhenDone();
                                return;
                        }
                        p->writeStdin(delpass,true);
                        required=TQString();

                }

		if (required.find("keyedit.prompt")!=-1) {
		       p->writeStdin(TQString("save"));
                        required=TQString();
		}

		if ((required.find("GET_")!=-1)) /////// gpg asks for something unusal, turn to konsole mode
                {
                        kdDebug(2100)<<"unknown request"<<endl;
                        p->writeStdin(TQString("quit"));
			addSuccess=false;
                        p->closeWhenDone();

                }
        }
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  key revocation

void KgpgInterface::KgpgRevokeKey(TQString keyID,TQString revokeUrl,int reason,TQString description)
{
//	kdDebug(2100) << k_funcinfo << endl;
        revokeReason=reason;
        revokeSuccess=false;
        revokeDescription=description;
        certificateUrl=revokeUrl;
        output=TQString();
        TDEProcIO *conprocess=new TDEProcIO(TQTextCodec::codecForLocale());
        *conprocess<< "gpg"<<"--no-tty"<<"--status-fd=2"<<"--logger-fd=2"<<"--command-fd=0"<<"--utf8-strings";
        if (!revokeUrl.isEmpty())
                *conprocess<<"-o"<<revokeUrl;
        *conprocess<<"--gen-revoke"<<keyID;
        TQObject::connect(conprocess, TQ_SIGNAL(processExited(TDEProcess *)),this, TQ_SLOT(revokeover(TDEProcess *)));
        TQObject::connect(conprocess, TQ_SIGNAL(readReady(TDEProcIO *)),this, TQ_SLOT(revokeprocess(TDEProcIO *)));
        conprocess->start(TDEProcess::NotifyOnExit,true);
}

void KgpgInterface::revokeover(TDEProcess *)
{
//	kdDebug(2100) << k_funcinfo << endl;
        if (!revokeSuccess)
                KMessageBox::detailedSorry(0,i18n("Creation of the revocation certificate failed..."),output);
        else {
                output=output.section("-----BEGIN",1);
                output.prepend("-----BEGIN");
                output=output.section("BLOCK-----",0);
                emit revokecertificate(output);
                if (!certificateUrl.isEmpty())
                        emit revokeurl(certificateUrl);
        }
}

void KgpgInterface::revokeprocess(TDEProcIO *p)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString required=TQString();
        while (p->readln(required,true)!=-1) {
                output+=required+"\n";
		//	kdDebug(2100) << k_funcinfo << " line " << required << endl;

                if (required.find("USERID_HINT",0,false)!=-1)
		updateIDs(required);

                if ((required.find("GOOD_PASSPHRASE")!=-1))
		//	kdDebug(2100) << k_funcinfo << " GOOD_PASSPHRASE " << endl;
                        revokeSuccess=true;

                if ((required.find("gen_revoke.okay")!=-1) || (required.find("ask_revocation_reason.okay")!=-1) || (required.find("openfile.overwrite.okay")!=-1)) {
		//	kdDebug(2100) << k_funcinfo << " gen_revoke.okay " << endl;
                        p->writeStdin(TQString("YES"));
                        required=TQString();
                }

                if (required.find("ask_revocation_reason.code")!=-1) {
		//	kdDebug(2100) << k_funcinfo << " ask_revocation_reason.code " << endl;
                        p->writeStdin(TQString::number(revokeReason));
                        required=TQString();
                }

                if (required.find("passphrase.enter")!=-1) {
		//	kdDebug(2100) << k_funcinfo << " passphrase.enter " << endl;
                        TQString signpass;
                        int code=KPasswordDialog::getPassword(signpass,i18n("<qt>Enter passphrase for <b>%1</b>:</qt>").arg(userIDs));
                        if (code!=TQDialog::Accepted) {
                                expSuccess=3;  /////  aborted by user mode
                                p->writeStdin(TQString("quit"));
                                p->closeWhenDone();
                                return;
                        }
                        p->writeStdin(signpass,true);
                        required=TQString();

                }
                if (required.find("ask_revocation_reason.text")!=-1) {
		//	kdDebug(2100) << k_funcinfo << " ask_revocation_reason.text " << endl;
                        //		kdDebug(2100)<<"description"<<endl;
                        p->writeStdin(revokeDescription);
                        revokeDescription=TQString();
                        required=TQString();
                }
                if ((required.find("GET_")!=-1)) /////// gpg asks for something unusal, turn to konsole mode
                {
                        kdDebug(2100)<<"unknown request"<<endl;
                        expSuccess=1;  /////  switching to console mode
                        p->writeStdin(TQString("quit"));
                        p->closeWhenDone();

                }
        }
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   parsing of ./gnupg/options file

TQString KgpgInterface::getGpgSetting(TQString name,TQString configFile)
{
//	kdDebug(2100) << k_funcinfo << endl;
        name=name.stripWhiteSpace()+" ";
        TQFile qfile(TQFile::encodeName(configFile));
        if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
                TQString result;
                TQTextStream t( &qfile );
                result=t.readLine();
                while (result!=NULL) {
                        if (result.stripWhiteSpace().startsWith(name)) {
                                result=result.stripWhiteSpace();
                                result.remove(0,name.length());
                                result=result.stripWhiteSpace();
                                return result.section(" ",0,0);
                        }
                        result=t.readLine();
                }
                qfile.close();
        }
        return TQString();
}

TQString KgpgInterface::getGpgMultiSetting(TQString name,TQString configFile)
{
//	kdDebug(2100) << k_funcinfo << endl;
// get GnuPG setting for item that can have multiple entries (eg. encrypt-to)

TQString parsedResult=TQString();

        name=name.stripWhiteSpace()+" ";
        TQFile qfile(TQFile::encodeName(configFile));
        if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
                TQString result;
                TQTextStream t( &qfile );
                result=t.readLine();
                while (result!=NULL) {
                        if (result.stripWhiteSpace().startsWith(name)) {
                                result=result.stripWhiteSpace();
                                result.remove(0,name.length());
				if (parsedResult!=TQString())
				parsedResult+=" "+result.stripWhiteSpace();
				else
                                parsedResult+=result.stripWhiteSpace();
                                //return result.section(" ",0,0);
                        }
                        result=t.readLine();
                }
                qfile.close();
        }
        return parsedResult;
}

void KgpgInterface::delGpgGroup(TQString name, TQString configFile)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString textToWrite;
        TQFile qfile(TQFile::encodeName(configFile));
        if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
                TQString result;
                TQTextStream t( &qfile );
                result=t.readLine();
                while (result!=NULL) {
                        if (result.stripWhiteSpace().startsWith("group ")) {
                                TQString result2=result.stripWhiteSpace();
                                result2.remove(0,6);
                                result2=result2.stripWhiteSpace();
                                if (result2.startsWith(name) && (result2.remove(0,name.length()).stripWhiteSpace().startsWith("=")))
                                        result=TQString();
                        }
                       if (result!=TQString()) textToWrite+=result+"\n";
                        result=t.readLine();
                }
                qfile.close();
                if (qfile.open(IO_WriteOnly)) {
                        TQTextStream t( &qfile);
                        t << textToWrite;
                        qfile.close();
                }
        }
}

void KgpgInterface::setGpgGroupSetting(TQString name,TQStringList values, TQString configFile)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString textToWrite;
        bool found=false;
        TQFile qfile(TQFile::encodeName(configFile));
        kdDebug(2100)<<"Changing group: "<<name<<endl;
        if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
                TQString result;
                TQTextStream t( &qfile );
                result=t.readLine();
                while (result!=NULL) {
                        if (result.stripWhiteSpace().startsWith("group ")) {
                                TQString result2=result.stripWhiteSpace();
                                result2.remove(0,6);
                                result2=result2.stripWhiteSpace();
                                if (result2.startsWith(name) && (result2.remove(0,name.length()).stripWhiteSpace().startsWith("="))) {
//                                        kdDebug(2100)<<"Found group: "<<name<<endl;
                                        //kdDebug(2100)<<"New values: "<<values<<endl;
                                        result=TQString("group %1=%2").arg(name).arg(values.join(" "));
                                        found=true;
                                }
                        }
                        textToWrite+=result+"\n";
                        result=t.readLine();
                }
                qfile.close();
                if (!found)
                        textToWrite+="\n"+TQString("group %1=%2").arg(name).arg(values.join(" "));

                if (qfile.open(IO_WriteOnly)) {
                        TQTextStream t( &qfile);
                        t << textToWrite;
                        qfile.close();
                }
        }
}



TQStringList KgpgInterface::getGpgGroupSetting(TQString name,TQString configFile)
{
//	kdDebug(2100) << k_funcinfo << endl;

        TQFile qfile(TQFile::encodeName(configFile));
        if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
                TQString result;
                TQTextStream t( &qfile );
                result=t.readLine();
                while (result!=NULL) {
                        result=result.stripWhiteSpace();
                        if (result.startsWith("group ")) {
                                kdDebug(2100)<<"Found 1 group"<<endl;
                                result.remove(0,6);
                                if (result.stripWhiteSpace().startsWith(name)) {
                                        kdDebug(2100)<<"Found group: "<<name<<endl;
                                        result=result.section('=',1);
                                        result=result.section('#',0,0);
                                        return TQStringList::split (" ",result);
                                }
                        }
                        result=t.readLine();
                }
                qfile.close();
        }
        return TQString();
}

TQStringList KgpgInterface::getGpgGroupNames(TQString configFile)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQStringList groups;
        TQFile qfile(TQFile::encodeName(configFile));
        if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
                TQString result;
                TQTextStream t( &qfile );
                result=t.readLine();
                while (result!=NULL) {
                        result=result.stripWhiteSpace();
                        if (result.startsWith("group ")) {
                                result.remove(0,6);
                                groups<<result.section("=",0,0).stripWhiteSpace();
                        }
                        result=t.readLine();
                }
                qfile.close();
        }
        return groups;
}


bool KgpgInterface::getGpgBoolSetting(TQString name,TQString configFile)
{
//	kdDebug(2100) << k_funcinfo << endl;
        name=name;
        TQFile qfile(TQFile::encodeName(configFile));
        if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
                TQString result;
                TQTextStream t( &qfile );
                result=t.readLine();
                while (result!=NULL) {
                        if (result.stripWhiteSpace().startsWith(name)) {
                                return true;
                        }
                        result=t.readLine();
                }
                qfile.close();
        }
        return false;
}

void KgpgInterface::setGpgSetting(TQString name,TQString value,TQString url)
{
//	kdDebug(2100) << k_funcinfo << endl;
        name=name+" ";
        TQString textToWrite;
        bool found=false;
        TQFile qfile(TQFile::encodeName(url));

        if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
                TQString result;
                TQTextStream t( &qfile );
                result=t.readLine();
                while (result!=NULL) {
                        if (result.stripWhiteSpace().startsWith(name)) {
                                if (!value.isEmpty())
                                        result=name+" "+value;
                                else
                                        result=TQString();
                                found=true;
                        }
                        if (result!=TQString()) textToWrite+=result+"\n";
                        result=t.readLine();
                }
                qfile.close();
                if ((!found) && (!value.isEmpty()))
                        textToWrite+="\n"+name+" "+value;

                if (qfile.open(IO_WriteOnly)) {
                        TQTextStream t( &qfile);
                        t << textToWrite; // FIXME: this shouldn't write at the end of the gpg.conf file
                        qfile.close();
                }
        }
}


void KgpgInterface::setGpgMultiSetting(TQString name,TQStringList values,TQString url)
{
//	kdDebug(2100) << k_funcinfo << endl;
        name=name+" ";
        TQString textToWrite;
        bool found=false;
        TQFile qfile(TQFile::encodeName(url));

        if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
                TQString result;
                TQTextStream t( &qfile );
                result=t.readLine();
                while (result!=NULL) {
                        if (!result.stripWhiteSpace().startsWith(name))
				textToWrite+=result+"\n";
                        result=t.readLine();
                }
                qfile.close();

		while (!values.isEmpty())
		{
                        textToWrite+="\n"+name+" "+values.first();
			values.pop_front();
		}

                if (qfile.open(IO_WriteOnly)) {
                        TQTextStream t( &qfile);
                        t << textToWrite;
                        qfile.close();
                }
        }
}

void KgpgInterface::setGpgBoolSetting(TQString name,bool enable,TQString url)
{
//	kdDebug(2100) << k_funcinfo << endl;
        TQString textToWrite;
        bool found=false;
        TQFile qfile(TQFile::encodeName(url));

        if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
                TQString result;
                TQTextStream t( &qfile );
                result=t.readLine();
                while (result!=NULL) {
                        if (result.stripWhiteSpace().startsWith(name)) {
                                if (enable)
                                        result=name;
                                else
                                        result=TQString();
                                found=true;
                        }
                       if (result!=TQString()) textToWrite+=result+"\n";
                        result=t.readLine();
                }
                qfile.close();
                if ((!found) && (enable))
                        textToWrite+=name;

                if (qfile.open(IO_WriteOnly)) {
                        TQTextStream t( &qfile);
                        t << textToWrite;
                        qfile.close();
                }
        }
}

TQString KgpgInterface::checkForUtf8bis(TQString txt)
{
//	kdDebug(2100) << k_funcinfo << endl;
    if (strchr (txt.ascii(), 0xc3) || (txt.find("\\x")!=-1))
	txt=checkForUtf8(txt);
    else {
	txt=checkForUtf8(txt);
	txt=TQString::fromUtf8(txt.ascii());
    }
    return txt;
}


TQString KgpgInterface::checkForUtf8(TQString txt)
{
//	kdDebug(2100) << k_funcinfo << endl;
        //    code borrowed from gpa
        const char *s;

        /* Make sure the encoding is UTF-8.
         * Test structure suggested by Werner Koch */
        if (txt.isEmpty())
                return TQString();

        for (s = txt.ascii(); *s && !(*s & 0x80); s++)
                ;
        if (*s && !strchr (txt.ascii(), 0xc3) && (txt.find("\\x")==-1))
                return txt;

        /* The string is not in UTF-8 */
        //if (strchr (txt.ascii(), 0xc3)) return (txt+" +++");
        if (txt.find("\\x")==-1)
                return TQString::fromUtf8(txt.ascii());
        //        if (!strchr (txt.ascii(), 0xc3) || (txt.find("\\x")!=-1)) {
        for ( int idx = 0 ; (idx = txt.find( "\\x", idx )) >= 0 ; ++idx ) {
                char str[2] = "x";
                str[0] = (char) TQString( txt.mid( idx + 2, 2 ) ).toShort( 0, 16 );
                txt.replace( idx, 4, str );
        }
        if (!strchr (txt.ascii(), 0xc3))
            return TQString::fromUtf8(txt.ascii());
        else
            return TQString::fromUtf8(TQString::fromUtf8(txt.ascii()).ascii());  // perform Utf8 twice, or some keys display badly

        return txt;
}


#include "kgpginterface.moc"
