diff options
Diffstat (limited to 'Swift')
-rw-r--r-- | Swift/QtUI/QtWebKitChatView.cpp | 53 | ||||
-rw-r--r-- | Swift/QtUI/QtWebKitChatView.h | 4 |
2 files changed, 54 insertions, 3 deletions
diff --git a/Swift/QtUI/QtWebKitChatView.cpp b/Swift/QtUI/QtWebKitChatView.cpp index 260da8a..b543e34 100644 --- a/Swift/QtUI/QtWebKitChatView.cpp +++ b/Swift/QtUI/QtWebKitChatView.cpp @@ -1,43 +1,44 @@ /* - * Copyright (c) 2010-2015 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swift/QtUI/QtWebKitChatView.h> #include <QApplication> #include <QDesktopServices> #include <QEventLoop> #include <QFile> #include <QFileDialog> +#include <QFileInfo> #include <QInputDialog> #include <QKeyEvent> #include <QMessageBox> #include <QStackedWidget> #include <QTimer> #include <QVBoxLayout> #include <QWebFrame> #include <QtDebug> #include <Swiften/Base/FileSize.h> #include <Swiften/Base/Log.h> #include <Swiften/StringCodecs/Base64.h> #include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> #include <Swift/Controllers/UIEvents/UIEventStream.h> #include <Swift/QtUI/MessageSnippet.h> #include <Swift/QtUI/QtChatWindow.h> #include <Swift/QtUI/QtChatWindowJSBridge.h> #include <Swift/QtUI/QtScaledAvatarCache.h> #include <Swift/QtUI/QtSwiftUtil.h> #include <Swift/QtUI/QtUtilities.h> #include <Swift/QtUI/QtWebView.h> #include <Swift/QtUI/SystemMessageSnippet.h> namespace Swift { const QString QtWebKitChatView::ButtonWhiteboardSessionCancel = QString("whiteboard-cancel"); const QString QtWebKitChatView::ButtonWhiteboardSessionAcceptRequest = QString("whiteboard-acceptrequest"); const QString QtWebKitChatView::ButtonWhiteboardShowWindow = QString("whiteboard-showwindow"); @@ -720,93 +721,141 @@ void QtWebKitChatView::setFileTransferStatus(std::string id, const ChatWindow::F } std::string QtWebKitChatView::addWhiteboardRequest(const QString& contact, bool senderIsSelf) { QString wb_id = QString("wb%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++))); QString htmlString; QString actionText; if (senderIsSelf) { actionText = tr("Starting whiteboard chat"); htmlString = "<div id='" + wb_id + "'>" + actionText + "<br />"+ buildChatWindowButton(tr("Cancel"), ButtonWhiteboardSessionCancel, wb_id) + "</div>"; } else { actionText = tr("%1 would like to start a whiteboard chat"); htmlString = "<div id='" + wb_id + "'>" + actionText.arg(QtUtilities::htmlEscape(contact)) + ": <br/>" + buildChatWindowButton(tr("Cancel"), ButtonWhiteboardSessionCancel, wb_id) + buildChatWindowButton(tr("Accept"), ButtonWhiteboardSessionAcceptRequest, wb_id) + "</div>"; } QString qAvatarPath = "qrc:/icons/avatar.png"; std::string id = "wbmessage" + boost::lexical_cast<std::string>(idCounter_++); addMessageBottom(boost::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(contact), B2QDATE(boost::posix_time::second_clock::universal_time()), qAvatarPath, false, false, theme_, P2QSTRING(id), ChatSnippet::getDirection(actionText))); previousMessageWasSelf_ = false; previousSenderName_ = contact; return Q2PSTRING(wb_id); } void QtWebKitChatView::setWhiteboardSessionStatus(const std::string& id, const ChatWindow::WhiteboardSessionState state) { setWhiteboardSessionStatus(P2QSTRING(id), state); } +static bool isFilePathWritable(const QString& path) { + QFileInfo fileInfo = QFileInfo(path); + if (fileInfo.exists()) { + return fileInfo.isWritable(); + } + else { + bool writable = false; + QFile writeTestFile(path); + if (writeTestFile.open(QIODevice::ReadWrite)) { + writeTestFile.write("test"); + if (writeTestFile.error() == QFileDevice::NoError) { + writable = true; + } + } + writeTestFile.close(); + writeTestFile.remove(); + return writable; + } +} + +void QtWebKitChatView::setFileTransferWarning(QString id, QString warningText) { + QWebElement ftElement = findElementWithID(document_, "div", id); + if (ftElement.isNull()) { + SWIFT_LOG(debug) << "Tried to access FT UI via invalid id! id = " << Q2PSTRING(id) << std::endl; + return; + } + + removeFileTransferWarning(id); + ftElement.appendInside(QString("<div class='ft_warning' style='color: red;'><br/>%1</div>").arg(QtUtilities::htmlEscape(warningText))); +} + +void QtWebKitChatView::removeFileTransferWarning(QString id) { + QWebElement ftElement = findElementWithID(document_, "div", id); + if (ftElement.isNull()) { + SWIFT_LOG(debug) << "Tried to access FT UI via invalid id! id = " << Q2PSTRING(id) << std::endl; + return; + } + + QWebElement warningElement = ftElement.findFirst(".ft_warning"); + if (!warningElement.isNull()) { + warningElement.removeFromDocument(); + } +} + void QtWebKitChatView::handleHTMLButtonClicked(QString id, QString encodedArgument1, QString encodedArgument2, QString encodedArgument3, QString encodedArgument4, QString encodedArgument5) { QString arg1 = decodeButtonArgument(encodedArgument1); QString arg2 = decodeButtonArgument(encodedArgument2); QString arg3 = decodeButtonArgument(encodedArgument3); QString arg4 = decodeButtonArgument(encodedArgument4); QString arg5 = decodeButtonArgument(encodedArgument5); if (id.startsWith(ButtonFileTransferCancel)) { QString ft_id = arg1; window_->onFileTransferCancel(Q2PSTRING(ft_id)); } else if (id.startsWith(ButtonFileTransferSetDescription)) { QString ft_id = arg1; bool ok = false; QString text = QInputDialog::getText(this, tr("File transfer description"), tr("Description:"), QLineEdit::Normal, "", &ok); if (ok) { descriptions_[ft_id] = text; } } else if (id.startsWith(ButtonFileTransferSendRequest)) { QString ft_id = arg1; QString text = descriptions_.find(ft_id) == descriptions_.end() ? QString() : descriptions_[ft_id]; window_->onFileTransferStart(Q2PSTRING(ft_id), Q2PSTRING(text)); } else if (id.startsWith(ButtonFileTransferAcceptRequest)) { QString ft_id = arg1; QString filename = arg2; QString path = QFileDialog::getSaveFileName(this, tr("Save File"), filename); - if (!path.isEmpty()) { + if (!path.isEmpty() && isFilePathWritable(path)) { filePaths_[ft_id] = path; window_->onFileTransferAccept(Q2PSTRING(ft_id), Q2PSTRING(path)); + removeFileTransferWarning(ft_id); + } + else { + setFileTransferWarning(ft_id, tr("The chosen save location is not writable! Click the 'Accept' button to select a different save location.")); } } else if (id.startsWith(ButtonFileTransferOpenFile)) { QString ft_id = arg1; QString filename = arg2; askDesktopToOpenFile(filename); } else if (id.startsWith(ButtonWhiteboardSessionAcceptRequest)) { QString id = arg1; setWhiteboardSessionStatus(id, ChatWindow::WhiteboardAccepted); window_->onWhiteboardSessionAccept(); } else if (id.startsWith(ButtonWhiteboardSessionCancel)) { QString id = arg1; setWhiteboardSessionStatus(id, ChatWindow::WhiteboardTerminated); window_->onWhiteboardSessionCancel(); } else if (id.startsWith(ButtonWhiteboardShowWindow)) { QString id = arg1; window_->onWhiteboardWindowShow(); } else if (id.startsWith(ButtonMUCInvite)) { QString roomJID = arg1; QString password = arg2; QString elementID = arg3; QString isImpromptu = arg4; QString isContinuation = arg5; eventStream_->send(boost::make_shared<JoinMUCUIEvent>(Q2PSTRING(roomJID), Q2PSTRING(password), boost::optional<std::string>(), false, false, isImpromptu.contains("true"), isContinuation.contains("true"))); setMUCInvitationJoined(elementID); } diff --git a/Swift/QtUI/QtWebKitChatView.h b/Swift/QtUI/QtWebKitChatView.h index 99375f7..173a05b 100644 --- a/Swift/QtUI/QtWebKitChatView.h +++ b/Swift/QtUI/QtWebKitChatView.h @@ -1,32 +1,32 @@ /* - * Copyright (c) 2010-2015 Isode Limited. + * Copyright (c) 2010-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <boost/shared_ptr.hpp> #include <QList> #include <QString> #include <QWebElement> #include <QWidget> #include <Swiften/Base/Override.h> #include <Swift/Controllers/UIInterfaces/ChatWindow.h> #include <Swift/QtUI/ChatSnippet.h> #include <Swift/QtUI/QtChatView.h> class QWebPage; class QUrl; class QDate; namespace Swift { class QtWebView; class QtChatTheme; class QtChatWindowJSBridge; class UIEventStream; class QtChatWindow; @@ -68,60 +68,62 @@ namespace Swift { virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description) SWIFTEN_OVERRIDE; virtual void setFileTransferProgress(std::string, const int percentageDone) SWIFTEN_OVERRIDE; virtual void setFileTransferStatus(std::string, const ChatWindow::FileTransferState state, const std::string& msg = "") SWIFTEN_OVERRIDE; virtual void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct, bool isImpromptu, bool isContinuation) SWIFTEN_OVERRIDE; virtual std::string addWhiteboardRequest(const QString& contact, bool senderIsSelf) SWIFTEN_OVERRIDE; virtual void setWhiteboardSessionStatus(const std::string& id, const ChatWindow::WhiteboardSessionState state) SWIFTEN_OVERRIDE; virtual void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) SWIFTEN_OVERRIDE; virtual void showEmoticons(bool show) SWIFTEN_OVERRIDE; void addMessageTop(boost::shared_ptr<ChatSnippet> snippet); void addMessageBottom(boost::shared_ptr<ChatSnippet> snippet); int getSnippetPositionByDate(const QDate& date); // FIXME : This probably shouldn't have been public virtual void addLastSeenLine() SWIFTEN_OVERRIDE; private: // previously public, now private void replaceLastMessage(const QString& newMessage, const ChatWindow::TimestampBehaviour timestampBehaviour); void replaceLastMessage(const QString& newMessage, const QString& note); void replaceMessage(const QString& newMessage, const QString& id, const QDateTime& time); void replaceSystemMessage(const QString& newMessage, const QString&id, const ChatWindow::TimestampBehaviour timestampBehaviour); void rememberScrolledToBottom(); void setAckXML(const QString& id, const QString& xml); void setReceiptXML(const QString& id, const QString& xml); void displayReceiptInfo(const QString& id, bool showIt); QString getLastSentMessage(); void addToJSEnvironment(const QString&, QObject*); void setFileTransferProgress(QString id, const int percentageDone); void setFileTransferStatus(QString id, const ChatWindow::FileTransferState state, const QString& msg); + void setFileTransferWarning(QString id, QString warningText); + void removeFileTransferWarning(QString id); void setWhiteboardSessionStatus(QString id, const ChatWindow::WhiteboardSessionState state); void setMUCInvitationJoined(QString id); void askDesktopToOpenFile(const QString& filename); signals: void gotFocus(); void fontResized(int); void logCleared(); void scrollRequested(int pos); void scrollReachedTop(); void scrollReachedBottom(); public slots: void copySelectionToClipboard(); void handleLinkClicked(const QUrl&); void resetView(); void resetTopInsertPoint(); void increaseFontSize(int numSteps = 1); void decreaseFontSize(); virtual void resizeFont(int fontSizeSteps) SWIFTEN_OVERRIDE; virtual void scrollToBottom() SWIFTEN_OVERRIDE; virtual void handleKeyPressEvent(QKeyEvent* event) SWIFTEN_OVERRIDE; private slots: void handleViewLoadFinished(bool); void handleFrameSizeChanged(); void handleClearRequested(); void handleScrollRequested(int dx, int dy, const QRect& rectToScroll); void handleHTMLButtonClicked(QString id, QString arg1, QString arg2, QString arg3, QString arg4, QString arg5); |