Add settings option for preferring plaintext e-mails over HTML ones
[trojita.git] / src / Gui / SettingsDialog.cpp
blob1cd9b0c7f4b8b3b6196e635e99e59a96a8b3337e
1 /* Copyright (C) 2006 - 2012 Jan Kundrát <jkt@flaska.net>
2 Copyright (C) 2012 Mohammed Nafees <nafees.technocool@gmail.com>
4 This file is part of the Trojita Qt IMAP e-mail client,
5 http://trojita.flaska.net/
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of
10 the License or (at your option) version 3 or any later version
11 accepted by the membership of KDE e.V. (or its successor approved
12 by the membership of KDE e.V.), which shall act as a proxy
13 defined in Section 14 of version 3 of the license.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <QCheckBox>
24 #include <QComboBox>
25 #include <QDesktopServices>
26 #include <QDialogButtonBox>
27 #include <QDir>
28 #include <QFormLayout>
29 #include <QGroupBox>
30 #include <QInputDialog>
31 #include <QLineEdit>
32 #include <QListWidget>
33 #include <QRadioButton>
34 #include <QSpinBox>
35 #include <QTabWidget>
36 #include <QVBoxLayout>
37 #include <QProcess>
38 #include <QPushButton>
39 #include <QResizeEvent>
40 #include <QDebug>
41 #include <QStandardItemModel>
42 #include <QMessageBox>
43 #include <QDataWidgetMapper>
44 #include "SettingsDialog.h"
45 #include "Composer/SenderIdentitiesModel.h"
46 #include "Common/PortNumbers.h"
47 #include "Common/SettingsNames.h"
49 namespace Gui
52 QString SettingsDialog::warningStyleSheet = QLatin1String("border: 2px solid red; background-color: #E7C575; "
53 "font-weight: bold; padding: 5px; margin: 5px; "
54 "text-align: center;");
56 SettingsDialog::SettingsDialog(QWidget *parent, Composer::SenderIdentitiesModel *identitiesModel):
57 QDialog(parent), m_senderIdentities(identitiesModel)
59 setWindowTitle(tr("Settings"));
60 QSettings s;
62 QVBoxLayout *layout = new QVBoxLayout(this);
63 stack = new QTabWidget(this);
64 layout->addWidget(stack);
65 stack->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
67 general = new GeneralPage(this, s, m_senderIdentities);
68 stack->addTab(general, tr("General"));
69 imap = new ImapPage(stack, s);
70 stack->addTab(imap, tr("IMAP"));
71 cache = new CachePage(this, s);
72 stack->addTab(cache, tr("Offline"));
73 outgoing = new OutgoingPage(this, s);
74 stack->addTab(outgoing, tr("SMTP"));
75 #ifdef XTUPLE_CONNECT
76 xtConnect = new XtConnectPage(this, s, imap);
77 stack->addTab(xtConnect, tr("xTuple"));
78 #endif
80 QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel, Qt::Horizontal, this);
81 connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
82 connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
83 layout->addWidget(buttons);
86 void SettingsDialog::accept()
88 QSettings s;
89 #ifndef Q_OS_WIN
90 // Try to wour around QSettings' inability to set umask for its file access. We don't want to set umask globally.
91 QFile settingsFile(s.fileName());
92 settingsFile.setPermissions(QFile::ReadUser | QFile::WriteUser);
93 #endif
94 general->save(s);
95 imap->save(s);
96 cache->save(s);
97 outgoing->save(s);
98 #ifdef XTUPLE_CONNECT
99 xtConnect->save(s);
100 #endif
101 s.sync();
102 #ifndef Q_OS_WIN
103 settingsFile.setPermissions(QFile::ReadUser | QFile::WriteUser);
104 #endif
105 QDialog::accept();
108 void SettingsDialog::reject()
110 // The changes were performed on the live data, so we have to make sure they are discarded when user cancels
111 QSettings s;
112 m_senderIdentities->loadFromSettings(s);
113 QDialog::reject();
116 GeneralPage::GeneralPage(QWidget *parent, QSettings &s, Composer::SenderIdentitiesModel *identitiesModel):
117 QScrollArea(parent), Ui_GeneralPage(), m_identitiesModel(identitiesModel)
119 Ui_GeneralPage::setupUi(this);
120 Q_ASSERT(m_identitiesModel);
121 editButton->setEnabled(false);
122 deleteButton->setEnabled(false);
123 moveUpButton->setIcon(QIcon::fromTheme("go-up", QIcon(":/icons/arrow-up.png")));
124 moveDownButton->setIcon(QIcon::fromTheme("go-down", QIcon(":/icons/arrow-down.png")));
125 moveUpButton->setEnabled(false);
126 moveDownButton->setEnabled(false);
127 identityTabelView->setModel(m_identitiesModel);
128 identityTabelView->setSelectionBehavior(QAbstractItemView::SelectRows);
129 identityTabelView->setSelectionMode(QAbstractItemView::SingleSelection);
130 identityTabelView->setGridStyle(Qt::NoPen);
131 identityTabelView->hideColumn(Composer::SenderIdentitiesModel::COLUMN_ORGANIZATION);
132 identityTabelView->setColumnHidden(Composer::SenderIdentitiesModel::COLUMN_SIGNATURE, true);
133 identityTabelView->resizeColumnToContents(Composer::SenderIdentitiesModel::COLUMN_NAME);
134 identityTabelView->resizeRowsToContents();
135 identityTabelView->horizontalHeader()->setStretchLastSection(true);
137 showHomepageCheckbox->setChecked(s.value(Common::SettingsNames::appLoadHomepage, QVariant(true)).toBool());
138 showHomepageCheckbox->setToolTip(trUtf8("<p>If enabled, Trojitá will show its homepage upon startup.</p>"
139 "<p>The remote server will receive the user's IP address and versions of Trojitá, the Qt library, "
140 "and the underlying operating system. No private information, like account settings "
141 "or IMAP server details, are collected.</p>"));
142 preferPlaintextCheckbox->setChecked(s.value(Common::SettingsNames::guiPreferPlaintextRendering).toBool());
144 connect(identityTabelView, SIGNAL(clicked(QModelIndex)), SLOT(updateWidgets()));
145 connect(identityTabelView, SIGNAL(doubleClicked(QModelIndex)), SLOT(editButtonClicked()));
146 connect(m_identitiesModel, SIGNAL(layoutChanged()), SLOT(updateWidgets()));
147 connect(m_identitiesModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(updateWidgets()));
148 connect(m_identitiesModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(updateWidgets()));
149 connect(m_identitiesModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(updateWidgets()));
150 connect(moveUpButton, SIGNAL(clicked()), SLOT(moveIdentityUp()));
151 connect(moveDownButton, SIGNAL(clicked()), SLOT(moveIdentityDown()));
152 connect(addButton, SIGNAL(clicked()), SLOT(addButtonClicked()));
153 connect(editButton, SIGNAL(clicked()), SLOT(editButtonClicked()));
154 connect(deleteButton, SIGNAL(clicked()), SLOT(deleteButtonClicked()));
157 void GeneralPage::updateWidgets()
159 bool enabled = identityTabelView->currentIndex().isValid();
160 deleteButton->setEnabled(enabled);
161 editButton->setEnabled(enabled);
162 bool upEnabled = m_identitiesModel->rowCount() > 0 && identityTabelView->currentIndex().row() > 0;
163 bool downEnabled = m_identitiesModel->rowCount() > 0 && identityTabelView->currentIndex().row() < m_identitiesModel->rowCount() - 1;
164 moveUpButton->setEnabled(upEnabled);
165 moveDownButton->setEnabled(downEnabled);
167 identityTabelView->resizeColumnToContents(Composer::SenderIdentitiesModel::COLUMN_NAME);
170 void GeneralPage::moveIdentityUp()
172 int from = identityTabelView->currentIndex().row();
173 int to = identityTabelView->currentIndex().row() - 1;
175 m_identitiesModel->moveIdentity(from, to);
178 void GeneralPage::moveIdentityDown()
180 int from = identityTabelView->currentIndex().row();
181 int to = identityTabelView->currentIndex().row() + 1;
183 m_identitiesModel->moveIdentity(from, to);
186 void GeneralPage::addButtonClicked()
188 m_identitiesModel->appendIdentity(Composer::ItemSenderIdentity());
189 identityTabelView->setCurrentIndex(m_identitiesModel->index(m_identitiesModel->rowCount() - 1, 0));
190 EditIdentity *dialog = new EditIdentity(this, m_identitiesModel, identityTabelView->currentIndex());
191 dialog->setDeleteOnReject();
192 dialog->setWindowTitle(tr("Add New Identity"));
193 dialog->show();
194 updateWidgets();
197 void GeneralPage::editButtonClicked()
199 EditIdentity *dialog = new EditIdentity(this, m_identitiesModel, identityTabelView->currentIndex());
200 dialog->setWindowTitle(tr("Edit Identity"));
201 dialog->show();
204 void GeneralPage::deleteButtonClicked()
206 Q_ASSERT(identityTabelView->currentIndex().isValid());
207 QMessageBox::StandardButton answer =
208 QMessageBox::question(this, tr("Delete Identity?"),
209 tr("Are you sure you want to delete identity %1 <%2>?").arg(
210 m_identitiesModel->index(identityTabelView->currentIndex().row(),
211 Composer::SenderIdentitiesModel::COLUMN_NAME).data().toString(),
212 m_identitiesModel->index(identityTabelView->currentIndex().row(),
213 Composer::SenderIdentitiesModel::COLUMN_EMAIL).data().toString()),
214 QMessageBox::Yes | QMessageBox::No);
215 if (answer == QMessageBox::Yes) {
216 m_identitiesModel->removeIdentityAt(identityTabelView->currentIndex().row());
217 updateWidgets();
221 void GeneralPage::save(QSettings &s)
223 m_identitiesModel->saveToSettings(s);
224 s.setValue(Common::SettingsNames::appLoadHomepage, showHomepageCheckbox->isChecked());
225 s.setValue(Common::SettingsNames::guiPreferPlaintextRendering, preferPlaintextCheckbox->isChecked());
228 EditIdentity::EditIdentity(QWidget *parent, Composer::SenderIdentitiesModel *identitiesModel, const QModelIndex &currentIndex):
229 QDialog(parent), Ui_EditIdentity(), m_identitiesModel(identitiesModel), m_deleteOnReject(false)
231 Ui_EditIdentity::setupUi(this);
232 m_mapper = new QDataWidgetMapper(this);
233 m_mapper->setModel(m_identitiesModel);
234 m_mapper->addMapping(realNameLineEdit, Composer::SenderIdentitiesModel::COLUMN_NAME);
235 m_mapper->addMapping(emailLineEdit, Composer::SenderIdentitiesModel::COLUMN_EMAIL);
236 m_mapper->addMapping(organisationLineEdit, Composer::SenderIdentitiesModel::COLUMN_ORGANIZATION);
237 m_mapper->addMapping(signaturePlainTextEdit, Composer::SenderIdentitiesModel::COLUMN_SIGNATURE);
238 m_mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
239 m_mapper->setCurrentIndex(currentIndex.row());
240 buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
241 connect(realNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(enableButton()));
242 connect(emailLineEdit, SIGNAL(textChanged(QString)), this, SLOT(enableButton()));
243 connect(organisationLineEdit, SIGNAL(textChanged(QString)), this, SLOT(enableButton()));
244 connect(signaturePlainTextEdit, SIGNAL(textChanged()), this, SLOT(enableButton()));
245 connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept()));
246 connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject()));
247 connect(this, SIGNAL(accepted()), m_mapper, SLOT(submit()));
248 connect(this, SIGNAL(rejected()), this, SLOT(onReject()));
249 setModal(true);
251 // See ComposeWidget.cpp for details on the selection of font
252 QFont font(QLatin1String("x-trojita-terminus-like-fixed-width"));
253 font.setStyleHint(QFont::TypeWriter);
254 signaturePlainTextEdit->setFont(font);
255 // The QFontMetrics prodocues weird results, unfortunately :(
256 /*QFontMetrics(font).boundingRect(
257 QLatin1String("A simple signature which spans 80 column is surprisingly hard to come up with...")).width()*/
260 void EditIdentity::enableButton()
262 buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
263 !realNameLineEdit->text().isEmpty() && !emailLineEdit->text().isEmpty());
266 /** @short If enabled, make sure that the current row gets deleted when the dialog is rejected */
267 void EditIdentity::setDeleteOnReject(const bool reject)
269 m_deleteOnReject = reject;
272 void EditIdentity::onReject()
274 if (m_deleteOnReject)
275 m_identitiesModel->removeIdentityAt(m_mapper->currentIndex());
278 ImapPage::ImapPage(QWidget *parent, QSettings &s): QScrollArea(parent), Ui_ImapPage()
280 Ui_ImapPage::setupUi(this);
281 method->insertItem(0, tr("TCP"), QVariant(TCP));
282 method->insertItem(1, tr("SSL"), QVariant(SSL));
283 method->insertItem(2, tr("Local Process"), QVariant(PROCESS));
284 using Common::SettingsNames;
285 if (QSettings().value(SettingsNames::imapMethodKey).toString() == SettingsNames::methodTCP) {
286 method->setCurrentIndex(0);
287 } else if (QSettings().value(SettingsNames::imapMethodKey).toString() == SettingsNames::methodSSL) {
288 method->setCurrentIndex(1);
289 } else {
290 method->setCurrentIndex(2);
293 imapHost->setText(s.value(SettingsNames::imapHostKey).toString());
294 imapPort->setText(s.value(SettingsNames::imapPortKey, QString::number(Common::PORT_IMAP)).toString());
295 imapPort->setValidator(new QIntValidator(1, 65535, this));
296 passwordWarning->setStyleSheet(SettingsDialog::warningStyleSheet);
297 connect(imapPass, SIGNAL(textChanged(QString)), this, SLOT(maybeShowPasswordWarning()));
298 startTls->setChecked(s.value(SettingsNames::imapStartTlsKey, true).toBool());
299 imapUser->setText(s.value(SettingsNames::imapUserKey).toString());
300 imapPass->setText(s.value(SettingsNames::imapPassKey).toString());
301 processPath->setText(s.value(SettingsNames::imapProcessKey).toString());
302 startOffline->setChecked(s.value(SettingsNames::imapStartOffline).toBool());
303 imapEnableId->setChecked(s.value(SettingsNames::imapEnableId, true).toBool());
304 imapCapabilitiesBlacklist->setText(s.value(SettingsNames::imapBlacklistedCapabilities).toStringList().join(QLatin1String(" ")));
306 connect(method, SIGNAL(currentIndexChanged(int)), this, SLOT(updateWidgets()));
307 updateWidgets();
308 maybeShowPasswordWarning();
311 void ImapPage::resizeEvent(QResizeEvent *event)
313 QScrollArea::resizeEvent(event);
314 scrollAreaWidgetContents->setMinimumSize(event->size());
315 scrollAreaWidgetContents->adjustSize();
318 void ImapPage::updateWidgets()
320 QFormLayout *lay = formLayout;
321 Q_ASSERT(lay);
323 switch (method->itemData(method->currentIndex()).toInt()) {
324 case TCP:
325 imapHost->setEnabled(true);
326 lay->labelForField(imapHost)->setEnabled(true);
327 imapPort->setEnabled(true);
328 if (imapPort->text().isEmpty() || imapPort->text() == QString::number(Common::PORT_IMAPS))
329 imapPort->setText(QString::number(Common::PORT_IMAP));
330 else if (QSettings().contains(Common::SettingsNames::imapPortKey))
331 imapPort->setText(QSettings().value(Common::SettingsNames::imapPortKey).toString());
332 lay->labelForField(imapPort)->setEnabled(true);
333 startTls->setEnabled(true);
334 startTls->setChecked(QSettings().value(Common::SettingsNames::imapStartTlsKey, true).toBool());
335 lay->labelForField(startTls)->setEnabled(true);
336 processPath->setEnabled(false);
337 lay->labelForField(processPath)->setEnabled(false);
338 break;
339 case SSL:
340 imapHost->setEnabled(true);
341 lay->labelForField(imapHost)->setEnabled(true);
342 imapPort->setEnabled(true);
343 if (imapPort->text().isEmpty() || imapPort->text() == QString::number(Common::PORT_IMAP))
344 imapPort->setText(QString::number(Common::PORT_IMAPS));
345 else if (QSettings().contains(Common::SettingsNames::imapPortKey))
346 imapPort->setText(QSettings().value(Common::SettingsNames::imapPortKey).toString());
347 lay->labelForField(imapPort)->setEnabled(true);
348 startTls->setEnabled(false);
349 startTls->setChecked(true);
350 lay->labelForField(startTls)->setEnabled(false);
351 processPath->setEnabled(false);
352 lay->labelForField(processPath)->setEnabled(false);
353 break;
354 default:
355 imapHost->setEnabled(false);
356 lay->labelForField(imapHost)->setEnabled(false);
357 imapPort->setEnabled(false);
358 lay->labelForField(imapPort)->setEnabled(false);
359 startTls->setEnabled(false);
360 lay->labelForField(startTls)->setEnabled(false);
361 processPath->setEnabled(true);
362 lay->labelForField(processPath)->setEnabled(true);
366 void ImapPage::save(QSettings &s)
368 using Common::SettingsNames;
369 if (s.value(SettingsNames::imapHostKey) != imapHost->text()) {
370 s.remove(Common::SettingsNames::imapSslPemCertificate);
372 switch (method->currentIndex()) {
373 case TCP:
374 s.setValue(SettingsNames::imapMethodKey, SettingsNames::methodTCP);
375 s.setValue(SettingsNames::imapHostKey, imapHost->text());
376 s.setValue(SettingsNames::imapPortKey, imapPort->text());
377 s.setValue(SettingsNames::imapStartTlsKey, startTls->isChecked());
378 break;
379 case SSL:
380 s.setValue(SettingsNames::imapMethodKey, SettingsNames::methodSSL);
381 s.setValue(SettingsNames::imapHostKey, imapHost->text());
382 s.setValue(SettingsNames::imapPortKey, imapPort->text());
383 s.setValue(SettingsNames::imapStartTlsKey, startTls->isChecked());
384 break;
385 default:
386 s.setValue(SettingsNames::imapMethodKey, SettingsNames::methodProcess);
387 s.setValue(SettingsNames::imapProcessKey, processPath->text());
389 s.setValue(SettingsNames::imapUserKey, imapUser->text());
390 s.setValue(SettingsNames::imapPassKey, imapPass->text());
391 s.setValue(SettingsNames::imapStartOffline, startOffline->isChecked());
392 s.setValue(SettingsNames::imapEnableId, imapEnableId->isChecked());
393 s.setValue(SettingsNames::imapBlacklistedCapabilities, imapCapabilitiesBlacklist->text().split(QChar(' ')));
396 void ImapPage::maybeShowPasswordWarning()
398 passwordWarning->setVisible(!imapPass->text().isEmpty());
401 CachePage::CachePage(QWidget *parent, QSettings &s): QScrollArea(parent), Ui_CachePage()
403 Ui_CachePage::setupUi(this);
405 using Common::SettingsNames;
407 QString val = s.value(SettingsNames::cacheOfflineKey).toString();
408 if (val == SettingsNames::cacheOfflineAll) {
409 offlineEverything->setChecked(true);
410 } else if (val == SettingsNames::cacheOfflineNone) {
411 offlineNope->setChecked(true);
412 } else {
413 offlineXDays->setChecked(true);
416 offlineNumberOfDays->setValue(s.value(SettingsNames::cacheOfflineNumberDaysKey, QVariant(30)).toInt());
418 updateWidgets();
419 connect(offlineNope, SIGNAL(clicked()), this, SLOT(updateWidgets()));
420 connect(offlineXDays, SIGNAL(clicked()), this, SLOT(updateWidgets()));
421 connect(offlineEverything, SIGNAL(clicked()), this, SLOT(updateWidgets()));
424 void CachePage::resizeEvent(QResizeEvent *event)
426 QScrollArea::resizeEvent(event);
427 scrollAreaWidgetContents->setMinimumSize(event->size());
428 scrollAreaWidgetContents->adjustSize();
431 void CachePage::updateWidgets()
433 offlineNumberOfDays->setEnabled(offlineXDays->isChecked());
436 void CachePage::save(QSettings &s)
438 using Common::SettingsNames;
440 if (offlineEverything->isChecked())
441 s.setValue(SettingsNames::cacheOfflineKey, SettingsNames::cacheOfflineAll);
442 else if (offlineXDays->isChecked())
443 s.setValue(SettingsNames::cacheOfflineKey, SettingsNames::cacheOfflineXDays);
444 else
445 s.setValue(SettingsNames::cacheOfflineKey, SettingsNames::cacheOfflineNone);
447 s.setValue(SettingsNames::cacheOfflineNumberDaysKey, offlineNumberOfDays->value());
450 OutgoingPage::OutgoingPage(QWidget *parent, QSettings &s): QScrollArea(parent), Ui_OutgoingPage()
452 using Common::SettingsNames;
453 Ui_OutgoingPage::setupUi(this);
454 method->insertItem(0, tr("SMTP"), QVariant(SMTP));
455 method->insertItem(1, tr("Secure SMTP"), QVariant(SSMTP));
456 method->insertItem(2, tr("Local sendmail-compatible"), QVariant(SENDMAIL));
457 method->insertItem(3, tr("IMAP SENDMAIL Extension"), QVariant(IMAP_SENDMAIL));
458 QString selectedMethod = s.value(SettingsNames::msaMethodKey).toString();
459 if (selectedMethod == SettingsNames::methodSMTP) {
460 method->setCurrentIndex(0);
461 } else if (selectedMethod == SettingsNames::methodSSMTP) {
462 method->setCurrentIndex(1);
463 } else if (selectedMethod == SettingsNames::methodSENDMAIL) {
464 method->setCurrentIndex(2);
465 } else if (selectedMethod == SettingsNames::methodImapSendmail) {
466 method->setCurrentIndex(3);
469 smtpHost->setText(s.value(SettingsNames::smtpHostKey).toString());
470 smtpPort->setText(s.value(SettingsNames::smtpPortKey, Common::PORT_SMTP_SUBMISSION).toString());
471 smtpPort->setValidator(new QIntValidator(1, 65535, this));
472 smtpStartTls->setChecked(s.value(SettingsNames::smtpStartTlsKey).toBool());
473 smtpAuth->setChecked(s.value(SettingsNames::smtpAuthKey, false).toBool());
474 smtpUser->setText(s.value(SettingsNames::smtpUserKey).toString());
475 smtpPass->setText(s.value(SettingsNames::smtpPassKey).toString());
476 sendmail->setText(s.value(SettingsNames::sendmailKey, SettingsNames::sendmailDefaultCmd).toString());
477 saveToImap->setChecked(s.value(SettingsNames::composerSaveToImapKey, true).toBool());
478 // Would be cool to support the special-use mailboxes
479 saveFolderName->setText(s.value(SettingsNames::composerImapSentKey, QLatin1String("Sent")).toString());
480 smtpBurl->setChecked(s.value(SettingsNames::smtpUseBurlKey, false).toBool());
482 connect(method, SIGNAL(currentIndexChanged(int)), this, SLOT(updateWidgets()));
483 connect(smtpAuth, SIGNAL(toggled(bool)), this, SLOT(updateWidgets()));
484 connect(saveToImap, SIGNAL(toggled(bool)), this, SLOT(updateWidgets()));
485 updateWidgets();
488 void OutgoingPage::resizeEvent(QResizeEvent *event)
490 QScrollArea::resizeEvent(event);
491 scrollAreaWidgetContents->setMinimumSize(event->size());
492 scrollAreaWidgetContents->adjustSize();
495 void OutgoingPage::updateWidgets()
497 QFormLayout *lay = formLayout;
498 Q_ASSERT(lay);
499 int smtpMethod = method->itemData(method->currentIndex()).toInt();
500 switch (smtpMethod) {
501 case SMTP:
502 case SSMTP:
504 smtpHost->setEnabled(true);
505 lay->labelForField(smtpHost)->setEnabled(true);
506 smtpPort->setEnabled(true);
507 lay->labelForField(smtpPort)->setEnabled(true);
508 smtpStartTls->setEnabled(smtpMethod == SMTP);
509 lay->labelForField(smtpStartTls)->setEnabled(smtpMethod == SMTP);
510 smtpAuth->setEnabled(true);
511 lay->labelForField(smtpAuth)->setEnabled(true);
512 bool authEnabled = smtpAuth->isChecked();
513 smtpUser->setEnabled(authEnabled);
514 lay->labelForField(smtpUser)->setEnabled(authEnabled);
515 smtpPass->setEnabled(authEnabled);
516 lay->labelForField(smtpPass)->setEnabled(authEnabled);
517 sendmail->setEnabled(false);
518 lay->labelForField(sendmail)->setEnabled(false);
519 smtpBurl->setEnabled(saveToImap->isChecked());
520 lay->labelForField(smtpBurl)->setEnabled(saveToImap->isChecked());
522 // Toggle the default ports upon changing the delivery method
523 if (smtpMethod == SMTP && (smtpPort->text().isEmpty() ||
524 smtpPort->text() == QString::number(Common::PORT_SMTP_SSL))) {
525 smtpPort->setText(QString::number(Common::PORT_SMTP_SUBMISSION));
526 } else if (smtpMethod == SSMTP && (smtpPort->text().isEmpty() ||
527 smtpPort->text() == QString::number(Common::PORT_SMTP_OBSOLETE) ||
528 smtpPort->text() == QString::number(Common::PORT_SMTP_SUBMISSION))) {
529 smtpPort->setText(QString::number(Common::PORT_SMTP_SSL));
531 break;
533 case SENDMAIL:
534 case IMAP_SENDMAIL:
535 smtpHost->setEnabled(false);
536 lay->labelForField(smtpHost)->setEnabled(false);
537 smtpPort->setEnabled(false);
538 lay->labelForField(smtpPort)->setEnabled(false);
539 smtpStartTls->setEnabled(false);
540 lay->labelForField(smtpStartTls)->setEnabled(false);
541 smtpAuth->setEnabled(false);
542 lay->labelForField(smtpAuth)->setEnabled(false);
543 smtpUser->setEnabled(false);
544 lay->labelForField(smtpUser)->setEnabled(false);
545 smtpPass->setEnabled(false);
546 lay->labelForField(smtpPass)->setEnabled(false);
547 if (smtpMethod == SENDMAIL) {
548 sendmail->setEnabled(true);
549 lay->labelForField(sendmail)->setEnabled(true);
550 if (sendmail->text().isEmpty())
551 sendmail->setText(Common::SettingsNames::sendmailDefaultCmd);
552 saveToImap->setEnabled(true);
553 lay->labelForField(saveToImap)->setEnabled(true);
554 } else {
555 sendmail->setEnabled(false);
556 lay->labelForField(sendmail)->setEnabled(false);
557 saveToImap->setChecked(true);
558 saveToImap->setEnabled(false);
559 lay->labelForField(saveToImap)->setEnabled(false);
561 smtpBurl->setEnabled(false);
562 lay->labelForField(smtpBurl)->setEnabled(false);
564 saveFolderName->setEnabled(saveToImap->isChecked());
567 void OutgoingPage::save(QSettings &s)
569 using Common::SettingsNames;
570 switch (method->currentIndex()) {
571 case SMTP:
572 s.setValue(SettingsNames::msaMethodKey, SettingsNames::methodSMTP);
573 s.setValue(SettingsNames::smtpHostKey, smtpHost->text());
574 s.setValue(SettingsNames::smtpPortKey, smtpPort->text());
575 s.setValue(SettingsNames::smtpStartTlsKey, smtpStartTls->isChecked());
576 s.setValue(SettingsNames::smtpAuthKey, smtpAuth->isChecked());
577 s.setValue(SettingsNames::smtpUserKey, smtpUser->text());
578 s.setValue(SettingsNames::smtpPassKey, smtpPass->text());
579 break;
580 case SSMTP:
581 s.setValue(SettingsNames::msaMethodKey, SettingsNames::methodSSMTP);
582 s.setValue(SettingsNames::smtpHostKey, smtpHost->text());
583 s.setValue(SettingsNames::smtpPortKey, smtpPort->text());
584 s.setValue(SettingsNames::smtpAuthKey, smtpAuth->isChecked());
585 s.setValue(SettingsNames::smtpUserKey, smtpUser->text());
586 s.setValue(SettingsNames::smtpPassKey, smtpPass->text());
587 break;
588 case SENDMAIL:
589 s.setValue(SettingsNames::msaMethodKey, SettingsNames::methodSENDMAIL);
590 s.setValue(SettingsNames::sendmailKey, sendmail->text());
591 break;
592 case IMAP_SENDMAIL:
593 s.setValue(SettingsNames::msaMethodKey, SettingsNames::methodImapSendmail);
594 break;
596 s.setValue(SettingsNames::composerSaveToImapKey, saveToImap->isChecked());
597 if (saveToImap->isChecked()) {
598 s.setValue(SettingsNames::composerImapSentKey, saveFolderName->text());
599 s.setValue(SettingsNames::smtpUseBurlKey, smtpBurl->isChecked());
600 } else {
601 // BURL depends on having that message available on IMAP somewhere
602 s.setValue(SettingsNames::smtpUseBurlKey, false);
606 #ifdef XTUPLE_CONNECT
607 XtConnectPage::XtConnectPage(QWidget *parent, QSettings &s, ImapPage *imapPage): QWidget(parent), imap(imapPage)
609 // Take care not to clash with the cache of the GUI
610 QString cacheLocation = QDesktopServices::storageLocation(QDesktopServices::CacheLocation);
611 if (cacheLocation.isEmpty())
612 cacheLocation = QDir::homePath() + QLatin1String("/.xtconnect-trojita");
613 else
614 cacheLocation += QString::fromAscii("/xtconnect-trojita");
615 QFormLayout *layout = new QFormLayout(this);
616 cacheDir = new QLineEdit(s.value(Common::SettingsNames::xtConnectCacheDirectory, cacheLocation).toString(), this);
617 layout->addRow(tr("Cache Directory"), cacheDir);
619 QGroupBox *box = new QGroupBox(tr("Mailboxes to synchronize"), this);
620 QVBoxLayout *boxLayout = new QVBoxLayout(box);
621 QListWidget *mailboxes = new QListWidget(box);
622 mailboxes->addItems(QSettings().value(Common::SettingsNames::xtSyncMailboxList).toStringList());
623 for (int i = 0; i < mailboxes->count(); ++i) {
624 mailboxes->item(i)->setFlags(Qt::ItemIsEnabled);
626 mailboxes->setToolTip(tr("Please use context menu inside the main application to select mailboxes to synchronize"));
627 boxLayout->addWidget(mailboxes);
628 layout->addRow(box);
630 QString optionHost = s.value(Common::SettingsNames::xtDbHost).toString();
631 int optionPort = s.value(Common::SettingsNames::xtDbPort, QVariant(5432)).toInt();
632 QString optionDbname = s.value(Common::SettingsNames::xtDbDbName).toString();
633 QString optionUsername = s.value(Common::SettingsNames::xtDbUser).toString();
635 QStringList args = QCoreApplication::arguments();
636 for (int i = 1; i < args.length(); i++) {
637 if (args.at(i) == "-h" && args.length() > i)
638 optionHost = args.at(++i);
639 else if (args.at(i) == "-d" && args.length() > i)
640 optionDbname = args.at(++i);
641 else if (args.at(i) == "-p" && args.length() > i)
642 optionPort = args.at(++i).toInt();
643 else if (args.at(i) == "-U" && args.length() > i)
644 optionUsername = args.at(++i);
648 hostName = new QLineEdit(optionHost);
649 layout->addRow(tr("DB Hostname"), hostName);
650 port = new QSpinBox();
651 port->setRange(1, 65535);
652 port->setValue(optionPort);
653 layout->addRow(tr("DB Port"), port);
654 dbName = new QLineEdit(optionDbname);
655 layout->addRow(tr("DB Name"), dbName);
656 username = new QLineEdit(optionUsername);
657 layout->addRow(tr("DB Username"), username);
659 imapPasswordWarning = new QLabel(tr("Please fill in all IMAP options, including the password, at the IMAP page. "
660 "If you do not save the password, background synchronization will not run."), this);
661 imapPasswordWarning->setWordWrap(true);
662 imapPasswordWarning->setStyleSheet(SettingsDialog::warningStyleSheet);
663 layout->addRow(imapPasswordWarning);
664 debugLog = new QCheckBox();
665 layout->addRow(tr("Debugging"), debugLog);
667 QPushButton *btn = new QPushButton(tr("Run xTuple Synchronization"));
668 connect(btn, SIGNAL(clicked()), this, SLOT(runXtConnect()));
669 layout->addRow(btn);
672 void XtConnectPage::save(QSettings &s)
674 s.setValue(Common::SettingsNames::xtConnectCacheDirectory, cacheDir->text());
675 s.setValue(Common::SettingsNames::xtDbHost, hostName->text());
676 s.setValue(Common::SettingsNames::xtDbPort, port->value());
677 s.setValue(Common::SettingsNames::xtDbDbName, dbName->text());
678 s.setValue(Common::SettingsNames::xtDbUser, username->text());
679 saveXtConfig();
682 void XtConnectPage::saveXtConfig()
684 QSettings s(QSettings::UserScope, QString::fromAscii("xTuple.com"), QString::fromAscii("xTuple"));
686 // Copy the IMAP settings
687 Q_ASSERT(imap);
688 imap->save(s);
690 // XtConnect-specific stuff
691 s.setValue(Common::SettingsNames::xtConnectCacheDirectory, cacheDir->text());
692 QStringList keys = QStringList() <<
693 Common::SettingsNames::xtSyncMailboxList <<
694 Common::SettingsNames::xtDbHost <<
695 Common::SettingsNames::xtDbPort <<
696 Common::SettingsNames::xtDbDbName <<
697 Common::SettingsNames::xtDbUser <<
698 Common::SettingsNames::imapSslPemCertificate;
699 Q_FOREACH(const QString &key, keys) {
700 s.setValue(key, QSettings().value(key));
704 void XtConnectPage::runXtConnect()
706 // First of all, let's save the XTuple-specific configuration to save useless debugging
707 saveXtConfig();
709 QString path = QCoreApplication::applicationFilePath();
710 QStringList args;
712 #ifdef Q_OS_WIN
713 path = path.replace(
714 QLatin1String("Gui/debug/trojita"),
715 QLatin1String("XtConnect/debug/xtconnect-trojita")).replace(
716 QLatin1String("Gui/release/trojita"),
717 QLatin1String("XtConnect/release/xtconnect-trojita"));
718 QString cmd = path;
719 #else
720 path = path.replace(QLatin1String("src/Gui/trojita"),
721 QLatin1String("src/XtConnect/xtconnect-trojita"));
722 args << QLatin1String("-e") << path;
723 QString cmd = QLatin1String("xterm");
724 #endif
726 if (! hostName->text().isEmpty())
727 args << QLatin1String("-h") << hostName->text();
729 if (port->value() != 5432)
730 args << QLatin1String("-p") << QString::number(port->value());
732 if (! dbName->text().isEmpty())
733 args << QLatin1String("-d") << dbName->text();
735 if (! username->text().isEmpty())
736 args << QLatin1String("-U") << username->text();
738 QString password = QInputDialog::getText(this, tr("Database Connection"), tr("Password"), QLineEdit::Password);
739 args << QLatin1String("-W") << password;
741 if (debugLog->isChecked())
742 args << QLatin1String("--log") << cacheDir->text() + QLatin1String("/xt-trojita-log");
744 QProcess::startDetached(cmd, args);
747 void XtConnectPage::showEvent(QShowEvent *event)
749 if (imap) {
750 imapPasswordWarning->setVisible(! imap->hasPassword());
752 QWidget::showEvent(event);
755 bool ImapPage::hasPassword() const
757 return ! imapPass->text().isEmpty();
760 #endif