├── src ├── resources │ ├── rs.ico │ ├── retroshare_win.rc │ └── retroshare_win.rc.h ├── qml │ ├── icons │ │ ├── email-128.png │ │ ├── contacts-128.png │ │ ├── star-2-128.png │ │ └── settings-4-128.png │ ├── GxsGroupDelegate.qml │ ├── AppButton.qml │ ├── ApplicationBar.qml │ ├── ChannelGroupDelegate.qml │ ├── GxsIdDelegate.qml │ ├── ForumMsgDelegate.qml │ ├── PostedMsgDelegate.qml │ ├── ChannelMsgDelegate.qml │ ├── ContactBox.qml │ ├── main.qml │ └── GxsService.qml ├── rsqml_main.h ├── models │ ├── forummsgmodel.h │ ├── peermodel.h │ ├── forumgroupmodel.h │ ├── postedgroupmodel.h │ ├── dhtmodel.h │ ├── gxsidmodel.h │ ├── channelgroupmodel.h │ ├── postedmsgmodel.h │ ├── rsapplicationdata.h │ ├── channelmsgmodel.h │ ├── gxsmsgmodel.h │ ├── gxscommentmodel.cc │ ├── gxscommentmodel.h │ ├── forummsgmodel.cc │ ├── gxsgroupmodel.h │ ├── postedgroupmodel.cc │ ├── peermodel.cc │ ├── forumgroupmodel.cc │ ├── postedmsgmodel.cc │ ├── channelgroupmodel.cc │ ├── gxsidmodel.cc │ ├── dhtmodel.cc │ ├── rsmodel.cc │ ├── gxsmsgmodel.cc │ ├── gxsgroupmodel.cc │ └── channelmsgmodel.cc ├── rsqml.qrc ├── rsqml_main.cc ├── notifytxt.h ├── retroshare.cc ├── rsqml.pro └── notifytxt.cc ├── .gitignore ├── README.md └── LICENSE /src/resources/rs.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/rsqml-models/master/src/resources/rs.ico -------------------------------------------------------------------------------- /src/qml/icons/email-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/rsqml-models/master/src/qml/icons/email-128.png -------------------------------------------------------------------------------- /src/qml/icons/contacts-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/rsqml-models/master/src/qml/icons/contacts-128.png -------------------------------------------------------------------------------- /src/qml/icons/star-2-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/rsqml-models/master/src/qml/icons/star-2-128.png -------------------------------------------------------------------------------- /src/qml/icons/settings-4-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/rsqml-models/master/src/qml/icons/settings-4-128.png -------------------------------------------------------------------------------- /src/resources/retroshare_win.rc: -------------------------------------------------------------------------------- 1 | #include "retroshare_win.rc.h" 2 | 3 | IDI_ICON1 ICON "rs.ico" 4 | -------------------------------------------------------------------------------- /src/rsqml_main.h: -------------------------------------------------------------------------------- 1 | #ifndef RSQML_MAIN 2 | #define RSQML_MAIN 3 | 4 | int rsqml_main(int argc, char **argv); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rsqml-models 2 | Example Models for Interfacing between libretroshare and QML 3 | 4 | This repository uses the retroshare-nogui code to launch Retroshare. 5 | A QML Gui is then launched with example interfacing to Forum / Channel / Posted services. 6 | 7 | To compile this code: 8 | 9 | 1) Checkout Retroshare from sourceforge.net 10 | 11 | 2) Clone this repository at the same level as libretroshare / retroshare-nogui. 12 | 13 | 3) qmake; make - like the other repositories 14 | 15 | -------------------------------------------------------------------------------- /src/qml/GxsGroupDelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import "." 3 | 4 | Item { 5 | id: item 6 | property var msgModel: {} 7 | 8 | width: parent.width 9 | height: 50 10 | 11 | Column { 12 | Text { text: 'Name: ' + model.GroupName } 13 | Text { text: 'Number: ' + GroupId } 14 | } 15 | 16 | MouseArea { 17 | hoverEnabled: false 18 | anchors.fill: parent 19 | onClicked: { 20 | item.ListView.view.currentIndex = index 21 | item.msgModel.updateEntries(model.GroupId) 22 | } 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/qml/AppButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import QtQuick.Layouts 1.1 3 | import "." 4 | 5 | Rectangle { 6 | id: appButton 7 | property alias icon: appIcon.source 8 | 9 | signal buttonClicked 10 | 11 | width: parent.height 12 | height: parent.height 13 | color: "#00000000" 14 | 15 | Image { 16 | id: appIcon 17 | anchors.centerIn: parent 18 | width: 25 19 | height: 25 20 | } 21 | MouseArea { 22 | hoverEnabled: false 23 | anchors.fill: parent 24 | onClicked: { 25 | appButton.buttonClicked() 26 | } 27 | } 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/models/forummsgmodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gxsmsgmodel.h" 4 | #include 5 | 6 | 7 | class ForumMsgModel : public GxsMsgModel 8 | { 9 | Q_OBJECT 10 | public: 11 | enum ForumMsgRoles { 12 | MsgRole = GxsMsgModel::MsgExtraRole + 1, 13 | }; 14 | 15 | ForumMsgModel(QObject *parent = 0); 16 | 17 | public slots: 18 | virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; 19 | virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 20 | 21 | protected: 22 | virtual void load(uint32_t token); 23 | virtual QHash roleNames() const; 24 | 25 | std::vector mEntries; 26 | }; 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/rsqml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | qml/main.qml 4 | qml/ContactBox.qml 5 | qml/GxsService.qml 6 | qml/GxsGroupDelegate.qml 7 | qml/ChannelGroupDelegate.qml 8 | qml/ChannelMsgDelegate.qml 9 | qml/ForumMsgDelegate.qml 10 | qml/PostedMsgDelegate.qml 11 | qml/GxsIdDelegate.qml 12 | qml/ApplicationBar.qml 13 | qml/AppButton.qml 14 | 15 | qml/icons/contacts-128.png 16 | qml/icons/settings-4-128.png 17 | qml/icons/star-2-128.png 18 | qml/icons/email-128.png 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/qml/ApplicationBar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import QtQuick.Layouts 1.1 3 | import "." 4 | 5 | Rectangle { 6 | id: status 7 | anchors.fill: parent 8 | color: "#FF7733" 9 | height: 50 10 | 11 | default property alias contents: placeholder.children 12 | 13 | RowLayout { 14 | id: placeholder 15 | spacing: 0 16 | width: 200 17 | height: parent.height 18 | anchors.top: parent.top 19 | anchors.left: parent.left 20 | 21 | } 22 | 23 | ContactBox { 24 | 25 | width: 200 26 | height: parent.height 27 | anchors.top: parent.top 28 | anchors.right: parent.right 29 | 30 | icon: "icons/contacts-128.png" 31 | name: "Harry" 32 | status: "Away" 33 | } 34 | } 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/models/peermodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class PeerModel : public QAbstractListModel 8 | { 9 | Q_OBJECT 10 | public: 11 | enum PeerRoles { 12 | DhtIdRole = Qt::UserRole + 1, 13 | AddrRole, 14 | PeerIdRole 15 | }; 16 | 17 | PeerModel(QObject *parent = 0); 18 | 19 | void addEntry(const RsDhtNetPeer &id); 20 | void updateEntry(const RsDhtNetPeer &update); 21 | 22 | int rowCount(const QModelIndex & parent = QModelIndex()) const; 23 | 24 | QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 25 | 26 | protected: 27 | QHash roleNames() const; 28 | 29 | private: 30 | 31 | std::map mEntries; 32 | }; 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/qml/ChannelGroupDelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import "." 3 | 4 | Item { 5 | id: item 6 | width: parent.width 7 | height: 50 8 | 9 | Column { 10 | Text { text: '' + model.GroupName + '' } 11 | Text { text: GroupId } 12 | } 13 | 14 | MouseArea { 15 | hoverEnabled: false 16 | anchors.fill: parent 17 | onClicked: { 18 | item.ListView.view.currentIndex = index 19 | channelMsgModel.updateEntries(model.GroupId) 20 | console.log("Clicked on Channel GroupId: " + model.GroupId) 21 | } 22 | } 23 | 24 | Rectangle { 25 | width: parent.width 26 | height: 1 27 | color: "#AAAAAA" 28 | anchors.left: parent.left 29 | anchors.top: parent.bottom 30 | } 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/qml/GxsIdDelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import "." 3 | 4 | Item { 5 | id: item 6 | width: parent.width 7 | height: 50 8 | 9 | Column { 10 | Text { text: '' + model.GroupName + '' } 11 | Text { text: GroupId } 12 | } 13 | 14 | MouseArea { 15 | hoverEnabled: false 16 | anchors.fill: parent 17 | onClicked: { 18 | item.ListView.view.currentIndex = index 19 | //channelMsgModel.updateEntries(model.GroupId) 20 | //console.log("Clicked on Channel GroupId: " + model.GroupId) 21 | } 22 | } 23 | 24 | Rectangle { 25 | width: parent.width 26 | height: 1 27 | color: "#AAAAAA" 28 | anchors.left: parent.left 29 | anchors.top: parent.bottom 30 | } 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/models/forumgroupmodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gxsgroupmodel.h" 4 | #include 5 | 6 | 7 | class ForumGroupModel : public GxsGroupModel 8 | { 9 | Q_OBJECT 10 | public: 11 | enum ForumGroupRoles { 12 | DescRole = GxsGroupModel::GroupExtraRole + 1, 13 | }; 14 | 15 | ForumGroupModel(QObject *parent = 0); 16 | 17 | public slots: 18 | //virtual void updateEntries(); 19 | //virtual void createGroup(); 20 | 21 | 22 | 23 | virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; 24 | virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 25 | 26 | protected: 27 | virtual void load(uint32_t token); 28 | virtual QHash roleNames() const; 29 | 30 | std::vector mEntries; 31 | }; 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/models/postedgroupmodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gxsgroupmodel.h" 4 | #include 5 | 6 | 7 | class PostedGroupModel : public GxsGroupModel 8 | { 9 | Q_OBJECT 10 | public: 11 | enum PostedGroupRoles { 12 | DescRole = GxsGroupModel::GroupExtraRole + 1, 13 | }; 14 | 15 | PostedGroupModel(QObject *parent = 0); 16 | 17 | public slots: 18 | //virtual void updateEntries(); 19 | //virtual void createGroup(); 20 | 21 | 22 | 23 | virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; 24 | virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 25 | 26 | protected: 27 | virtual void load(uint32_t token); 28 | virtual QHash roleNames() const; 29 | 30 | std::vector mEntries; 31 | }; 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/models/dhtmodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class DhtModel : public QAbstractListModel 8 | { 9 | Q_OBJECT 10 | public: 11 | enum DhtRoles { 12 | IdRole = Qt::UserRole + 1, 13 | AddrRole, 14 | BucketRole, 15 | PeerFlagsRole, 16 | ExtraFlagsRole 17 | }; 18 | 19 | DhtModel(QObject *parent = 0); 20 | 21 | void updateEntries(uint16_t bucket, std::list &entries); 22 | 23 | int rowCount(const QModelIndex & parent = QModelIndex()) const; 24 | 25 | QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 26 | 27 | protected: 28 | QHash roleNames() const; 29 | 30 | private: 31 | 32 | std::vector > mEntries; 33 | }; 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/models/gxsidmodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gxsgroupmodel.h" 4 | #include 5 | 6 | 7 | class GxsIdModel : public GxsGroupModel 8 | { 9 | Q_OBJECT 10 | public: 11 | enum GxsIdRoles { 12 | PgpKnownRole = GxsGroupModel::GroupExtraRole + 1, 13 | PgpIdRole, 14 | AvatarRole, 15 | ReputationRole, 16 | }; 17 | 18 | GxsIdModel(QObject *parent = 0); 19 | 20 | public slots: 21 | //virtual void updateEntries(); 22 | //virtual void createGroup(); 23 | 24 | virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; 25 | virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 26 | 27 | protected: 28 | virtual void load(uint32_t token); 29 | virtual QHash roleNames() const; 30 | 31 | std::vector mEntries; 32 | }; 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/models/channelgroupmodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gxsgroupmodel.h" 4 | #include 5 | 6 | 7 | class ChannelGroupModel : public GxsGroupModel 8 | { 9 | Q_OBJECT 10 | public: 11 | enum ForumGroupRoles { 12 | DescRole = GxsGroupModel::GroupExtraRole + 1, 13 | ImageRole, 14 | AutoDownloadRole, 15 | }; 16 | 17 | ChannelGroupModel(QObject *parent = 0); 18 | 19 | public slots: 20 | //virtual void updateEntries(); 21 | //virtual void createGroup(); 22 | 23 | 24 | 25 | virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; 26 | virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 27 | 28 | protected: 29 | virtual void load(uint32_t token); 30 | virtual QHash roleNames() const; 31 | 32 | std::vector mEntries; 33 | }; 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/models/postedmsgmodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gxsmsgmodel.h" 4 | #include 5 | 6 | 7 | class PostedMsgModel : public GxsMsgModel 8 | { 9 | Q_OBJECT 10 | public: 11 | enum PostedMsgRoles { 12 | LinkRole = GxsMsgModel::MsgExtraRole + 1, 13 | NotesRole, 14 | 15 | HotScoreRole, 16 | TopScoreRole, 17 | NewScoreRole, 18 | 19 | HaveVotedRole, 20 | UpVotesRole, 21 | DownVotesRole, 22 | CommentsRole, 23 | }; 24 | 25 | PostedMsgModel(QObject *parent = 0); 26 | 27 | public slots: 28 | virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; 29 | virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 30 | 31 | protected: 32 | virtual void load(uint32_t token); 33 | virtual QHash roleNames() const; 34 | 35 | std::vector mEntries; 36 | }; 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/qml/ForumMsgDelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import "." 3 | 4 | Item { 5 | id: msgDelegate 6 | 7 | width: parent.width 8 | height: col.height 9 | 10 | Column { 11 | id: col 12 | Text { text: 'MsgId: ' + AuthorId } 13 | Text { text: 'AuthorId: ' + AuthorId } 14 | Row { 15 | Text { text: 'Name: ' + MsgName } 16 | Text { text: ' PublishTs: ' + PublishTs } 17 | } 18 | Text { 19 | wrapMode: Text.Wrap 20 | text: 'Msg: ' + Msg 21 | } 22 | } 23 | 24 | MouseArea { 25 | hoverEnabled: false 26 | anchors.fill: parent 27 | onClicked: { 28 | item.ListView.view.currentIndex = index 29 | } 30 | } 31 | 32 | Rectangle { 33 | width: parent.width 34 | height: 2 35 | color: "#AAAAAA" 36 | anchors.left: parent.left 37 | anchors.top: parent.bottom 38 | } 39 | 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/models/rsapplicationdata.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class RsApplicationData : public QObject 8 | { 9 | Q_OBJECT 10 | public: 11 | 12 | Q_PROPERTY(QColor backgroundColor 13 | READ backgroundColor 14 | WRITE setBackgroundColor 15 | NOTIFY backgroundColorChanged) 16 | enum DhtRoles { 17 | IdRole = Qt::UserRole + 1, 18 | AddrRole, 19 | BucketRole, 20 | PeerFlagsRole, 21 | ExtraFlagsRole 22 | }; 23 | 24 | DhtModel(QObject *parent = 0); 25 | 26 | void updateEntries(uint16_t bucket, std::list &entries); 27 | 28 | int rowCount(const QModelIndex & parent = QModelIndex()) const; 29 | 30 | QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 31 | 32 | protected: 33 | QHash roleNames() const; 34 | 35 | private: 36 | 37 | std::vector > mEntries; 38 | }; 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/models/channelmsgmodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gxsmsgmodel.h" 4 | #include 5 | 6 | 7 | class ChannelMsgModel : public GxsMsgModel 8 | { 9 | Q_OBJECT 10 | public: 11 | enum ChannelMsgRoles { 12 | MsgRole = GxsMsgModel::MsgExtraRole + 1, 13 | 14 | ThumbnailRole, 15 | NumberFilesRole, 16 | TotalFileSizeRole, 17 | 18 | // This are returned as a StringList... could be handled better. 19 | FileNamesRole, 20 | FileSizesRole, 21 | FileHashesRole, 22 | 23 | // These are not in ChannelPosts Yet - but they should be! 24 | HaveVotedRole, 25 | UpVotesRole, 26 | DownVotesRole, 27 | CommentsRole, 28 | }; 29 | 30 | ChannelMsgModel(QObject *parent = 0); 31 | 32 | public slots: 33 | virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; 34 | virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 35 | 36 | protected: 37 | virtual void load(uint32_t token); 38 | virtual QHash roleNames() const; 39 | 40 | std::vector mEntries; 41 | }; 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/resources/retroshare_win.rc.h: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | * RetroShare is distributed under the following license: 3 | * 4 | * Copyright (C) 20010, RetroShare Team 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 | * Boston, MA 02110-1301, USA. 20 | ****************************************************************/ 21 | 22 | 23 | #define IDI_ICON1 101 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 drbob 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /src/models/gxsmsgmodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | // Low Base Model for any GXS system. 8 | // This includes a basic selection. 9 | 10 | class GxsMsgModel : public QAbstractListModel 11 | { 12 | Q_OBJECT 13 | public: 14 | enum MsgRoles { 15 | GroupIdRole = Qt::UserRole + 1, 16 | MsgIdRole, 17 | ThreadIdRole, 18 | ParentIdRole, 19 | OrigMsgIdRole, 20 | AuthorIdRole, 21 | 22 | MsgNameRole, 23 | PublishTsRole, 24 | MsgFlagsRole, 25 | MsgStatusRole, 26 | ChildTsRole, 27 | 28 | // space for extra ones in Gxs specific subclasses. 29 | MsgExtraRole 30 | }; 31 | 32 | GxsMsgModel(RsTokenService *service, QObject *parent = 0); 33 | 34 | public slots: 35 | void refresh(uint32_t token); 36 | void check_load(); 37 | void updateEntries(QString grpId); 38 | 39 | protected: 40 | virtual void load(const uint32_t token) = 0; 41 | virtual QVariant metadata(const RsMsgMetaData &data, int role) const; 42 | virtual QHash roleNames() const; 43 | 44 | RsTokenService *mService; 45 | uint32_t mToken; 46 | }; 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/models/gxscommentmodel.cc: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | // Low Base Model for any GXS system. 8 | // This includes a basic selection. 9 | 10 | class GxsMsgModel : public QAbstractListModel 11 | { 12 | Q_OBJECT 13 | public: 14 | enum MsgRoles { 15 | GroupIdRole = Qt::UserRole + 1, 16 | MsgIdRole, 17 | ThreadIdRole, 18 | ParentIdRole, 19 | OrigMsgIdRole, 20 | AuthorIdRole, 21 | 22 | MsgNameRole, 23 | PublishTsRole, 24 | MsgFlagsRole, 25 | MsgStatusRole, 26 | ChildTsRole, 27 | 28 | // space for extra ones in Gxs specific subclasses. 29 | MsgExtraRole 30 | }; 31 | 32 | GxsMsgModel(RsTokenService *service, QObject *parent = 0); 33 | 34 | public slots: 35 | void refresh(uint32_t token); 36 | void check_load(); 37 | void updateEntries(QString grpId); 38 | 39 | protected: 40 | virtual void load(const uint32_t token) = 0; 41 | virtual QVariant metadata(const RsMsgMetaData &data, int role) const; 42 | virtual QHash roleNames() const; 43 | 44 | RsTokenService *mService; 45 | uint32_t mToken; 46 | }; 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/models/gxscommentmodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | // Low Base Model for any GXS system. 8 | // This includes a basic selection. 9 | 10 | class GxsMsgModel : public QAbstractListModel 11 | { 12 | Q_OBJECT 13 | public: 14 | enum MsgRoles { 15 | GroupIdRole = Qt::UserRole + 1, 16 | MsgIdRole, 17 | ThreadIdRole, 18 | ParentIdRole, 19 | OrigMsgIdRole, 20 | AuthorIdRole, 21 | 22 | MsgNameRole, 23 | PublishTsRole, 24 | MsgFlagsRole, 25 | MsgStatusRole, 26 | ChildTsRole, 27 | 28 | // space for extra ones in Gxs specific subclasses. 29 | MsgExtraRole 30 | }; 31 | 32 | GxsMsgModel(RsTokenService *service, QObject *parent = 0); 33 | 34 | public slots: 35 | void refresh(uint32_t token); 36 | void check_load(); 37 | void updateEntries(QString grpId); 38 | 39 | protected: 40 | virtual void load(const uint32_t token) = 0; 41 | virtual QVariant metadata(const RsMsgMetaData &data, int role) const; 42 | virtual QHash roleNames() const; 43 | 44 | RsTokenService *mService; 45 | uint32_t mToken; 46 | }; 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/qml/PostedMsgDelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import "." 3 | 4 | Item { 5 | id: msgDelegate 6 | 7 | width: parent.width 8 | height: 150 9 | 10 | Column { 11 | Text { text: 'MsgId: ' + AuthorId } 12 | Text { text: 'AuthorId: ' + AuthorId } 13 | Row { 14 | Text { text: 'Name: ' + MsgName } 15 | Text { text: ' PublishTs: ' + PublishTs } 16 | } 17 | Text { text: 'Link: ' + Link } 18 | Text { text: 'Notes: ' + Notes } 19 | Row { 20 | Text { text: 'Hot: ' + HotScore } 21 | Text { text: ' Top: ' + HotScore } 22 | Text { text: ' New: ' + HotScore } 23 | } 24 | Row { 25 | Text { text: 'HaveVoted: ' + HaveVoted } 26 | Text { text: ' UpVotes: ' + UpVotes } 27 | Text { text: ' DownVotes: ' + DownVotes } 28 | Text { text: ' Comments: ' + Comments } 29 | } 30 | } 31 | 32 | MouseArea { 33 | hoverEnabled: false 34 | anchors.fill: parent 35 | onClicked: { 36 | item.ListView.view.currentIndex = index 37 | } 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/qml/ChannelMsgDelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import "." 3 | 4 | Item { 5 | id: msgDelegate 6 | 7 | width: parent.width 8 | height: 150 9 | 10 | Column { 11 | Text { text: 'MsgId: ' + AuthorId } 12 | Text { text: 'AuthorId: ' + AuthorId } 13 | Row { 14 | Text { text: 'Name: ' + MsgName } 15 | Text { text: ' PublishTs: ' + PublishTs } 16 | } 17 | Text { text: 'Msg: ' + Msg } 18 | Row { 19 | Text { text: 'NumberFiles: ' + NumberFiles } 20 | Text { text: ' TotalFileSize: ' + TotalFileSize } 21 | } 22 | 23 | Text { text: 'FileNames: ' + FileNames } 24 | Text { text: 'FileSizes: ' + FileSizes } 25 | Text { text: 'FileHashes: ' + FileHashes } 26 | Row { 27 | Text { text: 'HaveVoted: ' + HaveVoted } 28 | Text { text: ' UpVotes: ' + UpVotes } 29 | Text { text: ' DownVotes: ' + DownVotes } 30 | Text { text: ' Comments: ' + Comments } 31 | } 32 | } 33 | 34 | MouseArea { 35 | hoverEnabled: false 36 | anchors.fill: parent 37 | onClicked: { 38 | item.ListView.view.currentIndex = index 39 | } 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/models/forummsgmodel.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "forummsgmodel.h" 3 | #include 4 | 5 | #include 6 | 7 | 8 | ForumMsgModel::ForumMsgModel(QObject *parent) 9 | : GxsMsgModel(rsGxsForums->getTokenService(), parent) 10 | { 11 | } 12 | 13 | 14 | void ForumMsgModel::load(uint32_t token) 15 | { 16 | beginResetModel(); 17 | 18 | mEntries.clear(); 19 | rsGxsForums->getMsgData(mToken, mEntries); 20 | 21 | endResetModel(); 22 | } 23 | 24 | 25 | int ForumMsgModel::rowCount(const QModelIndex & parent) const 26 | { 27 | return mEntries.size(); 28 | } 29 | 30 | 31 | QVariant ForumMsgModel::data(const QModelIndex & index, int role) const 32 | { 33 | int idx = index.row(); 34 | if (idx < 0 || idx >= mEntries.size()) 35 | return QVariant(); 36 | 37 | if (role < GxsMsgModel::MsgExtraRole) 38 | { 39 | const RsMsgMetaData &peerData = mEntries[idx].mMeta; 40 | return GxsMsgModel::metadata(peerData, role); 41 | } 42 | 43 | const RsGxsForumMsg &entry = mEntries[idx]; 44 | 45 | //std::cerr << "ForumMsgModel::data() row: " << index.row() << " b#: " << bucketno << " e#: " << entryno; 46 | //std::cerr << std::endl; 47 | 48 | if (role == MsgRole) 49 | return QString::fromStdString(entry.mMsg); 50 | return QVariant(); 51 | } 52 | 53 | 54 | QHash ForumMsgModel::roleNames() const 55 | { 56 | QHash roles = GxsMsgModel::roleNames(); 57 | roles[MsgRole] = "Msg"; 58 | return roles; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/models/gxsgroupmodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | // Low Base Model for any GXS system. 8 | // This includes a basic selection. 9 | 10 | class GxsGroupModel : public QAbstractListModel 11 | { 12 | Q_OBJECT 13 | public: 14 | enum GroupRoles { 15 | GroupIdRole = Qt::UserRole + 1, 16 | GroupNameRole, 17 | GroupFlagsRole, 18 | SignFlagsRole, 19 | PublishTsRole, 20 | AuthorIdRole, 21 | CircleIdRole, 22 | CircleTypeRole, 23 | AuthenFlagsRole, 24 | ParentIdRole, 25 | SubscribeFlagsRole, 26 | SubscribeStatusRole, 27 | // space for extra ones in Gxs specific subclasses. 28 | GroupExtraRole 29 | }; 30 | 31 | GxsGroupModel(RsTokenService *service, QObject *parent = 0); 32 | 33 | public slots: 34 | void refresh(uint32_t token); 35 | void check_load(); 36 | void updateEntries(); 37 | 38 | //virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; 39 | //virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 40 | 41 | protected: 42 | virtual void load(const uint32_t token) = 0; 43 | virtual QVariant metadata(const RsGroupMetaData &data, int role) const; 44 | virtual QHash roleNames() const; 45 | 46 | RsTokenService *mService; 47 | uint32_t mToken; 48 | }; 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/rsqml_main.cc: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "rsqml_main.h" 10 | 11 | #include "models/gxsidmodel.h" 12 | #include "models/forumgroupmodel.h" 13 | #include "models/forummsgmodel.h" 14 | #include "models/channelgroupmodel.h" 15 | #include "models/channelmsgmodel.h" 16 | #include "models/postedgroupmodel.h" 17 | #include "models/postedmsgmodel.h" 18 | 19 | int rsqml_main(int argc, char **argv) 20 | { 21 | QApplication app(argc, argv); 22 | 23 | QQuickView *view = new QQuickView; 24 | view->setResizeMode(QQuickView::SizeRootObjectToView); 25 | 26 | QQmlContext *ctxt = view->rootContext(); 27 | 28 | GxsIdModel gxsIdModel; 29 | gxsIdModel.updateEntries(); 30 | 31 | ForumGroupModel forumGroupModel; 32 | forumGroupModel.updateEntries(); 33 | 34 | ChannelGroupModel channelGroupModel; 35 | channelGroupModel.updateEntries(); 36 | 37 | PostedGroupModel postedGroupModel; 38 | postedGroupModel.updateEntries(); 39 | 40 | ForumMsgModel forumMsgModel; 41 | ChannelMsgModel channelMsgModel; 42 | PostedMsgModel postedMsgModel; 43 | 44 | ctxt->setContextProperty("gxsIdModel", &gxsIdModel); 45 | ctxt->setContextProperty("forumGroupModel", &forumGroupModel); 46 | ctxt->setContextProperty("channelGroupModel", &channelGroupModel); 47 | ctxt->setContextProperty("postedGroupModel", &postedGroupModel); 48 | 49 | ctxt->setContextProperty("forumMsgModel", &forumMsgModel); 50 | ctxt->setContextProperty("channelMsgModel", &channelMsgModel); 51 | ctxt->setContextProperty("postedMsgModel", &postedMsgModel); 52 | 53 | view->setSource(QUrl("qrc:/qml/main.qml")); 54 | view->show(); 55 | 56 | 57 | return app.exec(); 58 | } 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/qml/ContactBox.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import "." 3 | 4 | Item { 5 | 6 | property alias icon: contactIcon.source 7 | property alias name: contactName.text 8 | property alias status: contactStatus.text 9 | 10 | Rectangle { 11 | 12 | anchors.fill: parent 13 | color: "#00000000" 14 | 15 | Image { 16 | id: contactIcon 17 | anchors.verticalCenter: parent.verticalCenter 18 | anchors.left: parent.left 19 | width: 40 20 | height: 40 21 | source: "icons/contacts-128.png" 22 | } 23 | 24 | Rectangle { 25 | height: contactIcon.height 26 | anchors.verticalCenter: parent.verticalCenter 27 | anchors.left: contactIcon.right 28 | color: parent.color 29 | 30 | Text { 31 | id: contactName 32 | text: "Username" 33 | anchors.left: parent.left 34 | anchors.leftMargin: 10 35 | anchors.bottom: contactStatus.top 36 | anchors.bottomMargin: 2 37 | 38 | horizontalAlignment: Text.AlignHCenter 39 | font.pointSize: 14 40 | font.bold: false 41 | color: "#FFFFFF" 42 | } 43 | 44 | Text { 45 | id: contactStatus 46 | text: "Hello world!" 47 | anchors.left: parent.right 48 | anchors.leftMargin: 10 49 | anchors.bottom: parent.bottom 50 | anchors.bottomMargin: 1 51 | 52 | horizontalAlignment: Text.AlignHCenter 53 | font.pointSize: 10 54 | font.bold: false 55 | color: "#FFFFFF" 56 | } 57 | } 58 | } 59 | } 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/models/postedgroupmodel.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "postedgroupmodel.h" 3 | #include 4 | 5 | #include 6 | 7 | 8 | PostedGroupModel::PostedGroupModel(QObject *parent) 9 | : GxsGroupModel(rsPosted->getTokenService(), parent) 10 | { 11 | } 12 | 13 | 14 | void PostedGroupModel::load(uint32_t token) 15 | { 16 | beginResetModel(); 17 | 18 | mEntries.clear(); 19 | 20 | // sort them into Subscription order. 21 | std::vector entries; 22 | rsPosted->getGroupData(mToken, entries); 23 | 24 | std::vector::iterator it; 25 | for(it = entries.begin(); it != entries.end();) 26 | { 27 | if (IS_GROUP_ADMIN(it->mMeta.mSubscribeFlags)) { 28 | mEntries.push_back(*it); 29 | it = entries.erase(it); 30 | } else { 31 | it++; 32 | } 33 | } 34 | 35 | for(it = entries.begin(); it != entries.end();) 36 | { 37 | if (IS_GROUP_SUBSCRIBED(it->mMeta.mSubscribeFlags)) { 38 | mEntries.push_back(*it); 39 | it = entries.erase(it); 40 | } else { 41 | it++; 42 | } 43 | } 44 | 45 | /* add in the last */ 46 | mEntries.insert(mEntries.end(), entries.begin(), entries.end()); 47 | 48 | endResetModel(); 49 | } 50 | 51 | 52 | int PostedGroupModel::rowCount(const QModelIndex & parent) const 53 | { 54 | return mEntries.size(); 55 | } 56 | 57 | 58 | QVariant PostedGroupModel::data(const QModelIndex & index, int role) const 59 | { 60 | int idx = index.row(); 61 | if (idx < 0 || idx >= mEntries.size()) 62 | return QVariant(); 63 | 64 | if (role < GxsGroupModel::GroupExtraRole) 65 | { 66 | const RsGroupMetaData &peerData = mEntries[idx].mMeta; 67 | return GxsGroupModel::metadata(peerData, role); 68 | } 69 | 70 | const RsPostedGroup &entry = mEntries[idx]; 71 | 72 | if (role == DescRole) 73 | return QString::fromStdString(entry.mDescription); 74 | return QVariant(); 75 | } 76 | 77 | 78 | QHash PostedGroupModel::roleNames() const 79 | { 80 | QHash roles = GxsGroupModel::roleNames(); 81 | roles[DescRole] = "Desc"; 82 | return roles; 83 | } 84 | 85 | -------------------------------------------------------------------------------- /src/models/peermodel.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "peermodel.h" 3 | #include 4 | 5 | 6 | PeerModel::PeerModel(QObject *parent) 7 | : QAbstractListModel(parent) 8 | { 9 | } 10 | 11 | void PeerModel::addEntry(const RsDhtNetPeer &entry) 12 | { 13 | beginResetModel(); 14 | 15 | mEntries[entry.mDhtId] = entry; 16 | 17 | endResetModel(); 18 | } 19 | 20 | void PeerModel::updateEntry(const RsDhtNetPeer &entry) 21 | { 22 | std::map::iterator it; 23 | it = mEntries.find(entry.mDhtId); 24 | if (it == mEntries.end()) 25 | { 26 | return addEntry(entry); 27 | } 28 | 29 | /* exists already */ 30 | it->second = entry; 31 | /* which entry is it? */ 32 | int index = 0; 33 | for(; it != mEntries.begin(); it--, index++) ; 34 | 35 | QModelIndex topLeft = createIndex(index, 0); 36 | QModelIndex bottomRight = createIndex(index, 0); 37 | emit dataChanged(topLeft, bottomRight); 38 | } 39 | 40 | 41 | int PeerModel::rowCount(const QModelIndex & parent) const { 42 | return mEntries.size(); 43 | } 44 | 45 | QVariant PeerModel::data(const QModelIndex & index, int role) const 46 | { 47 | if (index.row() < 0 || index.row() >= mEntries.size()) 48 | return QVariant(); 49 | 50 | std::map::const_iterator it; 51 | int i = 0; 52 | for(it = mEntries.begin(); (it != mEntries.end()) && (i < index.row()); it++, i++) ; 53 | 54 | if (it == mEntries.end()) 55 | return QVariant(); 56 | 57 | const RsDhtNetPeer &entry = it->second; 58 | 59 | //std::cerr << "PeerModel::data() row: " << index.row() << " b#: " << bucketno << " e#: " << entryno; 60 | //std::cerr << std::endl; 61 | 62 | if (role == DhtIdRole) 63 | return QString::fromStdString(entry.mDhtId); 64 | else if (role == AddrRole) 65 | return QString::fromStdString("No Addr"); 66 | else if (role == PeerIdRole) 67 | return QString::fromStdString(entry.mRsId); 68 | 69 | return QVariant(); 70 | } 71 | 72 | QHash PeerModel::roleNames() const { 73 | QHash roles; 74 | roles[DhtIdRole] = "dhtid"; 75 | roles[AddrRole] = "addr"; 76 | roles[PeerIdRole] = "peerid"; 77 | return roles; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/models/forumgroupmodel.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "forumgroupmodel.h" 3 | #include 4 | 5 | #include 6 | 7 | 8 | ForumGroupModel::ForumGroupModel(QObject *parent) 9 | : GxsGroupModel(rsGxsForums->getTokenService(), parent) 10 | { 11 | } 12 | 13 | 14 | void ForumGroupModel::load(uint32_t token) 15 | { 16 | beginResetModel(); 17 | 18 | mEntries.clear(); 19 | 20 | // sort them into Subscription order. 21 | std::vector entries; 22 | rsGxsForums->getGroupData(mToken, entries); 23 | 24 | std::vector::iterator it; 25 | for(it = entries.begin(); it != entries.end();) 26 | { 27 | if (IS_GROUP_ADMIN(it->mMeta.mSubscribeFlags)) { 28 | mEntries.push_back(*it); 29 | it = entries.erase(it); 30 | } else { 31 | it++; 32 | } 33 | } 34 | 35 | for(it = entries.begin(); it != entries.end();) 36 | { 37 | if (IS_GROUP_SUBSCRIBED(it->mMeta.mSubscribeFlags)) { 38 | mEntries.push_back(*it); 39 | it = entries.erase(it); 40 | } else { 41 | it++; 42 | } 43 | } 44 | 45 | /* add in the last */ 46 | mEntries.insert(mEntries.end(), entries.begin(), entries.end()); 47 | 48 | endResetModel(); 49 | } 50 | 51 | 52 | int ForumGroupModel::rowCount(const QModelIndex & parent) const 53 | { 54 | return mEntries.size(); 55 | } 56 | 57 | 58 | QVariant ForumGroupModel::data(const QModelIndex & index, int role) const 59 | { 60 | int idx = index.row(); 61 | if (idx < 0 || idx >= mEntries.size()) 62 | return QVariant(); 63 | 64 | if (role < GxsGroupModel::GroupExtraRole) 65 | { 66 | const RsGroupMetaData &peerData = mEntries[idx].mMeta; 67 | return GxsGroupModel::metadata(peerData, role); 68 | } 69 | 70 | const RsGxsForumGroup &entry = mEntries[idx]; 71 | 72 | //std::cerr << "ForumGroupModel::data() row: " << index.row() << " b#: " << bucketno << " e#: " << entryno; 73 | //std::cerr << std::endl; 74 | 75 | if (role == DescRole) 76 | return QString::fromStdString(entry.mDescription); 77 | return QVariant(); 78 | } 79 | 80 | 81 | QHash ForumGroupModel::roleNames() const 82 | { 83 | QHash roles = GxsGroupModel::roleNames(); 84 | roles[DescRole] = "Desc"; 85 | return roles; 86 | } 87 | 88 | -------------------------------------------------------------------------------- /src/models/postedmsgmodel.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "postedmsgmodel.h" 3 | #include 4 | 5 | #include 6 | 7 | 8 | PostedMsgModel::PostedMsgModel(QObject *parent) 9 | : GxsMsgModel(rsPosted->getTokenService(), parent) 10 | { 11 | } 12 | 13 | 14 | void PostedMsgModel::load(uint32_t token) 15 | { 16 | beginResetModel(); 17 | 18 | mEntries.clear(); 19 | rsPosted->getPostData(mToken, mEntries); 20 | 21 | endResetModel(); 22 | } 23 | 24 | 25 | int PostedMsgModel::rowCount(const QModelIndex & parent) const 26 | { 27 | return mEntries.size(); 28 | } 29 | 30 | 31 | QVariant PostedMsgModel::data(const QModelIndex & index, int role) const 32 | { 33 | int idx = index.row(); 34 | if (idx < 0 || idx >= mEntries.size()) 35 | return QVariant(); 36 | 37 | if (role < GxsMsgModel::MsgExtraRole) 38 | { 39 | const RsMsgMetaData &peerData = mEntries[idx].mMeta; 40 | return GxsMsgModel::metadata(peerData, role); 41 | } 42 | 43 | const RsPostedPost &entry = mEntries[idx]; 44 | 45 | if (role == LinkRole) 46 | { 47 | return QString::fromStdString(entry.mLink); 48 | } 49 | else if (role == NotesRole) 50 | { 51 | return QString::fromUtf8(entry.mNotes.c_str()); 52 | } 53 | else if (role == HotScoreRole) 54 | { 55 | return QVariant(entry.mHotScore); 56 | } 57 | else if (role == TopScoreRole) 58 | { 59 | return QVariant(entry.mTopScore); 60 | } 61 | else if (role == NewScoreRole) 62 | { 63 | return QVariant(entry.mNewScore); 64 | } 65 | else if (role == HaveVotedRole) 66 | { 67 | bool v = entry.mHaveVoted; 68 | return QVariant(v); 69 | } 70 | else if (role == UpVotesRole) 71 | { 72 | uint32_t v = entry.mUpVotes; 73 | return QVariant(v); 74 | } 75 | else if (role ==DownVotesRole) 76 | { 77 | uint32_t v = entry.mDownVotes; 78 | return QVariant(v); 79 | } 80 | else if (role ==CommentsRole) 81 | { 82 | uint32_t v = entry.mComments; 83 | return QVariant(v); 84 | } 85 | 86 | return QVariant(); 87 | } 88 | 89 | 90 | QHash PostedMsgModel::roleNames() const 91 | { 92 | QHash roles = GxsMsgModel::roleNames(); 93 | roles[LinkRole] = "Link"; 94 | roles[NotesRole] = "Notes"; 95 | 96 | roles[HotScoreRole] = "HotScore"; 97 | roles[TopScoreRole] = "TopScore"; 98 | roles[NewScoreRole] = "NewScore"; 99 | 100 | roles[HaveVotedRole] = "HaveVoted"; 101 | roles[UpVotesRole] = "UpVotes"; 102 | roles[DownVotesRole] = "DownVotes"; 103 | roles[CommentsRole] = "Comments"; 104 | 105 | return roles; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /src/notifytxt.h: -------------------------------------------------------------------------------- 1 | #ifndef RSIFACE_NOTIFY_TXT_H 2 | #define RSIFACE_NOTIFY_TXT_H 3 | /* 4 | * "$Id: notifytxt.h,v 1.1 2007-02-19 20:08:30 rmf24 Exp $" 5 | * 6 | * RetroShare C++ Interface. 7 | * 8 | * Copyright 2004-2006 by Robert Fernie. 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Library General Public 12 | * License Version 2 as published by the Free Software Foundation. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Library General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Library General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 22 | * USA. 23 | * 24 | * Please report all bugs and problems to "retroshare@lunamutt.com". 25 | * 26 | */ 27 | 28 | 29 | #include 30 | #include 31 | #include "util/rsthreads.h" 32 | 33 | #include 34 | 35 | class NotifyTxt: public NotifyClient 36 | { 37 | public: 38 | NotifyTxt():mNotifyMtx("NotifyMtx") { return; } 39 | virtual ~NotifyTxt() { return; } 40 | 41 | virtual void notifyListChange(int list, int type); 42 | virtual void notifyErrorMsg(int list, int sev, std::string msg); 43 | virtual void notifyChat(); 44 | virtual bool askForPassword(const std::string& question, bool prev_is_bad, std::string& password); 45 | virtual bool askForPluginConfirmation(const std::string& plugin_file, const std::string& plugin_hash); 46 | 47 | virtual void notifyTurtleSearchResult(uint32_t search_id,const std::list& found_files); 48 | 49 | /* interface for handling SearchResults */ 50 | void getSearchIds(std::list &searchIds); 51 | 52 | int getSearchResultCount(uint32_t id); 53 | int getSearchResults(uint32_t id, std::list &searchResults); 54 | 55 | // only collect results for selected searches. 56 | // will drop others. 57 | int collectSearchResults(uint32_t searchId); 58 | int clearSearchId(uint32_t searchId); 59 | 60 | 61 | private: 62 | 63 | void displayNeighbours(); 64 | void displayFriends(); 65 | void displayDirectories(); 66 | void displaySearch(); 67 | void displayMessages(); 68 | void displayChannels(); 69 | void displayTransfers(); 70 | 71 | /* store TurtleSearchResults */ 72 | RsMutex mNotifyMtx; 73 | 74 | std::map > mSearchResults; 75 | }; 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /src/models/channelgroupmodel.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "channelgroupmodel.h" 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | ChannelGroupModel::ChannelGroupModel(QObject *parent) 11 | : GxsGroupModel(rsGxsChannels->getTokenService(), parent) 12 | { 13 | } 14 | 15 | 16 | void ChannelGroupModel::load(uint32_t token) 17 | { 18 | beginResetModel(); 19 | 20 | mEntries.clear(); 21 | 22 | // sort them into Subscription order. 23 | std::vector entries; 24 | rsGxsChannels->getGroupData(mToken, entries); 25 | 26 | std::vector::iterator it; 27 | for(it = entries.begin(); it != entries.end();) 28 | { 29 | if (IS_GROUP_ADMIN(it->mMeta.mSubscribeFlags)) { 30 | mEntries.push_back(*it); 31 | it = entries.erase(it); 32 | } else { 33 | it++; 34 | } 35 | } 36 | 37 | for(it = entries.begin(); it != entries.end();) 38 | { 39 | if (IS_GROUP_SUBSCRIBED(it->mMeta.mSubscribeFlags)) { 40 | mEntries.push_back(*it); 41 | it = entries.erase(it); 42 | } else { 43 | it++; 44 | } 45 | } 46 | 47 | /* add in the last */ 48 | mEntries.insert(mEntries.end(), entries.begin(), entries.end()); 49 | 50 | endResetModel(); 51 | } 52 | 53 | 54 | int ChannelGroupModel::rowCount(const QModelIndex & parent) const 55 | { 56 | return mEntries.size(); 57 | } 58 | 59 | 60 | QVariant ChannelGroupModel::data(const QModelIndex & index, int role) const 61 | { 62 | int idx = index.row(); 63 | if (idx < 0 || idx >= mEntries.size()) 64 | return QVariant(); 65 | 66 | if (role < GxsGroupModel::GroupExtraRole) 67 | { 68 | const RsGroupMetaData &peerData = mEntries[idx].mMeta; 69 | return GxsGroupModel::metadata(peerData, role); 70 | } 71 | 72 | const RsGxsChannelGroup &entry = mEntries[idx]; 73 | 74 | //std::cerr << "ChannelGroupModel::data() row: " << index.row() << " b#: " << bucketno << " e#: " << entryno; 75 | //std::cerr << std::endl; 76 | 77 | if (role == DescRole) 78 | { 79 | return QString::fromStdString(entry.mDescription); 80 | } 81 | else if (role == ImageRole) 82 | { 83 | QPixmap pix ; 84 | if (entry.mImage.mSize == 0 || !pix.loadFromData(entry.mImage.mData, entry.mImage.mSize, "PNG")) 85 | { 86 | QVariant(); 87 | } 88 | return pix; 89 | } 90 | else if (role == AutoDownloadRole) 91 | { 92 | return QVariant(entry.mAutoDownload); 93 | } 94 | return QVariant(); 95 | } 96 | 97 | 98 | QHash ChannelGroupModel::roleNames() const 99 | { 100 | QHash roles = GxsGroupModel::roleNames(); 101 | roles[DescRole] = "Desc"; 102 | roles[ImageRole] = "Image"; 103 | roles[AutoDownloadRole] = "AutoDownload"; 104 | 105 | return roles; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /src/models/gxsidmodel.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "gxsidmodel.h" 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | GxsIdModel::GxsIdModel(QObject *parent) 11 | : GxsGroupModel(rsIdentity->getTokenService(), parent) 12 | { 13 | } 14 | 15 | 16 | void GxsIdModel::load(uint32_t token) 17 | { 18 | beginResetModel(); 19 | 20 | mEntries.clear(); 21 | 22 | // sort them into Subscription order. 23 | std::vector entries; 24 | rsIdentity->getGroupData(mToken, entries); 25 | 26 | std::vector::iterator it; 27 | for(it = entries.begin(); it != entries.end();) 28 | { 29 | if (IS_GROUP_ADMIN(it->mMeta.mSubscribeFlags)) { 30 | mEntries.push_back(*it); 31 | it = entries.erase(it); 32 | } else { 33 | it++; 34 | } 35 | } 36 | 37 | for(it = entries.begin(); it != entries.end();) 38 | { 39 | if (IS_GROUP_SUBSCRIBED(it->mMeta.mSubscribeFlags)) { 40 | mEntries.push_back(*it); 41 | it = entries.erase(it); 42 | } else { 43 | it++; 44 | } 45 | } 46 | 47 | /* add in the last */ 48 | mEntries.insert(mEntries.end(), entries.begin(), entries.end()); 49 | 50 | endResetModel(); 51 | } 52 | 53 | 54 | int GxsIdModel::rowCount(const QModelIndex & parent) const 55 | { 56 | return mEntries.size(); 57 | } 58 | 59 | 60 | QVariant GxsIdModel::data(const QModelIndex & index, int role) const 61 | { 62 | int idx = index.row(); 63 | if (idx < 0 || idx >= mEntries.size()) 64 | return QVariant(); 65 | 66 | if (role < GxsGroupModel::GroupExtraRole) 67 | { 68 | const RsGroupMetaData &peerData = mEntries[idx].mMeta; 69 | return GxsGroupModel::metadata(peerData, role); 70 | } 71 | 72 | const RsGxsIdGroup &entry = mEntries[idx]; 73 | 74 | //std::cerr << "GxsIdModel::data() row: " << index.row() << " b#: " << bucketno << " e#: " << entryno; 75 | //std::cerr << std::endl; 76 | 77 | if (role == PgpKnownRole) 78 | { 79 | return QVariant(entry.mPgpKnown); 80 | } 81 | else if (role == PgpIdRole) 82 | { 83 | return QString::fromStdString(entry.mPgpId.toStdString()); 84 | } 85 | else if (role == AvatarRole) 86 | { 87 | QPixmap pix ; 88 | if (entry.mImage.mSize == 0 || !pix.loadFromData(entry.mImage.mData, entry.mImage.mSize, "PNG")) 89 | { 90 | QVariant(); 91 | } 92 | return pix; 93 | } 94 | else if (role == ReputationRole) 95 | { 96 | return QVariant(entry.mReputation.mOverallScore); 97 | } 98 | 99 | return QVariant(); 100 | } 101 | 102 | 103 | QHash GxsIdModel::roleNames() const 104 | { 105 | QHash roles = GxsGroupModel::roleNames(); 106 | roles[PgpKnownRole] = "PgpKnown"; 107 | roles[PgpIdRole] = "PgpId"; 108 | roles[AvatarRole] = "Avatar"; 109 | roles[ReputationRole] = "Reputation"; 110 | 111 | return roles; 112 | } 113 | 114 | -------------------------------------------------------------------------------- /src/models/dhtmodel.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "dhtmodel.h" 3 | #include 4 | 5 | #define DHT_BUCKET_COUNT 160U 6 | #define DHT_BUCKET_SIZE 10U 7 | 8 | DhtModel::DhtModel(QObject *parent) 9 | : QAbstractListModel(parent) 10 | { 11 | mEntries.resize(DHT_BUCKET_COUNT); 12 | std::vector >::iterator it; 13 | int i = 0; 14 | for(it = mEntries.begin(); it != mEntries.end(); it++, i++) 15 | { 16 | it->resize(DHT_BUCKET_SIZE); 17 | for(int j = 0; j < DHT_BUCKET_SIZE; j++) 18 | { 19 | RsDhtPeer peer; 20 | peer.mBucket = i; 21 | peer.mDhtId = "n/a"; 22 | peer.mAddr = "None"; 23 | (*it)[j] = peer; 24 | } 25 | } 26 | } 27 | 28 | void DhtModel::updateEntries(uint16_t bucketno, std::list &entries) 29 | { 30 | if (bucketno >= DHT_BUCKET_COUNT) 31 | { 32 | return; 33 | } 34 | 35 | std::vector &bucket = mEntries[bucketno]; 36 | 37 | /* sort policy ??? */ 38 | std::list::iterator it; 39 | uint16_t i = 0; 40 | for(it = entries.begin(); (it != entries.end()) && (i < DHT_BUCKET_SIZE); it++, i++) 41 | { 42 | bucket[i] = *it; 43 | } 44 | 45 | // clear rest of the bucket. 46 | for(; i < DHT_BUCKET_SIZE; i++) 47 | { 48 | RsDhtPeer peer; 49 | peer.mBucket = bucketno; 50 | bucket[i] = peer; 51 | } 52 | 53 | QModelIndex topLeft = createIndex((DHT_BUCKET_COUNT - bucketno - 1) * DHT_BUCKET_SIZE, 0); 54 | QModelIndex bottomRight = createIndex((DHT_BUCKET_COUNT - bucketno) * DHT_BUCKET_SIZE, 0); 55 | emit dataChanged(topLeft, bottomRight); 56 | } 57 | 58 | 59 | int DhtModel::rowCount(const QModelIndex & parent) const { 60 | return mEntries.size() * DHT_BUCKET_SIZE; 61 | } 62 | 63 | QVariant DhtModel::data(const QModelIndex & index, int role) const 64 | { 65 | if (index.row() < 0 || index.row() >= mEntries.size() * DHT_BUCKET_SIZE) 66 | return QVariant(); 67 | 68 | int bucketno = index.row() / DHT_BUCKET_SIZE; 69 | int entryno = index.row() - (bucketno * DHT_BUCKET_SIZE); 70 | 71 | //std::cerr << "DhtModel::data() row: " << index.row() << " b#: " << bucketno << " e#: " << entryno; 72 | //std::cerr << std::endl; 73 | 74 | const std::vector &bucket = mEntries[DHT_BUCKET_COUNT - 1 - bucketno]; 75 | const RsDhtPeer &entry = bucket[entryno]; 76 | 77 | if (role == IdRole) 78 | return QString::fromStdString(entry.mDhtId); 79 | else if (role == AddrRole) 80 | return QString::fromStdString(entry.mAddr); 81 | else if (role == BucketRole) 82 | return QString::number(entry.mBucket); 83 | else if (role == PeerFlagsRole) 84 | return QString::number(entry.mPeerFlags, 16); 85 | else if (role == ExtraFlagsRole) 86 | return QString::number(entry.mExtraFlags, 16); 87 | 88 | return QVariant(); 89 | } 90 | 91 | 92 | 93 | QHash DhtModel::roleNames() const { 94 | QHash roles; 95 | roles[IdRole] = "id"; 96 | roles[AddrRole] = "addr"; 97 | roles[BucketRole] = "bucket"; 98 | roles[PeerFlagsRole] = "peerflags"; 99 | roles[ExtraFlagsRole] = "extraflags"; 100 | return roles; 101 | } 102 | 103 | -------------------------------------------------------------------------------- /src/models/rsmodel.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "dhtmodel.h" 3 | #include 4 | 5 | #define DHT_BUCKET_COUNT 160U 6 | #define DHT_BUCKET_SIZE 10U 7 | 8 | DhtModel::DhtModel(QObject *parent) 9 | : QAbstractListModel(parent) 10 | { 11 | mEntries.resize(DHT_BUCKET_COUNT); 12 | std::vector >::iterator it; 13 | int i = 0; 14 | for(it = mEntries.begin(); it != mEntries.end(); it++, i++) 15 | { 16 | it->resize(DHT_BUCKET_SIZE); 17 | for(int j = 0; j < DHT_BUCKET_SIZE; j++) 18 | { 19 | RsDhtPeer peer; 20 | peer.mBucket = i; 21 | peer.mDhtId = "n/a"; 22 | peer.mAddr = "None"; 23 | (*it)[j] = peer; 24 | } 25 | } 26 | } 27 | 28 | void DhtModel::updateEntries(uint16_t bucketno, std::list &entries) 29 | { 30 | if (bucketno >= DHT_BUCKET_COUNT) 31 | { 32 | return; 33 | } 34 | 35 | std::vector &bucket = mEntries[bucketno]; 36 | 37 | /* sort policy ??? */ 38 | std::list::iterator it; 39 | uint16_t i = 0; 40 | for(it = entries.begin(); (it != entries.end()) && (i < DHT_BUCKET_SIZE); it++, i++) 41 | { 42 | bucket[i] = *it; 43 | } 44 | 45 | // clear rest of the bucket. 46 | for(; i < DHT_BUCKET_SIZE; i++) 47 | { 48 | RsDhtPeer peer; 49 | peer.mBucket = bucketno; 50 | bucket[i] = peer; 51 | } 52 | 53 | QModelIndex topLeft = createIndex((DHT_BUCKET_COUNT - bucketno - 1) * DHT_BUCKET_SIZE, 0); 54 | QModelIndex bottomRight = createIndex((DHT_BUCKET_COUNT - bucketno) * DHT_BUCKET_SIZE, 0); 55 | emit dataChanged(topLeft, bottomRight); 56 | } 57 | 58 | 59 | int DhtModel::rowCount(const QModelIndex & parent) const { 60 | return mEntries.size() * DHT_BUCKET_SIZE; 61 | } 62 | 63 | QVariant DhtModel::data(const QModelIndex & index, int role) const 64 | { 65 | if (index.row() < 0 || index.row() >= mEntries.size() * DHT_BUCKET_SIZE) 66 | return QVariant(); 67 | 68 | int bucketno = index.row() / DHT_BUCKET_SIZE; 69 | int entryno = index.row() - (bucketno * DHT_BUCKET_SIZE); 70 | 71 | //std::cerr << "DhtModel::data() row: " << index.row() << " b#: " << bucketno << " e#: " << entryno; 72 | //std::cerr << std::endl; 73 | 74 | const std::vector &bucket = mEntries[DHT_BUCKET_COUNT - 1 - bucketno]; 75 | const RsDhtPeer &entry = bucket[entryno]; 76 | 77 | if (role == IdRole) 78 | return QString::fromStdString(entry.mDhtId); 79 | else if (role == AddrRole) 80 | return QString::fromStdString(entry.mAddr); 81 | else if (role == BucketRole) 82 | return QString::number(entry.mBucket); 83 | else if (role == PeerFlagsRole) 84 | return QString::number(entry.mPeerFlags, 16); 85 | else if (role == ExtraFlagsRole) 86 | return QString::number(entry.mExtraFlags, 16); 87 | 88 | return QVariant(); 89 | } 90 | 91 | 92 | 93 | QHash DhtModel::roleNames() const { 94 | QHash roles; 95 | roles[IdRole] = "id"; 96 | roles[AddrRole] = "addr"; 97 | roles[BucketRole] = "bucket"; 98 | roles[PeerFlagsRole] = "peerflags"; 99 | roles[ExtraFlagsRole] = "extraflags"; 100 | return roles; 101 | } 102 | 103 | -------------------------------------------------------------------------------- /src/qml/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import QtQuick.Layouts 1.1 3 | import QtQuick.Controls 1.1 4 | import "." 5 | 6 | Rectangle { 7 | id: page 8 | width: 600; height: 400 9 | color: "#FFFFFF" 10 | 11 | Rectangle { 12 | id: header 13 | width: parent.width 14 | anchors.top: parent.top 15 | anchors.left: parent.left 16 | height: 50 17 | 18 | ApplicationBar { 19 | id: status 20 | 21 | AppButton { 22 | icon: "icons/contacts-128.png" 23 | onButtonClicked : { 24 | tabView.currentIndex = 0 25 | } 26 | } 27 | 28 | AppButton { 29 | icon: "icons/settings-4-128.png" 30 | onButtonClicked : { 31 | tabView.currentIndex = 1 32 | } 33 | } 34 | 35 | AppButton { 36 | icon: "icons/email-128.png" 37 | onButtonClicked : { 38 | tabView.currentIndex = 2 39 | } 40 | } 41 | 42 | AppButton { 43 | icon: "icons/star-2-128.png" 44 | onButtonClicked : { 45 | tabView.currentIndex = 3 46 | } 47 | } 48 | 49 | } 50 | 51 | } 52 | 53 | TabView { 54 | id: tabView 55 | width: parent.width 56 | anchors.top: header.bottom 57 | anchors.left: parent.left 58 | anchors.bottom: parent.bottom 59 | tabsVisible: false 60 | 61 | Tab { 62 | id: gxsIds 63 | 64 | GxsService { 65 | title: "Friends" 66 | 67 | groupDelegate: GxsIdDelegate {} 68 | groupModel: gxsIdModel 69 | } 70 | } 71 | 72 | Tab { 73 | id: forum 74 | 75 | GxsService { 76 | title: "Forums" 77 | 78 | // This one uses the default GxsGroupDelegate. 79 | groupModel: forumGroupModel 80 | 81 | msgDelegate: ForumMsgDelegate {} 82 | msgModel: forumMsgModel 83 | } 84 | } 85 | 86 | Tab { 87 | id: channelLinks 88 | GxsService { 89 | title: "Channels" 90 | 91 | // custom GroupDelegate. 92 | groupDelegate: ChannelGroupDelegate {} 93 | groupModel: channelGroupModel 94 | 95 | msgDelegate: ChannelMsgDelegate {} 96 | msgModel: channelMsgModel 97 | } 98 | } 99 | 100 | Tab { 101 | id: postedLinks 102 | 103 | GxsService { 104 | title: "Posted" 105 | 106 | // This one uses the default GxsGroupDelegate. 107 | groupModel: postedGroupModel 108 | 109 | msgDelegate: PostedMsgDelegate {} 110 | msgModel: postedMsgModel 111 | } 112 | } 113 | } 114 | } 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /src/models/gxsmsgmodel.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "gxsmsgmodel.h" 3 | #include 4 | 5 | #include 6 | 7 | 8 | GxsMsgModel::GxsMsgModel(RsTokenService *service, QObject *parent) 9 | :QAbstractListModel(parent), mService(service) 10 | { } 11 | 12 | 13 | void GxsMsgModel::updateEntries(QString grpStrId) 14 | { 15 | 16 | RsGxsGroupId grpId(grpStrId.toStdString()); 17 | std::list groupIds; 18 | groupIds.push_back(grpId); 19 | 20 | uint32_t token; 21 | RsTokReqOptions opts; 22 | opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; 23 | mService->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds); 24 | 25 | refresh(token); 26 | } 27 | 28 | 29 | void GxsMsgModel::refresh(uint32_t token) 30 | { 31 | mToken = token; 32 | QTimer::singleShot(100, this, SLOT(check_load())); 33 | } 34 | 35 | 36 | void GxsMsgModel::check_load() 37 | { 38 | /* check token */ 39 | uint32_t status = mService->requestStatus(mToken); 40 | bool complete = (RsTokenService::GXS_REQUEST_V2_STATUS_FAILED == status) || 41 | (RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE == status); 42 | 43 | if (complete) 44 | { 45 | load(mToken); 46 | } 47 | else 48 | { 49 | QTimer::singleShot(100, this, SLOT(check_load())); 50 | } 51 | } 52 | 53 | 54 | QVariant GxsMsgModel::metadata(const RsMsgMetaData &data, int role) const 55 | { 56 | switch(role) 57 | { 58 | case GroupIdRole: 59 | return QString::fromStdString(data.mGroupId.toStdString()); 60 | break; 61 | case MsgIdRole: 62 | return QString::fromStdString(data.mMsgId.toStdString()); 63 | break; 64 | case ThreadIdRole: 65 | return QString::fromStdString(data.mThreadId.toStdString()); 66 | break; 67 | case ParentIdRole: 68 | return QString::fromStdString(data.mParentId.toStdString()); 69 | break; 70 | case OrigMsgIdRole: 71 | return QString::fromStdString(data.mOrigMsgId.toStdString()); 72 | break; 73 | case AuthorIdRole: 74 | return QString::fromStdString(data.mAuthorId.toStdString()); 75 | break; 76 | 77 | case MsgNameRole: 78 | return QString::fromStdString(data.mMsgName); 79 | break; 80 | case MsgFlagsRole: 81 | return QVariant(data.mMsgFlags); 82 | break; 83 | case MsgStatusRole: 84 | return QVariant(data.mMsgStatus); 85 | break; 86 | case PublishTsRole: 87 | return QVariant((int) data.mPublishTs); 88 | break; 89 | case ChildTsRole: 90 | return QVariant((int) data.mChildTs); 91 | break; 92 | default: 93 | break; 94 | } 95 | 96 | return QVariant(); 97 | } 98 | 99 | 100 | QHash GxsMsgModel::roleNames() const 101 | { 102 | QHash roles; 103 | 104 | roles[GroupIdRole] = "GroupId"; 105 | roles[MsgIdRole] = "MsgId"; 106 | roles[ThreadIdRole] = "ThreadId"; 107 | roles[ParentIdRole] = "ParentId"; 108 | roles[OrigMsgIdRole] = "OrigMsgId"; 109 | roles[AuthorIdRole] = "AuthorId"; 110 | 111 | roles[MsgNameRole] = "MsgName"; 112 | roles[PublishTsRole] = "PublishTs"; 113 | roles[MsgFlagsRole] = "MsgFlags"; 114 | roles[MsgStatusRole] = "MsgStatus"; 115 | roles[ChildTsRole] = "ChildTs"; 116 | 117 | return roles; 118 | } 119 | 120 | -------------------------------------------------------------------------------- /src/models/gxsgroupmodel.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "gxsgroupmodel.h" 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | 9 | GxsGroupModel::GxsGroupModel(RsTokenService *service, QObject *parent) 10 | :QAbstractListModel(parent), mService(service) 11 | { } 12 | 13 | 14 | 15 | void GxsGroupModel::updateEntries() 16 | { 17 | uint32_t token; 18 | RsTokReqOptions opts; 19 | opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; 20 | mService->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts); 21 | 22 | refresh(token); 23 | } 24 | 25 | 26 | void GxsGroupModel::refresh(uint32_t token) 27 | { 28 | mToken = token; 29 | QTimer::singleShot(100, this, SLOT(check_load())); 30 | } 31 | 32 | 33 | void GxsGroupModel::check_load() 34 | { 35 | /* check token */ 36 | uint32_t status = mService->requestStatus(mToken); 37 | bool complete = (RsTokenService::GXS_REQUEST_V2_STATUS_FAILED == status) || 38 | (RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE == status); 39 | 40 | if (complete) 41 | { 42 | load(mToken); 43 | } 44 | else 45 | { 46 | QTimer::singleShot(100, this, SLOT(check_load())); 47 | } 48 | } 49 | 50 | 51 | QVariant GxsGroupModel::metadata(const RsGroupMetaData &data, int role) const 52 | { 53 | switch(role) 54 | { 55 | case GroupIdRole: 56 | return QString::fromStdString(data.mGroupId.toStdString()); 57 | break; 58 | case GroupNameRole: 59 | return QString::fromStdString(data.mGroupName); 60 | break; 61 | case GroupFlagsRole: 62 | return QVariant(data.mGroupFlags); 63 | break; 64 | case SignFlagsRole: 65 | return QVariant(data.mSignFlags); 66 | break; 67 | case PublishTsRole: 68 | return QVariant((int) data.mPublishTs); 69 | break; 70 | case AuthorIdRole: 71 | return QString::fromStdString(data.mAuthorId.toStdString()); 72 | break; 73 | case CircleIdRole: 74 | return QString::fromStdString(data.mCircleId.toStdString()); 75 | break; 76 | case CircleTypeRole: 77 | return QVariant(data.mCircleType); 78 | break; 79 | case AuthenFlagsRole: 80 | return QVariant(data.mAuthenFlags); 81 | break; 82 | case ParentIdRole: 83 | return QString::fromStdString(data.mParentGrpId.toStdString()); 84 | break; 85 | case SubscribeFlagsRole: 86 | return QVariant(data.mSubscribeFlags); 87 | break; 88 | case SubscribeStatusRole: 89 | if (IS_GROUP_ADMIN(data.mSubscribeFlags)) 90 | { 91 | return QString("Own Group"); 92 | } 93 | else if (IS_GROUP_SUBSCRIBED(data.mSubscribeFlags)) 94 | { 95 | return QString("Subscribed"); 96 | } 97 | else 98 | { 99 | return QString("Other"); 100 | } 101 | break; 102 | default: 103 | break; 104 | } 105 | return QVariant(); 106 | } 107 | 108 | 109 | QHash GxsGroupModel::roleNames() const 110 | { 111 | QHash roles; 112 | 113 | roles[GroupIdRole] = "GroupId"; 114 | roles[GroupNameRole] = "GroupName"; 115 | roles[GroupFlagsRole] = "GroupFlags"; 116 | roles[SignFlagsRole] = "SignFlags"; 117 | roles[PublishTsRole] = "PublishTs"; 118 | roles[AuthorIdRole] = "AuthorId"; 119 | roles[CircleIdRole] = "CircleId"; 120 | roles[CircleTypeRole] = "CircleType"; 121 | roles[AuthenFlagsRole] = "AuthenFlags"; 122 | roles[ParentIdRole] = "ParentId"; 123 | roles[SubscribeFlagsRole] = "SubscribeFlags"; 124 | roles[SubscribeStatusRole] = "SubscribeStatus"; 125 | 126 | return roles; 127 | } 128 | 129 | -------------------------------------------------------------------------------- /src/models/channelmsgmodel.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "channelmsgmodel.h" 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | ChannelMsgModel::ChannelMsgModel(QObject *parent) 11 | : GxsMsgModel(rsGxsChannels->getTokenService(), parent) 12 | { 13 | } 14 | 15 | 16 | void ChannelMsgModel::load(uint32_t token) 17 | { 18 | beginResetModel(); 19 | 20 | mEntries.clear(); 21 | rsGxsChannels->getPostData(mToken, mEntries); 22 | 23 | endResetModel(); 24 | } 25 | 26 | 27 | int ChannelMsgModel::rowCount(const QModelIndex & parent) const 28 | { 29 | return mEntries.size(); 30 | } 31 | 32 | 33 | QVariant ChannelMsgModel::data(const QModelIndex & index, int role) const 34 | { 35 | int idx = index.row(); 36 | if (idx < 0 || idx >= mEntries.size()) 37 | return QVariant(); 38 | 39 | if (role < GxsMsgModel::MsgExtraRole) 40 | { 41 | const RsMsgMetaData &peerData = mEntries[idx].mMeta; 42 | return GxsMsgModel::metadata(peerData, role); 43 | } 44 | 45 | const RsGxsChannelPost &entry = mEntries[idx]; 46 | 47 | if (role == MsgRole) 48 | { 49 | return QString::fromStdString(entry.mMsg); 50 | } 51 | else if (role == ThumbnailRole) 52 | { 53 | QPixmap pix ; 54 | if (entry.mThumbnail.mSize == 0 || !pix.loadFromData(entry.mThumbnail.mData, entry.mThumbnail.mSize, "PNG")) 55 | { 56 | QVariant(); 57 | } 58 | return pix; 59 | } 60 | else if (role == NumberFilesRole) 61 | { 62 | return QVariant(entry.mCount); 63 | } 64 | else if (role == TotalFileSizeRole) 65 | { 66 | return QVariant((int) entry.mSize); 67 | } 68 | else if (role == FileNamesRole) 69 | { 70 | QStringList names; 71 | std::list::const_iterator it; 72 | for(it = entry.mFiles.begin(); it != entry.mFiles.end(); it++) 73 | { 74 | names.push_back(QString::fromUtf8(it->mName.c_str())); 75 | } 76 | return names; 77 | } 78 | else if (role == FileSizesRole) 79 | { 80 | QStringList sizes; 81 | std::list::const_iterator it; 82 | for(it = entry.mFiles.begin(); it != entry.mFiles.end(); it++) 83 | { 84 | sizes.push_back(QString::number(it->mSize)); 85 | } 86 | return sizes; 87 | } 88 | else if (role == FileHashesRole) 89 | { 90 | QStringList hashes; 91 | std::list::const_iterator it; 92 | for(it = entry.mFiles.begin(); it != entry.mFiles.end(); it++) 93 | { 94 | hashes.push_back(QString::fromStdString(it->mHash.toStdString())); 95 | } 96 | return hashes; 97 | } 98 | 99 | else if (role == HaveVotedRole) 100 | { 101 | bool v = false; 102 | return QVariant(v); 103 | } 104 | else if (role == UpVotesRole) 105 | { 106 | int v = 0; 107 | return QVariant(v); 108 | } 109 | else if (role ==DownVotesRole) 110 | { 111 | int v = 0; 112 | return QVariant(v); 113 | } 114 | else if (role ==CommentsRole) 115 | { 116 | int v = 0; 117 | return QVariant(v); 118 | } 119 | 120 | return QVariant(); 121 | } 122 | 123 | 124 | QHash ChannelMsgModel::roleNames() const 125 | { 126 | QHash roles = GxsMsgModel::roleNames(); 127 | roles[MsgRole] = "Msg"; 128 | roles[ThumbnailRole] = "Thumbnail"; 129 | roles[NumberFilesRole] = "NumberFiles"; 130 | roles[TotalFileSizeRole] = "TotalFileSize"; 131 | 132 | roles[FileNamesRole] = "FileNames"; 133 | roles[FileSizesRole] = "FileSizes"; 134 | roles[FileHashesRole] = "FileHashes"; 135 | 136 | roles[HaveVotedRole] = "HaveVoted"; 137 | roles[UpVotesRole] = "UpVotes"; 138 | roles[DownVotesRole] = "DownVotes"; 139 | roles[CommentsRole] = "Comments"; 140 | 141 | return roles; 142 | } 143 | 144 | -------------------------------------------------------------------------------- /src/qml/GxsService.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import QtQuick.Layouts 1.1 3 | import QtQuick.Controls 1.1 4 | import "." 5 | 6 | 7 | Item { 8 | id: gxsService 9 | 10 | property alias icon: sideIcon.source 11 | property alias title: sideTitle.text 12 | 13 | property alias groupDelegate: sideList.delegate 14 | property alias groupModel: sideList.model 15 | 16 | property alias msgDelegate: mainList.delegate 17 | property alias msgModel: mainList.model 18 | 19 | RowLayout { 20 | spacing: 0 21 | anchors.fill: parent 22 | 23 | Rectangle { 24 | id: sideBar 25 | width: 200 26 | Layout.fillHeight: true 27 | 28 | Rectangle { 29 | id: sideHeader 30 | width: parent.width 31 | height: 30 32 | 33 | Text { 34 | id: sideTitle 35 | 36 | anchors.verticalCenter: parent.verticalCenter 37 | anchors.left: parent.left 38 | anchors.leftMargin: 10 39 | width: 20 40 | height: 20 41 | text: "Service" 42 | color: "#333333" 43 | } 44 | 45 | Image { 46 | id: sideIcon 47 | anchors.verticalCenter: parent.verticalCenter 48 | anchors.right: parent.right 49 | anchors.rightMargin: 10 50 | width: 20 51 | height: 20 52 | source: "icons/contacts-128.png" 53 | } 54 | } 55 | 56 | Rectangle { 57 | id: sideListBox 58 | width: parent.width 59 | 60 | anchors.top: sideHeader.bottom 61 | anchors.left: parent.left 62 | anchors.right: parent.right 63 | anchors.bottom: parent.bottom 64 | 65 | ListView { 66 | id: sideList 67 | anchors.fill: parent 68 | 69 | delegate: GxsGroupDelegate { 70 | msgModel: mainList.model 71 | } 72 | 73 | // section. 74 | section.property: "SubscribeStatus" 75 | section.criteria: ViewSection.FullString 76 | section.delegate: Rectangle { 77 | width: sideListBox.width 78 | height: childrenRect.height 79 | color: "blue" 80 | 81 | Text { 82 | text: section 83 | font.bold: true 84 | font.pixelSize: 20 85 | } 86 | } 87 | 88 | clip: true 89 | highlight: Rectangle { color: "lightsteelblue"; radius: 5 } 90 | focus: true 91 | 92 | onCurrentItemChanged: { 93 | console.log("SideBar Item Changed on " + gxsService.title) 94 | } 95 | } 96 | } 97 | } 98 | 99 | Rectangle { 100 | Layout.fillWidth: true 101 | Layout.fillHeight: true 102 | 103 | ListView { 104 | id: mainList 105 | anchors.fill: parent 106 | 107 | clip: true 108 | highlight: Rectangle { color: "lightsteelblue"; radius: 5 } 109 | focus: true 110 | onCurrentItemChanged: { 111 | console.log("item changed") 112 | } 113 | } 114 | 115 | } 116 | } 117 | } 118 | 119 | 120 | -------------------------------------------------------------------------------- /src/retroshare.cc: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * "$Id: retroshare.cc,v 1.4 2007-04-21 19:08:51 rmf24 Exp $" 4 | * 5 | * RetroShare C++ Interface. 6 | * 7 | * Copyright 2004-2006 by Robert Fernie. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Library General Public 11 | * License Version 2 as published by the Free Software Foundation. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Library General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Library General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 21 | * USA. 22 | * 23 | * Please report all bugs and problems to "retroshare@lunamutt.com". 24 | * 25 | */ 26 | 27 | #include /* definition of iface */ 28 | #include /* definition of iface */ 29 | 30 | #include "notifytxt.h" 31 | #include "rsqml_main.h" 32 | 33 | #include 34 | #include 35 | #include 36 | #ifdef WINDOWS_SYS 37 | #include 38 | #endif 39 | 40 | 41 | /* Basic instructions for running libretroshare as background thread. 42 | * ******************************************************************* * 43 | * This allows your program to communicate with authenticated peers. 44 | * 45 | * libretroshare's interfaces are defined in libretroshare/src/rsiface. 46 | * This should be the only headers that you need to include. 47 | * 48 | * The startup routine's are defined in rsiface.h 49 | */ 50 | 51 | int main(int argc, char **argv) 52 | { 53 | //return rsqml_main(argc, argv); 54 | 55 | /* Retroshare startup is configured using an RsInit object. 56 | * This is an opaque class, which the user cannot directly tweak 57 | * If you want to peek at whats happening underneath look in 58 | * libretroshare/src/rsserver/p3face-startup.cc 59 | * 60 | * You create it with InitRsConfig(), and delete with CleanupRsConfig() 61 | * InitRetroshare(argv, argc, config) parses the command line options, 62 | * and initialises the config paths. 63 | * 64 | * *** There are several functions that I should add to modify 65 | * **** the config the moment these can only be set via the commandline 66 | * - RsConfigDirectory(...) is probably the most useful. 67 | * - RsConfigNetAddr(...) for setting port, etc. 68 | * - RsConfigOutput(...) for logging and debugging. 69 | * 70 | * Next you need to worry about loading your certificate, or making 71 | * a new one: 72 | * 73 | * RsGenerateCertificate(...) To create a new key, certificate 74 | * LoadPassword(...) set password for existing certificate. 75 | **/ 76 | 77 | bool strictCheck = true; 78 | 79 | RsInit::InitRsConfig(); 80 | int initResult = RsInit::InitRetroShare(argc, argv, strictCheck); 81 | 82 | if (initResult < 0) { 83 | /* Error occured */ 84 | switch (initResult) { 85 | case RS_INIT_AUTH_FAILED: 86 | std::cerr << "RsInit::InitRetroShare AuthGPG::InitAuth failed" << std::endl; 87 | break; 88 | default: 89 | /* Unexpected return code */ 90 | std::cerr << "RsInit::InitRetroShare unexpected return code " << initResult << std::endl; 91 | break; 92 | } 93 | return 1; 94 | } 95 | 96 | /* load password should be called at this point: LoadPassword() 97 | * otherwise loaded from commandline. 98 | */ 99 | 100 | 101 | /* Now setup the libretroshare interface objs 102 | * You will need to create you own NotifyXXX class 103 | * if you want to receive notifications of events */ 104 | 105 | // This is needed to allocate rsNotify, so that it can be used to ask for PGP passphrase 106 | // 107 | RsControl::earlyInitNotificationSystem() ; 108 | 109 | NotifyTxt *notify = new NotifyTxt() ; 110 | rsNotify->registerNotifyClient(notify); 111 | 112 | /* PreferredId => Key + Certificate are loaded into libretroshare */ 113 | 114 | std::string error_string ; 115 | int retVal = RsInit::LockAndLoadCertificates(false,error_string); 116 | switch(retVal) 117 | { 118 | case 0: break; 119 | case 1: std::cerr << "Error: another instance of retroshare is already using this profile" << std::endl; 120 | return 1; 121 | case 2: std::cerr << "An unexpected error occurred while locking the profile" << std::endl; 122 | return 1; 123 | case 3: std::cerr << "An error occurred while login with the profile" << std::endl; 124 | return 1; 125 | default: std::cerr << "Main: Unexpected switch value " << retVal << std::endl; 126 | return 1; 127 | } 128 | 129 | /* Start-up libretroshare server threads */ 130 | RsControl::instance() -> StartupRetroShare(); 131 | 132 | /* pass control to the GUI */ 133 | rsqml_main(argc, argv); 134 | 135 | return 1; 136 | } 137 | 138 | 139 | -------------------------------------------------------------------------------- /src/rsqml.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | TARGET = rsqml 3 | 4 | QT += quick 5 | QT += declarative 6 | QT += widgets 7 | QT += qml 8 | 9 | RCC_DIR = temp/qrc 10 | UI_DIR = temp/ui 11 | MOC_DIR = temp/moc 12 | 13 | 14 | # if you are linking against the libretroshare with gxs. 15 | # this option links against the required sqlite library. 16 | CONFIG += bitdht 17 | CONFIG += gxs 18 | 19 | #CONFIG += debug 20 | debug { 21 | QMAKE_CFLAGS -= -O2 22 | QMAKE_CFLAGS += -O0 23 | QMAKE_CFLAGS += -g 24 | 25 | QMAKE_CXXFLAGS -= -O2 26 | QMAKE_CXXFLAGS += -O0 27 | QMAKE_CXXFLAGS += -g 28 | } 29 | 30 | ################################# Linux ########################################## 31 | linux-* { 32 | #CONFIG += version_detail_bash_script 33 | QMAKE_CXXFLAGS *= -D_FILE_OFFSET_BITS=64 34 | 35 | LIBS += ../../libretroshare/src/lib/libretroshare.a 36 | LIBS += ../../openpgpsdk/src/lib/libops.a -lbz2 37 | LIBS += -lssl -lupnp -lixml -lgnome-keyring 38 | LIBS *= -lcrypto -ldl -lz -lpthread 39 | LIBS *= -rdynamic 40 | 41 | gxs { 42 | SQLCIPHER_OK = $$system(pkg-config --exists sqlcipher && echo yes) 43 | isEmpty(SQLCIPHER_OK) { 44 | # We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database. 45 | 46 | exists(../../../lib/sqlcipher/.libs/libsqlcipher.a) { 47 | 48 | LIBS += ../../../lib/sqlcipher/.libs/libsqlcipher.a 49 | DEPENDPATH += ../../../lib/sqlcipher/src/ 50 | INCLUDEPATH += ../../../lib/sqlcipher/src/ 51 | } else { 52 | message(libsqlcipher.a not found. Compilation will not use SQLCIPHER. Database will be unencrypted.) 53 | DEFINES *= NO_SQLCIPHER 54 | LIBS *= -lsqlite3 55 | } 56 | 57 | } else { 58 | LIBS *= -lsqlcipher 59 | } 60 | } 61 | } 62 | 63 | linux-g++ { 64 | OBJECTS_DIR = temp/linux-g++/obj 65 | } 66 | 67 | linux-g++-64 { 68 | OBJECTS_DIR = temp/linux-g++-64/obj 69 | } 70 | 71 | #################### Cross compilation for windows under Linux ################### 72 | 73 | win32-x-g++ { 74 | OBJECTS_DIR = temp/win32-x-g++/obj 75 | 76 | LIBS += ../../../../lib/win32-x-g++/libretroshare.a 77 | LIBS += ../../../../lib/win32-x-g++/libssl.a 78 | LIBS += ../../../../lib/win32-x-g++/libcrypto.a 79 | LIBS += ../../../../lib/win32-x-g++/libminiupnpc.a 80 | LIBS += ../../../../lib/win32-x-g++/libz.a 81 | LIBS += -L${HOME}/.wine/drive_c/pthreads/lib -lpthreadGCE2 82 | LIBS += -lws2_32 -luuid -lole32 -liphlpapi -lcrypt32 -gdi32 83 | LIBS += -lole32 -lwinmm 84 | 85 | RC_FILE = gui/images/retroshare_win.rc 86 | 87 | DEFINES *= WIN32 88 | } 89 | 90 | #################################### Windows ##################################### 91 | 92 | win32 { 93 | CONFIG += console 94 | OBJECTS_DIR = temp/obj 95 | RCC_DIR = temp/qrc 96 | UI_DIR = temp/ui 97 | MOC_DIR = temp/moc 98 | 99 | PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a 100 | PRE_TARGETDEPS *= ../../openpgpsdk/src/lib/libops.a 101 | 102 | LIBS_DIR = $$PWD/../../../libs 103 | 104 | LIBS += ../../libretroshare/src/lib/libretroshare.a 105 | LIBS += ../../openpgpsdk/src/lib/libops.a -lbz2 106 | LIBS += -L"$$LIBS_DIR/lib" 107 | LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz 108 | # added after bitdht 109 | # LIBS += -lcrypto -lws2_32 -lgdi32 110 | LIBS += -luuid -lole32 -liphlpapi -lcrypt32 111 | LIBS += -lole32 -lwinmm 112 | 113 | PROTOCPATH=$$LIBS_DIR/bin/ 114 | 115 | RC_FILE = resources/retroshare_win.rc 116 | 117 | DEFINES *= WINDOWS_SYS _USE_32BIT_TIME_T 118 | 119 | DEPENDPATH += $$LIBS_DIR/include 120 | INCLUDEPATH += $$LIBS_DIR/include 121 | 122 | gxs { 123 | LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a 124 | LIBS += -lsqlcipher 125 | } 126 | } 127 | 128 | ##################################### MacOS ###################################### 129 | 130 | macx { 131 | # ENABLE THIS OPTION FOR Univeral Binary BUILD. 132 | # CONFIG += ppc x86 133 | 134 | LIBS += -Wl,-search_paths_first 135 | LIBS += ../../libretroshare/src/lib/libretroshare.a 136 | LIBS += ../../openpgpsdk/src/lib/libops.a -lbz2 137 | LIBS += -lssl -lcrypto -lz 138 | LIBS += ../../../miniupnpc-1.0/libminiupnpc.a 139 | LIBS += -framework CoreFoundation 140 | LIBS += -framework Security 141 | 142 | gxs { 143 | # We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database. 144 | # LIBS += ../../../lib/sqlcipher/.libs/libsqlcipher.a 145 | LIBS += ../../../lib/libsqlcipher.a 146 | } 147 | 148 | sshserver { 149 | LIBS += -L../../../lib 150 | #LIBS += -L../../../lib/libssh-0.6.0 151 | } 152 | 153 | QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dstat64=stat -Dstatvfs64=statvfs -Dfopen64=fopen 154 | 155 | } 156 | 157 | ##################################### FreeBSD ###################################### 158 | 159 | freebsd-* { 160 | INCLUDEPATH *= /usr/local/include/gpgme 161 | LIBS *= ../../libretroshare/src/lib/libretroshare.a 162 | LIBS *= -lssl 163 | LIBS *= -lgpgme 164 | LIBS *= -lupnp 165 | LIBS *= -lgnome-keyring 166 | PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a 167 | } 168 | 169 | ##################################### OpenBSD ###################################### 170 | 171 | openbsd-* { 172 | INCLUDEPATH *= /usr/local/include 173 | QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dstat64=stat -Dstatvfs64=statvfs -Dfopen64=fopen 174 | LIBS *= ../../libretroshare/src/lib/libretroshare.a 175 | LIBS *= ../../openpgpsdk/src/lib/libops.a -lbz2 176 | LIBS *= -lssl -lcrypto 177 | LIBS *= -lgpgme 178 | LIBS *= -lupnp 179 | LIBS *= -lgnome-keyring 180 | PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a 181 | PRE_TARGETDEPS *= ../../openpgpsdk/src/lib/libops.a 182 | LIBS *= -rdynamic 183 | } 184 | 185 | 186 | ############################## Common stuff ###################################### 187 | 188 | # bitdht config 189 | bitdht { 190 | LIBS += ../../libbitdht/src/lib/libbitdht.a 191 | } 192 | 193 | DEPENDPATH += . ../../libretroshare/src 194 | INCLUDEPATH += . ../../libretroshare/src 195 | 196 | # rs-nogui 197 | HEADERS += notifytxt.h 198 | SOURCES += notifytxt.cc \ 199 | retroshare.cc 200 | 201 | # rsqml 202 | HEADERS += rsqml_main.h 203 | SOURCES += rsqml_main.cc \ 204 | 205 | # models 206 | HEADERS += models/gxsgroupmodel.h \ 207 | models/gxsmsgmodel.h \ 208 | models/gxsidmodel.h \ 209 | models/forumgroupmodel.h \ 210 | models/forummsgmodel.h \ 211 | models/channelgroupmodel.h \ 212 | models/channelmsgmodel.h \ 213 | models/postedgroupmodel.h \ 214 | models/postedmsgmodel.h 215 | 216 | SOURCES += models/gxsgroupmodel.cc \ 217 | models/gxsmsgmodel.cc \ 218 | models/gxsidmodel.cc \ 219 | models/forumgroupmodel.cc \ 220 | models/forummsgmodel.cc \ 221 | models/channelgroupmodel.cc \ 222 | models/channelmsgmodel.cc \ 223 | models/postedgroupmodel.cc \ 224 | models/postedmsgmodel.cc 225 | 226 | RESOURCES += rsqml.qrc 227 | 228 | win32 { 229 | # must be added after ssh 230 | LIBS += -lcrypto -lws2_32 -lgdi32 231 | } 232 | -------------------------------------------------------------------------------- /src/notifytxt.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * "$Id: notifytxt.cc,v 1.1 2007-02-19 20:08:30 rmf24 Exp $" 3 | * 4 | * RetroShare C++ Interface. 5 | * 6 | * Copyright 2004-2006 by Robert Fernie. 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Library General Public 10 | * License Version 2 as published by the Free Software Foundation. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 20 | * USA. 21 | * 22 | * Please report all bugs and problems to "retroshare@lunamutt.com". 23 | * 24 | */ 25 | 26 | #include 27 | #include "notifytxt.h" 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #ifdef WINDOWS_SYS 36 | #include 37 | #include 38 | 39 | #define PASS_MAX 512 40 | 41 | char *getpass (const char *prompt) 42 | { 43 | static char getpassbuf [PASS_MAX + 1]; 44 | size_t i = 0; 45 | int c; 46 | 47 | if (prompt) { 48 | fputs (prompt, stderr); 49 | fflush (stderr); 50 | } 51 | 52 | for (;;) { 53 | c = _getch (); 54 | if (c == '\r') { 55 | getpassbuf [i] = '\0'; 56 | break; 57 | } 58 | else if (i < PASS_MAX) { 59 | getpassbuf[i++] = c; 60 | } 61 | 62 | if (i >= PASS_MAX) { 63 | getpassbuf [i] = '\0'; 64 | break; 65 | } 66 | } 67 | 68 | if (prompt) { 69 | fputs ("\r\n", stderr); 70 | fflush (stderr); 71 | } 72 | 73 | return getpassbuf; 74 | } 75 | #endif 76 | 77 | void NotifyTxt::notifyErrorMsg(int list, int type, std::string msg) 78 | { 79 | return; 80 | } 81 | 82 | void NotifyTxt::notifyChat() 83 | { 84 | return; 85 | } 86 | 87 | bool NotifyTxt::askForPluginConfirmation(const std::string& plugin_file_name, const std::string& plugin_file_hash) 88 | { 89 | std::cerr << "The following plugin is not registered as accepted or denied. You probably upgraded the main executable or the plugin itself." << std::endl; 90 | std::cerr << " Hash: " << plugin_file_hash << std::endl; 91 | std::cerr << " File: " << plugin_file_name << std::endl; 92 | 93 | char a = 0 ; 94 | while(a != 'y' && a != 'n') 95 | { 96 | std::cerr << "Enable this plugin ? (y/n) :" ; 97 | std::cerr.flush() ; 98 | 99 | a = fgetc(stdin) ; 100 | } 101 | return a == 'y' ; 102 | } 103 | 104 | bool NotifyTxt::askForPassword(const std::string& question, bool prev_is_bad, std::string& password) 105 | { 106 | std::string question1="Please enter your PGP password for key:\n " + question + " :"; 107 | char *passwd = getpass(question1.c_str()) ; 108 | password = passwd; 109 | 110 | return !password.empty(); 111 | } 112 | 113 | 114 | void NotifyTxt::notifyListChange(int list, int type) 115 | { 116 | //std::cerr << "NotifyTxt::notifyListChange()" << std::endl; 117 | switch(list) 118 | { 119 | // case NOTIFY_LIST_NEIGHBOURS: 120 | // displayNeighbours(); 121 | // break; 122 | case NOTIFY_LIST_FRIENDS: 123 | displayFriends(); 124 | break; 125 | case NOTIFY_LIST_DIRLIST_FRIENDS: 126 | displayDirectories(); 127 | break; 128 | case NOTIFY_LIST_SEARCHLIST: 129 | displaySearch(); 130 | break; 131 | case NOTIFY_LIST_MESSAGELIST: 132 | displayMessages(); 133 | break; 134 | case NOTIFY_LIST_CHANNELLIST: 135 | displayChannels(); 136 | break; 137 | case NOTIFY_LIST_TRANSFERLIST: 138 | displayTransfers(); 139 | break; 140 | default: 141 | break; 142 | } 143 | return; 144 | } 145 | 146 | void NotifyTxt::displayNeighbours() 147 | { 148 | std::list neighs; 149 | std::list::iterator it; 150 | 151 | rsPeers->getGPGAllList(neighs); 152 | 153 | std::ostringstream out; 154 | for(it = neighs.begin(); it != neighs.end(); it++) 155 | { 156 | RsPeerDetails detail; 157 | rsPeers->getGPGDetails(*it, detail); 158 | 159 | out << "Neighbour: "; 160 | out << detail; 161 | out << std::endl; 162 | } 163 | std::cerr << out.str(); 164 | } 165 | 166 | void NotifyTxt::displayFriends() 167 | { 168 | std::list ids; 169 | std::list::iterator it; 170 | 171 | rsPeers->getFriendList(ids); 172 | 173 | std::ostringstream out; 174 | for(it = ids.begin(); it != ids.end(); it++) 175 | { 176 | RsPeerDetails detail; 177 | rsPeers->getPeerDetails(*it, detail); 178 | 179 | out << "Neighbour: "; 180 | out << detail; 181 | out << std::endl; 182 | } 183 | std::cerr << out.str(); 184 | } 185 | 186 | void NotifyTxt::displayDirectories() 187 | { 188 | std::ostringstream out; 189 | std::cerr << out.str(); 190 | } 191 | 192 | 193 | void NotifyTxt::displaySearch() 194 | { 195 | std::ostringstream out; 196 | std::cerr << out.str(); 197 | } 198 | 199 | 200 | void NotifyTxt::displayMessages() 201 | { 202 | } 203 | 204 | void NotifyTxt::displayChannels() 205 | { 206 | std::ostringstream out; 207 | std::cerr << out.str(); 208 | } 209 | 210 | 211 | void NotifyTxt::displayTransfers() 212 | { 213 | std::ostringstream out; 214 | std::cerr << out.str(); 215 | } 216 | 217 | 218 | 219 | /******************* Turtle Search Interface **********/ 220 | 221 | void NotifyTxt::notifyTurtleSearchResult(uint32_t search_id,const std::list& found_files) 222 | { 223 | // std::cerr << "NotifyTxt::notifyTurtleSearchResult() " << found_files.size(); 224 | // std::cerr << " new results for Id: " << search_id; 225 | // std::cerr << std::endl; 226 | 227 | RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ 228 | 229 | std::map >::iterator it; 230 | it = mSearchResults.find(search_id); 231 | if (it == mSearchResults.end()) 232 | { 233 | std::cerr << "NotifyTxt::notifyTurtleSearchResult() " << found_files.size(); 234 | std::cerr << "ERROR: new results for Id: " << search_id; 235 | std::cerr << std::endl; 236 | std::cerr << "But list not installed..."; 237 | std::cerr << " DROPPING SEARCH RESULTS"; 238 | std::cerr << std::endl; 239 | 240 | /* new entry */ 241 | //mSearchResults[search_id] = found_files; 242 | return; 243 | } 244 | 245 | /* add to existing entry */ 246 | std::list::const_iterator fit; 247 | for(fit = found_files.begin(); fit != found_files.end(); fit++) 248 | { 249 | it->second.push_back(*fit); 250 | } 251 | return; 252 | } 253 | 254 | 255 | /* interface for handling SearchResults */ 256 | void NotifyTxt::getSearchIds(std::list &searchIds) 257 | { 258 | RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ 259 | 260 | std::map >::iterator it; 261 | for(it = mSearchResults.begin(); it != mSearchResults.end(); it++) 262 | { 263 | searchIds.push_back(it->first); 264 | } 265 | return; 266 | } 267 | 268 | 269 | int NotifyTxt::getSearchResults(uint32_t id, std::list &searchResults) 270 | { 271 | RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ 272 | 273 | std::map >::iterator it; 274 | it = mSearchResults.find(id); 275 | if (it == mSearchResults.end()) 276 | { 277 | return 0; 278 | } 279 | 280 | searchResults = it->second; 281 | return 1; 282 | } 283 | 284 | 285 | int NotifyTxt::getSearchResultCount(uint32_t id) 286 | { 287 | RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ 288 | 289 | std::map >::iterator it; 290 | it = mSearchResults.find(id); 291 | if (it == mSearchResults.end()) 292 | { 293 | return 0; 294 | } 295 | return it->second.size(); 296 | } 297 | 298 | // only collect results for selected searches. 299 | // will drop others. 300 | int NotifyTxt::collectSearchResults(uint32_t searchId) 301 | { 302 | std::cerr << "NotifyTxt::collectSearchResult(" << searchId << ")"; 303 | std::cerr << std::endl; 304 | 305 | RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ 306 | 307 | std::map >::iterator it; 308 | it = mSearchResults.find(searchId); 309 | if (it == mSearchResults.end()) 310 | { 311 | std::list emptyList; 312 | mSearchResults[searchId] = emptyList; 313 | return 1; 314 | } 315 | 316 | std::cerr << "NotifyTxt::collectSearchResult() ERROR Id exists"; 317 | std::cerr << std::endl; 318 | return 1; 319 | } 320 | 321 | int NotifyTxt::clearSearchId(uint32_t searchId) 322 | { 323 | std::cerr << "NotifyTxt::clearSearchId(" << searchId << ")"; 324 | std::cerr << std::endl; 325 | 326 | RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ 327 | 328 | std::map >::iterator it; 329 | it = mSearchResults.find(searchId); 330 | if (it == mSearchResults.end()) 331 | { 332 | std::cerr << "NotifyTxt::clearSearchId() ERROR Id not there"; 333 | std::cerr << std::endl; 334 | return 0; 335 | } 336 | 337 | mSearchResults.erase(it); 338 | return 1; 339 | } 340 | 341 | 342 | --------------------------------------------------------------------------------