/*
Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
This file is part of CamCOPS.
CamCOPS 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 3 of the License, or
(at your option) any later version.
CamCOPS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.
*/
// This task doesn't bother with XML downloads or translation; it's hard-coded.
#include "deakins1healthreview.h"
#include "core/camcopsapp.h"
#include "common/textconst.h"
#include "maths/mathfunc.h"
#include "questionnairelib/commonoptions.h"
#include "questionnairelib/questionnaire.h"
#include "questionnairelib/qulineeditinteger.h"
#include "questionnairelib/qumcq.h"
#include "questionnairelib/qumcqgrid.h"
#include "questionnairelib/qumcqgridsingleboolean.h"
#include "questionnairelib/qumultipleresponse.h"
#include "questionnairelib/qutext.h"
#include "questionnairelib/qutextedit.h"
#include "tasklib/taskfactory.h"
#include "tasklib/taskregistrar.h"
#include "tasks/gmcpq.h" // for ethnicity options
using mathfunc::noneNull;
const QString DeakinS1HealthReview::DEAKIN_S1_HEALTHREVIEW_TABLENAME(
"deakin_1_healthreview");
const QString ETHNICITY("ethnicity");
const QString ETHNICITY_TEXT("ethnicity_text");
const QString ETHNICITY_OTHER_DETAILS("ethnicity_other_details");
const QString HANDEDNESS("handedness");
const QString EDUCATION("education");
const QString ALLERGIES("allergies");
const QString ALLERGY_ASTHMA("allergy_asthma");
const QString ALLERGY_POLLEN_DUST("allergy_pollen_dust");
const QString ALLERGY_DERMATITIS("allergy_dermatitis");
const QString ALLERGY_FOOD("allergy_food");
const QString ALLERGY_DANDER("allergy_dander");
const QString ALLERGY_OTHER("allergy_other");
const QString ALLERGY_DETAILS("allergy_details");
const QString VACCINATIONS_LAST3MONTHS("vaccinations_last3months");
const QString VACCINATION_DETAILS("vaccination_details");
const QString INFECTIONS_LAST3MONTHS("infections_last3months");
const QString INFECTION_RECENT_RESPIRATORY("infection_recent_respiratory");
const QString INFECTION_RECENT_GASTROENTERITIS("infection_recent_gastroenteritis");
const QString INFECTION_RECENT_URINARY("infection_recent_urinary");
const QString INFECTION_RECENT_SEXUAL("infection_recent_sexual");
const QString INFECTION_RECENT_HEPATITIS("infection_recent_hepatitis");
const QString INFECTION_RECENT_OTHER("infection_recent_other");
const QString INFECTION_RECENT_DETAILS("infection_recent_details");
const QString INFECTIONS_CHRONIC("infections_chronic");
const QString INFECTION_CHRONIC_RESPIRATORY("infection_chronic_respiratory");
const QString INFECTION_CHRONIC_GASTROENTERITIS("infection_chronic_gastroenteritis");
const QString INFECTION_CHRONIC_URINARY("infection_chronic_urinary");
const QString INFECTION_CHRONIC_SEXUAL("infection_chronic_sexual");
const QString INFECTION_CHRONIC_HEPATITIS("infection_chronic_hepatitis");
const QString INFECTION_CHRONIC_OTHER("infection_chronic_other");
const QString INFECTION_CHRONIC_DETAILS("infection_chronic_details");
const QString IMMUNE_DISORDERS("immune_disorders");
const QString IMMUNITY_MS("immunity_ms");
const QString IMMUNITY_SLE("immunity_sle");
const QString IMMUNITY_ARTHRITIS("immunity_arthritis");
const QString IMMUNITY_HIV("immunity_hiv");
const QString IMMUNITY_GRAVES("immunity_graves");
const QString IMMUNITY_DIABETES("immunity_diabetes");
const QString IMMUNITY_OTHER("immunity_other");
const QString IMMUNITY_DETAILS("immunity_details");
const QString FAMILY_HISTORY("family_history");
const QString FAMILYHISTORY_MS("familyhistory_ms");
const QString FAMILYHISTORY_SLE("familyhistory_sle");
const QString FAMILYHISTORY_ARTHRITIS("familyhistory_arthritis");
const QString FAMILYHISTORY_GRAVES("familyhistory_graves");
const QString FAMILYHISTORY_DIABETES("familyhistory_diabetes");
const QString FAMILYHISTORY_PSYCHOSIS_SZ("familyhistory_psychosis_sz");
const QString FAMILYHISTORY_BIPOLAR("familyhistory_bipolar");
const QString FAMILYHISTORY_DETAILS("familyhistory_details");
const QString HEALTH_ANYTHING_ELSE("health_anything_else");
const QString HEALTH_ANYTHING_ELSE_DETAILS("health_anything_else_details");
const QString DRUG_HISTORY("drug_history");
const QString FIRST_ANTIPSYCHOTIC_MEDICATION("first_antipsychotic_medication");
const QString RECREATIONAL_DRUG_IN_LAST_3_MONTHS("recreational_drug_in_last_3_months");
const QString RECDRUG_TOBACCO_FREQUENCY("recdrug_tobacco_frequency");
const QString RECDRUG_TOBACCO_CIGSPERWEEK("recdrug_tobacco_cigsperweek");
const QString RECDRUG_TOBACCO_PREVHEAVY("recdrug_tobacco_prevheavy");
const QString RECDRUG_CANNABIS_FREQUENCY("recdrug_cannabis_frequency");
const QString RECDRUG_CANNABIS_JOINTSPERWEEK("recdrug_cannabis_jointsperweek");
const QString RECDRUG_CANNABIS_PREVHEAVY("recdrug_cannabis_prevheavy");
const QString RECDRUG_ALCOHOL_FREQUENCY("recdrug_alcohol_frequency");
const QString RECDRUG_ALCOHOL_UNITSPERWEEK("recdrug_alcohol_unitsperweek");
const QString RECDRUG_ALCOHOL_PREVHEAVY("recdrug_alcohol_prevheavy");
const QString RECDRUG_MDMA_FREQUENCY("recdrug_mdma_frequency");
const QString RECDRUG_MDMA_PREVHEAVY("recdrug_mdma_prevheavy");
const QString RECDRUG_COCAINE_FREQUENCY("recdrug_cocaine_frequency");
const QString RECDRUG_COCAINE_PREVHEAVY("recdrug_cocaine_prevheavy");
const QString RECDRUG_CRACK_FREQUENCY("recdrug_crack_frequency");
const QString RECDRUG_CRACK_PREVHEAVY("recdrug_crack_prevheavy");
const QString RECDRUG_HEROIN_FREQUENCY("recdrug_heroin_frequency");
const QString RECDRUG_HEROIN_PREVHEAVY("recdrug_heroin_prevheavy");
const QString RECDRUG_METHADONE_FREQUENCY("recdrug_methadone_frequency");
const QString RECDRUG_METHADONE_PREVHEAVY("recdrug_methadone_prevheavy");
const QString RECDRUG_AMPHETAMINES_FREQUENCY("recdrug_amphetamines_frequency");
const QString RECDRUG_AMPHETAMINES_PREVHEAVY("recdrug_amphetamines_prevheavy");
const QString RECDRUG_BENZODIAZEPINES_FREQUENCY("recdrug_benzodiazepines_frequency");
const QString RECDRUG_BENZODIAZEPINES_PREVHEAVY("recdrug_benzodiazepines_prevheavy");
const QString RECDRUG_KETAMINE_FREQUENCY("recdrug_ketamine_frequency");
const QString RECDRUG_KETAMINE_PREVHEAVY("recdrug_ketamine_prevheavy");
const QString RECDRUG_LEGALHIGHS_FREQUENCY("recdrug_legalhighs_frequency");
const QString RECDRUG_LEGALHIGHS_PREVHEAVY("recdrug_legalhighs_prevheavy");
const QString RECDRUG_INHALANTS_FREQUENCY("recdrug_inhalants_frequency");
const QString RECDRUG_INHALANTS_PREVHEAVY("recdrug_inhalants_prevheavy");
const QString RECDRUG_HALLUCINOGENS_FREQUENCY("recdrug_hallucinogens_frequency");
const QString RECDRUG_HALLUCINOGENS_PREVHEAVY("recdrug_hallucinogens_prevheavy");
const QString RECDRUG_DETAILS("recdrug_details");
const QString RECDRUG_PREVHEAVY("recdrug_prevheavy");
const QString RECDRUG_PREVHEAVY_DETAILS("recdrug_prevheavy_details");
const QString MRI_CLAUSTROPHOBIC("mri_claustrophobic");
const QString MRI_DIFFICULTY_LYING_1_HOUR("mri_difficulty_lying_1_hour");
const QString MRI_NONREMOVABLE_METAL("mri_nonremovable_metal");
const QString MRI_METAL_FROM_OPERATIONS("mri_metal_from_operations");
const QString MRI_TATTOOS_NICOTINE_PATCHES("mri_tattoos_nicotine_patches");
const QString MRI_WORKED_WITH_METAL("mri_worked_with_metal");
const QString MRI_PREVIOUS_BRAIN_SCAN("mri_previous_brain_scan");
const QString MRI_PREVIOUS_BRAIN_SCAN_DETAILS("mri_previous_brain_scan_details");
const QString OTHER_RELEVANT_THINGS("other_relevant_things");
const QString OTHER_RELEVANT_THINGS_DETAILS("other_relevant_things_details");
const QString WILLING_TO_PARTICIPATE_IN_FURTHER_STUDIES("willing_to_participate_in_further_studies");
const QString STR_DETAILS_IF_YES("If you answered YES, please give details:");
const QString STR_DETAILS("Details:");
const QString TICK_ANY_THAT_APPLY("Tick any that apply:");
const QStringList DRUGLIST{ // order is important
"tobacco",
"cannabis",
"alcohol",
"Ecstasy (MDMA)",
"cocaine",
"crack cocaine",
"amphetamines",
"heroin",
"methadone (heroin substitute)",
"benzodiazepines",
"ketamine",
"legal highs (e.g. Salvia)",
"inhalants",
"hallucinogens",
};
const QStringList INFECTIONLIST{ // order is important
"respiratory infection",
"gastroenteritis",
"urinary tract infection",
"sexually transmitted infection",
"hepatitis",
"other"
};
const QString PT_ETHNICITY("eth");
const QString PT_ALLERGY("all");
const QString PT_VACCINES("vac");
const QString PT_ACUTE_INFECTIONS("acinf");
const QString PT_CHRONIC_INFECTIONS("chinf");
const QString PT_IMMUNE("imm");
const QString PT_FH("fh");
const QString PT_HEALTH_OTHER("ho");
const QString PT_RECDRUGS("recdrug");
const QString PT_MRI("mri");
const QString ET_ETHNICITY_OTHER("eth_other");
const QString ET_ALLERGY("all");
const QString ET_VACCINES("vacc");
const QString ET_ACUTE_INFECTIONS("acinf");
const QString ET_CHRONIC_INFECTIONS("chinf");
const QString ET_IMMUNE("imm");
const QString ET_FH("fh");
const QString ET_HEALTH_OTHER("ho");
const QString ET_RECDRUGS("recdrug");
const QString ET_PREVSCAN("prevscan");
const QString ET_OTHERDETAILS("otherdetails");
void initializeDeakinS1HealthReview(TaskFactory& factory)
{
static TaskRegistrar<DeakinS1HealthReview> registered(factory);
}
DeakinS1HealthReview::DeakinS1HealthReview(
CamcopsApp& app, DatabaseManager& db, const int load_pk) :
Task(app, db, DEAKIN_S1_HEALTHREVIEW_TABLENAME, false, false, false) // ... anon, clin, resp
{
addField(ETHNICITY, QMetaType::fromType<int>());
addField(ETHNICITY_TEXT, QMetaType::fromType<QString>()); // SEEMS TO BE UNUSED!
addField(ETHNICITY_OTHER_DETAILS, QMetaType::fromType<QString>());
addField(HANDEDNESS, QMetaType::fromType<QString>());
addField(EDUCATION, QMetaType::fromType<QString>());
addField(ALLERGIES, QMetaType::fromType<bool>());
addField(ALLERGY_ASTHMA, QMetaType::fromType<bool>());
addField(ALLERGY_POLLEN_DUST, QMetaType::fromType<bool>());
addField(ALLERGY_DERMATITIS, QMetaType::fromType<bool>());
addField(ALLERGY_FOOD, QMetaType::fromType<bool>());
addField(ALLERGY_DANDER, QMetaType::fromType<bool>());
addField(ALLERGY_OTHER, QMetaType::fromType<bool>());
addField(ALLERGY_DETAILS, QMetaType::fromType<QString>());
addField(VACCINATIONS_LAST3MONTHS, QMetaType::fromType<bool>());
addField(VACCINATION_DETAILS, QMetaType::fromType<QString>());
addField(INFECTIONS_LAST3MONTHS, QMetaType::fromType<bool>());
addField(INFECTION_RECENT_RESPIRATORY, QMetaType::fromType<bool>());
addField(INFECTION_RECENT_GASTROENTERITIS, QMetaType::fromType<bool>());
addField(INFECTION_RECENT_URINARY, QMetaType::fromType<bool>());
addField(INFECTION_RECENT_SEXUAL, QMetaType::fromType<bool>());
addField(INFECTION_RECENT_HEPATITIS, QMetaType::fromType<bool>());
addField(INFECTION_RECENT_OTHER, QMetaType::fromType<bool>());
addField(INFECTION_RECENT_DETAILS, QMetaType::fromType<QString>());
addField(INFECTIONS_CHRONIC, QMetaType::fromType<bool>());
addField(INFECTION_CHRONIC_RESPIRATORY, QMetaType::fromType<bool>());
addField(INFECTION_CHRONIC_GASTROENTERITIS, QMetaType::fromType<bool>());
addField(INFECTION_CHRONIC_URINARY, QMetaType::fromType<bool>());
addField(INFECTION_CHRONIC_SEXUAL, QMetaType::fromType<bool>());
addField(INFECTION_CHRONIC_HEPATITIS, QMetaType::fromType<bool>());
addField(INFECTION_CHRONIC_OTHER, QMetaType::fromType<bool>());
addField(INFECTION_CHRONIC_DETAILS, QMetaType::fromType<QString>());
addField(IMMUNE_DISORDERS, QMetaType::fromType<bool>());
addField(IMMUNITY_MS, QMetaType::fromType<bool>());
addField(IMMUNITY_SLE, QMetaType::fromType<bool>());
addField(IMMUNITY_ARTHRITIS, QMetaType::fromType<bool>());
addField(IMMUNITY_HIV, QMetaType::fromType<bool>());
addField(IMMUNITY_GRAVES, QMetaType::fromType<bool>());
addField(IMMUNITY_DIABETES, QMetaType::fromType<bool>());
addField(IMMUNITY_OTHER, QMetaType::fromType<bool>());
addField(IMMUNITY_DETAILS, QMetaType::fromType<QString>());
addField(FAMILY_HISTORY, QMetaType::fromType<bool>());
addField(FAMILYHISTORY_MS, QMetaType::fromType<bool>());
addField(FAMILYHISTORY_SLE, QMetaType::fromType<bool>());
addField(FAMILYHISTORY_ARTHRITIS, QMetaType::fromType<bool>());
addField(FAMILYHISTORY_GRAVES, QMetaType::fromType<bool>());
addField(FAMILYHISTORY_DIABETES, QMetaType::fromType<bool>());
addField(FAMILYHISTORY_PSYCHOSIS_SZ, QMetaType::fromType<bool>());
addField(FAMILYHISTORY_BIPOLAR, QMetaType::fromType<bool>());
addField(FAMILYHISTORY_DETAILS, QMetaType::fromType<QString>());
addField(HEALTH_ANYTHING_ELSE, QMetaType::fromType<bool>());
addField(HEALTH_ANYTHING_ELSE_DETAILS, QMetaType::fromType<QString>());
addField(DRUG_HISTORY, QMetaType::fromType<QString>());
addField(FIRST_ANTIPSYCHOTIC_MEDICATION, QMetaType::fromType<QString>());
addField(RECREATIONAL_DRUG_IN_LAST_3_MONTHS, QMetaType::fromType<bool>());
addField(RECDRUG_TOBACCO_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_TOBACCO_CIGSPERWEEK, QMetaType::fromType<int>());
addField(RECDRUG_TOBACCO_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_CANNABIS_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_CANNABIS_JOINTSPERWEEK, QMetaType::fromType<int>());
addField(RECDRUG_CANNABIS_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_ALCOHOL_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_ALCOHOL_UNITSPERWEEK, QMetaType::fromType<int>());
addField(RECDRUG_ALCOHOL_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_MDMA_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_MDMA_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_COCAINE_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_COCAINE_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_CRACK_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_CRACK_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_HEROIN_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_HEROIN_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_METHADONE_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_METHADONE_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_AMPHETAMINES_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_AMPHETAMINES_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_BENZODIAZEPINES_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_BENZODIAZEPINES_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_KETAMINE_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_KETAMINE_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_LEGALHIGHS_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_LEGALHIGHS_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_INHALANTS_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_INHALANTS_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_HALLUCINOGENS_FREQUENCY, QMetaType::fromType<int>());
addField(RECDRUG_HALLUCINOGENS_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_DETAILS, QMetaType::fromType<QString>());
addField(RECDRUG_PREVHEAVY, QMetaType::fromType<bool>());
addField(RECDRUG_PREVHEAVY_DETAILS, QMetaType::fromType<QString>());
addField(MRI_CLAUSTROPHOBIC, QMetaType::fromType<bool>());
addField(MRI_DIFFICULTY_LYING_1_HOUR, QMetaType::fromType<bool>());
addField(MRI_NONREMOVABLE_METAL, QMetaType::fromType<bool>());
addField(MRI_METAL_FROM_OPERATIONS, QMetaType::fromType<bool>());
addField(MRI_TATTOOS_NICOTINE_PATCHES, QMetaType::fromType<bool>());
addField(MRI_WORKED_WITH_METAL, QMetaType::fromType<bool>());
addField(MRI_PREVIOUS_BRAIN_SCAN, QMetaType::fromType<bool>());
addField(MRI_PREVIOUS_BRAIN_SCAN_DETAILS, QMetaType::fromType<QString>());
addField(OTHER_RELEVANT_THINGS, QMetaType::fromType<bool>());
addField(OTHER_RELEVANT_THINGS_DETAILS, QMetaType::fromType<QString>());
addField(WILLING_TO_PARTICIPATE_IN_FURTHER_STUDIES, QMetaType::fromType<bool>());
load(load_pk); // MUST ALWAYS CALL from derived Task constructor.
}
// ============================================================================
// Class info
// ============================================================================
QString DeakinS1HealthReview::shortname() const
{
return "Deakin_S1_HealthReview";
}
QString DeakinS1HealthReview::longname() const
{
return tr("Deakin JB — Antibody-mediated psychosis study — health review");
}
QString DeakinS1HealthReview::description() const
{
return tr("Health review for antibody-mediated psychosis study.");
}
QString DeakinS1HealthReview::infoFilenameStem() const
{
return "deakin_s1_healthreview";
}
// ============================================================================
// Instance info
// ============================================================================
bool DeakinS1HealthReview::isComplete() const
{
return noneNull(values(QStringList{
ETHNICITY,
HANDEDNESS,
EDUCATION,
ALLERGIES,
VACCINATIONS_LAST3MONTHS,
INFECTIONS_LAST3MONTHS,
INFECTIONS_CHRONIC,
IMMUNE_DISORDERS,
HEALTH_ANYTHING_ELSE,
RECREATIONAL_DRUG_IN_LAST_3_MONTHS,
RECDRUG_PREVHEAVY,
MRI_CLAUSTROPHOBIC,
MRI_DIFFICULTY_LYING_1_HOUR,
MRI_NONREMOVABLE_METAL,
MRI_METAL_FROM_OPERATIONS,
MRI_TATTOOS_NICOTINE_PATCHES,
MRI_WORKED_WITH_METAL,
MRI_PREVIOUS_BRAIN_SCAN,
OTHER_RELEVANT_THINGS,
WILLING_TO_PARTICIPATE_IN_FURTHER_STUDIES,
}));
}
QStringList DeakinS1HealthReview::summary() const
{
return QStringList{TextConst::noSummarySeeFacsimile()};
}
QStringList DeakinS1HealthReview::detail() const
{
return completenessInfo() + summary();
}
OpenableWidget* DeakinS1HealthReview::editor(const bool read_only)
{
const NameValueOptions yn_options = CommonOptions::yesNoBoolean();
const NameValueOptions handedness_options = NameValueOptions{
{"Left hand", "L"},
{"Right hand", "R"},
};
const NameValueOptions education_options = NameValueOptions{
{"None", "none"},
{"CSE", "cse"},
{"GCSE", "gcse"},
{"O-Level", "olevel"},
{"A-Level", "alevel"},
{"Vocational qualification, NVQ — full time", "nvq_fulltime"},
{"Vocational qualification, NVQ — part time", "nvq_parttime"},
{"Degree qualification — diploma", "degree_diploma"},
{"Degree qualification — bachelor’s", "degree_bachelor"},
{"Degree qualification — other", "degree_other"},
{"Postgraduate qualification — master’s", "postgrad_masters"},
{"Postgraduate qualification — PhD", "postgrad_phd"},
};
auto text = [](const QString& text) -> QuElement* {
return new QuText(text);
};
auto boldtext = [](const QString& text) -> QuElement* {
return (new QuText(text))->setBold();
};
auto mcq = [this](const QString& fieldname,
const NameValueOptions& options) -> QuElement* {
return new QuMcq(fieldRef(fieldname), options);
};
auto mcqhoriz = [this](const QString& fieldname,
const NameValueOptions& options) -> QuElement* {
return (new QuMcq(fieldRef(fieldname), options))->setHorizontal(true);
};
auto qf = [this](const QString& fieldname,
const QString& question) -> QuestionWithOneField {
return QuestionWithOneField(fieldRef(fieldname), question);
};
auto q2f = [this](const QString& fieldname1,
const QString& fieldname2,
const QString& question) -> QuestionWithTwoFields {
return QuestionWithTwoFields(question, fieldRef(fieldname1),
fieldRef(fieldname2));
};
auto yn = [this, &yn_options](const QString& fieldname) -> QuElement* {
return (new QuMcq(fieldRef(fieldname), yn_options))
->setHorizontal(true);
};
auto lineedit = [this](const QString& fieldname) -> QuElement* {
return new QuLineEdit(fieldRef(fieldname));
};
auto multiline = [this](const QString& fieldname,
bool mandatory = true) -> QuElement* {
return new QuTextEdit(fieldRef(fieldname, mandatory));
};
auto intedit = [this](const QString& fieldname) -> QuElement* {
return (new QuLineEditInteger(fieldRef(fieldname), 0, 1000))
->setHint("");
};
auto watch = [this](const QString& fieldname) -> void {
connect(fieldRef(fieldname).data(), &FieldRef::valueChanged,
this, &DeakinS1HealthReview::updateMandatory);
};
QVector<QuPagePtr> pages;
pages.append(QuPagePtr((new QuPage{
boldtext("Please enter your ethnicity:"),
mcq(ETHNICITY, GmcPq::ethnicityOptions(m_app)),
text(m_app.xstring(GmcPq::GMCPQ_TABLENAME, "ethnicity_other_s")),
lineedit(ETHNICITY_OTHER_DETAILS),
})->setTitle("Ethnicity")));
watch(ETHNICITY);
pages.append(QuPagePtr((new QuPage{
boldtext("I prefer to use my:"),
mcqhoriz(HANDEDNESS, handedness_options),
})->setTitle("Handedness")));
pages.append(QuPagePtr((new QuPage{
boldtext("Please enter your highest level of education, or nearest "
"equivalent:"),
mcqhoriz(EDUCATION, education_options),
})->setTitle("Education")));
QuMultipleResponse* mr_allergies = new QuMultipleResponse{
qf(ALLERGY_ASTHMA, "asthma"),
qf(ALLERGY_POLLEN_DUST, "pollen/dust"),
qf(ALLERGY_DERMATITIS, "dermatitis"),
qf(ALLERGY_FOOD, "food allergy"),
qf(ALLERGY_DANDER, "animal dander"),
qf(ALLERGY_OTHER, "other"),
};
pages.append(QuPagePtr((new QuPage{
boldtext("Do you have any allergies?"),
yn(ALLERGIES),
boldtext(STR_DETAILS_IF_YES),
mr_allergies,
text(STR_DETAILS),
multiline(ALLERGY_DETAILS),
})->setTitle("Allergies")));
watch(ALLERGIES);
watch(ALLERGY_OTHER);
connect(this, &DeakinS1HealthReview::setAllergyMinimum,
mr_allergies, &QuMultipleResponse::setMinimumAnswers);
pages.append(QuPagePtr((new QuPage{
boldtext("Have you had any vaccinations or inoculations in the last 3 "
"months?"),
yn(VACCINATIONS_LAST3MONTHS),
boldtext(STR_DETAILS_IF_YES),
text(STR_DETAILS),
multiline(VACCINATION_DETAILS),
})->setTitle("Recent vaccinations")));
connect(fieldRef(VACCINATIONS_LAST3MONTHS).data(), &FieldRef::valueChanged,
this, &DeakinS1HealthReview::updateMandatory);
QuMultipleResponse* mr_recent_infection = new QuMultipleResponse{
qf(INFECTION_RECENT_RESPIRATORY, INFECTIONLIST[0]),
qf(INFECTION_RECENT_GASTROENTERITIS, INFECTIONLIST[1]),
qf(INFECTION_RECENT_URINARY, INFECTIONLIST[2]),
qf(INFECTION_RECENT_SEXUAL, INFECTIONLIST[3]),
qf(INFECTION_RECENT_HEPATITIS, INFECTIONLIST[4]),
qf(INFECTION_RECENT_OTHER, INFECTIONLIST[5]),
};
pages.append(QuPagePtr((new QuPage{
boldtext("Have you had any infectious diseases in the last 3 months?"),
yn(INFECTIONS_LAST3MONTHS),
boldtext(STR_DETAILS_IF_YES),
mr_recent_infection,
text(STR_DETAILS),
multiline(INFECTION_RECENT_DETAILS),
})->setTitle("Recent infections")));
watch(INFECTIONS_LAST3MONTHS);
watch(INFECTION_RECENT_OTHER);
connect(this, &DeakinS1HealthReview::setRecentInfectionsMinimum,
mr_recent_infection, &QuMultipleResponse::setMinimumAnswers);
QuMultipleResponse* mr_chronic_infection = new QuMultipleResponse{
qf(INFECTION_CHRONIC_RESPIRATORY, INFECTIONLIST[0]),
qf(INFECTION_CHRONIC_GASTROENTERITIS, INFECTIONLIST[1]),
qf(INFECTION_CHRONIC_URINARY, INFECTIONLIST[2]),
qf(INFECTION_CHRONIC_SEXUAL, INFECTIONLIST[3]),
qf(INFECTION_CHRONIC_HEPATITIS, INFECTIONLIST[4]),
qf(INFECTION_CHRONIC_OTHER, INFECTIONLIST[5]),
};
pages.append(QuPagePtr((new QuPage{
boldtext("Are you currently experiencing or have you ever experienced "
"any chronic infections?"),
yn(INFECTIONS_CHRONIC),
boldtext(STR_DETAILS_IF_YES),
mr_chronic_infection,
text(STR_DETAILS),
multiline(INFECTION_CHRONIC_DETAILS),
})->setTitle("Chronic infections")));
watch(INFECTIONS_CHRONIC);
watch(INFECTION_CHRONIC_OTHER);
connect(this, &DeakinS1HealthReview::setChronicInfectionsMinimum,
mr_chronic_infection, &QuMultipleResponse::setMinimumAnswers);
QuMultipleResponse* mr_immune = new QuMultipleResponse{
qf(IMMUNITY_MS, "multiple sclerosis"),
qf(IMMUNITY_SLE, "lupus"),
qf(IMMUNITY_ARTHRITIS, "arthritis"),
qf(IMMUNITY_HIV, "HIV/AIDS"),
qf(IMMUNITY_GRAVES, "Graves’ disease"),
qf(IMMUNITY_DIABETES, "diabetes"),
qf(IMMUNITY_OTHER, "other"),
};
pages.append(QuPagePtr((new QuPage{
boldtext("Do you have any immune disorders?"),
yn(IMMUNE_DISORDERS),
boldtext(STR_DETAILS_IF_YES),
mr_immune,
text(STR_DETAILS),
multiline(IMMUNITY_DETAILS),
})->setTitle("Immune disorders")));
watch(IMMUNE_DISORDERS);
watch(IMMUNITY_OTHER);
connect(this, &DeakinS1HealthReview::setImmuneMinimum,
mr_immune, &QuMultipleResponse::setMinimumAnswers);
QuMultipleResponse* mr_fh_immune = new QuMultipleResponse{
qf(FAMILYHISTORY_MS, "multiple sclerosis"),
qf(FAMILYHISTORY_SLE, "lupus"),
qf(FAMILYHISTORY_ARTHRITIS, "arthritis"),
qf(FAMILYHISTORY_GRAVES, "Graves’ disease"),
qf(FAMILYHISTORY_PSYCHOSIS_SZ, "psychosis/schizophrenia"),
qf(FAMILYHISTORY_BIPOLAR, "mania/bipolar affective disorder"),
};
pages.append(QuPagePtr((new QuPage{
boldtext("Does anyone in your family have any of the disorders listed "
"below?"),
yn(FAMILY_HISTORY),
boldtext(STR_DETAILS_IF_YES),
mr_fh_immune,
text(STR_DETAILS),
multiline(FAMILYHISTORY_DETAILS),
})->setTitle("Family history")));
watch(FAMILY_HISTORY);
connect(this, &DeakinS1HealthReview::setFHImmuneMinimum,
mr_fh_immune, &QuMultipleResponse::setMinimumAnswers);
pages.append(QuPagePtr((new QuPage{
boldtext("Is there any other information about your general health "
"that we should know?"),
yn(HEALTH_ANYTHING_ELSE),
boldtext(STR_DETAILS_IF_YES),
multiline(HEALTH_ANYTHING_ELSE_DETAILS),
})->setTitle("Other aspects of health")));
pages.append(QuPagePtr((new QuPage{
boldtext("If you are taking prescribed medication please list below:"),
multiline(DRUG_HISTORY, false),
boldtext("If you are taking antipsychotic medication, when did you "
"first take a medication of this kind?"),
multiline(FIRST_ANTIPSYCHOTIC_MEDICATION, false),
})->setTitle("Medication")));
pages.append(QuPagePtr((new QuPage{
boldtext("Please answer the following questions about any history you "
"may have with drug taking. It is very important that you "
"are honest, because this history may affect your blood "
"sample. Previous drug taking will not necessarily exclude "
"you, and all information will be kept completely "
"confidential."),
boldtext("Have you taken any recreational drugs in the last 3 months? "
"(Recreational drugs include drugs used only occasionally "
"without being dependent on them.)"),
yn(RECREATIONAL_DRUG_IN_LAST_3_MONTHS),
boldtext("Have you ever had a period of very heavy use of any of the "
"drugs listed below?"),
text(DRUGLIST.join(", ")),
yn(RECDRUG_PREVHEAVY),
boldtext("If you answered YES to either question, please give details "
"(A–E below)."),
boldtext("(A) Please use the grid below to specify which drugs you "
"used in the past 3 months, and how often."),
boldtext("(B) If you have ever had a period of very heavy use of any "
"of these drugs, please tick its “Previous heavy use?” box."),
(new QuMcqGridSingleBoolean(
QVector<QuestionWithTwoFields>{
q2f(RECDRUG_TOBACCO_FREQUENCY, RECDRUG_TOBACCO_PREVHEAVY, DRUGLIST[0]),
q2f(RECDRUG_CANNABIS_FREQUENCY, RECDRUG_CANNABIS_PREVHEAVY, DRUGLIST[1]),
q2f(RECDRUG_ALCOHOL_FREQUENCY, RECDRUG_ALCOHOL_PREVHEAVY, DRUGLIST[2]),
q2f(RECDRUG_MDMA_FREQUENCY, RECDRUG_MDMA_PREVHEAVY, DRUGLIST[3]),
q2f(RECDRUG_COCAINE_FREQUENCY, RECDRUG_COCAINE_PREVHEAVY, DRUGLIST[4]),
q2f(RECDRUG_CRACK_FREQUENCY, RECDRUG_CRACK_PREVHEAVY, DRUGLIST[5]),
q2f(RECDRUG_AMPHETAMINES_FREQUENCY, RECDRUG_AMPHETAMINES_PREVHEAVY, DRUGLIST[6]),
q2f(RECDRUG_HEROIN_FREQUENCY, RECDRUG_HEROIN_PREVHEAVY, DRUGLIST[7]),
q2f(RECDRUG_METHADONE_FREQUENCY, RECDRUG_METHADONE_PREVHEAVY, DRUGLIST[8]),
q2f(RECDRUG_BENZODIAZEPINES_FREQUENCY, RECDRUG_BENZODIAZEPINES_PREVHEAVY, DRUGLIST[9]),
q2f(RECDRUG_KETAMINE_FREQUENCY, RECDRUG_KETAMINE_PREVHEAVY, DRUGLIST[10]),
q2f(RECDRUG_LEGALHIGHS_FREQUENCY, RECDRUG_LEGALHIGHS_PREVHEAVY, DRUGLIST[11]),
q2f(RECDRUG_INHALANTS_FREQUENCY, RECDRUG_INHALANTS_PREVHEAVY, DRUGLIST[12]),
q2f(RECDRUG_HALLUCINOGENS_FREQUENCY, RECDRUG_HALLUCINOGENS_PREVHEAVY, DRUGLIST[13]),
},
NameValueOptions{
{"Did not use", 0},
{"Occasionally", 1},
{"Monthly", 2},
{"Weekly", 3},
{"Daily", 4},
},
"Previous heavy use?" // boolean label
))->setSubtitles(QVector<McqGridSubtitle>{
McqGridSubtitle(3, ""),
McqGridSubtitle(7, ""),
McqGridSubtitle(10, ""),
}),
boldtext("(C) Please give any further details of your recreational "
"drug use in the previous 3 months:"),
multiline(RECDRUG_DETAILS),
boldtext("(D) If you have used tobacco, cannabis, or alcohol in the "
"last 3 months, please give the quantities:"),
text("Tobacco – cigarettes per week:"),
intedit(RECDRUG_TOBACCO_CIGSPERWEEK),
text("Cannabis – joints per week:"),
intedit(RECDRUG_CANNABIS_JOINTSPERWEEK),
text("Alcohol – units per week:"),
intedit(RECDRUG_ALCOHOL_UNITSPERWEEK),
boldtext("(E) If you have had a period of very heavy drug use, please "
"give details about when this was and how long you used the "
"drug heavily:"),
multiline(RECDRUG_PREVHEAVY_DETAILS),
})->setTitle("Recreational drug use")));
watch(RECREATIONAL_DRUG_IN_LAST_3_MONTHS);
watch(RECDRUG_PREVHEAVY);
pages.append(QuPagePtr((new QuPage{
new QuMcqGrid(QVector<QuestionWithOneField>{
qf(MRI_CLAUSTROPHOBIC,
"Are you claustrophobic, or have difficulties in small spaces "
"(e.g. lifts, confined spaces)?"),
qf(MRI_DIFFICULTY_LYING_1_HOUR,
"Would you have any difficulties with lying down for 1 hour "
"(e.g. problems with your back, neck, bladder, etc.)?"),
qf(MRI_NONREMOVABLE_METAL,
"Is there any metal in your body which is not removable (e.g. "
"piercings, splinters, etc.)?"),
qf(MRI_METAL_FROM_OPERATIONS,
"Have you ever had any operations where metal has been left in "
"your body?"),
qf(MRI_TATTOOS_NICOTINE_PATCHES,
"Do you have any tattoos or nicotine patches?"),
qf(MRI_WORKED_WITH_METAL,
"Have you ever worked with metal (e.g. as a machinist, "
"metalworker, etc.)?"),
qf(MRI_PREVIOUS_BRAIN_SCAN,
"Have you ever had any form of brain scan before? If so, "
"please give details below."),
qf(OTHER_RELEVANT_THINGS,
"Are there any points you feel may be relevant to your "
"participation in the study? If so, please give details "
"below."),
}, yn_options),
text("Details of previous brain scans, if applicable:"),
multiline(MRI_PREVIOUS_BRAIN_SCAN_DETAILS, false),
text("Any other points you feel may be relevant to your "
"participation, if applicable:"),
multiline(OTHER_RELEVANT_THINGS_DETAILS, false),
text("Finally:"),
new QuMcqGrid(QVector<QuestionWithOneField>{
qf(WILLING_TO_PARTICIPATE_IN_FURTHER_STUDIES,
"Would you be willing to participate in further studies run by "
"our department?"),
}, yn_options),
})->setTitle("Questions related to MRI scanning")));
pages.append(QuPagePtr((new QuPage{
boldtext(TextConst::thankYou()),
})->setTitle(TextConst::finished())));
updateMandatory();
auto questionnaire = new Questionnaire(m_app, pages);
questionnaire->setType(QuPage::PageType::Clinician);
questionnaire->setReadOnly(read_only);
return questionnaire;
}
// ============================================================================
// Signal handlers
// ============================================================================
void DeakinS1HealthReview::updateMandatory()
{
// This could be more efficient with lots of signal handlers, but...
fieldRef(ETHNICITY_OTHER_DETAILS)->setMandatory(
GmcPq::ethnicityOther(valueInt(ETHNICITY)));
emit setAllergyMinimum(valueInt(ALLERGIES));
fieldRef(ALLERGY_DETAILS)->setMandatory(valueBool(ALLERGY_OTHER));
fieldRef(VACCINATION_DETAILS)->setMandatory(
valueBool(VACCINATIONS_LAST3MONTHS));
emit setRecentInfectionsMinimum(valueInt(INFECTIONS_LAST3MONTHS));
fieldRef(INFECTION_RECENT_DETAILS)->setMandatory(
valueBool(INFECTION_RECENT_OTHER));
emit setChronicInfectionsMinimum(valueInt(INFECTIONS_CHRONIC));
fieldRef(INFECTION_CHRONIC_DETAILS)->setMandatory(
valueBool(INFECTION_CHRONIC_OTHER));
emit setImmuneMinimum(valueInt(IMMUNE_DISORDERS));
fieldRef(IMMUNITY_DETAILS)->setMandatory(valueBool(IMMUNITY_OTHER));
emit setFHImmuneMinimum(valueInt(FAMILY_HISTORY));
fieldRef(FAMILYHISTORY_DETAILS)->setMandatory(valueBool(FAMILY_HISTORY));
fieldRef(HEALTH_ANYTHING_ELSE_DETAILS)->setMandatory(
valueBool(HEALTH_ANYTHING_ELSE));
fieldRef(HEALTH_ANYTHING_ELSE_DETAILS)->setMandatory(
valueBool(HEALTH_ANYTHING_ELSE));
const bool recent_drugs = valueBool(RECREATIONAL_DRUG_IN_LAST_3_MONTHS);
const bool heavy_drugs = valueBool(RECDRUG_PREVHEAVY);
const bool drugs = recent_drugs || heavy_drugs;
fieldRef(RECDRUG_TOBACCO_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_TOBACCO_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_CANNABIS_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_CANNABIS_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_ALCOHOL_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_ALCOHOL_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_MDMA_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_MDMA_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_COCAINE_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_COCAINE_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_CRACK_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_CRACK_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_AMPHETAMINES_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_AMPHETAMINES_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_HEROIN_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_HEROIN_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_METHADONE_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_METHADONE_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_BENZODIAZEPINES_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_BENZODIAZEPINES_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_KETAMINE_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_KETAMINE_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_LEGALHIGHS_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_LEGALHIGHS_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_INHALANTS_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_INHALANTS_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_HALLUCINOGENS_FREQUENCY)->setMandatory(drugs);
fieldRef(RECDRUG_HALLUCINOGENS_PREVHEAVY)->setMandatory(drugs);
fieldRef(RECDRUG_DETAILS)->setMandatory(recent_drugs);
fieldRef(RECDRUG_TOBACCO_CIGSPERWEEK)->setMandatory(recent_drugs);
fieldRef(RECDRUG_TOBACCO_CIGSPERWEEK)->setMandatory(recent_drugs);
fieldRef(RECDRUG_TOBACCO_CIGSPERWEEK)->setMandatory(recent_drugs);
fieldRef(RECDRUG_PREVHEAVY_DETAILS)->setMandatory(heavy_drugs);
}