//virtual
bool MTPageAddContract::validatePage()
{
    QString qstrType(this->field("contractType").toString());

    // If we're creating a server contract, I want to display a warning to the user.
    //
    if ((0 == qstrType.compare("server")) &&
        ui->radioButton_2->isChecked() && // "Create" (versus "Import".)
        (opentxs::OTAPI_Wrap::It()->GetAccountCount() > 0)) {
        QMessageBox::StandardButton reply;

        reply = QMessageBox::question(this, "", QString("%1<br/><br/>%2<br/><br/>%3").arg(tr("Are you sure you want to create a server contract?")).
                                      arg(tr("WARNING: A server contract should be created using a throwaway wallet, which should then be "
                                             "discarded after the contract is created.")).
                                      arg(tr("But the current wallet has accounts in it! (And most likely you do NOT want to discard those accounts.) "
                                             "Therefore you probably do NOT want to proceed with this action. "
                                             "Are you SURE you want to do this? (No, you do not want to do this. Click 'No'.)")),
                                      QMessageBox::Yes|QMessageBox::No);
        if (reply == QMessageBox::No)
            return false;
    }

    return true;
}
void DlgDecrypt::on_pushButtonDecrypt_clicked()
{
    bool bSuccessDecrypting = false;
    bool bSuccessVerifying  = false;

    QString qstrNymWhoDecrypted;
    QString qstrNymWhoVerified;

    QString qstrText = ui->plainTextEdit->toPlainText().trimmed();
    // --------------------------------
    if (qstrText.isEmpty())
    {
        // pop up a message box warning that the input text is empty.
        //
        QMessageBox::warning(this, tr("Ciphertext is Empty"),
                             tr("Please paste something to be decrypted/verified."));
        return;
    }
    // --------------------------------
    else //qstrText not empty.
    {
        std::string str_input(qstrText.toStdString());
        opentxs::String    strInput (str_input.c_str());

        if (strInput.Exists())
        {
            if (strInput.Contains("-----BEGIN OT ARMORED ENVELOPE-----"))
            {
                opentxs::OTEnvelope theEnvelope;

                if (theEnvelope.SetFromBookendedString(strInput))
                {
                    opentxs::String strOutput;
                    // -------------------------
                    // First we'll try the default nym, if one is available.
                    //
                    QString qstrTempID = Moneychanger::It()->get_default_nym_id();

                    if (!qstrTempID.isEmpty()) // Default Nym IS available.
                    {
                        std::string  str_nym    (qstrTempID.toStdString());
                        opentxs::String     strNym     (str_nym.c_str());
                        opentxs::Identifier nym_id     (strNym);

                        if (!nym_id.IsEmpty())
                        {
                            opentxs::OTPasswordData thePWData("Recipient passphrase");

                            opentxs::Nym * pNym = opentxs::OTAPI_Wrap::OTAPI()->GetOrLoadPrivateNym(nym_id,
                                                                                   false, //bChecking=false
                                                                                   __FUNCTION__,
                                                                                   &thePWData);
                            if (NULL != pNym)
                            {
                                if (theEnvelope.Open(*pNym, strOutput) && strOutput.Exists())
                                {
                                    bSuccessDecrypting = true;
                                    qstrNymWhoDecrypted = qstrTempID;

                                    strInput  = strOutput;
                                    str_input = strInput.Get();
                                    qstrText  = QString::fromStdString(str_input);
                                }
                            }
                        }
                    }
                    // ------------
                    if (!bSuccessDecrypting) // Default nym is NOT available. Okay let's loop through all the Nyms in the wallet then, and try then all...
                    {
                        const int32_t nym_count = opentxs::OTAPI_Wrap::It()->GetNymCount();
                        // -----------------------------------------------
                        for (int32_t ii = 0; ii < nym_count; ++ii)
                        {
                            //Get OT Nym ID
                            QString OT_nym_id = QString::fromStdString(opentxs::OTAPI_Wrap::It()->GetNym_ID(ii));

                            if (!OT_nym_id.isEmpty())
                            {
                                std::string         str_nym    (OT_nym_id.toStdString());
                                opentxs::String     strNym     (str_nym.c_str());
                                opentxs::Identifier nym_id     (strNym);

                                if (!nym_id.IsEmpty())
                                {
                                    opentxs::OTPasswordData thePWData("Recipient passphrase");

                                    opentxs::Nym * pNym = opentxs::OTAPI_Wrap::OTAPI()->GetOrLoadPrivateNym(nym_id,
                                                                                           false, //bChecking=false
                                                                                           "DlgEncrypt::on_pushButtonDecrypt_clicked",
                                                                                           &thePWData);
                                    if (NULL != pNym)
                                    {
                                        // Okay there is a private key available for this Nym, so let's
                                        // try to open the envelope using it.
                                        //
                                        if (theEnvelope.Open(*pNym, strOutput) && strOutput.Exists())
                                        {
                                            bSuccessDecrypting = true;
                                            qstrNymWhoDecrypted = OT_nym_id;

                                            strInput  = strOutput;
                                            str_input = strInput.Get();
                                            qstrText  = QString::fromStdString(str_input);

                                            break;
                                        }
                                    }
                                }
                                // ------------
                            }
                        } // for
                    } // else default nym not available.
                    // -----------------------
                    if (!bSuccessDecrypting)
                    {
                        QMessageBox::warning(this, tr("Failed Decrypting"),
                                             tr("None of the identities in your wallet (including your default identity, "
                                                "if applicable) were able to open this message."));
                        return;

                    }
                    // -----------------------
                } // if (theEnvelope.SetFromBookendedString(strInput))

            } // if (strInput.Contains("-----BEGIN OT ARMORED ENVELOPE-----"))
            // --------------------------------------------
            // This call to DecodeIfArmored is what handles the: "-----BEGIN OT ARMORED ... -----"

            if (strInput.DecodeIfArmored(false)) // bEscapedIsAllowed=true by default.
            {
                std::string str_decoded(strInput.Get());
                QString qstrDecoded(QString::fromStdString(str_decoded));

                if (!qstrDecoded.isEmpty())
                    qstrText = qstrDecoded;
                // -----------------------------------
                // At this point, we know it's been decrypted, if applicable, and it's been
                // de-armored, if applicable. So now we check to see if it's a signed file.
                //
                if (strInput.Contains("-----BEGIN SIGNED FILE-----"))
                {
                    opentxs::OTSignedFile theSignedFile;

                    if (theSignedFile.LoadContractFromString(strInput))
                    {
                        opentxs::String strSignerNymID = theSignedFile.GetSignerNymID();
                        std::string str_signer_nym(strSignerNymID.Get());
                        QString qstrSignerNym(QString::fromStdString(str_signer_nym));

                        if (!str_signer_nym.empty())
                        {
                            opentxs::OTPasswordData thePWData("Sometimes need to load private part of nym in order to use its public key. (Fix that!)");
                            opentxs::Identifier id_signer_nym(strSignerNymID);
                            const opentxs::Nym * pNym = opentxs::OTAPI_Wrap::OTAPI()->GetOrLoadNym(id_signer_nym,
                                                                                   false, //bChecking=false
                                                                                   __FUNCTION__,
                                                                                   &thePWData);
                            if (NULL != pNym)
                            {
                                if (theSignedFile.VerifySignature(*pNym, &thePWData))
                                {
                                    bSuccessVerifying = true;
                                    qstrNymWhoVerified = qstrSignerNym;

                                    opentxs::String strContents = theSignedFile.GetFilePayload();

                                    if (strContents.Exists())
                                    {
                                        strInput  = strContents;
                                        str_input = strInput.Get();
                                        qstrText  = QString::fromStdString(str_input);
                                    }
                                } // signature verified
                            } // pNym exists
                        } // if str_signer_nym exists
                    } // signed file: load contract from string.
                } // "BEGIN SIGNED FILE"
            } // Decode If Armored.
            // -----------------------------------------------
            // if qstrText still contains something, pop up a dialog to display the result to the user.
            //
            if (!qstrText.isEmpty())
            {
                MTNameLookupQT theLookup;
                QString qstrNymWhoDecryptedName(""), qstrNymWhoVerifiedName("");

                if (!qstrNymWhoDecrypted.isEmpty())
                    qstrNymWhoDecryptedName = QString::fromStdString(theLookup.GetNymName(qstrNymWhoDecrypted.toStdString(), ""));
                if (!qstrNymWhoVerified.isEmpty())
                    qstrNymWhoVerifiedName = QString::fromStdString(theLookup.GetNymName(qstrNymWhoVerified.toStdString(), ""));
                // -------------------------------
                if (qstrNymWhoDecryptedName.isEmpty())
                    qstrNymWhoDecryptedName = qstrNymWhoDecrypted;
                else if (qstrNymWhoDecryptedName != qstrNymWhoDecrypted)
                    qstrNymWhoDecryptedName += QString(" (%1)").arg(qstrNymWhoDecrypted);
                // -------------------------------
                if (qstrNymWhoVerifiedName.isEmpty())
                    qstrNymWhoVerifiedName = qstrNymWhoVerified;
                else if (qstrNymWhoVerifiedName != qstrNymWhoVerified)
                    qstrNymWhoVerifiedName += QString(" (%1)").arg(qstrNymWhoVerified);
                // -------------------------------
                QString qstrType("Output:");

                if (bSuccessVerifying)
                {
                    qstrType = QString("%1: %2").arg(tr("Verified signature by Nym")).arg(qstrNymWhoVerifiedName);
                }
                // -----------
                if (bSuccessDecrypting)
                {
                    if (bSuccessVerifying)
                        qstrType = QString("%1: %2\n%3: %4").arg(tr("Decrypted using Nym")).arg(qstrNymWhoDecryptedName).arg(tr("Verified signature by Nym")).arg(qstrNymWhoVerifiedName);
                    else
                        qstrType = QString("%1: %2").arg(tr("Decrypted using Nym")).arg(qstrNymWhoDecryptedName);
                }
                // -----------
                QString qstrSubTitle(tr("Be sure to copy it somewhere before closing this dialog."));
                // -----------
                // Pop up the result dialog.
                //
                DlgExportedToPass dlgExported(this, qstrText,
                                              qstrType,
                                              qstrSubTitle, false);
                dlgExported.exec();
            } // if (!qstrText.isEmpty())
        } // if strInput
    } //qstrText not empty
}
void DlgEncrypt::on_pushButtonEncrypt_clicked()
{
    QString qstrText = ui->plainTextEdit->toPlainText().trimmed();
    // --------------------------------
    if (qstrText.isEmpty())
    {
        // pop up a message box warning that the input text is empty.
        //
        QMessageBox::warning(this, tr("Input Text is Empty"),
                             tr("Please paste some text to be signed/encrypted."));
        return;
    }
    else
    {
        if (m_bSign)
        {
            if (m_nymId.isEmpty())
            {
                QMessageBox::warning(this, tr("Missing Signer"),
                                     tr("No signer is selected. Perhaps you need to create an identity first, to sign with."));
                return;
            }
            else
            {
                // Sign the contents.
                //
                std::string  str_nym    (m_nymId.toStdString());
                opentxs::String     strNym     (str_nym.c_str());
                opentxs::Identifier nym_id     (strNym);

                std::string  str_text   (qstrText.toStdString());
                opentxs::String     strText    (str_text.c_str());
//              opentxs::OTASCIIArmor ascText    (strText);
//              std::string  str_encoded(ascText.Get());
//              opentxs::String     strEncoded (str_encoded.c_str());
//              std::string  str_type   ("MESSAGE");

                if (!nym_id.IsEmpty())
                {
                    opentxs::OTPasswordData thePWData("Signer passphrase");

                    opentxs::Nym * pNym = opentxs::OTAPI_Wrap::OTAPI()->GetOrLoadPrivateNym(nym_id,
                                                                           false, //bChecking=false
                                                                           __FUNCTION__,
                                                                           &thePWData);
                    if (NULL == pNym)
                    {
                        QString qstrErrorMsg = QString("%1: %2").arg(tr("Failed loading the signer; unable to continue. NymID")).arg(m_nymId);
                        QMessageBox::warning(this, tr("Failed Loading Signer"), qstrErrorMsg);
                        return;
                    }
                    else
                    {
                        // FOR VERIFY STEP:
    //                  inline opentxs::String & opentxs::OTSignedFile::GetFilePayload()                       { return m_strSignedFilePayload;   }

                        opentxs::String     strSignedOutput;
                        opentxs::OTSignedFile theSignedFile;

                        theSignedFile.SetSignerNymID(strNym);

                        theSignedFile.SetFilePayload(strText);
                        theSignedFile.SignContract(*pNym, &thePWData);
                        theSignedFile.SaveContract();
                        theSignedFile.SaveContractRaw(strSignedOutput);

                        // Set the result onto qstrText
                        //
                        if (!strSignedOutput.Exists())
                        {
                            QMessageBox::warning(this, tr("Signing Failed"),
                                                 tr("Failed trying to sign, using the selected identity."));
                            return;
                        }
                        else if (!theSignedFile.VerifySignature(*pNym))
                        {
                            QMessageBox::warning(this, tr("Test Verification Failed"),
                                                 tr("Failed trying to test verify, immediately after signing. Trying authentication key..."));

                            if (!theSignedFile.VerifySigAuthent(*pNym))
                            {
                                QMessageBox::warning(this, tr("Authent Test Also Failed"),
                                                     tr("Failed trying to verify signature with authentication key as well."));
                                return;
                            }
                            else
                                QMessageBox::information(this, tr("SUCCESS USING AUTHENTICATION KEY"), tr("Tried authent key instead of signing key, and it worked!"));
                        }
                        else
                        {
                            std::string str_signed_output(strSignedOutput.Get());
                            qstrText = QString::fromStdString(str_signed_output);
                        }
                    } // else (we have pNym.)
                }
//              std::string  str_output (opentxs::OTAPI_Wrap::It()->FlatSign(str_nym, str_encoded, str_type));
            }
        }
        // --------------------------------
        // Encrypt qstrText and pop up a dialog with the encrypted result.
        //
        if (m_bEncrypt)
        {
            if (ui->listWidgetAdded->count() > 0)
            {
                std::set<const opentxs::Nym*> setRecipients;
                bool      bRecipientsShouldBeAvailable = false;

                // Loop through each NymID in listWidgetAdded, and put them on a opentxs::setOfNyms
                // so we can pass them along to opentxs::OTEnvelope (and so we can clean them up afterwards.)
                // UPDATE: Can't clean them up! Because the wallet only owns private nyms, not public
                // ones, we never know for sure which ones are safe to erase. TODO: Fix in OT by using
                // shared_ptr.
                //
                for (int nIndex = 0; nIndex < ui->listWidgetAdded->count(); ++nIndex)
                {
                    bRecipientsShouldBeAvailable = true;

                    QListWidgetItem   * pItem    = ui->listWidgetAdded->item(nIndex);
                    QVariant            qvarItem = pItem->data(Qt::UserRole);
                    QString             qstrNymID(qvarItem.toString());
                    std::string         str_nym(qstrNymID.toStdString());
                    opentxs::String     strNym(str_nym.c_str());
                    opentxs::Identifier nym_id(strNym);

                    if (!nym_id.IsEmpty())
                    {
                        opentxs::OTPasswordData thePWData("Sometimes need to load private part of nym in order to use its public key. (Fix that!)");

                        const opentxs::Nym * pNym = opentxs::OTAPI_Wrap::OTAPI()->GetOrLoadNym(nym_id,
                                                                               false, //bChecking=false
                                                                               __FUNCTION__,
                                                                               &thePWData);
                        if (NULL == pNym)
                        {
                            QString qstrErrorMsg = QString("%1: %2").arg(tr("Failed loading a recipient; attempting to continue without. NymID")).arg(qstrNymID);

                            QMessageBox::warning(this, tr("Failed Loading Recipient"), qstrErrorMsg);
                        }
                        else
                        {
                            setRecipients.insert(setRecipients.begin(), pNym);
                        }
                    }
                    // qstrNymID will be passed to opentxs::OTEnvelope on its recipient list.
                } // for (selected Nyms.)
                // ---------------------------------------------------
                // We might also want to encrypt to the Signer's Nym, if there is one.
                // We'll default this to ON, but give users the choice to deactivate it.
                //
                if (ui->checkBoxAlso->isVisible() &&
                    ui->checkBoxAlso->isEnabled() &&
                    ui->checkBoxAlso->isChecked() &&
                    !m_nymId.isEmpty())
                {
                    std::string str_signer_nym(m_nymId.toStdString());
                    opentxs::String strSignerNymID(str_signer_nym.c_str());
                    bool bSignerIsAlreadyThere = false;

                    //FOR_EACH(opentxs::setOfNyms(), setRecipients) // See if it's already there, in which case we don't need to do anything else.
                    for(auto it = setRecipients.begin(); it != setRecipients.end(); ++ it)
                    {
                        const opentxs::Nym       * pNym = *it;
                        opentxs::String            strNymID;
                        pNym->GetIdentifier(strNymID);

                        if (strSignerNymID.Compare(strNymID))
                            bSignerIsAlreadyThere = true;
                    }
                    // -------------------------
                    if (!bSignerIsAlreadyThere) // Not already there? Add signer to list of recipients.
                    {
                        bRecipientsShouldBeAvailable = true;

                        opentxs::Identifier signer_nym_id(strSignerNymID);

                        if (!signer_nym_id.IsEmpty())
                        {
                            opentxs::OTPasswordData thePWData("Sometimes need to load private part of nym in order to use its public key. (Fix that!)");

                            auto pNym =
                                opentxs::App::Me().Contract().Nym(signer_nym_id);
                            if (!pNym)
                            {
                                QString qstrErrorMsg = QString("%1: %2").
                                        arg(tr("Failed trying to load the signer; attempting to continue without. NymID")).arg(m_nymId);
                                QMessageBox::warning(this, tr("Failed Loading Signer"), qstrErrorMsg);
                            }
                            else
                            {
                                setRecipients.insert(setRecipients.begin(), pNym.get());
                            }
                        }
                    }
                }
                // ---------------------------------------------------
                if (setRecipients.size() > 0)
                {
                    opentxs::OTEnvelope theEnvelope;
                    opentxs::String   strInput(qstrText.toStdString().c_str());

                    if (!theEnvelope.Seal(setRecipients, strInput))
                    {
                        QMessageBox::warning(this, tr("Encryption Failed"),
                                             tr("Failed trying to encrypt message."));
                        return;
                    }
                    else
                    {
                        // Success encrypting!
                        //
                        opentxs::String     strOutput;
                        opentxs::OTASCIIArmor ascCiphertext(theEnvelope);

                        if (ascCiphertext.WriteArmoredString(strOutput, "ENVELOPE")) // -----BEGIN OT ARMORED ENVELOPE-----
                        {
                            std::string str_output(strOutput.Get());
                            qstrText = QString::fromStdString(str_output);
                        }
                    }
                }
                else if (bRecipientsShouldBeAvailable) // They should be, but they weren't.
                {
                    QMessageBox::warning(this, tr("Failed Loading Recipients"),
                                         tr("Due to failure loading any of the recipients, unable to commence."));
                    return;
                }
            } // if (listItems.size() > 0)
        } // if (m_bEncrypt)
        // -------------------
        // If it's NOT encrypted, but it IS signed, then we want to OT ARMOR it as well.
        // (We don't have to if it's encrypted, since that process already armors it for us.
        //  But this is for the case where it's signed and NOT encrypted.)
        //
        else if (m_bSign && !qstrText.isEmpty())
        {
            std::string  str_text(qstrText.toStdString());
            opentxs::String     strText (str_text.c_str());
            opentxs::String     strOutput;
            opentxs::OTASCIIArmor ascText (strText);

            if (ascText.WriteArmoredString(strOutput, "SIGNED FILE")) // -----BEGIN OT ARMORED SIGNED FILE-----
            {
                std::string str_output(strOutput.Get());
                qstrText = QString::fromStdString(str_output);
            }
        }
        // -----------------------------------------------
        // if qstrText still contains something, pop up a dialog to display the result to the user.
        //
        if (!qstrText.isEmpty())
        {
            QString qstrType("Output:");

            if (m_bSign)
            {
                qstrType = QString(tr("Signed Output:"));
            }
            // -----------
            if (m_bEncrypt)
            {
                if (m_bSign)
                    qstrType = QString(tr("Signed and Encrypted Output:"));
                else
                    qstrType = QString(tr("Encrypted Output:"));
            }
            // -----------
            QString qstrSubTitle(tr("Be sure to copy it somewhere before closing this dialog."));
            // -----------
            // Pop up the result dialog.
            //
            DlgExportedToPass dlgExported(this, qstrText,
                                          qstrType,
                                          qstrSubTitle, false);
            dlgExported.exec();
        }
    } // if (!qstrText.isEmpty())
}