File indexing completed on 2024-04-28 04:55:40

0001 /*
0002     This file is part of Choqok, the KDE micro-blogging client
0003 
0004     SPDX-FileCopyrightText: 2008-2012 Mehrdad Momeny <mehrdad.momeny@gmail.com>
0005 
0006     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0007 */
0008 
0009 #include "composerwidget.h"
0010 
0011 #include <QGridLayout>
0012 #include <QLabel>
0013 #include <QPointer>
0014 #include <QPushButton>
0015 
0016 #include "account.h"
0017 #include "choqoktextedit.h"
0018 #include "libchoqokdebug.h"
0019 #include "microblog.h"
0020 #include "notifymanager.h"
0021 #include "shortenmanager.h"
0022 
0023 namespace Choqok
0024 {
0025 namespace UI
0026 {
0027 
0028 class ComposerWidget::Private
0029 {
0030 public:
0031     Private(Account *account)
0032         : editor(nullptr), currentAccount(account), postToSubmit(nullptr)
0033     {}
0034     QPointer<TextEdit> editor;
0035     Account *currentAccount;
0036     Choqok::Post *postToSubmit;
0037     QWidget *editorContainer;
0038     QPointer<QLabel> replyToUsernameLabel;
0039     QPointer<QPushButton> btnCancelReply;
0040 };
0041 
0042 ComposerWidget::ComposerWidget(Choqok::Account *account, QWidget *parent /*= 0*/)
0043     : QWidget(parent), btnAbort(nullptr), d(new Private(account))
0044 {
0045     QVBoxLayout *layout = new QVBoxLayout(this);
0046     layout->setContentsMargins(0, 0, 0, 0);
0047     d->editorContainer = new QWidget(this);
0048     QGridLayout *internalLayout = new QGridLayout;
0049     internalLayout->setContentsMargins(0, 0, 0, 0);
0050     d->editorContainer->setLayout(internalLayout);
0051     layout->addWidget(editorContainer());
0052     setEditor(new TextEdit(account->postCharLimit(), this));
0053 
0054     d->replyToUsernameLabel = new QLabel(editorContainer());
0055     d->btnCancelReply = new QPushButton(editorContainer());
0056     d->btnCancelReply->setIcon(QIcon::fromTheme(QLatin1String("dialog-cancel")));
0057     d->btnCancelReply->setToolTip(i18n("Discard Reply"));
0058     d->btnCancelReply->setMaximumWidth(d->btnCancelReply->height());
0059     connect(d->btnCancelReply, &QPushButton::clicked, this, &ComposerWidget::editorCleared);
0060     internalLayout->addWidget(d->replyToUsernameLabel, 2, 0);
0061     internalLayout->addWidget(d->btnCancelReply, 2, 1);
0062 
0063     d->btnCancelReply->hide();
0064     d->replyToUsernameLabel->hide();
0065 }
0066 
0067 ComposerWidget::~ComposerWidget()
0068 {
0069     delete d;
0070 }
0071 
0072 void ComposerWidget::setEditor(TextEdit *editor)
0073 {
0074     qCDebug(CHOQOK);
0075     if (d->editor) {
0076         d->editor->deleteLater();
0077     }
0078     d->editor = editor;
0079     qCDebug(CHOQOK);
0080     if (d->editor) {
0081         QGridLayout *internalLayout = qobject_cast<QGridLayout *>(d->editorContainer->layout());
0082         internalLayout->addWidget(d->editor, 0, 0);
0083         connect(d->editor, &TextEdit::returnPressed, this, &ComposerWidget::submitPost);
0084         connect(d->editor, &TextEdit::textChanged, this, &ComposerWidget::editorTextChanged);
0085         connect(d->editor, &TextEdit::cleared, this, &ComposerWidget::editorCleared);
0086         editorTextChanged();
0087     } else {
0088         qCDebug(CHOQOK) << "Editor is NULL!";
0089     }
0090 }
0091 
0092 void ComposerWidget::setText(const QString &text, const QString &replyToId, const QString &replyToUsername)
0093 {
0094     d->editor->prependText(text);
0095     this->replyToId = replyToId;
0096     this->replyToUsername = replyToUsername;
0097     if (!replyToUsername.isEmpty()) {
0098         d->replyToUsernameLabel->setText(i18n("Replying to <b>%1</b>", replyToUsername));
0099         d->btnCancelReply->show();
0100         d->replyToUsernameLabel->show();
0101     }
0102     d->editor->setFocus();
0103 }
0104 
0105 void ComposerWidget::submitPost(const QString &txt)
0106 {
0107     qCDebug(CHOQOK);
0108     editorContainer()->setEnabled(false);
0109     QString text = txt;
0110     if (currentAccount()->postCharLimit() &&
0111             text.size() > (int)currentAccount()->postCharLimit()) {
0112         text = Choqok::ShortenManager::self()->parseText(text);
0113     }
0114     delete d->postToSubmit;
0115     d->postToSubmit = new Choqok::Post;
0116     d->postToSubmit->content = text;
0117     if (!replyToId.isEmpty()) {
0118         d->postToSubmit->replyToPostId = replyToId;
0119     }
0120     connect(d->currentAccount->microblog(), &MicroBlog::postCreated,
0121             this, &ComposerWidget::slotPostSubmited);
0122     connect(d->currentAccount->microblog(), &MicroBlog::errorPost,
0123             this, &ComposerWidget::slotErrorPost);
0124     btnAbort = new QPushButton(QIcon::fromTheme(QLatin1String("dialog-cancel")), i18n("Abort"), this);
0125     layout()->addWidget(btnAbort);
0126     connect(btnAbort, &QPushButton::clicked, this, &ComposerWidget::abort);
0127     currentAccount()->microblog()->createPost(currentAccount(), d->postToSubmit);
0128 }
0129 
0130 void ComposerWidget::slotPostSubmited(Choqok::Account *theAccount, Choqok::Post *post)
0131 {
0132     qCDebug(CHOQOK);
0133     if (currentAccount() == theAccount && post == d->postToSubmit) {
0134         qCDebug(CHOQOK) << "Accepted";
0135         disconnect(d->currentAccount->microblog(), &MicroBlog::postCreated,
0136                    this, &ComposerWidget::slotPostSubmited);
0137         disconnect(d->currentAccount->microblog(), &MicroBlog::errorPost,
0138                    this, &ComposerWidget::slotErrorPost);
0139         if (btnAbort) {
0140             btnAbort->deleteLater();
0141         }
0142         d->editor->clear();
0143         editorCleared();
0144         editorContainer()->setEnabled(true);
0145         delete d->postToSubmit;
0146         d->postToSubmit = nullptr;
0147         currentAccount()->microblog()->updateTimelines(currentAccount());
0148     }
0149 }
0150 
0151 void ComposerWidget::slotErrorPost(Account *theAccount, Post *post)
0152 {
0153     qCDebug(CHOQOK);
0154     if (theAccount == d->currentAccount && post == d->postToSubmit) {
0155         qCDebug(CHOQOK);
0156         disconnect(d->currentAccount->microblog(), &MicroBlog::postCreated,
0157                    this, &ComposerWidget::slotPostSubmited);
0158         disconnect(d->currentAccount->microblog(), &MicroBlog::errorPost,
0159                    this, &ComposerWidget::slotErrorPost);
0160         if (btnAbort) {
0161             btnAbort->deleteLater();
0162         }
0163         editorContainer()->setEnabled(true);
0164         editor()->setFocus();
0165     }
0166 }
0167 
0168 void ComposerWidget::editorTextChanged()
0169 {
0170     if (d->editor->toPlainText().length()) {
0171         d->editor->setMaximumHeight(qMax(d->editor->fontMetrics().height() * 3,
0172                                          80));
0173         d->editor->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
0174     } else {
0175         d->editor->setMaximumHeight(qMax(d->editor->fontMetrics().height(),
0176                                          30));
0177         d->editor->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0178     }
0179 }
0180 
0181 TextEdit *ComposerWidget::editor()
0182 {
0183     return d->editor;
0184 }
0185 
0186 QWidget *ComposerWidget::editorContainer()
0187 {
0188     return d->editorContainer;
0189 }
0190 
0191 Post *ComposerWidget::postToSubmit()
0192 {
0193     return d->postToSubmit;
0194 }
0195 
0196 void ComposerWidget::setPostToSubmit(Post *post)
0197 {
0198     delete d->postToSubmit;
0199     d->postToSubmit = post;
0200 }
0201 
0202 QPointer< QPushButton > ComposerWidget::btnCancelReply()
0203 {
0204     return d->btnCancelReply;
0205 }
0206 
0207 Account *ComposerWidget::currentAccount()
0208 {
0209     return d->currentAccount;
0210 }
0211 
0212 QPointer< QLabel > ComposerWidget::replyToUsernameLabel()
0213 {
0214     return d->replyToUsernameLabel;
0215 }
0216 
0217 void ComposerWidget::editorCleared()
0218 {
0219     replyToId.clear();
0220     replyToUsername.clear();
0221     d->btnCancelReply->hide();
0222     d->replyToUsernameLabel->hide();
0223 }
0224 
0225 void ComposerWidget::abort()
0226 {
0227     if (btnAbort) {
0228         btnAbort->deleteLater();
0229     }
0230     editorContainer()->setEnabled(true);
0231     currentAccount()->microblog()->abortCreatePost(currentAccount(), d->postToSubmit);
0232     editor()->setFocus();
0233 }
0234 
0235 }
0236 }
0237 
0238 #include "moc_composerwidget.cpp"