2 * CommandoJikkyouSennyou - Commando Jikkyou Sennyou Client for twitter for Qt.
4 * Author: amayav (vamayav@yahoo.co.jp)
7 * CommandoJikkyouSennyou is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * CommandoJikkyouSennyou is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with CommandoJikkyouSennyou. If not, see <http://www.gnu.org/licenses/>.
21 #include "ui_widget.h"
25 #include "extrapushbutton.h"
27 #include <QLayoutItem>
30 #include <QSslConfiguration>
31 #include <QSslCertificate>
32 #include <QDirIterator>
35 using namespace picojson;
37 #define LATEST_NUMBER_FOR_TIME 128
39 //QString _consumerKey("nXrjGagSLIQxCC4AmJ1J3g");
40 //QString _consumerSecretKey("QkTRr36zT6wAMERWqKUefyshxXIeaGzPKxB5pwMN0tg");
44 Widget::Widget(QWidget *parent)
47 _oauthManager(new KQOAuthManager(parent)),
48 _oauthRequest(new KQOAuthRequest),
49 _oauthSettings(new QSettings(qApp->applicationDirPath() + "/verification.ini",
50 QSettings::IniFormat)),
51 _shortCutKeysSettings(new QSettings(qApp->applicationDirPath() + "/key.txt",
52 QSettings::IniFormat)),
53 _sizeSettings(new QSettings(qApp->applicationDirPath() + "/size.ini",
54 QSettings::IniFormat)),
55 _proxy(new QNetworkProxy()),
58 _clockCountTimer(new QTimer),
59 _latestTweetsForTime(),
60 _subject(new WidgetDomain)
62 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf-8"));
63 QTextCodec::setCodecForTr(QTextCodec::codecForName("utf-8"));
64 QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8"));
67 this->setPostShortcutKeys();
68 this->setJikkyouShortcutKeys();
69 this->setWindowSize();
70 this->setProxyLineEdits();
71 this->setConsumerKeyAndConsumerSecretLineEdits();
72 this->setConsumerKeyAndConsumerSecret();
75 _oauthSettings->setIniCodec("utf-8");
76 if (_oauthSettings->childKeys().size() == 3) { //number, consumer_key, consumer_secret_key
77 ui->lineEdit->setText(_oauthSettings->value("number").toString());
80 this->initializeKQOAuth();
81 this->initializeOwnPostsWidgets();
84 _clockCountTimer->setInterval(1000);
85 _clockCountTimer->start();
86 connect(_clockCountTimer, SIGNAL(timeout()), this, SLOT(countDownClock()), Qt::UniqueConnection);
92 delete _oauthSettings;
93 delete _shortCutKeysSettings;
96 delete _clockCountTimer;
101 bool Widget::initializeKQOAuth(){
102 _oauthManager->setNetworkManager(new QNetworkAccessManager);
103 connect(_oauthManager->networkManager(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
104 this, SLOT(receiveSSLError(QNetworkReply*,QList<QSslError>)), Qt::UniqueConnection);
105 _oauthRequest->setEnableDebugOutput(false);
109 bool Widget::setPostShortcutKeys(){
110 // Short Cut Key for Post.
111 QList<QShortcut*> postShortCutList;
112 postShortCutList << new QShortcut(ui->lineEdit_2)
113 << new QShortcut(ui->lineEdit_3)
114 << new QShortcut(ui->lineEdit_4)
115 << new QShortcut(ui->lineEdit_5)
116 << new QShortcut(ui->lineEdit_6);
117 for(QList<QShortcut*>::const_iterator it = postShortCutList.begin();it != postShortCutList.end();++it){
118 this->setShortCutKeyAndContext(*it,
119 QKeySequence(Qt::CTRL + Qt::Key_Return),
121 connect(*it, SIGNAL(activated()), ui->postButton, SLOT(click()));
126 bool Widget::setJikkyouShortcutKeys(){
127 _shortCutKeysSettings->setIniCodec("utf-8");
128 ExtraPushButton *button;
129 for(int i=0;i<_shortCutKeysSettings->childKeys().size();++i){
130 _subject->getKeysHash()->insert(_shortCutKeysSettings->childKeys().at(i),
131 _shortCutKeysSettings->value(_shortCutKeysSettings->childKeys().at(i)).toString());
132 button = new ExtraPushButton(_shortCutKeysSettings->childKeys().at(i),
133 _shortCutKeysSettings->value(_shortCutKeysSettings->childKeys().at(i)).toString(),
135 button->setToolTip(_shortCutKeysSettings->value(_shortCutKeysSettings->childKeys().at(i)).toString());
136 ui->buttonsGridLayout->addWidget(button,0,i);
137 // Succession of slots can not go well.
138 connect(button, SIGNAL(clicked()), button, SLOT(click()));
139 connect(button, SIGNAL(clicked(QString)), this, SLOT(sendTweet(QString)));
140 connect(button, SIGNAL(showingToolTip(QString)), ui->plainTextEdit, SLOT(setPlainText(QString)));
145 bool Widget::setWindowSize(){
146 _sizeSettings->beginGroup("size");
147 if(_sizeSettings->value("width").isNull())
150 resize(_sizeSettings->value("width").toInt(), _sizeSettings->value("height").toInt());
151 _sizeSettings->endGroup();
155 bool Widget::setProxyLineEdits(){
156 _sizeSettings->beginGroup("proxy");
157 if(_sizeSettings->value("hostName").isNull()){
158 _sizeSettings->endGroup();
161 _proxy->setHostName(_sizeSettings->value("hostName").toString());
162 _proxy->setPort(_sizeSettings->value("port").toInt());
163 _proxy->setUser(_sizeSettings->value("user").toString());
164 _proxy->setPassword(_sizeSettings->value("password").toString());
165 ui->proxyHostNameLineEdit->setText(_sizeSettings->value("hostName").toString());
166 ui->proxyPortLineEdit->setText(_sizeSettings->value("port").toString());
167 ui->proxyUserLineEdit->setText(_sizeSettings->value("user").toString());
168 ui->proxyPasswordLineEdit->setText(_sizeSettings->value("password").toString());
169 _sizeSettings->endGroup();
173 bool Widget::setConsumerKeyAndConsumerSecretLineEdits(){
174 _sizeSettings->beginGroup("consumerKey");
175 if(_sizeSettings->value("consumerKey").isNull()){
176 _sizeSettings->endGroup();
179 ui->consumerKeyLineEdit->setText(_sizeSettings->value("consumerKey").toString());
180 ui->consumerSecretKeyLineEdit->setText(_sizeSettings->value("consumerSecretKey").toString());
181 _sizeSettings->endGroup();
185 bool Widget::setConsumerKeyAndConsumerSecret(){
186 _consumerKey = ui->consumerKeyLineEdit->text();
187 _consumerSecretKey = ui->consumerSecretKeyLineEdit->text();
191 bool Widget::SSLconnect(KQOAuthRequest *request)
194 _oauthRequest = request;
195 QNetworkRequest networkRequest;
196 networkRequest.setUrl( _oauthRequest->requestEndpoint() );
197 QSslConfiguration sslcon;
198 sslcon.setCaCertificates(QSslCertificate::fromPath("./veri\\.cer",
201 if(sslcon.caCertificates().size()==0){
202 throw "There is not verification file \"veri.cer\".";
204 networkRequest.setSslConfiguration(sslcon);
206 //_oauthRequest->setCallbackUrl(QUrl("oob"));
208 networkRequest.setRawHeader("Authorization", makeAuthHeaderFrom(_oauthRequest->requestParameters()));
210 connect(_oauthManager->networkManager(), SIGNAL(finished(QNetworkReply *)),
211 _oauthManager, SLOT(onRequestReplyReceived(QNetworkReply *)), Qt::UniqueConnection);
213 if (_oauthRequest->httpMethod() == KQOAuthRequest::GET) {
214 // Get the requested additional params as a list of pairs we can give QUrl
215 QList< QPair<QString, QString> > urlParams;
216 for(int i=0; i<_oauthRequest->additionalParameters().keys().size(); i++) {
217 urlParams.append( qMakePair(_oauthRequest->additionalParameters().keys().at(i),
218 _oauthRequest->additionalParameters().values().at(i)) );
221 // Take the original URL and append the query params to it.
222 QUrl urlWithParams = networkRequest.url();
223 urlWithParams.setQueryItems(urlParams);
224 networkRequest.setUrl(urlWithParams);
226 // Submit the request including the params.
227 //_replyOfUserStreamsAPI = _oauthManager->networkManager()->get(networkRequest);
228 _subject->setReplyOfUserStreamsAPI(_oauthManager->networkManager()->get(networkRequest));
229 connect(_subject->getReplyOfUserStreamsAPI(), SIGNAL(readyRead()),
230 this, SLOT(onReadyRead()), Qt::UniqueConnection);
231 connect(_subject->getReplyOfUserStreamsAPI(), SIGNAL(error(QNetworkReply::NetworkError)),
232 _oauthManager, SLOT(slotError(QNetworkReply::NetworkError)), Qt::UniqueConnection);
234 } else if (_oauthRequest->httpMethod() == KQOAuthRequest::POST) {
235 networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, _oauthRequest->contentType());
237 qDebug() << networkRequest.rawHeaderList();
238 qDebug() << networkRequest.rawHeader("Authorization");
239 qDebug() << networkRequest.rawHeader("Content-Type");
241 QNetworkReply *reply;
242 if (_oauthRequest->contentType() == "application/x-www-form-urlencoded") {
243 reply = _oauthManager->networkManager()->post(networkRequest, _oauthRequest->requestBody());
245 reply = _oauthManager->networkManager()->post(networkRequest, _oauthRequest->rawData());
248 connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
249 this, SLOT(slotError(QNetworkReply::NetworkError)), Qt::UniqueConnection);
252 qDebug() << "Unexpected HTTP Method.";
255 qDebug() << "error" << str;
260 void Widget::onReadyRead()
262 if( this->isOAuthed() == false) {
263 qDebug() << "There are not oauth_token or oauth_token_secret";
266 onRequestReadyTimeline(_subject->getReplyOfUserStreamsAPI()->readAll());
269 void Widget::receiveSSLError(QNetworkReply *reply, const QList<QSslError> &errors)
271 for(int i=0;i<errors.size();++i) {
272 qDebug() << errors.at(i);
276 bool Widget::setShortCutKeyAndContext(QShortcut *sc, QKeySequence s, Qt::ShortcutContext c)
283 bool Widget::initializeRequest(QUrl url,
284 KQOAuthRequest::RequestHttpMethod requestMethod,
285 KQOAuthRequest::RequestType requestType)
287 _oauthRequest->initRequest(requestType, url);
288 _oauthRequest->setHttpMethod(requestMethod);
289 _oauthRequest->setConsumerKey(_consumerKey);
290 _oauthRequest->setConsumerSecretKey(_consumerSecretKey);
294 bool Widget::setTokenAndSecretTokenToRequest()
296 _oauthRequest->setToken(_oauthSettings->value("oauth_token").toString());
297 _oauthRequest->setTokenSecret(
298 _oauthSettings->value("oauth_token_secret").toString());
302 bool Widget::initializeOwnPostsWidgets()
304 if( this->isOAuthed() == false){
305 qDebug() << "Not Verified Yet.";
309 qDebug("Initializing Own Posts");
310 initializeRequest(QUrl("http://api.twitter.com/1/statuses/user_timeline.json"),
311 KQOAuthRequest::GET);
312 setTokenAndSecretTokenToRequest();
313 KQOAuthParameters params;
314 params.insert("count", QByteArray::number(LATEST_NUMBER_FOR_TIME).constData());
315 _oauthRequest->setAdditionalParameters(params);
317 disconnect(_oauthManager, SIGNAL(requestReady(QByteArray)), 0, 0);
319 // I cannot understand why this connection is invalid.
320 connect(_oauthManager, SIGNAL(requestReady(QByteArray)),
321 this, SLOT(onRequestReadyOwnPosts(QByteArray)), Qt::UniqueConnection);
323 _oauthManager->executeRequest(_oauthRequest);
325 connect(_oauthManager->networkManager(), SIGNAL(finished(QNetworkReply*)),
326 this, SLOT(on_showTimeLineButton_clicked()), Qt::UniqueConnection);
328 connect(_oauthManager->networkManager(), SIGNAL(finished(QNetworkReply*)),
329 this, SLOT(readOwnPosts(QNetworkReply*)), Qt::UniqueConnection);
333 void Widget::readOwnPosts(QNetworkReply *r)
335 onRequestReadyOwnPosts(r->readAll());
338 QByteArray Widget::makeAuthHeaderFrom(QList<QByteArray> requestParameters)
342 foreach (const QByteArray header, requestParameters) {
346 result.append("OAuth ");
349 result.append(header);
354 bool Widget::isOAuthed()
356 return _oauthSettings->value("oauth_token").toString().size()
357 + _oauthSettings->value("oauth_token_secret").toString().size() > 0;
360 QString Widget::getValueOfMatchedKey()
362 QStringList list(_subject->getKeysHash()->keys());
363 unsigned int check = 0;
364 for(int i=0;i<list.size();++i){
365 if(list.at(i).startsWith(_subject->getKeyString()))
368 qDebug() << "There are too many candities.";
373 qDebug() << "There is not such a short cut key.";
376 return _subject->getKeysHash()->value(_subject->getKeyString());
379 WidgetDomain* Widget::getWidgetDomain()
384 void Widget::countDownClock(){
385 if(ui->tableWidget_2->rowCount() < LATEST_NUMBER_FOR_TIME)
387 if(_latestTweetsForTime.getPostedDateTimeList().size() == 0)
389 for(int i=0; i < ui->tableWidget_2->rowCount(); ++i){
390 //latest number for time
391 if(ui->tableWidget_2->item(i, 0) == NULL)
394 QDateTime postedTime = _latestTweetsForTime.getPostedDateTimeList().at(i);
395 QDateTime fromNow = QDateTime::currentDateTime();
396 fromNow = fromNow.addYears(-postedTime.date().year());
397 fromNow = fromNow.addMonths(-postedTime.date().month());
398 fromNow = fromNow.addDays(-postedTime.date().day());
399 fromNow = fromNow.addSecs(-postedTime.time().hour()*60*60
400 -postedTime.time().minute()*60
401 -postedTime.time().second()
403 ui->tableWidget_2->setItem(
404 LATEST_NUMBER_FOR_TIME - i - 1 , 1, new QTableWidgetItem(
405 ( (postedTime.secsTo(QDateTime::currentDateTime()) > 60*60*24)
407 QString::number(postedTime.secsTo(QDateTime::currentDateTime())/(60*60*24))
409 (postedTime.secsTo(QDateTime::currentDateTime())/(60*60*24) == 1)
410 ? ( QString("day +") )
411 : ( QString("days +") )
416 + fromNow.toString("hh:mm:ss")
419 if(postedTime.secsTo(QDateTime::currentDateTime()) <= 60*60*3){
420 for(int j=0;j<ui->tableWidget_2->columnCount();++j){
421 if(ui->tableWidget_2->item(LATEST_NUMBER_FOR_TIME - i - 1,j)==NULL)
423 ui->tableWidget_2->item(LATEST_NUMBER_FOR_TIME - i - 1,j)->setBackground(QBrush(QColor(255, 0, 0), Qt::SolidPattern));
429 void Widget::updateData()
433 bool Widget::setConsumerKeyAndConsumerSecretSettings(){
434 _sizeSettings->beginGroup("consumerKey");
435 _sizeSettings->setValue("consumerKey", ui->consumerKeyLineEdit->text());
436 _sizeSettings->setValue("consumerSecretKey", ui->consumerSecretKeyLineEdit->text());
437 _sizeSettings->endGroup();
444 void Widget::keyPressEvent(QKeyEvent *keyEvent)
446 if(keyEvent->isAutoRepeat()
447 || (keyEvent->modifiers()!=Qt::ControlModifier)
448 || (keyEvent->key()==Qt::Key_Control) )
450 setAttribute(Qt::WA_KeyCompression);
464 QString key = (keyEvent->text().toAscii().toHex().toInt(0, 16) <= 31)
465 ? QByteArray::fromHex(QByteArray::number(keyEvent->text().toAscii().toHex().toInt(0, 16) + 64, 16))
467 _subject->setKeyString(_subject->getKeyString() + key.toLower());
468 qDebug() << "Pressed Keys :" << keyEvent->text() << _subject->getKeyString() << keyEvent->count();
470 for(int i=0;i<ui->buttonsGridLayout->count();++i){
471 if(dynamic_cast<ExtraPushButton*>(ui->buttonsGridLayout->itemAt(i)->widget())->getShortCutKey().indexOf(_subject->getKeyString())==0){
474 ui->buttonsGridLayout->itemAt(i)->widget()->setEnabled(false);
478 void Widget::keyReleaseEvent(QKeyEvent *keyEvent)
480 if(keyEvent->isAutoRepeat()
481 || keyEvent->key()!=Qt::Key_Control
482 || _subject->getKeyString().size()==0 )
484 qDebug() << "ctrl!" << _subject->getKeyString();
485 QString tweet = getValueOfMatchedKey();
486 // Exception of Exchanging Strings
487 if(tweet.contains(QRegExp("\\(\\d.*\\)"))){
488 ui->plainTextEdit->setPlainText(tweet);
489 for(int i=0;i<ui->buttonsGridLayout->count();++i)
490 if(ui->buttonsGridLayout->itemAt(i)->widget()->isEnabled()==true)
491 ui->buttonsGridLayout->itemAt(i)->widget()->setEnabled(false);
492 ui->lineEdit_2->setFocus();
494 // Enable All Buttons
495 for(int i=0;i<ui->buttonsGridLayout->count();++i)
496 if(ui->buttonsGridLayout->itemAt(i)->widget()->isEnabled()==false)
497 ui->buttonsGridLayout->itemAt(i)->widget()->setEnabled(true);
500 _subject->setKeyString("");
504 void Widget::resizeEvent(QResizeEvent *)
506 _sizeSettings->beginGroup("size");
507 _sizeSettings->setValue("width", width());
508 _sizeSettings->setValue("height", height());
509 _sizeSettings->endGroup();
511 int beforeColumnsNumber =0;
512 for(int i=ui->buttonsGridLayout->columnCount()-1;i>=0;--i)
514 if(ui->buttonsGridLayout->itemAtPosition(0,i)!=NULL)
516 beforeColumnsNumber = i+1;
520 if(beforeColumnsNumber==0) {
525 for(int i=beforeColumnsNumber-1;i>=0;--i){
526 if(ui->buttonsGridLayout->itemAtPosition(0, i)!=NULL){
527 r = ui->buttonsGridLayout->itemAtPosition(0, i)->widget()->frameGeometry();
532 // When widget size becomes too small.
533 if(r.x()+r.width() > ui->groupBox->frameGeometry().x()+ui->groupBox->frameGeometry().width()){
534 int afterColumnsNumber = 0;
535 for(int i=beforeColumnsNumber-1;i>=0;--i){
536 r = ui->buttonsGridLayout->itemAtPosition(0,i)->widget()->frameGeometry();
538 < ui->groupBox->frameGeometry().x()+ui->groupBox->frameGeometry().width()){
539 afterColumnsNumber = i+1;
543 if(afterColumnsNumber==0) {
546 QList<QLayoutItem*> *list = new QList<QLayoutItem*>();
547 while(ui->buttonsGridLayout->itemAt(0)!=NULL){
548 list->append(ui->buttonsGridLayout->itemAt(0)); // There are only extraPushButtons.
549 ui->buttonsGridLayout->removeItem(ui->buttonsGridLayout->itemAt(0));
551 for(int i=0;i<list->size();++i){
552 ui->buttonsGridLayout->addItem(list->at(i),
553 floor((double)i/(double)afterColumnsNumber),
554 i%afterColumnsNumber);
557 // When widget size becomes too big
558 else if(r.x() + r.width() + ui->buttonsGridLayout->horizontalSpacing() + r.width()
559 < ui->groupBox->x() + ui->groupBox->frameGeometry().width()){
560 int afterColumnsNumber = 0;
561 for(int i=1;i<200;++i){
562 if(r.x()+r.width() + i*(ui->buttonsGridLayout->horizontalSpacing() + ui->buttonsGridLayout->itemAt(0)->widget()->width())
563 > ui->groupBox->frameGeometry().x()+ui->groupBox->frameGeometry().width()){
564 afterColumnsNumber = beforeColumnsNumber+i;
568 if(afterColumnsNumber > ui->buttonsGridLayout->count() || afterColumnsNumber==0){
571 QList<QLayoutItem*> *list = new QList<QLayoutItem*>();
572 while(ui->buttonsGridLayout->itemAt(0)!=NULL){
573 list->append(ui->buttonsGridLayout->itemAt(0)); // There are only extraPushButtons.
574 ui->buttonsGridLayout->removeItem(ui->buttonsGridLayout->itemAt(0));
576 for(int i=0;i<list->size();++i){
577 ui->buttonsGridLayout->addItem(list->at(i),
578 floor((double)i/(double)afterColumnsNumber),
579 i%afterColumnsNumber);
584 void Widget::showEvent(QShowEvent *)
586 // Here is for use of resizeEvent() when program is going to start.
587 resize(size()-QSize(1,0));
588 resize(size()+QSize(1,0));
594 void Widget::onTemporaryTokenReceived(QString token, QString tokenSecret)
596 if( _oauthManager->lastError() != KQOAuthManager::NoError) {
599 qDebug() << "Opening authorization web site: " << QUrl("https://api.twitter.com/oauth/authorize");
600 _oauthManager->getUserAuthorization(QUrl("https://api.twitter.com/oauth/authorize"));
603 void Widget::onAuthorizationReceived(QString token, QString verifier)
605 qDebug() << "User authorization received: " << token << verifier;
607 _oauthManager->getUserAccessTokens(QUrl(tr("https://api.twitter.com/oauth/access_token")));
608 if (_oauthManager->lastError() != KQOAuthManager::NoError) {
609 showOAuthError(_oauthManager->lastError());
610 //QCoreApplication::exit();
614 void Widget::onAccessTokenReceived(QString token, QString tokenSecret)
616 qDebug() << "Access token received: " << token << tokenSecret;
618 _oauthSettings->setValue(tr("oauth_token"), token);
619 _oauthSettings->setValue(tr("oauth_token_secret"), tokenSecret);
621 qDebug() << "Access tokens now stored. "
622 "You are ready to send Tweets from user's account!";
624 this->initializeOwnPostsWidgets();
625 //QCoreApplication::exit();
628 void Widget::onAuthorizedRequestDone() {
629 qDebug() << "Request sent to Twitter!";
630 //QCoreApplication::exit(0);
633 void Widget::onRequestReady(QByteArray response)
635 if(response.size()<=0){
636 showOAuthError(_oauthManager->lastError());
639 qDebug() << "Response from the service: " << response;
642 void Widget::on_authorizationButton_clicked() {
643 qDebug() << "Attempting new consumer key and consumer secret.";
645 _subject->getReplyOfUserStreamsAPI()->disconnect(this);
646 _subject->getReplyOfUserStreamsAPI()->disconnect(SIGNAL(error(QNetworkReply::NetworkError)));
648 this->setConsumerKeyAndConsumerSecretSettings();
649 this->setConsumerKeyAndConsumerSecret();
650 ui->lineEdit->clear();
651 _oauthSettings->clear();
652 ui->lineEdit->setEnabled(true);
653 ui->verificationButton->setEnabled(true);
655 delete _oauthManager;
656 _oauthManager = new KQOAuthManager();
657 this->initializeKQOAuth();
658 this->initializeOwnPostsWidgets();
661 connect(_oauthManager, SIGNAL(temporaryTokenReceived(QString,QString)),
662 this, SLOT(onTemporaryTokenReceived(QString, QString)), Qt::UniqueConnection);
664 connect(_oauthManager, SIGNAL(authorizationReceived(QString,QString)),
665 this, SLOT(onAuthorizationReceived(QString, QString)), Qt::UniqueConnection);
667 connect(_oauthManager, SIGNAL(accessTokenReceived(QString,QString)),
668 this, SLOT(onAccessTokenReceived(QString,QString)), Qt::UniqueConnection);
670 connect(_oauthManager, SIGNAL(requestReady(QByteArray)),
671 this, SLOT(onRequestReady(QByteArray)), Qt::UniqueConnection);
673 // Start OAuth Verification.
674 this->initializeRequest(QUrl("https://api.twitter.com/oauth/request_token"),
675 KQOAuthRequest::POST,
676 KQOAuthRequest::TemporaryCredentials);
678 _oauthManager->setHandleUserAuthorization(true);
679 //_oauthManager->setHandleUserAuthorization(false);
681 _oauthManager->executeRequest(_oauthRequest);
684 if (_oauthManager->lastError() != KQOAuthManager::NoError) {
685 qDebug("authorization error");
686 showOAuthError(_oauthManager->lastError());
690 void Widget::on_showTimeLineButton_clicked() {
691 disconnect(_oauthManager->networkManager(), SIGNAL(finished(QNetworkReply*)),
692 this, SLOT(on_showTimeLineButton_clicked()));
694 if( this->isOAuthed() == false){
695 qDebug() << "Not Verified Yet.";
698 qDebug("Attempting reading TimeLine.");
700 ui->listWidget->clear();
702 //QUrl("https://api.twitter.com/1/statuses/home_timeline.json");
703 initializeRequest(QUrl("https://userstream.twitter.com/2/user.json"),
704 KQOAuthRequest::GET);
705 setTokenAndSecretTokenToRequest();
707 connect(_oauthManager, SIGNAL(requestReady(QByteArray)),
708 this, SLOT(onRequestReadyTimeline(QByteArray)), Qt::UniqueConnection);
710 // connect(_oauthManager, SIGNAL(authorizedRequestDone()),
711 // this, SLOT(onAuthorizedRequestDone()));
713 //_oauthManager->executeRequest(_oauthRequest);
714 this->SSLconnect(_oauthRequest);
716 if (_oauthManager->lastError() != KQOAuthManager::NoError) {
717 qDebug("Showing timeline error.");
718 showOAuthError(_oauthManager->lastError());
722 void Widget::onRequestReadyTimeline(QByteArray response) {
723 qDebug("Reading TimeLine");
725 qDebug("This is JSON format.");
726 if(response.startsWith("{\"friends\":[")) { // User Streams
727 response = QString(response).remove(QRegExp("(\\{\"friends\":\\[[\\d,]+\\]\\}|\\r|\\n)")).toUtf8();
731 parse(value, response.data(), response.data() + response.size(), &error);
733 cerr << error << endl;
737 if(value.to_str() == string("array")){
738 array jsonArray = value.get<array>();
740 ui->listWidget->clear();
741 for (it = jsonArray.begin(); it != jsonArray.end(); ++it)
743 jsonObject = it->get<object>();
744 qDebug() << QString::fromStdString(jsonObject["text"].to_str());
745 if(!QString::fromStdString(jsonObject["text"].to_str()).contains("#commando")){
746 ui->listWidget->addItem(QString::fromStdString(jsonObject["text"].to_str()));
750 else if(value.to_str() == string("object")){
751 jsonObject = value.get<object>();
752 qDebug() << QString::fromStdString(jsonObject["text"].to_str());
753 if(QString::fromStdString(jsonObject["text"].to_str()).contains("#commando")){
754 ui->listWidget->addItem(QString::fromStdString(jsonObject["text"].to_str()));
757 ui->listWidget->scrollToBottom();
764 ["created_at"].toString() <<
768 ["id"].toLongLong() <<
770 ["id_str"].toString() <<
772 ["in_reply_to_screen_name"] <<
774 ["in_reply_to_status_id"]<<
776 ["in_reply_to_status_id"] <<
778 ["in_reply_to_user_id"] <<
780 ["in_reply_to_user_id_str"] <<
784 ["possibly_sensitive"].toBool() <<
786 ["retweet_count"].toULongLong() <<
788 ["retweeted"].toBool() <<
790 ["text"].toString() <<
792 ["truncated"].toBool() <<
794 ["user"]["contributors_enabled"].toBool() <<
796 ["user"]["created_at"].toString() <<
798 ["user"]["default_profile"].toBool() <<
800 ["user"]["default_profile_image"].toBool() <<
802 ["user"]["description"].toString() <<
804 ["user"]["favourites_count"].toULongLong() <<
806 ["user"]["followers_count"].toULongLong() <<
808 ["user"]["following"].toBool() <<
810 ["user"]["friends_count"].toULongLong() <<
812 ["user"]["geo_enabled"].toBool() <<
814 ["user"]["id"].toULongLong() <<
816 ["user"]["id_str"].toString() <<
818 ["user"]["is_translator"].toBool() <<
820 ["user"]["lang"].toString() <<
822 ["user"]["listed_count"].toULongLong() <<
824 ["user"]["location"].toString() <<
826 ["user"]["profile_background_color"].toString() <<
828 ["user"]["profile_background_image_url"].toString() <<
830 ["user"]["profile_background_image_url_https"].toString() <<
832 ["user"]["profile_background_tile"].toBool() <<
834 ["user"]["profile_image_url_https"].toString() <<
836 ["user"]["profile_sidebar_border_color"].toString() <<
838 ["user"]["profile_sidebar_fill_color"].toString() <<
840 ["user"]["profile_text_color"].toString() <<
842 ["user"]["profile_use_background_image"].toString() <<
844 ["user"]["protected"].toBool() <<
846 ["user"]["screen_name"].toBool() <<
848 ["user"]["show_all_inline_media"].toString() <<
850 ["user"]["statuses_count"].toULongLong() <<
852 ["user"]["time_zone"].toString() <<
854 ["user"]["url"].toString() <<
856 ["user"]["utc_offset"].toULongLong() <<
858 ["user"]["verified"].toBool() <<
863 void Widget::onRequestReadyOwnPosts(QByteArray response) {
864 qDebug() << "Request ready own posts";
866 qDebug("This is JSON format.");
869 parse(valueA, response.data(), response.data() + response.size(), &error);
871 qDebug() << response;
872 cerr << error << endl;
876 if(valueA.to_str() == string("array")){
877 int tweetNumberBeforeNow=0;
878 QHash<QString, int> monthsHash;
879 monthsHash.insert("Jan", 1);
880 monthsHash.insert("Feb", 2);
881 monthsHash.insert("Mar", 3);
882 monthsHash.insert("Apr", 4);
883 monthsHash.insert("May", 5);
884 monthsHash.insert("Jun", 6);
885 monthsHash.insert("Jul", 7);
886 monthsHash.insert("Aug", 8);
887 monthsHash.insert("Sep", 9);
888 monthsHash.insert("Oct", 10);
889 monthsHash.insert("Nov", 11);
890 monthsHash.insert("Dec", 12);
892 for(array::iterator it = valueA.get<array>().begin(); it != valueA.get<array>().end(); ++it){
893 jsonObject = it->get<object>();
895 // When latest 127 posts are in 3 hours, a new post is forbidden.
896 // as "Sat Feb 25 15:55:23 +0000 2012"
897 QStringList dateTimeElements = QString::fromStdString(jsonObject["created_at"].to_str()).split(" ");
898 QStringList timeElements = dateTimeElements.at(3).split(":");
899 QDateTime postedDateTime = QDateTime(QDate(dateTimeElements.at(5).toInt(),
900 monthsHash.value(dateTimeElements.at(1)),
901 dateTimeElements.at(2).toInt()
903 QTime(timeElements.at(0).toInt(),
904 timeElements.at(1).toInt(),
905 timeElements.at(2).toInt()
908 ).toTimeSpec(Qt::LocalTime);
909 _latestTweetsForTime.appendPostedDateTimeList(postedDateTime);
911 ui->tableWidget_2->setItem(
912 LATEST_NUMBER_FOR_TIME - tweetNumberBeforeNow - 1, 0,
913 new QTableWidgetItem(
914 postedDateTime.toString("dd, hh:mm:ss")
919 if(tweetNumberBeforeNow<10){
920 ui->tableWidget->setItem(10-tweetNumberBeforeNow-1, 0, new QTableWidgetItem(QString::fromStdString(jsonObject["text"].to_str()))); //posted contents
922 ++tweetNumberBeforeNow;
925 else if(valueA.to_str() == string("object")){
926 jsonObject = valueA.get<object>();
927 qDebug() << QString::fromStdString(jsonObject["text"].to_str());
928 if(QString::fromStdString(jsonObject["text"].to_str()).contains("#commando")){
929 ui->listWidget->addItem(QString::fromStdString(jsonObject["text"].to_str()));
934 void Widget::sendTweet(QString tweet) {
936 if( this->isOAuthed() == false) {
937 qDebug() << "No access tokens. Aborting.";
942 qDebug() << "There are no characters.";
946 tweet.replace(QRegExp("\\(\\d+:([^()]+)\\)"), "\\1");
947 tweet.append(" #commando");
949 initializeRequest(QUrl("https://api.twitter.com/1/statuses/update.xml"));
950 setTokenAndSecretTokenToRequest();
951 KQOAuthParameters params;
952 params.insert("status", tweet);
953 _oauthRequest->setAdditionalParameters(params);
955 disconnect(_oauthManager, SIGNAL(requestReady(QByteArray)),0,0);
957 qDebug() << "Attempting send tweet such as " << tweet;
958 _oauthManager->executeRequest(_oauthRequest);
960 ui->tableWidget->removeRow(0);
961 ui->tableWidget->setRowCount(ui->tableWidget->rowCount()+1);
962 ui->tableWidget->setItem(9,0,new QTableWidgetItem(tweet));
964 ui->tableWidget_2->removeRow(0);
965 ui->tableWidget_2->setRowCount(ui->tableWidget_2->rowCount()+1);
966 ui->tableWidget_2->setItem(129,0, new QTableWidgetItem( (QDateTime::currentDateTime().toString("dd hh:mm:ss"))));
967 // connect(_oauthManager, SIGNAL(authorizedRequestReady()),
968 // this, SLOT(onAuthorizedRequestReady()));
970 // LineEdits must clear contents.
971 ui->lineEdit_2->clear();
972 ui->lineEdit_3->clear();
973 ui->lineEdit_4->clear();
974 ui->lineEdit_5->clear();
975 ui->lineEdit_6->clear();
978 void Widget::showOAuthError(const int nErrNum)
980 qDebug() << "error is " << nErrNum;
983 void Widget::on_verificationButton_clicked()
985 ui->lineEdit->setEnabled(false);
986 ui->verificationButton->setEnabled(false);
987 _oauthSettings->setValue("number", ui->lineEdit->text());
988 _oauthManager->onVerificationReceived1(_oauthSettings->value("number").toString());
991 void Widget::on_postButton_clicked()
993 QString tweet = ui->plainTextEdit->toPlainText();
997 void Widget::on_lineEdit_2_textChanged(const QString &arg1)
999 replacePlainTextEditContent(1, arg1);
1002 void Widget::on_lineEdit_3_textChanged(const QString &arg1)
1004 replacePlainTextEditContent(1, arg1);
1007 void Widget::on_lineEdit_4_textChanged(const QString &arg1)
1009 replacePlainTextEditContent(1, arg1);
1012 void Widget::on_lineEdit_5_textChanged(const QString &arg1)
1014 replacePlainTextEditContent(1, arg1);
1017 void Widget::on_lineEdit_6_textChanged(const QString &arg1)
1019 replacePlainTextEditContent(1, arg1);
1022 bool Widget::replacePlainTextEditContent(int i, QString str)
1026 QString text = ui->plainTextEdit->toPlainText();
1027 text.replace(QRegExp("(\\(" + QString::number(i) + ":)[^()]+(\\))"), "\\1" + str + "\\2");
1028 ui->plainTextEdit->setPlainText(text);
1033 bool Widget::SetButtonsEnable(bool on)
1035 for(int i=0;i<ui->buttonsGridLayout->count();++i)
1037 if(ui->buttonsGridLayout->itemAt(i)->widget()->isEnabled()== (!on))
1039 ui->buttonsGridLayout->itemAt(i)->widget()->setEnabled(on);
1045 void Widget::on_proxyButton_clicked()
1047 _proxy->setHostName(ui->proxyHostNameLineEdit->text());
1048 _proxy->setPort(ui->proxyPortLineEdit->text().toInt());
1049 _proxy->setUser(ui->proxyUserLineEdit->text());
1050 _proxy->setUser(ui->proxyPasswordLineEdit->text());
1052 _sizeSettings->beginGroup("proxy");
1053 _sizeSettings->setValue("hostName", ui->proxyHostNameLineEdit->text());
1054 _sizeSettings->setValue("port", ui->proxyPortLineEdit->text());
1055 _sizeSettings->setValue("user", ui->proxyUserLineEdit->text());
1056 _sizeSettings->setValue("password", ui->proxyPasswordLineEdit->text());
1057 _sizeSettings->endGroup();