diff --git a/helperlibs/twitterapihelper/twitterapitextedit.cpp b/helperlibs/twitterapihelper/twitterapitextedit.cpp index 960707f1..ea16b922 100644 --- a/helperlibs/twitterapihelper/twitterapitextedit.cpp +++ b/helperlibs/twitterapihelper/twitterapitextedit.cpp @@ -1,282 +1,185 @@ /* This file is part of Choqok, the KDE micro-blogging client Copyright (C) 2010-2012 Mehrdad Momeny This program 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program 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 this program; if not, see http://www.gnu.org/licenses/ */ #include "twitterapitextedit.h" #include -#include #include -#include #include #include #include #include "urlutils.h" #include "twitterapiaccount.h" #include "twitterapidebug.h" -#include "twitterapimicroblog.h" class TwitterApiTextEdit::Private { public: Private(Choqok::Account *theAccount) - : acc(theAccount), c(0), tCoMaximumLength(0), tCoMaximumLengthHttps(0) + : acc(theAccount), c(0) {} Choqok::Account *acc; QCompleter *c; - int tCoMaximumLength; - int tCoMaximumLengthHttps; }; TwitterApiTextEdit::TwitterApiTextEdit(Choqok::Account *theAccount, QWidget *parent) : TextEdit(theAccount->postCharLimit(), parent), d(new Private(theAccount)) { qCDebug(CHOQOK); setTabChangesFocus(false); - fetchTCoMaximumLength(); } TwitterApiTextEdit::~TwitterApiTextEdit() { delete d; } void TwitterApiTextEdit::setCompleter(QCompleter *completer) { if (d->c) { QObject::disconnect(d->c, 0, this, 0); } d->c = completer; if (!d->c) { return; } d->c->setWidget(this); d->c->setCompletionMode(QCompleter::PopupCompletion); d->c->setCaseSensitivity(Qt::CaseInsensitive); QObject::connect(d->c, SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString))); } QCompleter *TwitterApiTextEdit::completer() const { return d->c; } void TwitterApiTextEdit::insertCompletion(const QString &completion) { if (d->c->widget() != this) { return; } QString textToInsert = completion + QLatin1Char(' '); QTextCursor tc = textCursor(); tc.movePosition(QTextCursor::EndOfWord); tc.select(QTextCursor::WordUnderCursor); bool startWithAt = toPlainText()[tc.selectionStart() - 1] != QLatin1Char('@'); if (startWithAt) { textToInsert.prepend(QLatin1Char('@')); } tc.insertText(textToInsert); setTextCursor(tc); } // QString TwitterApiTextEdit::textUnderCursor() const // { // QTextCursor tc = textCursor(); // tc.select(QTextCursor::WordUnderCursor); // return tc.selectedText(); // } void TwitterApiTextEdit::focusInEvent(QFocusEvent *e) { if (d->c) { d->c->setWidget(this); } KTextEdit::focusInEvent(e); } void TwitterApiTextEdit::keyPressEvent(QKeyEvent *e) { if (d->c && d->c->popup()->isVisible()) { // The following keys are forwarded by the completer to the widget switch (e->key()) { case Qt::Key_Enter: case Qt::Key_Return: case Qt::Key_Escape: // case Qt::Key_Backtab: e->ignore(); return; // let the completer do default behavior default: // Choqok::UI::TextEdit::keyPressEvent(e); break; } } else if (e->text().isEmpty()) { Choqok::UI::TextEdit::keyPressEvent(e); return; } if (e->key() == Qt::Key_Tab) { e->ignore(); return; } // bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_Space); // CTRL+E // if (!d->c )// || !isShortcut) // don't process the shortcut when we have a completer Choqok::UI::TextEdit::keyPressEvent(e); const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier | Qt::AltModifier | Qt::MetaModifier); if (!d->c || (ctrlOrShift && e->text().isEmpty())) { return; } static QString eow(QLatin1String("~!@#$%^&*()+{}|:\"<>?,./;'[]\\-= ")); // end of word // bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift; //Implemented internally to get the char before selection :D QTextCursor tc = textCursor(); tc.select(QTextCursor::WordUnderCursor); QString completionPrefix = tc.selectedText(); QChar charBeforeSelection; if (completionPrefix.startsWith(QLatin1Char('@'))) { charBeforeSelection = completionPrefix.at(0); completionPrefix.remove(0, 1); } else { if (!toPlainText().isEmpty() && tc.selectionStart() > 0) { charBeforeSelection = toPlainText()[tc.selectionStart() - 1]; } } if (!e->text().isEmpty() && (eow.contains(e->text().right(1)) || completionPrefix.length() < 1 || charBeforeSelection != QLatin1Char('@'))) { d->c->popup()->hide(); return; } else if ((e->key() != Qt::Key_Enter) && (e->key() != Qt::Key_Return)) { if (textCursor().selectedText().length() && textCursor().selectedText() != completionPrefix) { return; } if (completionPrefix != d->c->completionPrefix()) { d->c->setCompletionPrefix(completionPrefix); d->c->popup()->setCurrentIndex(d->c->completionModel()->index(0, 0)); } QRect cr = cursorRect(); cr.setWidth(d->c->popup()->sizeHintForColumn(0) + d->c->popup()->verticalScrollBar()->sizeHint().width()); d->c->complete(cr); // popup it up! } } - -void TwitterApiTextEdit::updateRemainingCharsCount() -{ - QString txt = this->toPlainText(); - int count = txt.count(); - if (count) { - lblRemainChar->show(); - if (charLimit()) { - int remain = charLimit() - count; - - for (const QString &url: UrlUtils::detectUrls(txt)) { - // Twitter does not wrapps urls with login informations - if (!url.contains(QLatin1Char('@'))) { - int diff = -1; - if (url.startsWith(QLatin1String("http://"))) { - diff = url.length() - d->tCoMaximumLength; - } else if (url.startsWith(QLatin1String("https://"))) { - diff = url.length() - d->tCoMaximumLengthHttps; - } - - if (diff > 0) { - remain += diff; - } - } - } - - if (remain < 0) { - lblRemainChar->setStyleSheet(QLatin1String("QLabel {color: red;}")); - } else if (remain < 30) { - lblRemainChar->setStyleSheet(QLatin1String("QLabel {color: rgb(242, 179, 19);}")); - } else { - lblRemainChar->setStyleSheet(QLatin1String("QLabel {color: green;}")); - } - lblRemainChar->setText(QString::number(remain)); - } else { - lblRemainChar->setText(QString::number(count)); - lblRemainChar->setStyleSheet(QLatin1String(QLatin1String("QLabel {color: blue;}"))); - } - txt.remove(QRegExp(QLatin1String("@([^\\s\\W]+)"))); - txt = txt.trimmed(); - if (firstChar() != txt[0]) { - setFirstChar(txt[0]); - txt.prepend(QLatin1Char(' ')); - QTextBlockFormat f; - f.setLayoutDirection((Qt::LayoutDirection) txt.isRightToLeft()); - textCursor().mergeBlockFormat(f); - } - } else { - lblRemainChar->hide(); - } -} - -void TwitterApiTextEdit::fetchTCoMaximumLength() -{ - TwitterApiAccount *acc = qobject_cast(d->acc); - if (acc) { - QUrl url = acc->apiUrl(); - url.setPath(url.path() + QLatin1String("/help/configuration.json")); - - KIO::StoredTransferJob *job = KIO::storedGet(url, KIO::Reload, KIO::HideProgressInfo); - if (!job) { - qCDebug(CHOQOK) << "Cannot create an http GET request!"; - return; - } - TwitterApiMicroBlog *mBlog = qobject_cast(acc->microblog()); - job->addMetaData(QStringLiteral("customHTTPHeader"), - QStringLiteral("Authorization: ") + - QLatin1String(mBlog->authorizationHeader(acc, url, QOAuth::GET))); - connect(job, SIGNAL(result(KJob*)), this, SLOT(slotTCoMaximumLength(KJob*))); - job->start(); - } else { - qCDebug(CHOQOK) << "the account is not a TwitterAPIAccount!"; - } -} - -void TwitterApiTextEdit::slotTCoMaximumLength(KJob *job) -{ - if (job->error()) { - qCDebug(CHOQOK) << "Job Error:" << job->errorString(); - } else { - KIO::StoredTransferJob *j = qobject_cast(job); - const QJsonDocument json = QJsonDocument::fromJson(j->data()); - if (!json.isNull()) { - const QVariantMap reply = json.toVariant().toMap(); - d->tCoMaximumLength = reply[QLatin1String("short_url_length")].toInt(); - d->tCoMaximumLengthHttps = reply[QLatin1String("short_url_length_https")].toInt(); - } else { - qCDebug(CHOQOK) << "Cannot parse JSON reply"; - } - } -} diff --git a/helperlibs/twitterapihelper/twitterapitextedit.h b/helperlibs/twitterapihelper/twitterapitextedit.h index dfaafbdf..f25ef0b7 100644 --- a/helperlibs/twitterapihelper/twitterapitextedit.h +++ b/helperlibs/twitterapihelper/twitterapitextedit.h @@ -1,65 +1,60 @@ /* This file is part of Choqok, the KDE micro-blogging client Copyright (C) 2010-2012 Mehrdad Momeny This program 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program 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 this program; if not, see http://www.gnu.org/licenses/ */ #ifndef TWITTERAPITEXTEDIT_H #define TWITTERAPITEXTEDIT_H #include #include "account.h" #include "choqoktextedit.h" #include "choqok_export.h" class KJob; class CHOQOK_HELPER_EXPORT TwitterApiTextEdit : public Choqok::UI::TextEdit { Q_OBJECT public: explicit TwitterApiTextEdit(Choqok::Account *theAccount, QWidget *parent = 0); ~TwitterApiTextEdit(); void setCompleter(QCompleter *c); QCompleter *completer() const; -protected Q_SLOTS: - virtual void updateRemainingCharsCount() override; - protected: void keyPressEvent(QKeyEvent *e) override; void focusInEvent(QFocusEvent *e) override; private Q_SLOTS: void insertCompletion(const QString &completion); - void slotTCoMaximumLength(KJob *job); private: // QString textUnderCursor() const; - void fetchTCoMaximumLength(); class Private; Private *const d; }; #endif // TWITTERAPITEXTEDIT_H diff --git a/microblogs/twitter/CMakeLists.txt b/microblogs/twitter/CMakeLists.txt index 3b16521b..2621e18b 100644 --- a/microblogs/twitter/CMakeLists.txt +++ b/microblogs/twitter/CMakeLists.txt @@ -1,44 +1,45 @@ include_directories( ${CHOQOK_INCLUDES} ) set(choqok_twitter_SRCS twittercomposerwidget.cpp twitteraccount.cpp twitterdebug.cpp twitterdmessagedialog.cpp twittermicroblog.cpp twitterpostwidget.cpp twittersearch.cpp + twittertextedit.cpp twittereditaccount.cpp twitterlistdialog.cpp twittertimelinewidget.cpp ) ki18n_wrap_ui(choqok_twitter_SRCS twittereditaccount_base.ui twitterlistdialog_base.ui ) add_library(choqok_twitter MODULE ${choqok_twitter_SRCS}) kcoreaddons_desktop_to_json(choqok_twitter choqok_twitter.desktop) target_link_libraries(choqok_twitter Qt5::Core Qt5::Widgets KF5::CoreAddons KF5::I18n KF5::KIOCore KF5::KIOWidgets KF5::WidgetsAddons ${QTOAUTH_LIBRARY} qca-qt5 choqok twitterapihelper ) install(TARGETS choqok_twitter DESTINATION ${PLUGIN_INSTALL_DIR}) install(FILES choqok_twitter.desktop DESTINATION ${SERVICES_INSTALL_DIR}) add_subdirectory(icons) diff --git a/microblogs/twitter/twittercomposerwidget.cpp b/microblogs/twitter/twittercomposerwidget.cpp index 23690448..b60ecd29 100644 --- a/microblogs/twitter/twittercomposerwidget.cpp +++ b/microblogs/twitter/twittercomposerwidget.cpp @@ -1,166 +1,177 @@ /* This file is part of Choqok, the KDE micro-blogging client Copyright (C) 2008-2012 Mehrdad Momeny This program 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program 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 this program; if not, see http://www.gnu.org/licenses/ */ #include "twittercomposerwidget.h" #include #include #include #include #include +#include #include #include #include "account.h" #include "choqoktextedit.h" #include "notifymanager.h" #include "shortenmanager.h" +#include "twitterapiaccount.h" + #include "twitterdebug.h" #include "twittermicroblog.h" +#include "twittertextedit.h" class TwitterComposerWidget::Private { public: Private() : btnAttach(0), mediumName(0), btnCancel(0) {} QString mediumToAttach; QPushButton *btnAttach; QPointer mediumName; QPointer btnCancel; QGridLayout *editorLayout; }; TwitterComposerWidget::TwitterComposerWidget(Choqok::Account *account, QWidget *parent) : TwitterApiComposerWidget(account, parent), d(new Private) { + TwitterTextEdit *edit = new TwitterTextEdit(account, this); + QStringListModel *model = new QStringListModel(qobject_cast(account)->friendsList(), this); + QCompleter *completer = new QCompleter(model, this); + completer->setCaseSensitivity(Qt::CaseInsensitive); + edit->setCompleter(completer); + setEditor(edit); + d->editorLayout = qobject_cast(editorContainer()->layout()); d->btnAttach = new QPushButton(editorContainer()); d->btnAttach->setIcon(QIcon::fromTheme(QLatin1String("mail-attachment"))); d->btnAttach->setToolTip(i18n("Attach a file")); d->btnAttach->setMaximumWidth(d->btnAttach->height()); connect(d->btnAttach, SIGNAL(clicked(bool)), this, SLOT(selectMediumToAttach())); QVBoxLayout *vLayout = new QVBoxLayout; vLayout->addWidget(d->btnAttach); vLayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Preferred, QSizePolicy::MinimumExpanding)); d->editorLayout->addItem(vLayout, 0, 1, 1, 1); } TwitterComposerWidget::~TwitterComposerWidget() { delete d; } void TwitterComposerWidget::submitPost(const QString &txt) { if (d->mediumToAttach.isEmpty()) { Choqok::UI::ComposerWidget::submitPost(txt); } else { qCDebug(CHOQOK); editorContainer()->setEnabled(false); QString text = txt; if (currentAccount()->postCharLimit() && text.size() > (int)currentAccount()->postCharLimit()) { text = Choqok::ShortenManager::self()->parseText(text); } setPostToSubmit(nullptr); setPostToSubmit(new Choqok::Post); postToSubmit()->content = text; if (!replyToId.isEmpty()) { postToSubmit()->replyToPostId = replyToId; } connect(currentAccount()->microblog(), SIGNAL(postCreated(Choqok::Account*,Choqok::Post*)), SLOT(slotPostMediaSubmitted(Choqok::Account*,Choqok::Post*))); connect(currentAccount()->microblog(), SIGNAL(errorPost(Choqok::Account *, Choqok::Post *, Choqok::MicroBlog::ErrorType, QString, Choqok::MicroBlog::ErrorLevel)), SLOT(slotErrorPost(Choqok::Account*,Choqok::Post*))); btnAbort = new QPushButton(QIcon::fromTheme(QLatin1String("dialog-cancel")), i18n("Abort"), this); layout()->addWidget(btnAbort); connect(btnAbort, SIGNAL(clicked(bool)), SLOT(abort())); TwitterMicroBlog *mBlog = qobject_cast(currentAccount()->microblog()); mBlog->createPostWithAttachment(currentAccount(), postToSubmit(), d->mediumToAttach); } } void TwitterComposerWidget::slotPostMediaSubmitted(Choqok::Account *theAccount, Choqok::Post *post) { qCDebug(CHOQOK); if (currentAccount() == theAccount && post == postToSubmit()) { qCDebug(CHOQOK) << "Accepted"; disconnect(currentAccount()->microblog(), SIGNAL(postCreated(Choqok::Account*,Choqok::Post*)), this, SLOT(slotPostMediaSubmitted(Choqok::Account*,Choqok::Post*))); disconnect(currentAccount()->microblog(), SIGNAL(errorPost(Choqok::Account *, Choqok::Post *, Choqok::MicroBlog::ErrorType, QString, Choqok::MicroBlog::ErrorLevel)), this, SLOT(slotErrorPost(Choqok::Account*,Choqok::Post*))); if (btnAbort) { btnAbort->deleteLater(); } Choqok::NotifyManager::success(i18n("New post submitted successfully")); editor()->clear(); replyToId.clear(); editorContainer()->setEnabled(true); setPostToSubmit(nullptr); cancelAttachMedium(); currentAccount()->microblog()->updateTimelines(currentAccount()); } } void TwitterComposerWidget::selectMediumToAttach() { qCDebug(CHOQOK); d->mediumToAttach = QFileDialog::getOpenFileName(this, i18n("Select Media to Upload"), QString(), QStringLiteral("Images")); if (d->mediumToAttach.isEmpty()) { return; } QString fileName = QUrl(d->mediumToAttach).fileName(); if (!d->mediumName) { qCDebug(CHOQOK) << fileName; d->mediumName = new QLabel(editorContainer()); d->btnCancel = new QPushButton(editorContainer()); d->btnCancel->setIcon(QIcon::fromTheme(QLatin1String("list-remove"))); d->btnCancel->setToolTip(i18n("Discard Attachment")); d->btnCancel->setMaximumWidth(d->btnCancel->height()); connect(d->btnCancel, SIGNAL(clicked(bool)), SLOT(cancelAttachMedium())); d->editorLayout->addWidget(d->mediumName, 1, 0); d->editorLayout->addWidget(d->btnCancel, 1, 1); } d->mediumName->setText(i18n("Attaching %1", fileName)); editor()->setFocus(); } void TwitterComposerWidget::cancelAttachMedium() { qCDebug(CHOQOK); delete d->mediumName; d->mediumName = 0; delete d->btnCancel; d->btnCancel = 0; d->mediumToAttach.clear(); } diff --git a/helperlibs/twitterapihelper/twitterapitextedit.cpp b/microblogs/twitter/twittertextedit.cpp similarity index 50% copy from helperlibs/twitterapihelper/twitterapitextedit.cpp copy to microblogs/twitter/twittertextedit.cpp index 960707f1..ae3b67e2 100644 --- a/helperlibs/twitterapihelper/twitterapitextedit.cpp +++ b/microblogs/twitter/twittertextedit.cpp @@ -1,282 +1,149 @@ /* This file is part of Choqok, the KDE micro-blogging client - Copyright (C) 2010-2012 Mehrdad Momeny + Copyright (C) 2017 Andrea Scarpino This program 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program 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 this program; if not, see http://www.gnu.org/licenses/ */ +#include "twittertextedit.h" -#include "twitterapitextedit.h" - -#include #include -#include #include -#include #include -#include - #include "urlutils.h" #include "twitterapiaccount.h" -#include "twitterapidebug.h" #include "twitterapimicroblog.h" -class TwitterApiTextEdit::Private +#include "twitterdebug.h" + +class TwitterTextEdit::Private { public: Private(Choqok::Account *theAccount) - : acc(theAccount), c(0), tCoMaximumLength(0), tCoMaximumLengthHttps(0) + : acc(theAccount), tCoMaximumLength(0), tCoMaximumLengthHttps(0) {} Choqok::Account *acc; - QCompleter *c; int tCoMaximumLength; int tCoMaximumLengthHttps; }; -TwitterApiTextEdit::TwitterApiTextEdit(Choqok::Account *theAccount, QWidget *parent) - : TextEdit(theAccount->postCharLimit(), parent), d(new Private(theAccount)) +TwitterTextEdit::TwitterTextEdit(Choqok::Account *theAccount, QWidget *parent) + : TwitterApiTextEdit(theAccount, parent), d(new Private(theAccount)) { qCDebug(CHOQOK); - setTabChangesFocus(false); fetchTCoMaximumLength(); } -TwitterApiTextEdit::~TwitterApiTextEdit() +TwitterTextEdit::~TwitterTextEdit() { delete d; } -void TwitterApiTextEdit::setCompleter(QCompleter *completer) -{ - if (d->c) { - QObject::disconnect(d->c, 0, this, 0); - } - - d->c = completer; - - if (!d->c) { - return; - } - - d->c->setWidget(this); - d->c->setCompletionMode(QCompleter::PopupCompletion); - d->c->setCaseSensitivity(Qt::CaseInsensitive); - QObject::connect(d->c, SIGNAL(activated(QString)), - this, SLOT(insertCompletion(QString))); -} - -QCompleter *TwitterApiTextEdit::completer() const -{ - return d->c; -} - -void TwitterApiTextEdit::insertCompletion(const QString &completion) -{ - if (d->c->widget() != this) { - return; - } - QString textToInsert = completion + QLatin1Char(' '); - QTextCursor tc = textCursor(); - tc.movePosition(QTextCursor::EndOfWord); - tc.select(QTextCursor::WordUnderCursor); - bool startWithAt = toPlainText()[tc.selectionStart() - 1] != QLatin1Char('@'); - if (startWithAt) { - textToInsert.prepend(QLatin1Char('@')); - } - tc.insertText(textToInsert); - setTextCursor(tc); -} - -// QString TwitterApiTextEdit::textUnderCursor() const -// { -// QTextCursor tc = textCursor(); -// tc.select(QTextCursor::WordUnderCursor); -// return tc.selectedText(); -// } - -void TwitterApiTextEdit::focusInEvent(QFocusEvent *e) -{ - if (d->c) { - d->c->setWidget(this); - } - KTextEdit::focusInEvent(e); -} - -void TwitterApiTextEdit::keyPressEvent(QKeyEvent *e) -{ - if (d->c && d->c->popup()->isVisible()) { - // The following keys are forwarded by the completer to the widget - switch (e->key()) { - case Qt::Key_Enter: - case Qt::Key_Return: - case Qt::Key_Escape: -// case Qt::Key_Backtab: - e->ignore(); - return; // let the completer do default behavior - default: -// Choqok::UI::TextEdit::keyPressEvent(e); - break; - } - } else if (e->text().isEmpty()) { - Choqok::UI::TextEdit::keyPressEvent(e); - return; - } - if (e->key() == Qt::Key_Tab) { - e->ignore(); - return; - } -// bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_Space); // CTRL+E -// if (!d->c )// || !isShortcut) // don't process the shortcut when we have a completer - Choqok::UI::TextEdit::keyPressEvent(e); - - const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier | Qt::AltModifier | - Qt::MetaModifier); - if (!d->c || (ctrlOrShift && e->text().isEmpty())) { - return; - } - - static QString eow(QLatin1String("~!@#$%^&*()+{}|:\"<>?,./;'[]\\-= ")); // end of word -// bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift; - //Implemented internally to get the char before selection :D - QTextCursor tc = textCursor(); - tc.select(QTextCursor::WordUnderCursor); - QString completionPrefix = tc.selectedText(); - QChar charBeforeSelection; - if (completionPrefix.startsWith(QLatin1Char('@'))) { - charBeforeSelection = completionPrefix.at(0); - completionPrefix.remove(0, 1); - } else { - if (!toPlainText().isEmpty() && tc.selectionStart() > 0) { - charBeforeSelection = toPlainText()[tc.selectionStart() - 1]; - } - } - - if (!e->text().isEmpty() && (eow.contains(e->text().right(1)) || completionPrefix.length() < 1 || - charBeforeSelection != QLatin1Char('@'))) { - d->c->popup()->hide(); - return; - } else if ((e->key() != Qt::Key_Enter) && (e->key() != Qt::Key_Return)) { - if (textCursor().selectedText().length() && - textCursor().selectedText() != completionPrefix) { - return; - } - - if (completionPrefix != d->c->completionPrefix()) { - d->c->setCompletionPrefix(completionPrefix); - d->c->popup()->setCurrentIndex(d->c->completionModel()->index(0, 0)); - } - QRect cr = cursorRect(); - cr.setWidth(d->c->popup()->sizeHintForColumn(0) - + d->c->popup()->verticalScrollBar()->sizeHint().width()); - d->c->complete(cr); // popup it up! - } -} - void TwitterApiTextEdit::updateRemainingCharsCount() { QString txt = this->toPlainText(); int count = txt.count(); if (count) { lblRemainChar->show(); if (charLimit()) { int remain = charLimit() - count; for (const QString &url: UrlUtils::detectUrls(txt)) { // Twitter does not wrapps urls with login informations if (!url.contains(QLatin1Char('@'))) { int diff = -1; if (url.startsWith(QLatin1String("http://"))) { diff = url.length() - d->tCoMaximumLength; } else if (url.startsWith(QLatin1String("https://"))) { diff = url.length() - d->tCoMaximumLengthHttps; } if (diff > 0) { remain += diff; } } } if (remain < 0) { lblRemainChar->setStyleSheet(QLatin1String("QLabel {color: red;}")); } else if (remain < 30) { lblRemainChar->setStyleSheet(QLatin1String("QLabel {color: rgb(242, 179, 19);}")); } else { lblRemainChar->setStyleSheet(QLatin1String("QLabel {color: green;}")); } lblRemainChar->setText(QString::number(remain)); } else { lblRemainChar->setText(QString::number(count)); lblRemainChar->setStyleSheet(QLatin1String(QLatin1String("QLabel {color: blue;}"))); } txt.remove(QRegExp(QLatin1String("@([^\\s\\W]+)"))); txt = txt.trimmed(); if (firstChar() != txt[0]) { setFirstChar(txt[0]); txt.prepend(QLatin1Char(' ')); QTextBlockFormat f; f.setLayoutDirection((Qt::LayoutDirection) txt.isRightToLeft()); textCursor().mergeBlockFormat(f); } } else { lblRemainChar->hide(); } } void TwitterApiTextEdit::fetchTCoMaximumLength() { TwitterApiAccount *acc = qobject_cast(d->acc); if (acc) { QUrl url = acc->apiUrl(); url.setPath(url.path() + QLatin1String("/help/configuration.json")); KIO::StoredTransferJob *job = KIO::storedGet(url, KIO::Reload, KIO::HideProgressInfo); if (!job) { qCDebug(CHOQOK) << "Cannot create an http GET request!"; return; } TwitterApiMicroBlog *mBlog = qobject_cast(acc->microblog()); job->addMetaData(QStringLiteral("customHTTPHeader"), QStringLiteral("Authorization: ") + QLatin1String(mBlog->authorizationHeader(acc, url, QOAuth::GET))); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotTCoMaximumLength(KJob*))); job->start(); } else { qCDebug(CHOQOK) << "the account is not a TwitterAPIAccount!"; } } void TwitterApiTextEdit::slotTCoMaximumLength(KJob *job) { if (job->error()) { qCDebug(CHOQOK) << "Job Error:" << job->errorString(); } else { KIO::StoredTransferJob *j = qobject_cast(job); const QJsonDocument json = QJsonDocument::fromJson(j->data()); if (!json.isNull()) { const QVariantMap reply = json.toVariant().toMap(); d->tCoMaximumLength = reply[QLatin1String("short_url_length")].toInt(); d->tCoMaximumLengthHttps = reply[QLatin1String("short_url_length_https")].toInt(); } else { qCDebug(CHOQOK) << "Cannot parse JSON reply"; } } } diff --git a/helperlibs/twitterapihelper/twitterapitextedit.h b/microblogs/twitter/twittertextedit.h similarity index 61% copy from helperlibs/twitterapihelper/twitterapitextedit.h copy to microblogs/twitter/twittertextedit.h index dfaafbdf..3ffdcb6a 100644 --- a/helperlibs/twitterapihelper/twitterapitextedit.h +++ b/microblogs/twitter/twittertextedit.h @@ -1,65 +1,50 @@ /* This file is part of Choqok, the KDE micro-blogging client - Copyright (C) 2010-2012 Mehrdad Momeny + Copyright (C) 2017 Andrea Scarpino This program 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 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program 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 this program; if not, see http://www.gnu.org/licenses/ */ -#ifndef TWITTERAPITEXTEDIT_H -#define TWITTERAPITEXTEDIT_H +#ifndef TWITTERTEXTEDIT_H +#define TWITTERTEXTEDIT_H -#include +#include "twitterapitextedit.h" -#include "account.h" -#include "choqoktextedit.h" -#include "choqok_export.h" - -class KJob; - -class CHOQOK_HELPER_EXPORT TwitterApiTextEdit : public Choqok::UI::TextEdit +class TwitterTextEdit : public TwitterApiTextEdit { Q_OBJECT public: - explicit TwitterApiTextEdit(Choqok::Account *theAccount, QWidget *parent = 0); - ~TwitterApiTextEdit(); - - void setCompleter(QCompleter *c); - QCompleter *completer() const; + explicit TwitterTextEdit(Choqok::Account *theAccount, QWidget *parent = 0); + ~TwitterTextEdit(); protected Q_SLOTS: virtual void updateRemainingCharsCount() override; -protected: - void keyPressEvent(QKeyEvent *e) override; - void focusInEvent(QFocusEvent *e) override; - private Q_SLOTS: - void insertCompletion(const QString &completion); void slotTCoMaximumLength(KJob *job); private: -// QString textUnderCursor() const; void fetchTCoMaximumLength(); class Private; Private *const d; }; -#endif // TWITTERAPITEXTEDIT_H +#endif // TWITTERTEXTEDIT_H