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 "postwidget.h" 0010 0011 #include <QCloseEvent> 0012 #include <QGridLayout> 0013 #include <QTimer> 0014 #include <QPushButton> 0015 0016 #include <KLocalizedString> 0017 #include <KMessageBox> 0018 0019 #include "choqokappearancesettings.h" 0020 #include "choqokbehaviorsettings.h" 0021 #include "choqoktools.h" 0022 #include "choqokuiglobal.h" 0023 #include "libchoqokdebug.h" 0024 #include "mediamanager.h" 0025 #include "quickpost.h" 0026 #include "timelinewidget.h" 0027 #include "textbrowser.h" 0028 #include "urlutils.h" 0029 0030 static const int _15SECS = 15000; 0031 static const int _MINUTE = 60000; 0032 static const int _HOUR = 60 * _MINUTE; 0033 0034 using namespace Choqok; 0035 using namespace Choqok::UI; 0036 0037 class PostWidget::Private 0038 { 0039 public: 0040 Private(Account *account, Choqok::Post *post) 0041 : mCurrentPost(post), mCurrentAccount(account), dir(QLatin1String("ltr")), timeline(nullptr) 0042 { 0043 mCurrentPost->owners++; 0044 0045 if (!mCurrentPost->media.isEmpty()) { 0046 imageUrl = mCurrentPost->media; 0047 } 0048 } 0049 QGridLayout *buttonsLayout; 0050 QMap<QString, QPushButton *> mUiButtons; //<Object name, Button> 0051 Post *mCurrentPost; 0052 Account *mCurrentAccount; 0053 // bool mRead; 0054 QTimer mTimer; 0055 0056 //BEGIN UI contents: 0057 QString mSign; 0058 QString mContent; 0059 QString mProfileImage; 0060 QString mImage; 0061 QUrl imageUrl; 0062 QString dir; 0063 QPixmap originalImage; 0064 QString extraContents; 0065 //END UI contents; 0066 0067 QStringList detectedUrls; 0068 0069 TimelineWidget *timeline; 0070 0071 static const QLatin1String resourceImageUrl; 0072 }; 0073 0074 const QString mImageTemplate(QLatin1String("<div style=\"padding-top:5px;padding-bottom:3px;\"><img width=\"%1\" height=\"%2\" src=\"%3\"/></div>")); 0075 0076 const QLatin1String PostWidget::Private::resourceImageUrl("img://postImage"); 0077 0078 const QString PostWidget::baseTextTemplate(QLatin1String("<table height=\"100%\" width=\"100%\"><tr><td width=\"48\" style=\"padding-right: 5px;\">%1</td><td dir=\"%4\" style=\"padding-right:3px;\"><p>%2</p></td></tr>%5%6<tr><td></td><td style=\"font-size:small;\" dir=\"ltr\" align=\"right\" valign=\"bottom\">%3</td></tr></table>")); 0079 0080 const QString PostWidget::baseStyle(QLatin1String("QTextBrowser {border: 1px solid rgb(150,150,150);\ 0081 border-radius:5px; color:%1; background-color:%2; %3}\ 0082 QPushButton{border:0px} QPushButton::menu-indicator{image:none;}")); 0083 0084 const QString PostWidget::hrefTemplate(QLatin1String("<a href='%1' title='%1' target='_blank'>%2</a>")); 0085 0086 const QRegExp PostWidget::dirRegExp(QLatin1String("(RT|RD)|(@([^\\s\\W]+))|(#([^\\s\\W]+))|(!([^\\s\\W]+))")); 0087 0088 QString PostWidget::readStyle; 0089 QString PostWidget::unreadStyle; 0090 QString PostWidget::ownStyle; 0091 const QString PostWidget::webIconText(QLatin1String("☛")); 0092 0093 PostWidget::PostWidget(Account *account, Choqok::Post *post, QWidget *parent/* = 0*/) 0094 : QWidget(parent), _mainWidget(new TextBrowser(this)), d(new Private(account, post)) 0095 { 0096 setAttribute(Qt::WA_DeleteOnClose); 0097 _mainWidget->setFrameShape(QFrame::NoFrame); 0098 if (isOwnPost()) { 0099 d->mCurrentPost->isRead = true; 0100 } 0101 d->mTimer.start(_MINUTE); 0102 connect(&d->mTimer, &QTimer::timeout, this, &PostWidget::updateUi); 0103 connect(_mainWidget, &TextBrowser::clicked, this, &PostWidget::mousePressEvent); 0104 connect(_mainWidget, &TextBrowser::anchorClicked, this, &PostWidget::checkAnchor); 0105 0106 d->timeline = qobject_cast<TimelineWidget *>(parent); 0107 0108 setHeight(); 0109 } 0110 0111 void PostWidget::checkAnchor(const QUrl &url) 0112 { 0113 if (url.scheme() == QLatin1String("choqok")) { 0114 if (url.host() == QLatin1String("showoriginalpost")) { 0115 setContent(prepareStatus(currentPost()->content).replace(QLatin1String("<a href"), QLatin1String("<a style=\"text-decoration:none\" href"), Qt::CaseInsensitive)); 0116 updateUi(); 0117 } 0118 } else { 0119 Choqok::openUrl(url); 0120 } 0121 } 0122 0123 PostWidget::~PostWidget() 0124 { 0125 if (d->mCurrentPost->owners < 2) { 0126 delete d->mCurrentPost; 0127 } else { 0128 d->mCurrentPost->owners--; 0129 } 0130 delete d; 0131 } 0132 0133 Account *PostWidget::currentAccount() 0134 { 0135 return d->mCurrentAccount; 0136 } 0137 0138 QString PostWidget::generateSign() 0139 { 0140 QString ss = QStringLiteral("<b>%1 - </b>").arg(getUsernameHyperlink(d->mCurrentPost->author)); 0141 0142 QDateTime time; 0143 if (d->mCurrentPost->repeatedDateTime.isNull()) { 0144 time = d->mCurrentPost->creationDateTime; 0145 } else { 0146 time = d->mCurrentPost->repeatedDateTime; 0147 } 0148 0149 ss += QStringLiteral("<a href=\"%1\" title=\"%2\">%3</a>").arg(d->mCurrentPost->link.toDisplayString()) 0150 .arg(time.toString(Qt::DefaultLocaleLongDate)).arg(QStringLiteral("%1")); 0151 0152 if (!d->mCurrentPost->source.isEmpty()) { 0153 ss += QLatin1String(" - ") + d->mCurrentPost->source; 0154 } 0155 0156 return ss; 0157 } 0158 0159 QString PostWidget::getUsernameHyperlink(const Choqok::User &user) const 0160 { 0161 return QStringLiteral("<a href=\"%1\" title=\"%2\">%3</a>") 0162 .arg(d->mCurrentAccount->microblog()->profileUrl(d->mCurrentAccount, user.userName).toDisplayString()) 0163 .arg(user.description.isEmpty() ? user.realName : user.description) 0164 .arg(user.userName); 0165 } 0166 0167 void PostWidget::setupUi() 0168 { 0169 setLayout(new QVBoxLayout); 0170 layout()->setMargin(0); 0171 layout()->setContentsMargins(0, 0, 0, 0); 0172 layout()->addWidget(_mainWidget); 0173 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); 0174 _mainWidget->setFocusProxy(this); 0175 0176 d->buttonsLayout = new QGridLayout(_mainWidget); 0177 d->buttonsLayout->setRowStretch(0, 100); 0178 d->buttonsLayout->setColumnStretch(5, 100); 0179 d->buttonsLayout->setMargin(0); 0180 d->buttonsLayout->setSpacing(0); 0181 0182 _mainWidget->setLayout(d->buttonsLayout); 0183 connect(_mainWidget, &TextBrowser::textChanged, this, &PostWidget::setHeight); 0184 0185 } 0186 0187 void PostWidget::initUi() 0188 { 0189 setupUi(); 0190 _mainWidget->document()->addResource(QTextDocument::ImageResource, QUrl(QLatin1String("img://profileImage")), 0191 MediaManager::self()->defaultImage()); 0192 0193 if (isRemoveAvailable()) { 0194 QPushButton *btnRemove = addButton(QLatin1String("btnRemove"), i18nc("@info:tooltip", "Remove"), QLatin1String("edit-delete")); 0195 connect(btnRemove, &QPushButton::clicked, this, &PostWidget::removeCurrentPost); 0196 } 0197 0198 if (isResendAvailable()) { 0199 QPushButton *btnResend = addButton(QLatin1String("btnResend"), i18nc("@info:tooltip", "ReSend"), QLatin1String("retweet")); 0200 connect(btnResend, &QPushButton::clicked, this, &PostWidget::slotResendPost); 0201 } 0202 0203 d->mProfileImage = QLatin1String("<img src=\"img://profileImage\" title=\"") + d->mCurrentPost->author.realName + QLatin1String("\" width=\"48\" height=\"48\" />"); 0204 d->mContent = prepareStatus(d->mCurrentPost->content); 0205 d->mSign = generateSign(); 0206 setupAvatar(); 0207 fetchImage(); 0208 d->dir = getDirection(d->mCurrentPost->content); 0209 setUiStyle(); 0210 0211 d->mContent.replace(QLatin1String("<a href"), QLatin1String("<a style=\"text-decoration:none\" href"), Qt::CaseInsensitive); 0212 d->mContent.replace(QLatin1String("\n"), QLatin1String("<br/>")); 0213 d->extraContents.replace(QLatin1String("<a href"), QLatin1String("<a style=\"text-decoration:none\" href"), Qt::CaseInsensitive); 0214 d->mSign.replace(QLatin1String("<a href"), QLatin1String("<a style=\"text-decoration:none\" href"), Qt::CaseInsensitive); 0215 0216 updateUi(); 0217 } 0218 0219 void PostWidget::updateUi() 0220 { 0221 QDateTime time; 0222 if (currentPost()->repeatedDateTime.isNull()) { 0223 time = currentPost()->creationDateTime; 0224 } else { 0225 time = currentPost()->repeatedDateTime; 0226 } 0227 0228 _mainWidget->setHtml(baseTextTemplate.arg( d->mProfileImage, /*1*/ 0229 d->mContent, /*2*/ 0230 d->mSign.arg(formatDateTime(time)), /*3*/ 0231 d->dir, /*4*/ 0232 d->mImage, /*5*/ 0233 d->extraContents /*6*/ 0234 )); 0235 } 0236 0237 void PostWidget::setStyle(const QColor &color, const QColor &back, const QColor &read, const QColor &readBack, const QColor &own, const QColor &ownBack, const QFont &font) 0238 { 0239 QString fntStr = QLatin1String("font-family:\"") + font.family() + QLatin1String("\"; font-size:") + QString::number(font.pointSize()) + QLatin1String("pt;"); 0240 fntStr += (font.bold() ? QLatin1String(" font-weight:bold;") : QString()) + (font.italic() ? QLatin1String(" font-style:italic;") : QString()); 0241 unreadStyle = baseStyle.arg(getColorString(color), getColorString(back), fntStr); 0242 readStyle = baseStyle.arg(getColorString(read), getColorString(readBack), fntStr); 0243 ownStyle = baseStyle.arg(getColorString(own), getColorString(ownBack), fntStr); 0244 } 0245 0246 QPushButton *PostWidget::addButton(const QString &objName, const QString &toolTip, const QString &icon) 0247 { 0248 return addButton(objName, toolTip, QIcon::fromTheme(icon)); 0249 0250 } 0251 0252 QPushButton *PostWidget::addButton(const QString &objName, const QString &toolTip, const QIcon &icon) 0253 { 0254 QPushButton *button = new QPushButton(icon, QString(), _mainWidget); 0255 button->setObjectName(objName); 0256 button->setToolTip(toolTip); 0257 button->setIconSize(QSize(16, 16)); 0258 button->setMinimumSize(QSize(20, 20)); 0259 button->setMaximumSize(QSize(20, 20)); 0260 button->setFlat(true); 0261 button->setVisible(false); 0262 button->setCursor(Qt::PointingHandCursor); 0263 0264 d->mUiButtons.insert(objName, button); 0265 d->buttonsLayout->addWidget(button, 1, d->mUiButtons.count()); 0266 return button; 0267 } 0268 0269 Post *PostWidget::currentPost() const 0270 { 0271 return d->mCurrentPost; 0272 } 0273 0274 void PostWidget::setCurrentPost(Post *post) 0275 { 0276 d->mCurrentPost = post; 0277 } 0278 0279 void PostWidget::setRead(bool read/* = true*/) 0280 { 0281 if (!read && !currentPost()->isRead && 0282 currentAccount()->username().compare(currentPost()->author.userName, Qt::CaseInsensitive) == 0) { 0283 d->mCurrentPost->isRead = true; ///Always Set own posts as read. 0284 setUiStyle(); 0285 } else if (currentPost()->isRead != read) { 0286 d->mCurrentPost->isRead = read; 0287 setUiStyle(); 0288 } 0289 } 0290 0291 void PostWidget::setReadWithSignal() 0292 { 0293 if (!isRead()) { 0294 setRead(); 0295 Q_EMIT postReaded(); 0296 } 0297 } 0298 0299 bool PostWidget::isRead() const 0300 { 0301 return currentPost()->isRead; 0302 } 0303 0304 void PostWidget::setUiStyle() 0305 { 0306 if (isOwnPost()) { 0307 setStyleSheet(ownStyle); 0308 } else { 0309 if (currentPost()->isRead) { 0310 setStyleSheet(readStyle); 0311 } else { 0312 setStyleSheet(unreadStyle); 0313 } 0314 } 0315 setHeight(); 0316 } 0317 0318 bool PostWidget::isOwnPost() 0319 { 0320 return currentAccount()->username().compare(currentPost()->author.userName, Qt::CaseInsensitive) == 0; 0321 } 0322 0323 void PostWidget::setHeight() 0324 { 0325 _mainWidget->document()->setTextWidth(width() - 2); 0326 int h = _mainWidget->document()->size().toSize().height() + 2; 0327 setFixedHeight(h); 0328 } 0329 0330 void PostWidget::closeEvent(QCloseEvent *event) 0331 { 0332 clearFocus(); 0333 if (!isRead()) { 0334 setReadWithSignal(); 0335 } 0336 Q_EMIT aboutClosing(currentPost()->postId, this); 0337 event->accept(); 0338 } 0339 0340 void PostWidget::mousePressEvent(QMouseEvent *ev) 0341 { 0342 if (!isRead()) { 0343 setReadWithSignal(); 0344 } 0345 QWidget::mousePressEvent(ev); 0346 } 0347 0348 void PostWidget::resizeEvent(QResizeEvent *event) 0349 { 0350 updatePostImage( event->size().width() ); 0351 setHeight(); 0352 updateUi(); 0353 QWidget::resizeEvent(event); 0354 } 0355 0356 void PostWidget::enterEvent(QEvent *event) 0357 { 0358 for (QPushButton *btn: buttons()) { 0359 if (btn) { //A crash happens here :/ 0360 btn->show(); 0361 } 0362 } 0363 QWidget::enterEvent(event); 0364 } 0365 0366 void PostWidget::leaveEvent(QEvent *event) 0367 { 0368 for (QPushButton *btn: buttons()) { 0369 if (btn) { 0370 btn->hide(); 0371 } 0372 } 0373 QWidget::enterEvent(event); 0374 } 0375 0376 void PostWidget::updatePostImage(int width) 0377 { 0378 if ( !d->originalImage.isNull() ) { 0379 // TODO: Find a way to calculate the difference we need to subtract. 0380 width -= 76; 0381 0382 QPixmap newPixmap = d->originalImage.scaledToWidth(width, Qt::SmoothTransformation); 0383 auto newW = newPixmap.width(); 0384 auto newH = newPixmap.height(); 0385 auto origW = d->originalImage.width(); 0386 auto origH = d->originalImage.height(); 0387 0388 const QUrl url(d->resourceImageUrl); 0389 // only use scaled image if it's smaller than the original one 0390 if (newW <= origW && newH <= origH) { // never scale up 0391 d->mImage = mImageTemplate.arg(QString::number(newW), QString::number(newH), d->resourceImageUrl); 0392 _mainWidget->document()->addResource(QTextDocument::ImageResource, url, newPixmap); 0393 } else { 0394 d->mImage = mImageTemplate.arg(QString::number(origW), QString::number(origH), d->resourceImageUrl); 0395 _mainWidget->document()->addResource(QTextDocument::ImageResource, url, d->originalImage); 0396 } 0397 } 0398 } 0399 0400 QString PostWidget::prepareStatus(const QString &txt) 0401 { 0402 QString text = removeTags(txt); 0403 0404 d->detectedUrls = UrlUtils::detectUrls(text); 0405 for (const QString &url: d->detectedUrls) { 0406 QString httpUrl(url); 0407 if (!httpUrl.startsWith(QLatin1String("http"), Qt::CaseInsensitive) && 0408 !httpUrl.startsWith(QLatin1String("ftp"), Qt::CaseInsensitive)) { 0409 httpUrl.prepend(QLatin1String("http://")); 0410 text.replace(url, httpUrl); 0411 } 0412 0413 text.replace(url, hrefTemplate.arg(httpUrl, url)); 0414 } 0415 0416 text = UrlUtils::detectEmails(text); 0417 0418 if (AppearanceSettings::isEmoticonsEnabled()) { 0419 text = MediaManager::self()->parseEmoticons(text); 0420 } 0421 0422 return text; 0423 } 0424 0425 QString PostWidget::removeTags(const QString &text) const 0426 { 0427 QString txt(text); 0428 0429 txt.replace(QLatin1Char('<'), QLatin1String("<")); 0430 txt.replace(QLatin1Char('>'), QLatin1String(">")); 0431 0432 return txt; 0433 } 0434 QLatin1String PostWidget::getDirection(QString txt) 0435 { 0436 txt.remove(dirRegExp); 0437 txt = txt.trimmed(); 0438 if (txt.isRightToLeft()) { 0439 return QLatin1String("rtl"); 0440 } 0441 else { 0442 return QLatin1String("ltr"); 0443 } 0444 } 0445 0446 QString PostWidget::formatDateTime(const QDateTime &time) 0447 { 0448 if (!time.isValid()) { 0449 return tr("Invalid Time"); 0450 } 0451 auto seconds = time.secsTo(QDateTime::currentDateTime()); 0452 if (seconds <= 15) { 0453 d->mTimer.setInterval(_15SECS); 0454 return i18n("Just now"); 0455 } 0456 0457 if (seconds <= 45) { 0458 d->mTimer.setInterval(_15SECS); 0459 return i18np("1 sec ago", "%1 secs ago", seconds); 0460 } 0461 0462 auto minutes = (seconds - 45 + 59) / 60; 0463 if (minutes <= 45) { 0464 d->mTimer.setInterval(_MINUTE); 0465 return i18np("1 min ago", "%1 mins ago", minutes); 0466 } 0467 0468 auto hours = (seconds - 45 * 60 + 3599) / 3600; 0469 if (hours <= 18) { 0470 d->mTimer.setInterval(_MINUTE * 15); 0471 return i18np("1 hour ago", "%1 hours ago", hours); 0472 } 0473 0474 d->mTimer.setInterval(_HOUR); 0475 auto days = (seconds - 18 * 3600 + 24 * 3600 - 1) / (24 * 3600); 0476 return i18np("1 day ago", "%1 days ago", days); 0477 } 0478 0479 void PostWidget::removeCurrentPost() 0480 { 0481 if (KMessageBox::warningYesNo(this, i18n("Are you sure you want to remove this post from the server?")) == KMessageBox::Yes) { 0482 connect(d->mCurrentAccount->microblog(), &MicroBlog::postRemoved, 0483 this, &PostWidget::slotCurrentPostRemoved); 0484 connect(d->mCurrentAccount->microblog(), &MicroBlog::errorPost, this, &PostWidget::slotPostError); 0485 setReadWithSignal(); 0486 d->mCurrentAccount->microblog()->removePost(d->mCurrentAccount, d->mCurrentPost); 0487 } 0488 } 0489 0490 void PostWidget::slotCurrentPostRemoved(Account *theAccount, Post *post) 0491 { 0492 if (theAccount == currentAccount() && post == d->mCurrentPost) { 0493 this->close(); 0494 } 0495 } 0496 0497 void PostWidget::slotResendPost() 0498 { 0499 QString text = generateResendText(); 0500 setReadWithSignal(); 0501 if ((BehaviorSettings::resendWithQuickPost() || currentAccount()->isReadOnly()) && Global::quickPostWidget()) { 0502 Global::quickPostWidget()->setText(text); 0503 } else { 0504 Q_EMIT resendPost(text); 0505 } 0506 } 0507 0508 QString PostWidget::generateResendText() 0509 { 0510 if (BehaviorSettings::useCustomRT()) { 0511 return QString(BehaviorSettings::customRT()) + QLatin1String(" @") + currentPost()->author.userName + QLatin1String(": ") + currentPost()->content; 0512 } else { 0513 QChar re(0x267B); 0514 return QString(re) + QLatin1String(" @") + currentPost()->author.userName + QLatin1String(": ") + currentPost()->content; 0515 } 0516 } 0517 0518 void PostWidget::fetchImage() 0519 { 0520 if (d->imageUrl.isEmpty()) { 0521 return; 0522 } 0523 0524 QPixmap pix = MediaManager::self()->fetchImage(d->imageUrl, MediaManager::Async); 0525 0526 if (!pix.isNull()) { 0527 slotImageFetched(d->imageUrl, pix); 0528 } else { 0529 connect(MediaManager::self(), &MediaManager::imageFetched, this, 0530 &PostWidget::slotImageFetched); 0531 } 0532 } 0533 0534 void PostWidget::slotImageFetched(const QUrl &remoteUrl, const QPixmap &pixmap) 0535 { 0536 if (remoteUrl == d->imageUrl) { 0537 disconnect(MediaManager::self(), &MediaManager::imageFetched, this, &PostWidget::slotImageFetched); 0538 d->originalImage = pixmap; 0539 updatePostImage( width() ); 0540 updateUi(); 0541 } 0542 } 0543 0544 void PostWidget::setupAvatar() 0545 { 0546 QPixmap pix = MediaManager::self()->fetchImage(d->mCurrentPost->author.profileImageUrl, 0547 MediaManager::Async); 0548 if (!pix.isNull()) { 0549 avatarFetched(d->mCurrentPost->author.profileImageUrl, pix); 0550 } else { 0551 connect(MediaManager::self(), &MediaManager::imageFetched, this, &PostWidget::avatarFetched); 0552 connect(MediaManager::self(), &MediaManager::fetchError, this, &PostWidget::avatarFetchError); 0553 } 0554 } 0555 0556 void PostWidget::avatarFetched(const QUrl &remoteUrl, const QPixmap &pixmap) 0557 { 0558 if (remoteUrl == d->mCurrentPost->author.profileImageUrl) { 0559 const QUrl url(QLatin1String("img://profileImage")); 0560 _mainWidget->document()->addResource(QTextDocument::ImageResource, url, pixmap); 0561 updateUi(); 0562 disconnect(MediaManager::self(), &MediaManager::imageFetched, this, &PostWidget::avatarFetched); 0563 disconnect(MediaManager::self(), &MediaManager::fetchError, this, &PostWidget::avatarFetchError); 0564 } 0565 } 0566 0567 void PostWidget::avatarFetchError(const QUrl &remoteUrl, const QString &errMsg) 0568 { 0569 Q_UNUSED(errMsg); 0570 if (remoteUrl == d->mCurrentPost->author.profileImageUrl) { 0571 ///Avatar fetching is failed! but will not disconnect to get the img if it fetches later! 0572 const QUrl url(QLatin1String("img://profileImage")); 0573 _mainWidget->document()->addResource(QTextDocument::ImageResource, 0574 url, QIcon::fromTheme(QLatin1String("image-missing")).pixmap(48)); 0575 updateUi(); 0576 } 0577 } 0578 0579 QMap<QString, QPushButton * > &PostWidget::buttons() 0580 { 0581 return d->mUiButtons; 0582 } 0583 0584 void PostWidget::slotPostError(Account *theAccount, Choqok::Post *post, 0585 MicroBlog::ErrorType , const QString &errorMessage) 0586 { 0587 if (theAccount == currentAccount() && post == d->mCurrentPost) { 0588 qCDebug(CHOQOK) << errorMessage; 0589 disconnect(d->mCurrentAccount->microblog(), &MicroBlog::postRemoved, 0590 this, &PostWidget::slotCurrentPostRemoved); 0591 disconnect(d->mCurrentAccount->microblog(), &MicroBlog::errorPost, 0592 this, &PostWidget::slotPostError); 0593 } 0594 } 0595 0596 QString PostWidget::avatarText() const 0597 { 0598 return d->mProfileImage; 0599 } 0600 0601 void PostWidget::setAvatarText(const QString &text) 0602 { 0603 d->mProfileImage = text; 0604 updateUi(); 0605 } 0606 0607 QString PostWidget::content() const 0608 { 0609 return d->mContent; 0610 } 0611 0612 void PostWidget::setContent(const QString &content) 0613 { 0614 d->mContent = content; 0615 updateUi(); 0616 } 0617 0618 QStringList PostWidget::urls() 0619 { 0620 return d->detectedUrls; 0621 } 0622 0623 QString PostWidget::sign() const 0624 { 0625 return d->mSign; 0626 } 0627 0628 void PostWidget::setSign(const QString &sign) 0629 { 0630 d->mSign = sign; 0631 updateUi(); 0632 } 0633 0634 void PostWidget::deleteLater() 0635 { 0636 close(); 0637 } 0638 0639 TextBrowser *PostWidget::mainWidget() 0640 { 0641 return _mainWidget; 0642 } 0643 0644 void PostWidget::wheelEvent(QWheelEvent *event) 0645 { 0646 event->ignore(); 0647 } 0648 0649 void PostWidget::addAction(QAction *action) 0650 { 0651 TextBrowser::addAction(action); 0652 } 0653 0654 TimelineWidget *PostWidget::timelineWidget() const 0655 { 0656 return d->timeline; 0657 } 0658 0659 class PostWidgetUserData::Private 0660 { 0661 public: 0662 Private(PostWidget *postwidget) 0663 : postWidget(postwidget) 0664 {} 0665 PostWidget *postWidget; 0666 }; 0667 0668 PostWidgetUserData::PostWidgetUserData(PostWidget *postWidget) 0669 : QObjectUserData(), d(new Private(postWidget)) 0670 { 0671 0672 } 0673 0674 PostWidgetUserData::~PostWidgetUserData() 0675 { 0676 delete d; 0677 } 0678 0679 PostWidget *PostWidgetUserData::postWidget() 0680 { 0681 return d->postWidget; 0682 } 0683 0684 void PostWidgetUserData::setPostWidget(PostWidget *widget) 0685 { 0686 d->postWidget = widget; 0687 } 0688 0689 QString PostWidget::getBaseStyle() 0690 { 0691 return baseStyle; 0692 } 0693 0694 bool PostWidget::isRemoveAvailable() 0695 { 0696 return d->mCurrentAccount->username().compare(d->mCurrentPost->author.userName, Qt::CaseInsensitive) == 0; 0697 } 0698 0699 bool PostWidget::isResendAvailable() 0700 { 0701 return d->mCurrentAccount->username().compare(d->mCurrentPost->author.userName, Qt::CaseInsensitive) != 0; 0702 } 0703 0704 void PostWidget::setExtraContents(const QString& text) 0705 { 0706 d->extraContents = text; 0707 } 0708 0709 QString PostWidget::extraContents() const 0710 { 0711 return d->extraContents; 0712 } 0713 0714 #include "moc_postwidget.cpp"