PageRenderTime 66ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/examples/pop3/mainwindow.cpp

https://gitlab.com/jeanim/libqxt
C++ | 445 lines | 423 code | 22 blank | 0 comment | 72 complexity | 9540442b7aedba77458a79abc29b873b MD5 | raw file
  1. #include "mainwindow.h"
  2. #include <QxtPop3Reply>
  3. #include <QPair>
  4. #include <QFileDialog>
  5. #include <QFile>
  6. #include <QSslSocket>
  7. MainWindow::MainWindow(QWidget* parent): QMainWindow(parent), pop(0), msg(0)
  8. {
  9. setupUi(this);
  10. settings = new QSettings(QSettings::UserScope,"Qxt", "MailTest", this);
  11. pop = new QxtPop3(this);
  12. pop->sslSocket()->setProtocol(QSsl::TlsV1);
  13. pop->sslSocket()->setPeerVerifyMode(QSslSocket::QueryPeer);
  14. QString username = settings->value("username").toString();
  15. QString hostname = settings->value("hostname").toString();
  16. QString pass = settings->value("password").toString();
  17. int port = settings->value("port").toInt();
  18. bool ok;
  19. Encryption enc = Encryption(settings->value("encryption").toInt(&ok));
  20. if (!ok) enc = Clear;
  21. switch (enc)
  22. {
  23. case UseSSL:
  24. sslRadioButton->setChecked(true);
  25. break;
  26. case UseStartTLS:
  27. startTLSRadioButton->setChecked(true);
  28. break;
  29. case Clear:
  30. default:
  31. clearRadioButton->setChecked(true);
  32. break;
  33. }
  34. usernameLineEdit->setText(username);
  35. hostnameLineEdit->setText(hostname);
  36. passwordLineEdit->setText(pass);
  37. if (port != 0) portLineEdit->setText(QString::number(port));
  38. connect(connectPushButton, SIGNAL(clicked()), this, SLOT(connectToHost()));
  39. connect(settingsPushButton, SIGNAL(clicked()), this, SLOT(saveSettings()));
  40. connect(pop, SIGNAL(disconnected()), this, SLOT(disconnected()));
  41. connect(pop, SIGNAL(connected()), this, SLOT(connected()));
  42. connect(pop, SIGNAL(connectionFailed(QByteArray)), this, SLOT(handleSslError(QByteArray)));
  43. connect(pop, SIGNAL(encryptionFailed(QByteArray)), this, SLOT(handleSslError(QByteArray)));
  44. connect(pop, SIGNAL(authenticationFailed(QByteArray)), this, SLOT(handleAuthError(QByteArray)));
  45. connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(newCmd()));
  46. help();
  47. }
  48. MainWindow::~MainWindow()
  49. {
  50. if (msg) delete msg;
  51. }
  52. void MainWindow::newCmd()
  53. {
  54. QxtPop3Reply* reply = 0;
  55. QString line = lineEdit->text();
  56. lineEdit->clear();
  57. QStringList words = line.split(" ", QString::SkipEmptyParts);
  58. if (words[0] == "quit")
  59. {
  60. if (!pop->isConnected()) return;
  61. reply = pop->quit();
  62. connect(reply, SIGNAL(finished(int)), this, SLOT(handleQuit(int)));
  63. plainTextEdit->appendPlainText("QUIT sent");
  64. }
  65. else if (words[0] == "stat")
  66. {
  67. if (!pop->isConnected()) return;
  68. reply = pop->stat();
  69. connect(reply, SIGNAL(finished(int)), this, SLOT(handleStat(int)));
  70. output("STAT sent");
  71. }
  72. else if (words[0] == "list")
  73. {
  74. if (!pop->isConnected()) return;
  75. reply = pop->messageList();
  76. connect(reply, SIGNAL(finished(int)), this, SLOT(handleList(int)));
  77. output("LIST sent");
  78. }
  79. else if (words[0] == "retr")
  80. {
  81. if (!pop->isConnected()) return;
  82. if (words.length() < 2)
  83. {
  84. output("Usage: retr <which>");
  85. return;
  86. }
  87. int which = words[1].toInt();
  88. reply = pop->retrieveMessage(which);
  89. connect(reply, SIGNAL(finished(int)), this, SLOT(handleRetr(int)));
  90. connect(reply, SIGNAL(progress(int)), this, SLOT(progress(int)));
  91. output("RETR sent");
  92. }
  93. else if (words[0] == "dele")
  94. {
  95. if (!pop->isConnected()) return;
  96. if (words.length() < 2)
  97. {
  98. output("Usage: dele <which>");
  99. return;
  100. }
  101. int which = words[1].toInt();
  102. reply = pop->deleteMessage(which);
  103. connect(reply, SIGNAL(finished(int)), this, SLOT(handleDele(int)));
  104. output("DELE sent");
  105. }
  106. else if (words[0] == "reset")
  107. {
  108. if (!pop->isConnected()) return;
  109. reply = pop->reset();
  110. connect(reply, SIGNAL(finished(int)), this, SLOT(handleRset(int)));
  111. output("RSET sent");
  112. }
  113. else if (words[0] == "help")
  114. {
  115. help();
  116. }
  117. else if (words[0] == "saveatt")
  118. {
  119. if (msg == 0)
  120. {
  121. output("no current message.");
  122. return;
  123. }
  124. if (words.length() < 2)
  125. {
  126. output("Usage: saveatt <attachment name>");
  127. return;
  128. }
  129. if (!msg->attachments().contains(words[1]))
  130. {
  131. output(QString("no such attachment: ") + words[1]);
  132. return;
  133. }
  134. QxtMailAttachment att = msg->attachment(words[1]);
  135. QString filename = QFileDialog::getSaveFileName(this, "Save attachment", QString("./") + words[1]);
  136. if (!filename.isEmpty())
  137. {
  138. QFile file(filename);
  139. QIODevice::OpenMode flags = QIODevice::WriteOnly;
  140. if (att.isText()) flags |= QIODevice::Text;
  141. file.open(flags);
  142. file.write(att.rawData());
  143. file.close();
  144. output("Attachment saved");
  145. }
  146. }
  147. else
  148. {
  149. output("unhandled command");
  150. }
  151. }
  152. void MainWindow::handleQuit(int code)
  153. {
  154. switch (code)
  155. {
  156. case QxtPop3Reply::OK:
  157. output("QUIT: OK received");
  158. break;
  159. case QxtPop3Reply::Aborted:
  160. printError();
  161. output("QUIT aborted.");
  162. break;
  163. case QxtPop3Reply::Timeout:
  164. output("QUIT: time out.");
  165. break;
  166. default:
  167. break;
  168. }
  169. }
  170. void MainWindow::handleStat(int code)
  171. {
  172. switch (code)
  173. {
  174. case QxtPop3Reply::OK:
  175. {
  176. QxtPop3StatReply* reply = dynamic_cast<QxtPop3StatReply*>(sender());
  177. if (reply == 0)
  178. {
  179. qWarning("MainWindow::handleStat: sender is not a QxtPop3StatReply !");
  180. return;
  181. }
  182. output(QString("STAT: %1 messages, %2 bytes").arg(reply->count()).arg(reply->size()));
  183. }
  184. break;
  185. case QxtPop3Reply::Aborted:
  186. printError();
  187. output("STAT aborted.");
  188. break;
  189. case QxtPop3Reply::Timeout:
  190. output("STAT: time out.");
  191. break;
  192. default:
  193. break;
  194. }
  195. }
  196. void MainWindow::handleList(int code)
  197. {
  198. switch (code)
  199. {
  200. case QxtPop3Reply::OK:
  201. output("LIST: OK received");
  202. {
  203. QxtPop3ListReply* reply = dynamic_cast<QxtPop3ListReply*>(sender());
  204. if (reply == 0)
  205. {
  206. qWarning("MainWindow::handleList: sender is not a QxtPop3ListReply !");
  207. return;
  208. }
  209. foreach (QxtPop3Reply::MessageInfo msginfo, reply->list())
  210. {
  211. output(QString("message %1: %2 bytes").arg(msginfo.id).arg(msginfo.size));
  212. }
  213. }
  214. break;
  215. case QxtPop3Reply::Aborted:
  216. printError();
  217. output("LIST aborted.");
  218. break;
  219. case QxtPop3Reply::Timeout:
  220. output("LIST: time out.");
  221. break;
  222. default:
  223. break;
  224. }
  225. }
  226. void MainWindow::handleRetr(int code)
  227. {
  228. switch (code)
  229. {
  230. case QxtPop3Reply::OK:
  231. output("RETR: OK received");
  232. {
  233. QxtPop3RetrReply* reply = dynamic_cast<QxtPop3RetrReply *>(sender());
  234. if (reply == 0)
  235. {
  236. qWarning("MainWindow::handleRetr: sender is not a QxtPop3RetrReply !");
  237. return;
  238. }
  239. if (msg)
  240. {
  241. delete msg;
  242. }
  243. msg = reply->message();
  244. output("------Message Headers:");
  245. foreach(QString key, msg->extraHeaders().keys())
  246. {
  247. output(QString("%1: %2").arg(key, msg->extraHeader(key)));
  248. }
  249. output("------Message Body:");
  250. output(msg->body());
  251. if (msg->attachments().size() > 0)
  252. {
  253. output("------Attachments:");
  254. foreach(QString filename, msg->attachments().keys())
  255. {
  256. output(QString("%1: Content-Type = %2, %3 bytes")
  257. .arg(filename)
  258. .arg(msg->attachment(filename).contentType())
  259. .arg(msg->attachment(filename).rawData().length()));
  260. }
  261. }
  262. output("------End of Message\n");
  263. }
  264. break;
  265. case QxtPop3Reply::Aborted:
  266. printError();
  267. output("RETR aborted.");
  268. break;
  269. case QxtPop3Reply::Timeout:
  270. output("RETR: time out.");
  271. break;
  272. default:
  273. break;
  274. }
  275. }
  276. void MainWindow::handleDele(int code)
  277. {
  278. switch (code)
  279. {
  280. case QxtPop3Reply::OK:
  281. output("DELE: OK received");
  282. break;
  283. case QxtPop3Reply::Aborted:
  284. printError();
  285. output("DELE aborted.");
  286. break;
  287. case QxtPop3Reply::Timeout:
  288. output("DELE: time out.");
  289. break;
  290. default:
  291. break;
  292. }
  293. }
  294. void MainWindow::handleRset(int code)
  295. {
  296. switch (code)
  297. {
  298. case QxtPop3Reply::OK:
  299. output("RSET: OK received");
  300. break;
  301. case QxtPop3Reply::Aborted:
  302. printError();
  303. output("RSET aborted.");
  304. break;
  305. case QxtPop3Reply::Timeout:
  306. output("RSET: time out.");
  307. break;
  308. default:
  309. break;
  310. }
  311. }
  312. void MainWindow::printError()
  313. {
  314. QObject* s = sender();
  315. if (s != 0)
  316. {
  317. QxtPop3Reply* reply = qobject_cast<QxtPop3Reply*>(s);
  318. if (reply->status() == QxtPop3Reply::Error)
  319. {
  320. output(reply->error());
  321. }
  322. }
  323. }
  324. void MainWindow::help()
  325. {
  326. output("Available commands:");
  327. output("help: print this help message\n"
  328. "quit\n"
  329. "stat\n"
  330. "list\n"
  331. "retr <nb>\n"
  332. "dele <nb>\n"
  333. "reset\n"
  334. "saveatt <attachment name>: save attachment of last retrieved message\n");
  335. }
  336. void MainWindow::connectToHost()
  337. {
  338. QString hostname = hostnameLineEdit->text();
  339. bool useSSL = sslRadioButton->isChecked();
  340. if (startTLSRadioButton->isChecked())
  341. {
  342. pop->setStartTlsDisabled(false);
  343. }
  344. else
  345. {
  346. pop->setStartTlsDisabled(true);
  347. }
  348. bool ok;
  349. int port = portLineEdit->text().toInt(&ok);
  350. if (!ok || port == 0)
  351. { // default port
  352. if (useSSL)
  353. {
  354. port = 995;
  355. }
  356. else
  357. {
  358. port = 110;
  359. }
  360. }
  361. QString username = usernameLineEdit->text();
  362. QString pass = passwordLineEdit->text();
  363. pop->setUsername(username.toLocal8Bit());
  364. pop->setPassword(pass.toLocal8Bit());
  365. if (useSSL)
  366. {
  367. pop->connectToSecureHost(hostname.toLocal8Bit(), port);
  368. }
  369. else
  370. {
  371. pop->connectToHost(hostname.toLocal8Bit(), port);
  372. }
  373. }
  374. void MainWindow::saveSettings()
  375. {
  376. QString hostname = hostnameLineEdit->text();
  377. settings->setValue("hostname", hostname);
  378. Encryption enc;
  379. if(sslRadioButton->isChecked())
  380. {
  381. enc = UseSSL;
  382. }
  383. else if (startTLSRadioButton->isChecked())
  384. {
  385. enc = UseStartTLS;
  386. }
  387. else
  388. {
  389. enc = Clear;
  390. }
  391. settings->setValue("Encryption", enc);
  392. bool ok;
  393. int port = portLineEdit->text().toInt(&ok);
  394. if (ok && port != 0) settings->setValue("port", port);
  395. QString username = usernameLineEdit->text();
  396. settings->setValue("username", username);
  397. QString pass = passwordLineEdit->text();
  398. settings->setValue("password", pass);
  399. settings->sync();
  400. }
  401. void MainWindow::connected()
  402. {
  403. connectPushButton->setDisabled(true);
  404. output("Connected to host");
  405. }
  406. void MainWindow::disconnected()
  407. {
  408. connectPushButton->setEnabled(true);
  409. output("Disconnected from Host");
  410. pop->clearReplies();
  411. }
  412. void MainWindow::handleSslError(const QByteArray& msg)
  413. {
  414. output(QString("Ssl handshake error: ") + msg);
  415. }
  416. void MainWindow::handleAuthError(const QByteArray& msg)
  417. {
  418. output(QString("Authentication error: ") + msg);
  419. }
  420. void MainWindow::progress(int percent)
  421. {
  422. output(QString("Progress: %1%").arg(percent));
  423. }