You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kdirstat/kdirstat/kfeedback.cpp

501 lines
9.3 KiB

/*
* File name: kfeedback.cpp
* Summary: User feedback form
* License: LGPL - See file COPYING.LIB for details.
* Author: Stefan Hundhammer <sh@suse.de>
*
* Updated: 2004-11-23
*/
#include <tqheader.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqmultilineedit.h>
#include <tqhbox.h>
#include <tdeglobal.h>
#include <kapp.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <tdeaboutdata.h>
#include <kiconloader.h>
#include <kurl.h>
#include "kfeedback.h"
KFeedbackDialog::KFeedbackDialog( const TQString & feedbackMailAddress,
const TQString & helpTopic )
: KDialogBase( Plain, // dialogFace
i18n( "Feedback" ), // caption
Apply | Cancel
| ( helpTopic.isEmpty() ? 0 : (int) Help ), // buttonMask
Apply ) // defaultButton
{
TQVBoxLayout * layout = new TQVBoxLayout( plainPage(), 0, spacingHint() );
setButtonApply( KGuiItem( i18n( "&Mail this..." ) ) );
if ( ! helpTopic.isEmpty() )
setHelp( helpTopic );
_form = new KFeedbackForm( feedbackMailAddress, plainPage() );
TQ_CHECK_PTR( _form );
layout->addWidget( _form );
checkSendButton();
connect( this, TQT_SIGNAL( applyClicked() ),
_form, TQT_SLOT ( sendMail() ) );
connect( _form, TQT_SIGNAL( mailSent() ),
this, TQT_SLOT ( hide() ) );
connect( _form, TQT_SIGNAL( mailSent() ),
this, TQT_SIGNAL( mailSent() ) );
connect( _form, TQT_SIGNAL( checkComplete() ),
this, TQT_SLOT ( checkSendButton() ) );
}
KFeedbackDialog::~KFeedbackDialog()
{
// NOP
}
void
KFeedbackDialog::checkSendButton()
{
enableButtonApply( _form->readyToSend() );
}
KFeedbackForm::KFeedbackForm( const TQString & feedbackMailAddress,
TQWidget * parent )
: TQVBox( parent )
, _feedbackMailAddress( feedbackMailAddress )
{
//
// Explanation above the question list
//
TQLabel * label = new TQLabel( i18n( "<p><b>Please tell us your opinion about this program.</b></p>"
"<p>You will be able to review everything in your mailer "
"before any mail is sent.<br>"
"Nothing will be sent behind your back.</p>"
), this );
//
// Question list
//
_questionList = new KFeedbackQuestionList( this );
TQ_CHECK_PTR( _questionList );
connect( _questionList, TQT_SIGNAL( checkComplete() ),
this, TQT_SLOT ( slotCheckComplete() ) );
//
// Explanation below the question list
//
TQHBox * hbox = new TQHBox( this );
TQ_CHECK_PTR( hbox );
TQSizePolicy pol( TQSizePolicy::Fixed, TQSizePolicy::Fixed ); // hor / vert
label = new TQLabel( i18n( "Questions marked with " ), hbox );
TQ_CHECK_PTR( label );
label->setSizePolicy( pol );
label = new TQLabel( hbox );
TQ_CHECK_PTR( label );
label->setPixmap( TDEGlobal::iconLoader()->loadIcon( "edit", TDEIcon::Small ) );
label->setSizePolicy( pol );
label = new TQLabel( i18n( " must be answered before a mail can be sent.") , hbox );
TQ_CHECK_PTR( label );
label->setSizePolicy( pol );
new TQWidget( hbox ); // Fill any leftover space to the right.
//
// Free-text comment field
//
label = new TQLabel( "\n" + i18n( "&Additional Comments:" ), this ); TQ_CHECK_PTR( label );
_comment = new TQMultiLineEdit( this ); TQ_CHECK_PTR( _comment );
label->setBuddy( _comment );
_comment->setWordWrap( TQMultiLineEdit::FixedColumnWidth );
_comment->setWrapColumnOrWidth( 70 );
}
KFeedbackForm::~KFeedbackForm()
{
// NOP
}
void
KFeedbackForm::sendMail()
{
//
// Build mail subject
//
TQString subject;
const TDEAboutData * aboutData = TDEGlobal::instance()->aboutData();
if ( aboutData )
subject = aboutData->programName() + "-" + aboutData->version();
else
subject = kapp->name();
subject = "[kde-feedback] " + subject + " user feedback";
//
// Build mail body
//
TQString body = subject + "\n\n"
+ formatComment()
+ _questionList->result();
//
// Build "mailto:" URL from all this
//
KURL mail;
mail.setProtocol( "mailto" );
mail.setPath( _feedbackMailAddress );
mail.setQuery( "?subject=" + KURL::encode_string( subject ) +
"&body=" + KURL::encode_string( body ) );
// TODO: Check for maximum command line length.
//
// The hard part with this is how to get this from all that 'autoconf'
// stuff into 'config.h' or some other include file without hardcoding
// anything - this is too system dependent.
//
// Actually send mail
//
kapp->invokeMailer( mail );
emit mailSent();
}
void
KFeedbackForm::slotCheckComplete()
{
emit checkComplete();
}
TQString
KFeedbackForm::formatComment()
{
TQString result = _comment->text();
if ( ! result.isEmpty() )
{
result = "<comment>\n" + result + "\n</comment>\n\n";
}
return result;
}
bool
KFeedbackForm::readyToSend()
{
return _questionList->isComplete();
}
KFeedbackQuestionList::KFeedbackQuestionList( TQWidget *parent )
: TQListView( parent )
{
addColumn( "" );
header()->hide();
}
KFeedbackQuestionList::~KFeedbackQuestionList()
{
// NOP
}
bool
KFeedbackQuestionList::isComplete()
{
KFeedbackQuestion * question = firstQuestion();
while ( question )
{
if ( question->isRequired() && ! question->isAnswered() )
return false;
question = question->nextQuestion();
}
return true;
}
TQString
KFeedbackQuestionList::result()
{
TQString res;
KFeedbackQuestion * question = firstQuestion();
while ( question )
{
res += question->result();
question = question->nextQuestion();
}
return res;
}
KFeedbackQuestion *
KFeedbackQuestionList::addQuestion( const TQString & text,
const TQString & id,
bool exclusiveAnswer,
bool required )
{
KFeedbackQuestion * question = new KFeedbackQuestion( this, text, id,
exclusiveAnswer,
required );
TQ_CHECK_PTR( question );
return question;
}
void
KFeedbackQuestionList::addYesNoQuestion( const TQString & text,
const TQString & id,
bool required )
{
KFeedbackQuestion * question = new KFeedbackQuestion( this, text, id,
true, // exclusive
required );
TQ_CHECK_PTR( question );
question->addAnswer( i18n( "yes" ), "yes" );
question->addAnswer( i18n( "no" ), "no" );
}
void
KFeedbackQuestionList::questionAnswered()
{
emit checkComplete();
}
void
KFeedbackQuestionList::questionAdded( KFeedbackQuestion * question)
{
if ( question->isRequired() )
emit checkComplete();
}
static int nextNo = 0;
KFeedbackQuestion::KFeedbackQuestion( KFeedbackQuestionList * parent,
const TQString & text,
const TQString & id,
bool exclusiveAnswer,
bool required,
bool open )
: TQCheckListItem( parent, text )
, _id( id )
, _exclusiveAnswer( exclusiveAnswer )
, _required( required )
{
if ( required )
{
setPixmap( 0, TDEGlobal::iconLoader()->loadIcon( "edit", TDEIcon::Small ) );
}
setOpen( open );
_no = nextNo++;
parent->questionAdded( this );
}
void
KFeedbackQuestion::addAnswer( const TQString & text,
const TQString & id )
{
new KFeedbackAnswer( this, text, id, _exclusiveAnswer );
}
bool
KFeedbackQuestion::isAnswered()
{
if ( ! _exclusiveAnswer )
{
/**
* If any number of answers is permitted for this question, this
* question is always considered to be answered.
**/
return true;
}
/**
* If this question requires an exclusive answer, exactly one of them
* should be checked. We don't need to bother about more than one being
* checked here - TQListView does that for us.
**/
KFeedbackAnswer *answer = firstAnswer();
while ( answer )
{
if ( answer->isChecked() )
return true;
answer = answer->nextAnswer();
}
return false;
}
TQString
KFeedbackQuestion::result()
{
TQString res;
int answers = 0;
KFeedbackAnswer *answer = firstAnswer();
while ( answer )
{
if ( answer->isChecked() )
{
res += _id + "=\"" + answer->id() + "\"\n";
answers++;
}
answer = answer->nextAnswer();
}
if ( answers > 1 )
{
res = "\n" + res + "\n";
}
return res;
}
TQString
KFeedbackQuestion::text()
{
return TQCheckListItem::text(0);
}
TQString
KFeedbackQuestion::key( int, bool ) const
{
TQString no;
no.sprintf( "%08d", _no );
return no;
}
KFeedbackQuestionList *
KFeedbackQuestion::questionList() const
{
return dynamic_cast<KFeedbackQuestionList *>( listView() );
}
KFeedbackAnswer::KFeedbackAnswer( KFeedbackQuestion * parent,
const TQString & text,
const TQString & id,
bool exclusive )
: TQCheckListItem( parent,
text,
exclusive
? TQCheckListItem::RadioButton
: TQCheckListItem::CheckBox )
, _id( id )
{
_no = nextNo++;
}
TQString
KFeedbackAnswer::text()
{
return TQCheckListItem::text(0);
}
TQString
KFeedbackAnswer::key( int, bool ) const
{
TQString no;
no.sprintf( "%08d", _no );
return no;
}
void
KFeedbackAnswer::stateChange( bool newState )
{
if ( newState && question()->isRequired() )
{
KFeedbackQuestionList * list = question()->questionList();
if ( list )
list->questionAnswered();
}
}
#include "kfeedback.moc"
// EOF