From 9f8937da994a27878a3b1239f815b856227e7dc3 Mon Sep 17 00:00:00 2001 From: Andre Jochems Date: Thu, 9 Jun 2016 12:16:49 +0200 Subject: [PATCH] Twitter Widget added to InfoPage --- casinocoin-qt-windows.pro | 9 +- casinocoin-qt-windows.pro.user | 88 ++------ src/qt/bitcoin.qrc | 6 + src/qt/forms/infopage.ui | 142 ++++++++++--- src/qt/infopage.cpp | 15 +- src/qt/infopage.h | 7 +- src/qt/overviewpage.cpp | 5 +- src/qt/overviewpage.h | 2 +- src/qt/twitter/CasinocoinTwitterFeed.qml | 139 +++++++++++++ src/qt/twitter/FlipBar.qml | 173 ++++++++++++++++ src/qt/twitter/TweetDelegate.qml | 188 ++++++++++++++++++ src/qt/twitter/TweetsModel.qml | 126 ++++++++++++ src/qt/twitter/resources/anonymous.png | Bin 0 -> 1788 bytes .../twitter/resources/bird-anim-sprites.png | Bin 0 -> 11079 bytes src/qt/twitter/resources/icon-clear.png | Bin 0 -> 1166 bytes src/qt/twitter/resources/icon-loading.png | Bin 0 -> 1542 bytes src/qt/twitter/resources/icon-refresh.png | Bin 0 -> 1202 bytes src/qt/twitter/resources/icon-search.png | Bin 0 -> 1284 bytes src/qt/twitter/tweetsearch.js | 62 ++++++ src/qt/twitter/twitterwidget.cpp | 40 ++++ src/qt/twitter/twitterwidget.h | 25 +++ src/qt/walletview.cpp | 2 +- 22 files changed, 919 insertions(+), 110 deletions(-) create mode 100644 src/qt/twitter/CasinocoinTwitterFeed.qml create mode 100644 src/qt/twitter/FlipBar.qml create mode 100644 src/qt/twitter/TweetDelegate.qml create mode 100644 src/qt/twitter/TweetsModel.qml create mode 100644 src/qt/twitter/resources/anonymous.png create mode 100644 src/qt/twitter/resources/bird-anim-sprites.png create mode 100644 src/qt/twitter/resources/icon-clear.png create mode 100644 src/qt/twitter/resources/icon-loading.png create mode 100644 src/qt/twitter/resources/icon-refresh.png create mode 100644 src/qt/twitter/resources/icon-search.png create mode 100644 src/qt/twitter/tweetsearch.js create mode 100644 src/qt/twitter/twitterwidget.cpp create mode 100644 src/qt/twitter/twitterwidget.h diff --git a/casinocoin-qt-windows.pro b/casinocoin-qt-windows.pro index 6ee3b2c..77948ff 100644 --- a/casinocoin-qt-windows.pro +++ b/casinocoin-qt-windows.pro @@ -220,7 +220,8 @@ HEADERS += src/qt/bitcoingui.h \ src/qt/qtquick_controls/cpp/qmlexchangeslistmodel.h \ src/qt/qtquick_controls/cpp/qmlexchangeslistitem.h \ src/qt/qtquick_controls/cpp/guiexchangeslistview.h \ - src/qt/qtquick_controls/cpp/guiexchangescontrol.h + src/qt/qtquick_controls/cpp/guiexchangescontrol.h \ + src/qt/twitter/twitterwidget.h SOURCES += src/qt/bitcoin.cpp \ src/qt/bitcoingui.cpp \ @@ -321,7 +322,8 @@ SOURCES += src/qt/bitcoin.cpp \ src/qt/qtquick_controls/cpp/qmlexchangeslistmodel.cpp \ src/qt/qtquick_controls/cpp/qmlexchangeslistitem.cpp \ src/qt/qtquick_controls/cpp/guiexchangeslistview.cpp \ - src/qt/qtquick_controls/cpp/guiexchangescontrol.cpp + src/qt/qtquick_controls/cpp/guiexchangescontrol.cpp \ + src/qt/twitter/twitterwidget.cpp RESOURCES += src/qt/bitcoin.qrc @@ -357,7 +359,8 @@ OTHER_FILES += README.md \ src/qt/qtquick_controls/qml/QmlGUIExchangesWindow.qml \ src/qt/qtquick_controls/qml/QmlGUIMenuToolbarWindow.qml \ src/qt/qtquick_controls/qml/QmlGUIMenuToolbarListView.qml \ - src/qt/qtquick_controls/qml/QmlGUIMenuToolbarControl.qml + src/qt/qtquick_controls/qml/QmlGUIMenuToolbarControl.qml \ + src/qt/twitter/*.qml DISTFILES += \ QmlImports.qml diff --git a/casinocoin-qt-windows.pro.user b/casinocoin-qt-windows.pro.user index eed2bdd..86fc534 100644 --- a/casinocoin-qt-windows.pro.user +++ b/casinocoin-qt-windows.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -40,6 +40,7 @@ true false 0 + true true 0 8 @@ -58,14 +59,14 @@ ProjectExplorer.Project.Target.0 - Desktop Qt MinGW-w64 32bit (MSYS2) - Desktop Qt MinGW-w64 32bit (MSYS2) - qt.M2_MinGW-w64_i686_kit - 0 + Qt 5.6.0 (mingw32) + Qt 5.6.0 (mingw32) + {b3cf2641-46bb-4b28-b7a6-2713d9074823} + 1 0 0 - C:/Users/a.jochems/Documents/GitHub/casinocoin-issue-18 + true @@ -73,61 +74,7 @@ QtProjectManager.QMakeBuildStep true - USE_UPNP=0 USE_QRCODE=1 USE_IPV6=1 - false - false - false - - - true - Make - - Qt4ProjectManager.MakeStep - - false - - - - 2 - Build - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - true - clean - - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Debug - - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - - C:/Users/a.jochems/Documents/GitHub/build-casinocoin-qt-windows-Desktop_Qt_MinGW_w64_32bit_MSYS2-Release - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - + "USE_UPNP=0" "USE_QRCODE=1" "USE_IPV6=1" false false false @@ -172,8 +119,8 @@ 0 true - - C:/Users/a.jochems/Documents/GitHub/build-casinocoin-qt-windows-Desktop_Qt_MinGW_w64_32bit_MSYS2-Profile + + C:/Users/a.jochems/Documents/GitHub/casinocoin-development true @@ -181,9 +128,9 @@ QtProjectManager.QMakeBuildStep true - + "USE_UPNP=0" "USE_QRCODE=1" "USE_IPV6=1" false - true + false false @@ -220,13 +167,13 @@ 2 false - Profile + Debug Qt4ProjectManager.Qt4BuildConfiguration - 0 + 2 true - 3 + 2 0 @@ -242,6 +189,7 @@ 1 + false false 1000 @@ -284,13 +232,13 @@ casinocoin-qt-windows - Qt4ProjectManager.Qt4RunConfiguration:C:/Users/a.jochems/Documents/GitHub/casinocoin-issue-18/casinocoin-qt-windows.pro + Qt4ProjectManager.Qt4RunConfiguration:C:/Users/a.jochems/Documents/GitHub/casinocoin-development/casinocoin-qt-windows.pro true casinocoin-qt-windows.pro false - false + C:/Users/a.jochems/Documents/GitHub/casinocoin-development 3768 false true diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index cf1cefd..ceefd75 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -135,5 +135,11 @@ qtquick_controls/qml/QmlGUIExchangesWindow.qml qtquick_controls/qml/QmlGUIExchangesListView.qml qtquick_controls/qml/QmlGUIExchangesControl.qml + twitter/FlipBar.qml + twitter/TweetDelegate.qml + twitter/tweetsearch.js + twitter/TweetsModel.qml + twitter/CasinocoinTwitterFeed.qml + twitter/resources/anonymous.png diff --git a/src/qt/forms/infopage.ui b/src/qt/forms/infopage.ui index cbcea39..4a1925d 100644 --- a/src/qt/forms/infopage.ui +++ b/src/qt/forms/infopage.ui @@ -38,9 +38,9 @@ - - 0 - 0 + + 3 + 1 @@ -58,6 +58,12 @@ + + + 0 + 0 + + 10 @@ -201,33 +207,13 @@ - - - Coin Fiat Value - - - - - - - - 75 - true - - - - - - - - - Coin Value - + @@ -240,7 +226,47 @@ + + + + Coin Fiat Value + + + + + + + + 75 + true + + + + - + + + + + + Estimated Marketcapital + + + + + + + + 75 + true + + + + - + + + + @@ -253,7 +279,7 @@ - + @@ -272,7 +298,7 @@ - + @@ -285,7 +311,7 @@ - + @@ -304,7 +330,7 @@ - + @@ -317,7 +343,7 @@ - + @@ -341,8 +367,64 @@ - + + + + + 2 + 1 + + + + Qt::LeftToRight + + + false + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + color: rgb(166, 27, 31); + + + Twitter + + + + + + + + + + 0 + 1 + + QFrame::StyledPanel diff --git a/src/qt/infopage.cpp b/src/qt/infopage.cpp index a0ad8f7..c4a360d 100644 --- a/src/qt/infopage.cpp +++ b/src/qt/infopage.cpp @@ -8,17 +8,21 @@ #include "main.h" #include "overviewpage.h" #include "qtquick_controls/cpp/guiexchangeswidget.h" +#include "twitter/twitterwidget.h" using namespace std; InfoPage::InfoPage(QWidget *parent) : QDialog(parent), ui(new Ui::InfoPage), - exchangesWidget( 0 ) + exchangesWidget( 0 ), + twitterWidget( 0 ) { ui->setupUi(this); ui->coinInfoBox->setMinimumHeight(250); + ui->twitterFeedBox->setMinimumHeight(250); ui->exchangeInfoBox->setMinimumHeight(250); + createTwitterWidget(); createExchangesWidget(); } @@ -101,6 +105,12 @@ InfoPage::~InfoPage() delete ui; } +void InfoPage::createTwitterWidget() +{ + twitterWidget = new TwitterWidget( this ); + ui->verticalLayoutTwitter->addWidget( twitterWidget->dockQmlToWidget() ); +} + void InfoPage::createExchangesWidget() { exchangesWidget = new GUIExchangesWidget( this ); @@ -108,8 +118,9 @@ void InfoPage::createExchangesWidget() ui->verticalLayoutExchanges->addWidget( exchangesWidget->dockQmlToWidget() ); } -void InfoPage::setCoinValues(QString coinValue, QString coinFiatValue) +void InfoPage::setCoinValues(QString coinValue, QString coinFiatValue, QString marketCapital) { ui->txtCoinValue->setText(coinValue); ui->txtCoinFiatValue->setText(coinFiatValue); + ui->txtEstimatedMarketCapital->setText(marketCapital); } diff --git a/src/qt/infopage.h b/src/qt/infopage.h index 776a5c8..f5910b5 100644 --- a/src/qt/infopage.h +++ b/src/qt/infopage.h @@ -6,6 +6,7 @@ class WalletModel; class ClientModel; class GUIExchangesWidget; +class TwitterWidget; namespace Ui { class InfoPage; @@ -21,7 +22,7 @@ public slots: /** Set number of blocks shown in the UI */ void setNumBlocks(int count, int countOfPeers); /** Set coin values */ - void setCoinValues(const QString coinValue, const QString coinFiatValue); + void setCoinValues(const QString coinValue, const QString coinFiatValue, const QString marketCapital); public: explicit InfoPage(QWidget *parent = 0); @@ -34,8 +35,10 @@ private: WalletModel *walletModel; ClientModel *clientModel; GUIExchangesWidget* exchangesWidget; + TwitterWidget* twitterWidget; - void createExchangesWidget(); + void createTwitterWidget(); + void createExchangesWidget(); double GetNetworkHashRate(int lookup, int height); }; diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 987716b..fdbcadd 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -284,10 +284,13 @@ void OverviewPage::updateFiatBalance(int currency) QString conversionCurrency = QString("Price").append(Currencies::name(currency)); QString coinValue = QString::number( coinInformation.find("PriceBTC").value().toDouble(), 'f', 8 ); double currencyValue = coinInformation.find(conversionCurrency).value().toDouble(); + double marketCapValue = coinInformation.find("MarketCapital").value().toDouble(); // create formated fiat value QString formattedFiatValue = Currencies::format(currency, currencyValue, true, 4, false); + // create formatted market capital value + QString formattedMarketCapital = Currencies::format(Currencies::USD, marketCapValue, true, 2, false); // emit signal for change value - emit coinValueChanged(coinValue, formattedFiatValue); + emit coinValueChanged(coinValue, formattedFiatValue, formattedMarketCapital); // calculate and set fiat balance double fiatBalance = currentBalance * currencyValue; QString fiatBalanceString = Currencies::format(currency,fiatBalance,true, 2, true); diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index dfa1ac2..cfd6b02 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -40,7 +40,7 @@ public slots: signals: void transactionClicked(const QModelIndex &index); - void coinValueChanged(const QString coinValue, const QString formattedCoinFiatValue); + void coinValueChanged(const QString coinValue, const QString formattedCoinFiatValue, const QString marketCapital); private: Ui::OverviewPage *ui; diff --git a/src/qt/twitter/CasinocoinTwitterFeed.qml b/src/qt/twitter/CasinocoinTwitterFeed.qml new file mode 100644 index 0000000..ff92942 --- /dev/null +++ b/src/qt/twitter/CasinocoinTwitterFeed.qml @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import "tweetsearch.js" as Helper +import QtQuick.Controls 1.4 + +Rectangle { + id: id_TwitterRoot + width: parent ? parent.width : 0 + height: parent ? parent.height : 0 + color: GUI20Skin.colorFrameBackground + + property int inAnimDur: 250 + property int counter: 0 + property alias isLoading: tweetsModel.isLoading + property var idx + property var ids + + Component.onCompleted: ids = new Array() + + function idInModel(id) + { + for (var j = 0; j < ids.length; j++) + if (ids[j] === id) + return 1 + return 0 + } + + TweetsModel { + id: tweetsModel + onIsLoaded: { + console.debug("Reload") + idx = new Array() + for (var i = 0; i < tweetsModel.model.count; i++) { + var id = tweetsModel.model.get(i).id + if (!idInModel(id)) + idx.push(i) + } + console.debug(idx.length + " new tweets") + id_TwitterRoot.counter = idx.length + } + } + + Timer { + id: timer + interval: 500; running: id_TwitterRoot.counter; repeat: true + onTriggered: { + id_TwitterRoot.counter--; + var id = tweetsModel.model.get(idx[id_TwitterRoot.counter]).id; + var item = tweetsModel.model.get(id_TwitterRoot.counter); + if(item.retweeted_status != undefined){ + item = item.retweeted_status; + } + mainListView.add( { "statusText": Helper.insertLinks(item.text, item.entities), + "twitterName": item.user.screen_name, + "name" : item.user.name, + "userImage": item.user.profile_image_url, + "source": item.source, + "id": id, + "uri": Helper.insertLinks(item.user.url, item.user.entities), + "published": item.created_at } ); + ids.push(id) + } + } + + Timer { + id: refreshTwitterFeedTimer + interval: 600000; + running: true; + repeat: true; + onTriggered: tweetsModel.reload() + } + + ScrollView { + id: mainScrollView + anchors.fill: id_TwitterRoot + + ListView { + id: mainListView + anchors.fill: mainScrollView + delegate: TweetDelegate { } + model: ListModel { id: finalModel } + + add: Transition { + NumberAnimation { property: "hm"; from: 0; to: 1.0; duration: 300; easing.type: Easing.OutQuad } + PropertyAction { property: "appear"; value: 250 } + } + + onDragEnded: tweetsModel.reload() + + function clear() { + ids = new Array() + model.clear() + } + + function add(obj) { + model.insert(0, obj) + } + } + } +} diff --git a/src/qt/twitter/FlipBar.qml b/src/qt/twitter/FlipBar.qml new file mode 100644 index 0000000..f1e240c --- /dev/null +++ b/src/qt/twitter/FlipBar.qml @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: container + property int animDuration: 300 + property Item front: Item {} + property Item back: Item {} + property real factor: 0.1 // amount the edges fold in for the 3D effect + property alias delta: effect.delta + property Item cur: frontShown ? front : back + property Item noncur: frontShown ? back : front + + function swap() { + var tmp = front; + front = back; + back = tmp; + resync(); + } + + width: cur.width + height: cur.height + onFrontChanged: resync(); + onBackChanged: resync(); + + function resync() {//TODO: Are the items ever actually visible? + back.parent = container; + front.parent = container; + frontShown ? back.visible = false : front.visible = false; + } + + property bool frontShown: true + + onFrontShownChanged: { + back.visible = !frontShown + front.visible = frontShown + } + + function flipUp(start) { + effect.visible = true; + effect.sourceA = effect.source1 + effect.sourceB = effect.source2 + if (start == undefined) + start = 1.0; + deltaAnim.from = start; + deltaAnim.to = 0.0 + dAnim.start(); + frontShown = false; + } + + function flipDown(start) { + effect.visible = true; + effect.sourceA = effect.source1 + effect.sourceB = effect.source2 + if (start == undefined) + start = 0.0; + deltaAnim.from = start; + deltaAnim.to = 1.0 + dAnim.start(); + frontShown = true; + } + + ShaderEffect { + id: effect + width: cur.width + height: cur.height + property real factor: container.factor * width + property real delta: 1.0 + + mesh: GridMesh { resolution: Qt.size(8,2) } + + SequentialAnimation on delta { + id: dAnim + running: false + NumberAnimation { + id: deltaAnim + duration: animDuration//expose anim + } + } + + property variant sourceA: source1 + property variant sourceB: source1 + property variant source1: ShaderEffectSource { + sourceItem: front + hideSource: effect.visible + } + + property variant source2: ShaderEffectSource { + sourceItem: back + hideSource: effect.visible + } + + fragmentShader: " + uniform lowp float qt_Opacity; + uniform sampler2D sourceA; + uniform sampler2D sourceB; + uniform highp float delta; + varying highp vec2 qt_TexCoord0; + void main() { + highp vec4 tex = vec4(qt_TexCoord0.x, qt_TexCoord0.y * 2.0, qt_TexCoord0.x, (qt_TexCoord0.y-0.5) * 2.0); + highp float shade = clamp(delta*2.0, 0.5, 1.0); + highp vec4 col; + if (qt_TexCoord0.y < 0.5) { + col = texture2D(sourceA, tex.xy) * (shade); + } else { + col = texture2D(sourceB, tex.zw) * (1.5 - shade); + col.w = 1.0; + } + gl_FragColor = col * qt_Opacity; + } + " + property real h: height + vertexShader: " + uniform highp float delta; + uniform highp float factor; + uniform highp float h; + uniform highp mat4 qt_Matrix; + attribute highp vec4 qt_Vertex; + attribute highp vec2 qt_MultiTexCoord0; + varying highp vec2 qt_TexCoord0; + void main() { + highp vec4 pos = qt_Vertex; + if (qt_MultiTexCoord0.y == 0.0) + pos.x += factor * (1. - delta) * (qt_MultiTexCoord0.x * -2.0 + 1.0); + else if (qt_MultiTexCoord0.y == 1.0) + pos.x += factor * (delta) * (qt_MultiTexCoord0.x * -2.0 + 1.0); + else + pos.y = delta * h; + gl_Position = qt_Matrix * pos; + qt_TexCoord0 = qt_MultiTexCoord0; + }" + + } +} diff --git a/src/qt/twitter/TweetDelegate.qml b/src/qt/twitter/TweetDelegate.qml new file mode 100644 index 0000000..6c52649 --- /dev/null +++ b/src/qt/twitter/TweetDelegate.qml @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import "tweetsearch.js" as Helper + +Item { + id: container + property real hm: 1.0 + property int appear: -1 + property real startRotation: 1 + + onAppearChanged: { + container.startRotation = 0.5 + flipBar.animDuration = appear; + delayedAnim.start(); + } + + SequentialAnimation { + id: delayedAnim + PauseAnimation { duration: 50 } + ScriptAction { script: flipBar.flipDown(startRotation); } + } + + width: parent ? parent.width : 0 + height: flipBar.height * hm + + FlipBar { + id: flipBar + + property bool flipped: false + delta: startRotation + + anchors.bottom: parent.bottom + width: container.ListView.view ? container.ListView.view.width : 0 + height: Math.max(72, tweet.y + tweet.height + 10) + + front: Rectangle { + width: container.ListView.view ? container.ListView.view.width : 0 + height: Math.max(72, tweet.y + tweet.height + 10) + + Rectangle { color: GUI20Skin.colorToolbarMainGradientEnd; width: parent.width; height: 1 } + Rectangle { color: GUI20Skin.colorToolbarMainGradientEnd; width: parent.width; height: 1; anchors.bottom: parent.bottom } + + Image { + id: placeHolder + source: "resources/anonymous.png" + x: 10; y: 9 + visible: avatar.status != Image.Ready + } + + Image { + id: avatar + source: model.userImage + anchors.fill: placeHolder + MouseArea { + id: mouseArea + anchors.fill: parent + onClicked: { + flipBar.flipUp() + flipBar.flipped = true + } + } + } + + Text { + id: name + text: model.name + anchors { left: avatar.right; leftMargin: 10; top: avatar.top; topMargin: -3 } + font.pixelSize: 12 + font.bold: true + color: GUI20Skin.colorToolbarMainGradientEnd + linkColor: "blue" + } + + Text { + id: tweet + text: model.statusText + anchors { left: avatar.right; leftMargin: 10; top: name.bottom; topMargin: 0; right: parent.right; rightMargin: 10 } + wrapMode: Text.WordWrap + font.pixelSize: 12 + font.bold: false + color: "black" + linkColor: "blue" + onLinkActivated: { + var tag = link.split("https://twitter.com/search?q=%23") + var user = link.split("https://twitter.com/") + if (tag[1] != undefined) { + mainListView.positionViewAtBeginning() + mainListView.clear() + mainListView.autoSearch('tag', tag[1]) + tweetsModel.from = "" + tweetsModel.phrase = "#" + tag[1] + } else if (user[1] != undefined) { + mainListView.positionViewAtBeginning() + mainListView.clear() + mainListView.autoSearch('user', user[1]) + tweetsModel.phrase = "" + tweetsModel.from = user[1] + } else + Qt.openUrlExternally(link) + } + } + } + + back: Rectangle { + width: container.ListView.view ? container.ListView.view.width : 0 + height: Math.max(72, tweet.y + tweet.height + 10) + color: "#be4a25" + + Rectangle { color: "#ff6633"; width: parent.width; height: 1 } + Rectangle { color: "#80341a"; width: parent.width; height: 1; anchors.bottom: parent.bottom } + + Image { + id: avatar2 + source: model.userImage + anchors.right: parent.right + anchors.rightMargin: 10 + y: 9 + MouseArea { + anchors.fill: parent + onClicked: { + flipBar.flipDown() + flipBar.flipped = false + } + } + } + + Text { + id: username + text: model.twitterName + x: 10; anchors { top: avatar2.top; topMargin: -3 } + font.pixelSize: 12 + font.bold: true + color: "black" + linkColor: "blue" + } + + Text { + text: model.source + "
" + Helper.formatDate(model.published) + "
" + model.uri + x: 10; anchors { top: username.bottom; topMargin: 0 } + wrapMode: Text.WordWrap + font.pixelSize: 12 + font.bold: false + color: "#ffc2ad" + linkColor: "blue" + onLinkActivated: Qt.openUrlExternally(link); + } + } + } +} diff --git a/src/qt/twitter/TweetsModel.qml b/src/qt/twitter/TweetsModel.qml new file mode 100644 index 0000000..d4ff925 --- /dev/null +++ b/src/qt/twitter/TweetsModel.qml @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import "tweetsearch.js" as Helper + +Item { + id: wrapper + +//! [auth tokens] + property string consumerKey : "" + property string consumerSecret : "" +//! [auth tokens] + property string bearerToken : "" + + property variant model: tweets + property string from : "CasinocoinNews" + property string phrase : "" + + property int status: XMLHttpRequest.UNSENT + property bool isLoading: status === XMLHttpRequest.LOADING + property bool wasLoading: false + signal isLoaded + + ListModel { id: tweets } + + function encodePhrase(x) { return encodeURIComponent(x); } + + function reload() { + tweets.clear() + + if (from == "" && phrase == "") + return; + +//! [requesting] + var req = new XMLHttpRequest; + req.open("GET", "https://api.twitter.com/1.1/statuses/user_timeline.json?" + + "&count=10&screen_name=" + from); + req.setRequestHeader("Authorization", "Bearer " + bearerToken); + req.onreadystatechange = function() { + status = req.readyState; + if (status === XMLHttpRequest.DONE) { + var objectArray = JSON.parse(req.responseText); + if (objectArray.errors !== undefined) + console.log("Error fetching tweets: " + objectArray.errors[0].message) + else { + for (var key in objectArray) { + var jsonObject = objectArray[key]; + tweets.append(jsonObject); + } + } + if (wasLoading == true) + wrapper.isLoaded() + } + wasLoading = (status === XMLHttpRequest.LOADING); + } + req.send(); +//! [requesting] + } + + onPhraseChanged: reload(); + onFromChanged: reload(); + + Component.onCompleted: { + if (consumerKey === "" || consumerSecret == "") { + bearerToken = encodeURIComponent(Helper.demoToken()) + return; + } + + var authReq = new XMLHttpRequest; + authReq.open("POST", "https://api.twitter.com/oauth2/token"); + authReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); + authReq.setRequestHeader("Authorization", "Basic " + Qt.btoa(consumerKey + ":" + consumerSecret)); + authReq.onreadystatechange = function() { + if (authReq.readyState === XMLHttpRequest.DONE) { + var jsonResponse = JSON.parse(authReq.responseText); + if (jsonResponse.errors !== undefined) + console.log("Authentication error: " + jsonResponse.errors[0].message) + else + { + bearerToken = jsonResponse.access_token; + reload(); + } + } + } + authReq.send("grant_type=client_credentials"); + } + +} diff --git a/src/qt/twitter/resources/anonymous.png b/src/qt/twitter/resources/anonymous.png new file mode 100644 index 0000000000000000000000000000000000000000..88fba26e90d3d793a4113366f3070bb0e31fff2f GIT binary patch literal 1788 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 E0IHsnKL7v# literal 0 HcmV?d00001 diff --git a/src/qt/twitter/resources/icon-search.png b/src/qt/twitter/resources/icon-search.png new file mode 100644 index 0000000000000000000000000000000000000000..e41935a6c16d4555b4f0222751aa176bcfbd3049 GIT binary patch literal 1284 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m{l@EB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%uvD1M9IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr4|esh**NZ(?$0 z9!LbN!`Ii!Gq1QLF)umQ)5TT^Xog;9W{Q=$lbfT3nTxrptFwWjp{t>jk+F%3lcS-L zskxz(i?I<*uSMv>2~2MaLazl*y`aR9TL84#CABECEH%ZgC_h&L>}jh^+-@<& zX&zK>3U0TU;nb@Sbc{YIYLTKECIn1BASOKF0y*%cpPC0u??u3by`u5$ZUzR%GEW!B zkcwMd!nzBa4S0HY@*UtPVJ>e@Y1+VemPJ)LrD>P2fEvf#h8_p=1QxRe=WTZ`xA-?z z=)Pv3@?!Oq=leS<=b87*`2TX|D15%+^)J!Oa$!;HILlhMdacxBQz&7TVQ5rc#=XYF zqo6^S!9;~I;2Q7e{tf(GDaXXZHnONOy=-FOSSSDHrn9=ulA4)`^}R3WzP-Ow>*S5^ z$8N20+N=1VTeo=ir)Y+(Ud^8(uU4`y`YxNPsoA%=$^7!?h-dS>+@jvqGE90_rg--( zsXvsd-t*F=%l@t1%M3T}mfGknr2L0f*gBpm>c=_7oqC)q z|Jifv9gU7(ynSVUo>Z`_2? vB~4nlEN_)Ycz0WP9OsX+`IUcqI|DPrrP=ec^{g1KfXXFLS3j3^P6' + + textForEntity(links[i]) + '' + + text.substring(links[i].indices[1]) + } + return text.replace(/\n/g, '
'); +} diff --git a/src/qt/twitter/twitterwidget.cpp b/src/qt/twitter/twitterwidget.cpp new file mode 100644 index 0000000..e55329b --- /dev/null +++ b/src/qt/twitter/twitterwidget.cpp @@ -0,0 +1,40 @@ +#include "twitterwidget.h" + +#include +#include +#include +#include + +#include "gui20_skin.h" + +TwitterWidget::TwitterWidget(QWidget *parent) + : QWidget(parent) +{ +} + +TwitterWidget::~TwitterWidget() +{ + // member objects are moved to qml engine and it manages their instances +} + +QWidget* TwitterWidget::dockQmlToWidget() +{ + QQuickView* pTwitterWindow = new QQuickView; + QWidget* pPlaceHolder = 0; + if ( pTwitterWindow ) + { + QQmlContext* pContext = pTwitterWindow->rootContext(); + if ( pContext ) + { + pContext->setContextProperty( "GUI20Skin", &GUI20Skin::Instance() ); + } + pTwitterWindow->setSource( QUrl( QStringLiteral( "qrc:/qml/twitter/CasinocoinTwitterFeed.qml" ) ) ); + pPlaceHolder = QWidget::createWindowContainer( pTwitterWindow, this ); + if ( pPlaceHolder ) + { + pPlaceHolder->setMinimumSize( 500, 170 ); + pPlaceHolder->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); + } + } + return pPlaceHolder; +} diff --git a/src/qt/twitter/twitterwidget.h b/src/qt/twitter/twitterwidget.h new file mode 100644 index 0000000..9b5f4fa --- /dev/null +++ b/src/qt/twitter/twitterwidget.h @@ -0,0 +1,25 @@ +#ifndef TWITTERWIDGET_H +#define TWITTERWIDGET_H + +#include + +class TwitterWidget : public QWidget +{ + Q_OBJECT + +public: + TwitterWidget( QWidget *parent = 0) ; + ~TwitterWidget(); + + QWidget* dockQmlToWidget(); + +public slots: + +private: + void registerCustomQmlTypes(); + +private slots: + +}; + +#endif // TWITTERWIDGET_H diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index c256dbc..7beb5a8 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -92,7 +92,7 @@ WalletView::WalletView(QWidget *parent, BitcoinGUI *_gui): // Clicking on "Export" allows to export the transaction list connect(exportButton, SIGNAL(clicked()), transactionView, SLOT(exportClicked())); // subscribe to coin value changes - connect(overviewPage, SIGNAL(coinValueChanged(const QString, const QString)), infoPage, SLOT(setCoinValues(const QString, const QString))); + connect(overviewPage, SIGNAL(coinValueChanged(const QString, const QString, const QString)), infoPage, SLOT(setCoinValues(const QString, const QString, const QString))); gotoOverviewPage(); }